1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.telephony.cdma;
18
19import com.android.internal.telephony.TelephonyProperties;
20import com.android.internal.telephony.MccTable;
21import com.android.internal.telephony.EventLogTags;
22import com.android.internal.telephony.uicc.RuimRecords;
23import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
24
25import android.telephony.CellInfo;
26import android.telephony.CellInfoLte;
27import android.telephony.CellSignalStrengthLte;
28import android.telephony.CellIdentityLte;
29import android.telephony.SignalStrength;
30import android.telephony.ServiceState;
31import android.telephony.cdma.CdmaCellLocation;
32import android.text.TextUtils;
33import android.os.AsyncResult;
34import android.os.Message;
35import android.os.SystemClock;
36import android.os.SystemProperties;
37
38import android.telephony.Rlog;
39import android.util.EventLog;
40
41import java.io.FileDescriptor;
42import java.io.PrintWriter;
43import java.util.ArrayList;
44import java.util.List;
45
46public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
47    private CDMALTEPhone mCdmaLtePhone;
48    private final CellInfoLte mCellInfoLte;
49
50    private CellIdentityLte mNewCellIdentityLte = new CellIdentityLte();
51    private CellIdentityLte mLasteCellIdentityLte = new CellIdentityLte();
52
53    public CdmaLteServiceStateTracker(CDMALTEPhone phone) {
54        super(phone, new CellInfoLte());
55        mCdmaLtePhone = phone;
56        mCellInfoLte = (CellInfoLte) mCellInfo;
57
58        ((CellInfoLte)mCellInfo).setCellSignalStrength(new CellSignalStrengthLte());
59        ((CellInfoLte)mCellInfo).setCellIdentity(new CellIdentityLte());
60
61        if (DBG) log("CdmaLteServiceStateTracker Constructors");
62    }
63
64    @Override
65    public void handleMessage(Message msg) {
66        AsyncResult ar;
67        int[] ints;
68        String[] strings;
69
70        if (!mPhone.mIsTheCurrentActivePhone) {
71            loge("Received message " + msg + "[" + msg.what + "]" +
72                    " while being destroyed. Ignoring.");
73            return;
74        }
75
76        switch (msg.what) {
77        case EVENT_POLL_STATE_GPRS:
78            if (DBG) log("handleMessage EVENT_POLL_STATE_GPRS");
79            ar = (AsyncResult)msg.obj;
80            handlePollStateResult(msg.what, ar);
81            break;
82        case EVENT_RUIM_RECORDS_LOADED:
83            updatePhoneObject();
84            RuimRecords ruim = (RuimRecords)mIccRecords;
85            if ((ruim != null) && ruim.isProvisioned()) {
86                mMdn = ruim.getMdn();
87                mMin = ruim.getMin();
88                parseSidNid(ruim.getSid(), ruim.getNid());
89                mPrlVersion = ruim.getPrlVersion();
90                mIsMinInfoReady = true;
91                updateOtaspState();
92            }
93            // SID/NID/PRL is loaded. Poll service state
94            // again to update to the roaming state with
95            // the latest variables.
96            pollState();
97            break;
98        default:
99            super.handleMessage(msg);
100        }
101    }
102
103    /**
104     * Handle the result of one of the pollState()-related requests
105     */
106    @Override
107    protected void handlePollStateResultMessage(int what, AsyncResult ar) {
108        if (what == EVENT_POLL_STATE_GPRS) {
109            String states[] = (String[])ar.result;
110            if (DBG) {
111                log("handlePollStateResultMessage: EVENT_POLL_STATE_GPRS states.length=" +
112                        states.length + " states=" + states);
113            }
114
115            int type = 0;
116            int regState = -1;
117            if (states.length > 0) {
118                try {
119                    regState = Integer.parseInt(states[0]);
120
121                    // states[3] (if present) is the current radio technology
122                    if (states.length >= 4 && states[3] != null) {
123                        type = Integer.parseInt(states[3]);
124                    }
125                } catch (NumberFormatException ex) {
126                    loge("handlePollStateResultMessage: error parsing GprsRegistrationState: "
127                                    + ex);
128                }
129                if (states.length >= 10) {
130                    int mcc;
131                    int mnc;
132                    int tac;
133                    int pci;
134                    int eci;
135                    int csgid;
136                    String operatorNumeric = null;
137
138                    try {
139                        operatorNumeric = mNewSS.getOperatorNumeric();
140                        mcc = Integer.parseInt(operatorNumeric.substring(0,3));
141                    } catch (Exception e) {
142                        try {
143                            operatorNumeric = mSS.getOperatorNumeric();
144                            mcc = Integer.parseInt(operatorNumeric.substring(0,3));
145                        } catch (Exception ex) {
146                            loge("handlePollStateResultMessage: bad mcc operatorNumeric=" +
147                                    operatorNumeric + " ex=" + ex);
148                            operatorNumeric = "";
149                            mcc = Integer.MAX_VALUE;
150                        }
151                    }
152                    try {
153                        mnc = Integer.parseInt(operatorNumeric.substring(3));
154                    } catch (Exception e) {
155                        loge("handlePollStateResultMessage: bad mnc operatorNumeric=" +
156                                operatorNumeric + " e=" + e);
157                        mnc = Integer.MAX_VALUE;
158                    }
159
160                    // Use Integer#decode to be generous in what we receive and allow
161                    // decimal, hex or octal values.
162                    try {
163                        tac = Integer.decode(states[6]);
164                    } catch (Exception e) {
165                        loge("handlePollStateResultMessage: bad tac states[6]=" +
166                                states[6] + " e=" + e);
167                        tac = Integer.MAX_VALUE;
168                    }
169                    try {
170                        pci = Integer.decode(states[7]);
171                    } catch (Exception e) {
172                        loge("handlePollStateResultMessage: bad pci states[7]=" +
173                                states[7] + " e=" + e);
174                        pci = Integer.MAX_VALUE;
175                    }
176                    try {
177                        eci = Integer.decode(states[8]);
178                    } catch (Exception e) {
179                        loge("handlePollStateResultMessage: bad eci states[8]=" +
180                                states[8] + " e=" + e);
181                        eci = Integer.MAX_VALUE;
182                    }
183                    try {
184                        csgid = Integer.decode(states[9]);
185                    } catch (Exception e) {
186                        // FIX: Always bad so don't pollute the logs
187                        // loge("handlePollStateResultMessage: bad csgid states[9]=" +
188                        //        states[9] + " e=" + e);
189                        csgid = Integer.MAX_VALUE;
190                    }
191                    mNewCellIdentityLte = new CellIdentityLte(mcc, mnc, eci, pci, tac);
192                    if (DBG) {
193                        log("handlePollStateResultMessage: mNewLteCellIdentity=" +
194                                mNewCellIdentityLte);
195                    }
196                }
197            }
198
199            mNewSS.setRilDataRadioTechnology(type);
200            int dataRegState = regCodeToServiceState(regState);
201            mNewSS.setDataRegState(dataRegState);
202            if (DBG) {
203                log("handlPollStateResultMessage: CdmaLteSST setDataRegState=" + dataRegState
204                        + " regState=" + regState
205                        + " dataRadioTechnology=" + type);
206            }
207        } else {
208            super.handlePollStateResultMessage(what, ar);
209        }
210    }
211
212    @Override
213    protected void pollState() {
214        mPollingContext = new int[1];
215        mPollingContext[0] = 0;
216
217        switch (mCi.getRadioState()) {
218            case RADIO_UNAVAILABLE:
219                mNewSS.setStateOutOfService();
220                mNewCellLoc.setStateInvalid();
221                setSignalStrengthDefaultValues();
222                mGotCountryCode = false;
223
224                pollStateDone();
225                break;
226
227            case RADIO_OFF:
228                mNewSS.setStateOff();
229                mNewCellLoc.setStateInvalid();
230                setSignalStrengthDefaultValues();
231                mGotCountryCode = false;
232
233                pollStateDone();
234                break;
235
236            default:
237                // Issue all poll-related commands at once, then count
238                // down the responses which are allowed to arrive
239                // out-of-order.
240
241                mPollingContext[0]++;
242                // RIL_REQUEST_OPERATOR is necessary for CDMA
243                mCi.getOperator(obtainMessage(EVENT_POLL_STATE_OPERATOR_CDMA, mPollingContext));
244
245                mPollingContext[0]++;
246                // RIL_REQUEST_VOICE_REGISTRATION_STATE is necessary for CDMA
247                mCi.getVoiceRegistrationState(obtainMessage(EVENT_POLL_STATE_REGISTRATION_CDMA,
248                        mPollingContext));
249
250                mPollingContext[0]++;
251                // RIL_REQUEST_DATA_REGISTRATION_STATE
252                mCi.getDataRegistrationState(obtainMessage(EVENT_POLL_STATE_GPRS,
253                                            mPollingContext));
254                break;
255        }
256    }
257
258    @Override
259    protected void pollStateDone() {
260        log("pollStateDone: lte 1 ss=[" + mSS + "] newSS=[" + mNewSS + "]");
261
262        useDataRegStateForDataOnlyDevices();
263
264        boolean hasRegistered = mSS.getVoiceRegState() != ServiceState.STATE_IN_SERVICE
265                && mNewSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE;
266
267        boolean hasDeregistered = mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE
268                && mNewSS.getVoiceRegState() != ServiceState.STATE_IN_SERVICE;
269
270        boolean hasCdmaDataConnectionAttached =
271            mSS.getDataRegState() != ServiceState.STATE_IN_SERVICE
272                && mNewSS.getDataRegState() == ServiceState.STATE_IN_SERVICE;
273
274        boolean hasCdmaDataConnectionDetached =
275                mSS.getDataRegState() == ServiceState.STATE_IN_SERVICE
276                && mNewSS.getDataRegState() != ServiceState.STATE_IN_SERVICE;
277
278        boolean hasCdmaDataConnectionChanged =
279            mSS.getDataRegState() != mNewSS.getDataRegState();
280
281        boolean hasVoiceRadioTechnologyChanged = mSS.getRilVoiceRadioTechnology()
282                != mNewSS.getRilVoiceRadioTechnology();
283
284        boolean hasDataRadioTechnologyChanged = mSS.getRilDataRadioTechnology()
285                != mNewSS.getRilDataRadioTechnology();
286
287        boolean hasChanged = !mNewSS.equals(mSS);
288
289        boolean hasRoamingOn = !mSS.getRoaming() && mNewSS.getRoaming();
290
291        boolean hasRoamingOff = mSS.getRoaming() && !mNewSS.getRoaming();
292
293        boolean hasLocationChanged = !mNewCellLoc.equals(mCellLoc);
294
295        boolean has4gHandoff =
296                mNewSS.getDataRegState() == ServiceState.STATE_IN_SERVICE &&
297                (((mSS.getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) &&
298                  (mNewSS.getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)) ||
299                 ((mSS.getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD) &&
300                  (mNewSS.getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_LTE)));
301
302        boolean hasMultiApnSupport =
303                (((mNewSS.getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) ||
304                  (mNewSS.getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)) &&
305                 ((mSS.getRilDataRadioTechnology() != ServiceState.RIL_RADIO_TECHNOLOGY_LTE) &&
306                  (mSS.getRilDataRadioTechnology() != ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)));
307
308        boolean hasLostMultiApnSupport =
309            ((mNewSS.getRilDataRadioTechnology() >= ServiceState.RIL_RADIO_TECHNOLOGY_IS95A) &&
310             (mNewSS.getRilDataRadioTechnology() <= ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A));
311
312        if (DBG) {
313            log("pollStateDone:"
314                + " hasRegistered=" + hasRegistered
315                + " hasDeegistered=" + hasDeregistered
316                + " hasCdmaDataConnectionAttached=" + hasCdmaDataConnectionAttached
317                + " hasCdmaDataConnectionDetached=" + hasCdmaDataConnectionDetached
318                + " hasCdmaDataConnectionChanged=" + hasCdmaDataConnectionChanged
319                + " hasVoiceRadioTechnologyChanged= " + hasVoiceRadioTechnologyChanged
320                + " hasDataRadioTechnologyChanged=" + hasDataRadioTechnologyChanged
321                + " hasChanged=" + hasChanged
322                + " hasRoamingOn=" + hasRoamingOn
323                + " hasRoamingOff=" + hasRoamingOff
324                + " hasLocationChanged=" + hasLocationChanged
325                + " has4gHandoff = " + has4gHandoff
326                + " hasMultiApnSupport=" + hasMultiApnSupport
327                + " hasLostMultiApnSupport=" + hasLostMultiApnSupport);
328        }
329        // Add an event log when connection state changes
330        if (mSS.getVoiceRegState() != mNewSS.getVoiceRegState()
331                || mSS.getDataRegState() != mNewSS.getDataRegState()) {
332            EventLog.writeEvent(EventLogTags.CDMA_SERVICE_STATE_CHANGE, mSS.getVoiceRegState(),
333                    mSS.getDataRegState(), mNewSS.getVoiceRegState(), mNewSS.getDataRegState());
334        }
335
336        ServiceState tss;
337        tss = mSS;
338        mSS = mNewSS;
339        mNewSS = tss;
340        // clean slate for next time
341        mNewSS.setStateOutOfService();
342
343        CdmaCellLocation tcl = mCellLoc;
344        mCellLoc = mNewCellLoc;
345        mNewCellLoc = tcl;
346
347        mNewSS.setStateOutOfService(); // clean slate for next time
348
349        if (hasVoiceRadioTechnologyChanged) {
350            updatePhoneObject();
351        }
352
353        if (hasDataRadioTechnologyChanged) {
354            mPhone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
355                    ServiceState.rilRadioTechnologyToString(mSS.getRilDataRadioTechnology()));
356        }
357
358        if (hasRegistered) {
359            mNetworkAttachedRegistrants.notifyRegistrants();
360        }
361
362        if (hasChanged) {
363            if (mPhone.isEriFileLoaded()) {
364                String eriText;
365                // Now the CDMAPhone sees the new ServiceState so it can get the
366                // new ERI text
367                if (mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE) {
368                    eriText = mPhone.getCdmaEriText();
369                } else if (mSS.getVoiceRegState() == ServiceState.STATE_POWER_OFF) {
370                    eriText = (mIccRecords != null) ? mIccRecords.getServiceProviderName() : null;
371                    if (TextUtils.isEmpty(eriText)) {
372                        // Sets operator alpha property by retrieving from
373                        // build-time system property
374                        eriText = SystemProperties.get("ro.cdma.home.operator.alpha");
375                    }
376                } else {
377                    // Note that ServiceState.STATE_OUT_OF_SERVICE is valid used
378                    // for mRegistrationState 0,2,3 and 4
379                    eriText = mPhone.getContext()
380                            .getText(com.android.internal.R.string.roamingTextSearching).toString();
381                }
382                mSS.setOperatorAlphaLong(eriText);
383            }
384
385            if (mUiccApplcation != null && mUiccApplcation.getState() == AppState.APPSTATE_READY &&
386                    mIccRecords != null) {
387                // SIM is found on the device. If ERI roaming is OFF, and SID/NID matches
388                // one configured in SIM, use operator name  from CSIM record.
389                boolean showSpn =
390                    ((RuimRecords)mIccRecords).getCsimSpnDisplayCondition();
391                int iconIndex = mSS.getCdmaEriIconIndex();
392
393                if (showSpn && (iconIndex == EriInfo.ROAMING_INDICATOR_OFF) &&
394                    isInHomeSidNid(mSS.getSystemId(), mSS.getNetworkId()) &&
395                    mIccRecords != null) {
396                    mSS.setOperatorAlphaLong(mIccRecords.getServiceProviderName());
397                }
398            }
399
400            String operatorNumeric;
401
402            mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
403                    mSS.getOperatorAlphaLong());
404
405            String prevOperatorNumeric =
406                    SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, "");
407            operatorNumeric = mSS.getOperatorNumeric();
408            mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
409            updateCarrierMccMncConfiguration(operatorNumeric,
410                    prevOperatorNumeric, mPhone.getContext());
411
412            if (operatorNumeric == null) {
413                if (DBG) log("operatorNumeric is null");
414                mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
415                mGotCountryCode = false;
416            } else {
417                String isoCountryCode = "";
418                String mcc = operatorNumeric.substring(0, 3);
419                try {
420                    isoCountryCode = MccTable.countryCodeForMcc(Integer.parseInt(operatorNumeric
421                            .substring(0, 3)));
422                } catch (NumberFormatException ex) {
423                    loge("countryCodeForMcc error" + ex);
424                } catch (StringIndexOutOfBoundsException ex) {
425                    loge("countryCodeForMcc error" + ex);
426                }
427
428                mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY,
429                        isoCountryCode);
430                mGotCountryCode = true;
431
432                if (shouldFixTimeZoneNow(mPhone, operatorNumeric, prevOperatorNumeric,
433                        mNeedFixZone)) {
434                    fixTimeZone(isoCountryCode);
435                }
436            }
437
438            mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
439                    mSS.getRoaming() ? "true" : "false");
440
441            updateSpnDisplay();
442            mPhone.notifyServiceStateChanged(mSS);
443        }
444
445        if (hasCdmaDataConnectionAttached || has4gHandoff) {
446            mAttachedRegistrants.notifyRegistrants();
447        }
448
449        if (hasCdmaDataConnectionDetached) {
450            mDetachedRegistrants.notifyRegistrants();
451        }
452
453        if ((hasCdmaDataConnectionChanged || hasDataRadioTechnologyChanged)) {
454            notifyDataRegStateRilRadioTechnologyChanged();
455            mPhone.notifyDataConnection(null);
456        }
457
458        if (hasRoamingOn) {
459            mRoamingOnRegistrants.notifyRegistrants();
460        }
461
462        if (hasRoamingOff) {
463            mRoamingOffRegistrants.notifyRegistrants();
464        }
465
466        if (hasLocationChanged) {
467            mPhone.notifyLocationChanged();
468        }
469
470        ArrayList<CellInfo> arrayCi = new ArrayList<CellInfo>();
471        synchronized(mCellInfo) {
472            CellInfoLte cil = (CellInfoLte)mCellInfo;
473
474            boolean cidChanged = ! mNewCellIdentityLte.equals(mLasteCellIdentityLte);
475            if (hasRegistered || hasDeregistered || cidChanged) {
476                // TODO: Handle the absence of LteCellIdentity
477                long timeStamp = SystemClock.elapsedRealtime() * 1000;
478                boolean registered = mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE;
479                mLasteCellIdentityLte = mNewCellIdentityLte;
480
481                cil.setRegisterd(registered);
482                cil.setCellIdentity(mLasteCellIdentityLte);
483                if (DBG) {
484                    log("pollStateDone: hasRegistered=" + hasRegistered +
485                            " hasDeregistered=" + hasDeregistered +
486                            " cidChanged=" + cidChanged +
487                            " mCellInfo=" + mCellInfo);
488                }
489                arrayCi.add(mCellInfo);
490            }
491            mPhoneBase.notifyCellInfo(arrayCi);
492        }
493    }
494
495    @Override
496    protected boolean onSignalStrengthResult(AsyncResult ar, boolean isGsm) {
497        if (mSS.getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) {
498            isGsm = true;
499        }
500        boolean ssChanged = super.onSignalStrengthResult(ar, isGsm);
501
502        synchronized (mCellInfo) {
503            if (mSS.getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) {
504                mCellInfoLte.setTimeStamp(SystemClock.elapsedRealtime() * 1000);
505                mCellInfoLte.setTimeStampType(CellInfo.TIMESTAMP_TYPE_JAVA_RIL);
506                mCellInfoLte.getCellSignalStrength()
507                                .initialize(mSignalStrength,SignalStrength.INVALID);
508            }
509            if (mCellInfoLte.getCellIdentity() != null) {
510                ArrayList<CellInfo> arrayCi = new ArrayList<CellInfo>();
511                arrayCi.add(mCellInfoLte);
512                mPhoneBase.notifyCellInfo(arrayCi);
513            }
514        }
515        return ssChanged;
516    }
517
518    @Override
519    public boolean isConcurrentVoiceAndDataAllowed() {
520        // Using the Conncurrent Service Supported flag for CdmaLte devices.
521        return mSS.getCssIndicator() == 1;
522    }
523
524    /**
525     * Check whether the specified SID and NID pair appears in the HOME SID/NID list
526     * read from NV or SIM.
527     *
528     * @return true if provided sid/nid pair belongs to operator's home network.
529     */
530    private boolean isInHomeSidNid(int sid, int nid) {
531        // if SID/NID is not available, assume this is home network.
532        if (isSidsAllZeros()) return true;
533
534        // length of SID/NID shold be same
535        if (mHomeSystemId.length != mHomeNetworkId.length) return true;
536
537        if (sid == 0) return true;
538
539        for (int i = 0; i < mHomeSystemId.length; i++) {
540            // Use SID only if NID is a reserved value.
541            // SID 0 and NID 0 and 65535 are reserved. (C.0005 2.6.5.2)
542            if ((mHomeSystemId[i] == sid) &&
543                ((mHomeNetworkId[i] == 0) || (mHomeNetworkId[i] == 65535) ||
544                 (nid == 0) || (nid == 65535) || (mHomeNetworkId[i] == nid))) {
545                return true;
546            }
547        }
548        // SID/NID are not in the list. So device is not in home network
549        return false;
550    }
551
552    /**
553     * TODO: Remove when we get new ril/modem for Galaxy Nexus.
554     *
555     * @return all available cell information, the returned List maybe empty but never null.
556     */
557    @Override
558    public List<CellInfo> getAllCellInfo() {
559        if (mCi.getRilVersion() >= 8) {
560            return super.getAllCellInfo();
561        } else {
562            ArrayList<CellInfo> arrayList = new ArrayList<CellInfo>();
563            CellInfo ci;
564            synchronized(mCellInfo) {
565                arrayList.add(mCellInfoLte);
566            }
567            if (DBG) log ("getAllCellInfo: arrayList=" + arrayList);
568            return arrayList;
569        }
570    }
571
572    @Override
573    protected void log(String s) {
574        Rlog.d(LOG_TAG, "[CdmaLteSST] " + s);
575    }
576
577    @Override
578    protected void loge(String s) {
579        Rlog.e(LOG_TAG, "[CdmaLteSST] " + s);
580    }
581
582    @Override
583    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
584        pw.println("CdmaLteServiceStateTracker extends:");
585        super.dump(fd, pw, args);
586        pw.println(" mCdmaLtePhone=" + mCdmaLtePhone);
587    }
588}
589