CdmaLteServiceStateTracker.java revision e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4
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.PhoneBase;
20import com.android.internal.telephony.TelephonyProperties;
21import com.android.internal.telephony.MccTable;
22import com.android.internal.telephony.EventLogTags;
23import com.android.internal.telephony.RILConstants;
24import com.android.internal.telephony.IccCard;
25
26import android.telephony.CellInfo;
27import android.telephony.CellInfoLte;
28import android.telephony.CellSignalStrengthLte;
29import android.telephony.CellIdentityLte;
30import android.telephony.SignalStrength;
31import android.telephony.ServiceState;
32import android.telephony.cdma.CdmaCellLocation;
33import android.text.TextUtils;
34import android.os.AsyncResult;
35import android.os.Message;
36import android.os.SystemClock;
37import android.os.SystemProperties;
38
39import android.text.TextUtils;
40import android.util.Log;
41import android.util.EventLog;
42
43import com.android.internal.telephony.gsm.GsmDataConnectionTracker;
44import com.android.internal.telephony.IccCardConstants;
45
46import java.io.FileDescriptor;
47import java.io.PrintWriter;
48import java.util.ArrayList;
49import java.util.List;
50
51public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
52    private CDMALTEPhone mCdmaLtePhone;
53    private final CellInfoLte mCellInfoLte;
54
55    private ServiceState  mLteSS;  // The last LTE state from Voice Registration
56
57    private CellIdentityLte mNewCellIdentityLte = new CellIdentityLte();
58    private CellIdentityLte mLasteCellIdentityLte = new CellIdentityLte();
59
60    public CdmaLteServiceStateTracker(CDMALTEPhone phone) {
61        super(phone, new CellInfoLte());
62        mCdmaLtePhone = phone;
63        mCellInfoLte = (CellInfoLte) mCellInfo;
64
65        mLteSS = new ServiceState();
66        ((CellInfoLte)mCellInfo).setCellSignalStrength(new CellSignalStrengthLte());
67        ((CellInfoLte)mCellInfo).setCellIdentity(new CellIdentityLte());
68
69        if (DBG) log("CdmaLteServiceStateTracker Constructors");
70    }
71
72    @Override
73    public void handleMessage(Message msg) {
74        AsyncResult ar;
75        int[] ints;
76        String[] strings;
77        switch (msg.what) {
78        case EVENT_POLL_STATE_GPRS:
79            if (DBG) log("handleMessage EVENT_POLL_STATE_GPRS");
80            ar = (AsyncResult)msg.obj;
81            handlePollStateResult(msg.what, ar);
82            break;
83        case EVENT_RUIM_RECORDS_LOADED:
84            CdmaLteUiccRecords sim = (CdmaLteUiccRecords)mIccRecords;
85            if ((sim != null) && sim.isProvisioned()) {
86                mMdn = sim.getMdn();
87                mMin = sim.getMin();
88                parseSidNid(sim.getSid(), sim.getNid());
89                mPrlVersion = sim.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     * Set the cdmaSS for EVENT_POLL_STATE_REGISTRATION_CDMA
105     */
106    @Override
107    protected void setCdmaTechnology(int radioTechnology) {
108        // Called on voice registration state response.
109        // Just record new CDMA radio technology
110        newSS.setRadioTechnology(radioTechnology);
111    }
112
113    /**
114     * Handle the result of one of the pollState()-related requests
115     */
116    @Override
117    protected void handlePollStateResultMessage(int what, AsyncResult ar) {
118        if (what == EVENT_POLL_STATE_GPRS) {
119            String states[] = (String[])ar.result;
120            if (DBG) {
121                log("handlePollStateResultMessage: EVENT_POLL_STATE_GPRS states.length=" +
122                        states.length + " states=" + states);
123            }
124
125            int type = 0;
126            int regState = -1;
127            if (states.length > 0) {
128                try {
129                    regState = Integer.parseInt(states[0]);
130
131                    // states[3] (if present) is the current radio technology
132                    if (states.length >= 4 && states[3] != null) {
133                        type = Integer.parseInt(states[3]);
134                    }
135                } catch (NumberFormatException ex) {
136                    loge("handlePollStateResultMessage: error parsing GprsRegistrationState: "
137                                    + ex);
138                }
139                if (states.length >= 10) {
140                    int mcc;
141                    int mnc;
142                    int tac;
143                    int pci;
144                    int eci;
145                    int csgid;
146                    String operatorNumeric = null;
147
148                    try {
149                        operatorNumeric = mLteSS.getOperatorNumeric();
150                        mcc = Integer.parseInt(operatorNumeric.substring(0,3));
151                    } catch (Exception e) {
152                        try {
153                            operatorNumeric = ss.getOperatorNumeric();
154                            mcc = Integer.parseInt(operatorNumeric.substring(0,3));
155                        } catch (Exception ex) {
156                            loge("handlePollStateResultMessage: bad mcc operatorNumeric=" +
157                                    operatorNumeric + " ex=" + ex);
158                            operatorNumeric = "";
159                            mcc = Integer.MAX_VALUE;
160                        }
161                    }
162                    try {
163                        mnc = Integer.parseInt(operatorNumeric.substring(3));
164                    } catch (Exception e) {
165                        loge("handlePollStateResultMessage: bad mnc operatorNumeric=" +
166                                operatorNumeric + " e=" + e);
167                        mnc = Integer.MAX_VALUE;
168                    }
169                    try {
170                        tac = Integer.parseInt(states[6], 16);
171                    } catch (Exception e) {
172                        loge("handlePollStateResultMessage: bad tac states[6]=" +
173                                states[6] + " e=" + e);
174                        tac = Integer.MAX_VALUE;
175                    }
176                    try {
177                        pci = Integer.parseInt(states[7], 16);
178                    } catch (Exception e) {
179                        loge("handlePollStateResultMessage: bad pci states[7]=" +
180                                states[7] + " e=" + e);
181                        pci = Integer.MAX_VALUE;
182                    }
183                    try {
184                        eci = Integer.parseInt(states[8], 16);
185                    } catch (Exception e) {
186                        loge("handlePollStateResultMessage: bad eci states[8]=" +
187                                states[8] + " e=" + e);
188                        eci = Integer.MAX_VALUE;
189                    }
190                    try {
191                        csgid = Integer.parseInt(states[9], 16);
192                    } catch (Exception e) {
193                        // FIX: Always bad so don't pollute the logs
194                        // loge("handlePollStateResultMessage: bad csgid states[9]=" +
195                        //        states[9] + " e=" + e);
196                        csgid = Integer.MAX_VALUE;
197                    }
198                    mNewCellIdentityLte = new CellIdentityLte(mcc, mnc, eci, pci, tac);
199                    if (DBG) {
200                        log("handlePollStateResultMessage: mNewLteCellIdentity=" +
201                                mNewCellIdentityLte);
202                    }
203                }
204            }
205
206            mLteSS.setRadioTechnology(type);
207            mLteSS.setState(regCodeToServiceState(regState));
208        } else {
209            super.handlePollStateResultMessage(what, ar);
210        }
211    }
212
213    @Override
214    protected void pollState() {
215        pollingContext = new int[1];
216        pollingContext[0] = 0;
217
218        switch (cm.getRadioState()) {
219            case RADIO_UNAVAILABLE:
220                newSS.setStateOutOfService();
221                newCellLoc.setStateInvalid();
222                setSignalStrengthDefaultValues();
223                mGotCountryCode = false;
224
225                pollStateDone();
226                break;
227
228            case RADIO_OFF:
229                newSS.setStateOff();
230                newCellLoc.setStateInvalid();
231                setSignalStrengthDefaultValues();
232                mGotCountryCode = false;
233
234                pollStateDone();
235                break;
236
237            default:
238                // Issue all poll-related commands at once, then count
239                // down the responses which are allowed to arrive
240                // out-of-order.
241
242                pollingContext[0]++;
243                // RIL_REQUEST_OPERATOR is necessary for CDMA
244                cm.getOperator(obtainMessage(EVENT_POLL_STATE_OPERATOR_CDMA, pollingContext));
245
246                pollingContext[0]++;
247                // RIL_REQUEST_VOICE_REGISTRATION_STATE is necessary for CDMA
248                cm.getVoiceRegistrationState(obtainMessage(EVENT_POLL_STATE_REGISTRATION_CDMA,
249                        pollingContext));
250
251                pollingContext[0]++;
252                // RIL_REQUEST_DATA_REGISTRATION_STATE
253                cm.getDataRegistrationState(obtainMessage(EVENT_POLL_STATE_GPRS,
254                                            pollingContext));
255                break;
256        }
257    }
258
259    @Override
260    protected void pollStateDone() {
261        // determine data RadioTechnology from both LET and CDMA SS
262        if (mLteSS.getState() == ServiceState.STATE_IN_SERVICE) {
263            //in LTE service
264            mNewRilRadioTechnology = mLteSS.getRilRadioTechnology();
265            mNewDataConnectionState = mLteSS.getState();
266            newSS.setRadioTechnology(mNewRilRadioTechnology);
267            log("pollStateDone LTE/eHRPD STATE_IN_SERVICE mNewRilRadioTechnology = " +
268                    mNewRilRadioTechnology);
269        } else {
270            // LTE out of service, get CDMA Service State
271            mNewRilRadioTechnology = newSS.getRilRadioTechnology();
272            mNewDataConnectionState = radioTechnologyToDataServiceState(mNewRilRadioTechnology);
273            log("pollStateDone CDMA STATE_IN_SERVICE mNewRilRadioTechnology = " +
274                    mNewRilRadioTechnology + " mNewDataConnectionState = " +
275                    mNewDataConnectionState);
276        }
277
278        // TODO: Add proper support for LTE Only, we should be looking at
279        //       the preferred network mode, to know when newSS state should
280        //       be coming from mLteSs state. This was needed to pass a VZW
281        //       LTE Only test.
282        //
283        // If CDMA service is OOS, double check if the device is running with LTE only
284        // mode. If that is the case, derive the service state from LTE side.
285        // To set in LTE only mode, sqlite3 /data/data/com.android.providers.settings/
286        // databases/settings.db "update secure set value='11' where name='preferred_network_mode'"
287        if (newSS.getState() == ServiceState.STATE_OUT_OF_SERVICE) {
288            int networkMode = android.provider.Settings.Secure.getInt(phone.getContext()
289                                  .getContentResolver(),
290                                  android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
291                                  RILConstants.PREFERRED_NETWORK_MODE);
292            if (networkMode == RILConstants.NETWORK_MODE_LTE_ONLY) {
293                if (DBG) log("pollState: LTE Only mode");
294                newSS.setState(mLteSS.getState());
295            }
296        }
297
298        if (DBG) log("pollStateDone: oldSS=[" + ss + "] newSS=[" + newSS + "]");
299
300        boolean hasRegistered = ss.getState() != ServiceState.STATE_IN_SERVICE
301                && newSS.getState() == ServiceState.STATE_IN_SERVICE;
302
303        boolean hasDeregistered = ss.getState() == ServiceState.STATE_IN_SERVICE
304                && newSS.getState() != ServiceState.STATE_IN_SERVICE;
305
306        boolean hasCdmaDataConnectionAttached =
307            mDataConnectionState != ServiceState.STATE_IN_SERVICE
308                && mNewDataConnectionState == ServiceState.STATE_IN_SERVICE;
309
310        boolean hasCdmaDataConnectionDetached =
311            mDataConnectionState == ServiceState.STATE_IN_SERVICE
312                && mNewDataConnectionState != ServiceState.STATE_IN_SERVICE;
313
314        boolean hasCdmaDataConnectionChanged =
315            mDataConnectionState != mNewDataConnectionState;
316
317        boolean hasRadioTechnologyChanged = mRilRadioTechnology != mNewRilRadioTechnology;
318
319        boolean hasChanged = !newSS.equals(ss);
320
321        boolean hasRoamingOn = !ss.getRoaming() && newSS.getRoaming();
322
323        boolean hasRoamingOff = ss.getRoaming() && !newSS.getRoaming();
324
325        boolean hasLocationChanged = !newCellLoc.equals(cellLoc);
326
327        boolean has4gHandoff =
328                mNewDataConnectionState == ServiceState.STATE_IN_SERVICE &&
329                (((mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) &&
330                  (mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)) ||
331                 ((mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD) &&
332                  (mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE)));
333
334        boolean hasMultiApnSupport =
335                (((mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) ||
336                  (mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)) &&
337                 ((mRilRadioTechnology != ServiceState.RIL_RADIO_TECHNOLOGY_LTE) &&
338                  (mRilRadioTechnology != ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)));
339
340        boolean hasLostMultiApnSupport =
341            ((mNewRilRadioTechnology >= ServiceState.RIL_RADIO_TECHNOLOGY_IS95A) &&
342             (mNewRilRadioTechnology <= ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A));
343
344        if (DBG) {
345            log("pollStateDone:"
346                + " hasRegistered=" + hasRegistered
347                + " hasDeegistered=" + hasDeregistered
348                + " hasCdmaDataConnectionAttached=" + hasCdmaDataConnectionAttached
349                + " hasCdmaDataConnectionDetached=" + hasCdmaDataConnectionDetached
350                + " hasCdmaDataConnectionChanged=" + hasCdmaDataConnectionChanged
351                + " hasRadioTechnologyChanged = " + hasRadioTechnologyChanged
352                + " hasChanged=" + hasChanged
353                + " hasRoamingOn=" + hasRoamingOn
354                + " hasRoamingOff=" + hasRoamingOff
355                + " hasLocationChanged=" + hasLocationChanged
356                + " has4gHandoff = " + has4gHandoff
357                + " hasMultiApnSupport=" + hasMultiApnSupport
358                + " hasLostMultiApnSupport=" + hasLostMultiApnSupport);
359        }
360        // Add an event log when connection state changes
361        if (ss.getState() != newSS.getState()
362                || mDataConnectionState != mNewDataConnectionState) {
363            EventLog.writeEvent(EventLogTags.CDMA_SERVICE_STATE_CHANGE, ss.getState(),
364                    mDataConnectionState, newSS.getState(), mNewDataConnectionState);
365        }
366
367        ServiceState tss;
368        tss = ss;
369        ss = newSS;
370        newSS = tss;
371        // clean slate for next time
372        newSS.setStateOutOfService();
373        mLteSS.setStateOutOfService();
374
375        if ((hasMultiApnSupport)
376                && (phone.mDataConnectionTracker instanceof CdmaDataConnectionTracker)) {
377            if (DBG) log("GsmDataConnectionTracker Created");
378            phone.mDataConnectionTracker.dispose();
379            phone.mDataConnectionTracker = new GsmDataConnectionTracker(mCdmaLtePhone);
380        }
381
382        if ((hasLostMultiApnSupport)
383                && (phone.mDataConnectionTracker instanceof GsmDataConnectionTracker)) {
384            if (DBG)log("GsmDataConnectionTracker disposed");
385            phone.mDataConnectionTracker.dispose();
386            phone.mDataConnectionTracker = new CdmaDataConnectionTracker(phone);
387        }
388
389        CdmaCellLocation tcl = cellLoc;
390        cellLoc = newCellLoc;
391        newCellLoc = tcl;
392
393        mDataConnectionState = mNewDataConnectionState;
394        mRilRadioTechnology = mNewRilRadioTechnology;
395        mNewRilRadioTechnology = 0;
396
397        newSS.setStateOutOfService(); // clean slate for next time
398
399        if (hasRadioTechnologyChanged) {
400            phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
401                    ServiceState.rilRadioTechnologyToString(mRilRadioTechnology));
402        }
403
404        if (hasRegistered) {
405            mNetworkAttachedRegistrants.notifyRegistrants();
406        }
407
408        if (hasChanged) {
409            if (phone.isEriFileLoaded()) {
410                String eriText;
411                // Now the CDMAPhone sees the new ServiceState so it can get the
412                // new ERI text
413                if (ss.getState() == ServiceState.STATE_IN_SERVICE) {
414                    eriText = phone.getCdmaEriText();
415                } else if (ss.getState() == ServiceState.STATE_POWER_OFF) {
416                    eriText = (mIccRecords != null) ? mIccRecords.getServiceProviderName() : null;
417                    if (TextUtils.isEmpty(eriText)) {
418                        // Sets operator alpha property by retrieving from
419                        // build-time system property
420                        eriText = SystemProperties.get("ro.cdma.home.operator.alpha");
421                    }
422                } else {
423                    // Note that ServiceState.STATE_OUT_OF_SERVICE is valid used
424                    // for mRegistrationState 0,2,3 and 4
425                    eriText = phone.getContext()
426                            .getText(com.android.internal.R.string.roamingTextSearching).toString();
427                }
428                ss.setOperatorAlphaLong(eriText);
429            }
430
431            if (mIccCard != null && mIccCard.getState() == IccCardConstants.State.READY &&
432                    mIccRecords != null) {
433                // SIM is found on the device. If ERI roaming is OFF, and SID/NID matches
434                // one configfured in SIM, use operator name  from CSIM record.
435                boolean showSpn =
436                    ((CdmaLteUiccRecords)mIccRecords).getCsimSpnDisplayCondition();
437                int iconIndex = ss.getCdmaEriIconIndex();
438
439                if (showSpn && (iconIndex == EriInfo.ROAMING_INDICATOR_OFF) &&
440                    isInHomeSidNid(ss.getSystemId(), ss.getNetworkId()) &&
441                    mIccRecords != null) {
442                    ss.setOperatorAlphaLong(mIccRecords.getServiceProviderName());
443                }
444            }
445
446            String operatorNumeric;
447
448            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
449                    ss.getOperatorAlphaLong());
450
451            String prevOperatorNumeric =
452                    SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, "");
453            operatorNumeric = ss.getOperatorNumeric();
454            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
455
456            if (operatorNumeric == null) {
457                if (DBG) log("operatorNumeric is null");
458                phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
459                mGotCountryCode = false;
460            } else {
461                String isoCountryCode = "";
462                String mcc = operatorNumeric.substring(0, 3);
463                try {
464                    isoCountryCode = MccTable.countryCodeForMcc(Integer.parseInt(operatorNumeric
465                            .substring(0, 3)));
466                } catch (NumberFormatException ex) {
467                    loge("countryCodeForMcc error" + ex);
468                } catch (StringIndexOutOfBoundsException ex) {
469                    loge("countryCodeForMcc error" + ex);
470                }
471
472                phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY,
473                        isoCountryCode);
474                mGotCountryCode = true;
475
476                if (shouldFixTimeZoneNow(phone, operatorNumeric, prevOperatorNumeric,
477                        mNeedFixZone)) {
478                    fixTimeZone(isoCountryCode);
479                }
480            }
481
482            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
483                    ss.getRoaming() ? "true" : "false");
484
485            updateSpnDisplay();
486            phone.notifyServiceStateChanged(ss);
487        }
488
489        if (hasCdmaDataConnectionAttached || has4gHandoff) {
490            mAttachedRegistrants.notifyRegistrants();
491        }
492
493        if (hasCdmaDataConnectionDetached) {
494            mDetachedRegistrants.notifyRegistrants();
495        }
496
497        if ((hasCdmaDataConnectionChanged || hasRadioTechnologyChanged)) {
498            phone.notifyDataConnection(null);
499        }
500
501        if (hasRoamingOn) {
502            mRoamingOnRegistrants.notifyRegistrants();
503        }
504
505        if (hasRoamingOff) {
506            mRoamingOffRegistrants.notifyRegistrants();
507        }
508
509        if (hasLocationChanged) {
510            phone.notifyLocationChanged();
511        }
512
513        ArrayList<CellInfo> arrayCi = new ArrayList<CellInfo>();
514        synchronized(mCellInfo) {
515            CellInfoLte cil = (CellInfoLte)mCellInfo;
516
517            boolean cidChanged = ! mNewCellIdentityLte.equals(mLasteCellIdentityLte);
518            if (hasRegistered || hasDeregistered || cidChanged) {
519                // TODO: Handle the absence of LteCellIdentity
520                long timeStamp = SystemClock.elapsedRealtime() * 1000;
521                boolean registered = ss.getState() == ServiceState.STATE_IN_SERVICE;
522                mLasteCellIdentityLte = mNewCellIdentityLte;
523
524                cil.setRegisterd(registered);
525                cil.setCellIdentity(mLasteCellIdentityLte);
526                if (DBG) {
527                    log("pollStateDone: hasRegistered=" + hasRegistered +
528                            " hasDeregistered=" + hasDeregistered +
529                            " cidChanged=" + cidChanged +
530                            " mCellInfo=" + mCellInfo);
531                }
532                arrayCi.add(mCellInfo);
533            }
534            mPhoneBase.notifyCellInfo(arrayCi);
535        }
536    }
537
538    @Override
539    protected boolean onSignalStrengthResult(AsyncResult ar, boolean isGsm) {
540        if (mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) {
541            isGsm = true;
542        }
543        boolean ssChanged = super.onSignalStrengthResult(ar, isGsm);
544
545        synchronized (mCellInfo) {
546            if (mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) {
547                mCellInfoLte.setTimeStamp(SystemClock.elapsedRealtime() * 1000);
548                mCellInfoLte.setTimeStampType(CellInfo.TIMESTAMP_TYPE_JAVA_RIL);
549                mCellInfoLte.getCellSignalStrength()
550                                .initialize(mSignalStrength,SignalStrength.INVALID);
551            }
552            if (mCellInfoLte.getCellIdentity() != null) {
553                ArrayList<CellInfo> arrayCi = new ArrayList<CellInfo>();
554                arrayCi.add(mCellInfoLte);
555                mPhoneBase.notifyCellInfo(arrayCi);
556            }
557        }
558        return ssChanged;
559    }
560
561    @Override
562    public boolean isConcurrentVoiceAndDataAllowed() {
563        // Note: it needs to be confirmed which CDMA network types
564        // can support voice and data calls concurrently.
565        // For the time-being, the return value will be false.
566        return (mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE);
567    }
568
569    /**
570     * Check whether the specified SID and NID pair appears in the HOME SID/NID list
571     * read from NV or SIM.
572     *
573     * @return true if provided sid/nid pair belongs to operator's home network.
574     */
575    private boolean isInHomeSidNid(int sid, int nid) {
576        // if SID/NID is not available, assume this is home network.
577        if (isSidsAllZeros()) return true;
578
579        // length of SID/NID shold be same
580        if (mHomeSystemId.length != mHomeNetworkId.length) return true;
581
582        if (sid == 0) return true;
583
584        for (int i = 0; i < mHomeSystemId.length; i++) {
585            // Use SID only if NID is a reserved value.
586            // SID 0 and NID 0 and 65535 are reserved. (C.0005 2.6.5.2)
587            if ((mHomeSystemId[i] == sid) &&
588                ((mHomeNetworkId[i] == 0) || (mHomeNetworkId[i] == 65535) ||
589                 (nid == 0) || (nid == 65535) || (mHomeNetworkId[i] == nid))) {
590                return true;
591            }
592        }
593        // SID/NID are not in the list. So device is not in home network
594        return false;
595    }
596
597    /**
598     * @return all available cell information, the returned List maybe empty but never null.
599     */
600    @Override
601    public List<CellInfo> getAllCellInfo() {
602        ArrayList<CellInfo> arrayList = new ArrayList<CellInfo>();
603        CellInfo ci;
604        synchronized(mCellInfo) {
605            arrayList.add(mCellInfoLte);
606        }
607        if (DBG) log ("getAllCellInfo: arrayList=" + arrayList);
608        return arrayList;
609    }
610
611    @Override
612    protected void log(String s) {
613        Log.d(LOG_TAG, "[CdmaLteSST] " + s);
614    }
615
616    @Override
617    protected void loge(String s) {
618        Log.e(LOG_TAG, "[CdmaLteSST] " + s);
619    }
620
621    @Override
622    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
623        pw.println("CdmaLteServiceStateTracker extends:");
624        super.dump(fd, pw, args);
625        pw.println(" mCdmaLtePhone=" + mCdmaLtePhone);
626        pw.println(" mLteSS=" + mLteSS);
627    }
628}
629