10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/*
20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2006 The Android Open Source Project
30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License.
60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at
70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software
110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and
140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License.
150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
19b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwaltimport android.content.Context;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult;
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler;
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Registrant;
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.RegistrantList;
250c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Savilleimport android.os.SystemClock;
26ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Savilleimport android.telephony.CellInfo;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.ServiceState;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.SignalStrength;
29b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwaltimport android.text.TextUtils;
30203e588e3c42a81aa8a56f595119c181a63b12caWink Savilleimport android.util.Pair;
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.TimeUtils;
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.FileDescriptor;
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.PrintWriter;
355fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Savilleimport java.util.ArrayList;
36ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Savilleimport java.util.List;
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
38454b1dfd508844b42eb775e4ab2359be74d3672bWink Savilleimport com.android.internal.telephony.dataconnection.DcTrackerBase;
39d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
40d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccRecords;
41d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.UiccCardApplication;
42e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenkaimport com.android.internal.telephony.uicc.UiccController;
43e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic abstract class ServiceStateTracker extends Handler {
485fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected  static final boolean DBG = true;
495fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected static final boolean VDBG = false;
505fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
5160ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkey    protected static final String PROP_FORCE_ROAMING = "telephony.test.forceRoaming";
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected CommandsInterface mCi;
54e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected UiccController mUiccController = null;
55e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    protected UiccCardApplication mUiccApplcation = null;
56e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected IccRecords mIccRecords = null;
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
58ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected PhoneBase mPhoneBase;
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
60f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville    protected boolean mVoiceCapable;
61f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville
6222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    public ServiceState mSS = new ServiceState();
6322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected ServiceState mNewSS = new ServiceState();
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
650c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville    private static final long LAST_CELL_INFO_LIST_MAX_AGE_MS = 2000;
660c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville    protected long mLastCellInfoListTime;
675fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected List<CellInfo> mLastCellInfoList = null;
68ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
69ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    // This is final as subclasses alias to a more specific type
70ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    // so we don't want the reference to change.
71ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected final CellInfo mCellInfo;
72ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
73ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected SignalStrength mSignalStrength = new SignalStrength();
74ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
75ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    // TODO - this should not be public, right now used externally GsmConnetion.
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public RestrictedState mRestrictedState = new RestrictedState();
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* The otaspMode passed to PhoneStateListener#onOtaspChanged */
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_UNINITIALIZED = 0;
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_UNKNOWN = 1;
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_NEEDED = 2;
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_NOT_NEEDED = 3;
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * A unique identifier to track requests associated with a poll
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * and ignore stale responses.  The value is a count-down of
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * expected responses in this pollingContext.
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
8922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected int[] mPollingContext;
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean mDesiredPowerState;
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * By default, strength polling is enabled.  However, if we're
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * getting unsolicited signal strength updates from the radio, set
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * value to true and don't bother polling any more.
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
9722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected boolean mDontPollSignalStrength = false;
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mRoamingOnRegistrants = new RegistrantList();
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mRoamingOffRegistrants = new RegistrantList();
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mAttachedRegistrants = new RegistrantList();
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mDetachedRegistrants = new RegistrantList();
103203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    protected RegistrantList mDataRegStateOrRatChangedRegistrants = new RegistrantList();
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mNetworkAttachedRegistrants = new RegistrantList();
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mPsRestrictEnabledRegistrants = new RegistrantList();
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mPsRestrictDisabledRegistrants = new RegistrantList();
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* Radio power off pending flag and tag counter */
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mPendingRadioPowerOffAfterDataOff = false;
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mPendingRadioPowerOffAfterDataOffTag = 0;
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Signal strength poll rate. */
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int POLL_PERIOD_MILLIS = 20 * 1000;
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Waiting period before recheck gprs and voice registration. */
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** GSM events */
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RADIO_STATE_CHANGED               = 1;
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NETWORK_STATE_CHANGED             = 2;
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_SIGNAL_STRENGTH               = 3;
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_REGISTRATION           = 4;
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_GPRS                   = 5;
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_OPERATOR               = 6;
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_SIGNAL_STRENGTH              = 10;
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NITZ_TIME                         = 11;
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SIGNAL_STRENGTH_UPDATE            = 12;
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RADIO_AVAILABLE                   = 13;
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_NETWORK_SELECTION_MODE = 14;
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_LOC_DONE                      = 15;
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SIM_RECORDS_LOADED                = 16;
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SIM_READY                         = 17;
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_LOCATION_UPDATES_ENABLED          = 18;
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_PREFERRED_NETWORK_TYPE        = 19;
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SET_PREFERRED_NETWORK_TYPE        = 20;
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RESET_PREFERRED_NETWORK_TYPE      = 21;
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_CHECK_REPORT_GPRS                 = 22;
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RESTRICTED_STATE_CHANGED          = 23;
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** CDMA events */
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_REGISTRATION_CDMA      = 24;
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_OPERATOR_CDMA          = 25;
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RUIM_READY                        = 26;
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RUIM_RECORDS_LOADED               = 27;
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_SIGNAL_STRENGTH_CDMA         = 28;
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_SIGNAL_STRENGTH_CDMA          = 29;
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NETWORK_STATE_CHANGED_CDMA        = 30;
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_LOC_DONE_CDMA                 = 31;
149ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    //protected static final int EVENT_UNUSED                            = 32;
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NV_LOADED                         = 33;
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_CDMA_SUBSCRIPTION      = 34;
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NV_READY                          = 35;
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_ERI_FILE_LOADED                   = 36;
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_OTA_PROVISION_STATUS_CHANGE       = 37;
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SET_RADIO_POWER_OFF               = 38;
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED  = 39;
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_CDMA_PRL_VERSION_CHANGED          = 40;
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RADIO_ON                          = 41;
159e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected static final int EVENT_ICC_CHANGED                       = 42;
1605fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected static final int EVENT_GET_CELL_INFO_LIST                = 43;
1615fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected static final int EVENT_UNSOL_CELL_INFO_LIST              = 44;
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * List of ISO codes for countries that can have an offset of
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * GMT+0 when not in daylight savings time.  This ignores some
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * small places such as the Canary Islands (Spain) and
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Danmarkshavn (Denmark).  The list must be sorted by code.
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    */
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String[] GMT_COUNTRY_CODES = {
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "bf", // Burkina Faso
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ci", // Cote d'Ivoire
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "eh", // Western Sahara
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "fo", // Faroe Islands, Denmark
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gb", // United Kingdom of Great Britain and Northern Ireland
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gh", // Ghana
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gm", // Gambia
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gn", // Guinea
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gw", // Guinea Bissau
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ie", // Ireland
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "lr", // Liberia
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "is", // Iceland
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ma", // Morocco
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ml", // Mali
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "mr", // Mauritania
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "pt", // Portugal
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "sl", // Sierra Leone
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "sn", // Senegal
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "st", // Sao Tome and Principe
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "tg", // Togo
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1945fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    private class CellInfoResult {
1955fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        List<CellInfo> list;
1965fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        Object lockObj = new Object();
1975fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    }
1985fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Reason for registration denial. */
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String REGISTRATION_DENIED_GEN  = "General";
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String REGISTRATION_DENIED_AUTH = "Authentication Failure";
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
203049ab0421f32e6effc5d1277b69bd382cebadb18Wink Saville    protected ServiceStateTracker(PhoneBase phoneBase, CommandsInterface ci, CellInfo cellInfo) {
204ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        mPhoneBase = phoneBase;
205ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        mCellInfo = cellInfo;
20622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi = ci;
207f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville        mVoiceCapable = mPhoneBase.getContext().getResources().getBoolean(
208f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville                com.android.internal.R.bool.config_voice_capable);
209e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        mUiccController = UiccController.getInstance();
210e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
21122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
2125fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        mCi.registerForCellInfoList(this, EVENT_UNSOL_CELL_INFO_LIST, null);
213c4161078eff3305894f1f9f1b2f00952ea0e83d8Kazuya Ohshiro
214c4161078eff3305894f1f9f1b2f00952ea0e83d8Kazuya Ohshiro        mPhoneBase.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
215c4161078eff3305894f1f9f1b2f00952ea0e83d8Kazuya Ohshiro            ServiceState.rilRadioTechnologyToString(ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN));
216ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
217ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
218ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    public void dispose() {
21922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unSetOnSignalStrengthUpdate(this);
220c26fb77c4e637466cf0483a4995fe82e6f68b8d3Alex Yakavenka        mUiccController.unregisterForIccChanged(this);
2215fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        mCi.unregisterForCellInfoList(this);
2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean getDesiredPowerState() {
2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return mDesiredPowerState;
2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
228ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    private SignalStrength mLastSignalStrength = null;
229ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected boolean notifySignalStrength() {
230ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        boolean notified = false;
231ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        synchronized(mCellInfo) {
232ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville            if (!mSignalStrength.equals(mLastSignalStrength)) {
233ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                try {
234ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                    mPhoneBase.notifySignalStrength();
235ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                    notified = true;
236ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                } catch (NullPointerException ex) {
237ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                    loge("updateSignalStrength() Phone already destroyed: " + ex
238ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                            + "SignalStrength not notified");
239ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                }
240ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville            }
241ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        }
242ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        return notified;
243ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
244ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
245ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    /**
246203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * Notify all mDataConnectionRatChangeRegistrants using an
247203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * AsyncResult in msg.obj where AsyncResult#result contains the
248203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * new RAT as an Integer Object.
249203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     */
250203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    protected void notifyDataRegStateRilRadioTechnologyChanged() {
251203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        int rat = mSS.getRilDataRadioTechnology();
252203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        int drs = mSS.getDataRegState();
253203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        if (DBG) log("notifyDataRegStateRilRadioTechnologyChanged: drs=" + drs + " rat=" + rat);
254203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        mPhoneBase.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
255203e588e3c42a81aa8a56f595119c181a63b12caWink Saville                ServiceState.rilRadioTechnologyToString(rat));
256203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        mDataRegStateOrRatChangedRegistrants.notifyResult(new Pair<Integer, Integer>(drs, rat));
257203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    }
258203e588e3c42a81aa8a56f595119c181a63b12caWink Saville
259203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    /**
260f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville     * Some operators have been known to report registration failure
261f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville     * data only devices, to fix that use DataRegState.
262f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville     */
263f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville    protected void useDataRegStateForDataOnlyDevices() {
264f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville        if (mVoiceCapable == false) {
265f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville            if (DBG) {
266f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville                log("useDataRegStateForDataOnlyDevice: VoiceRegState=" + mNewSS.getVoiceRegState()
267f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville                    + " DataRegState=" + mNewSS.getDataRegState());
268f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville            }
269f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville            // TODO: Consider not lying and instead have callers know the difference.
270f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville            mNewSS.setVoiceRegState(mNewSS.getDataRegState());
271f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville        }
272f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville    }
273f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville
274b54cd09892e0676d719e6df00e60c77b663f993cWink Saville    protected void updatePhoneObject() {
275b54cd09892e0676d719e6df00e60c77b663f993cWink Saville        mPhoneBase.updatePhoneObject(mSS.getRilVoiceRadioTechnology());
276b54cd09892e0676d719e6df00e60c77b663f993cWink Saville    }
277f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville
278f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville    /**
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for combined roaming on
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * combined roaming is true when roaming is true and ONS differs SPN
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public  void registerForRoamingOn(Handler h, int what, Object obj) {
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mRoamingOnRegistrants.add(r);
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
29022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mSS.getRoaming()) {
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public  void unregisterForRoamingOn(Handler h) {
2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mRoamingOnRegistrants.remove(h);
2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for combined roaming off
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * combined roaming is true when roaming is true and ONS differs SPN
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public  void registerForRoamingOff(Handler h, int what, Object obj) {
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mRoamingOffRegistrants.add(r);
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
31122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (!mSS.getRoaming()) {
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public  void unregisterForRoamingOff(Handler h) {
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mRoamingOffRegistrants.remove(h);
3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Re-register network by toggling preferred network type.
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * This is a work-around to deregister and register network since there is
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * no ril api to set COPS=2 (deregister) only.
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param onComplete is dispatched when this is complete.  it will be
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * an AsyncResult, and onComplete.obj.exception will be non-null
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * on failure.
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void reRegisterNetwork(Message onComplete) {
33022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.getPreferredNetworkType(
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE, onComplete));
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    setRadioPower(boolean power) {
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDesiredPowerState = power;
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        setPowerStateToDesired();
3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * These two flags manage the behavior of the cell lock -- the
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * lock should be held if either flag is true.  The intention is
3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * to allow temporary acquisition of the lock to get a single
3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * update.  Such a lock grab and release can thus be made to not
3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * interfere with more permanent lock holds -- in other words, the
3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * lock will only be released if both flags are false, and so
3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * releases by temporary users will only affect the lock state if
3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * there is no continuous user.
3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mWantContinuousLocationUpdates;
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mWantSingleLocationUpdate;
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void enableSingleLocationUpdate() {
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return;
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantSingleLocationUpdate = true;
35722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED));
3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void enableLocationUpdates() {
3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return;
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantContinuousLocationUpdates = true;
36322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED));
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void disableSingleLocationUpdate() {
3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantSingleLocationUpdate = false;
3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) {
36922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.setLocationUpdates(false, null);
3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void disableLocationUpdates() {
3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantContinuousLocationUpdates = false;
3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) {
37622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.setLocationUpdates(false, null);
3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void handleMessage(Message msg) {
3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (msg.what) {
3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SET_RADIO_POWER_OFF:
3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                synchronized(this) {
3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (mPendingRadioPowerOffAfterDataOff &&
3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            (msg.arg1 == mPendingRadioPowerOffAfterDataOffTag)) {
3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now.");
3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        hangupAndPowerOff();
3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mPendingRadioPowerOffAfterDataOffTag += 1;
3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mPendingRadioPowerOffAfterDataOff = false;
3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("EVENT_SET_RADIO_OFF is stale arg1=" + msg.arg1 +
3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                "!= tag=" + mPendingRadioPowerOffAfterDataOffTag);
3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
398e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            case EVENT_ICC_CHANGED:
399e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                onUpdateIccAvailability();
400e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                break;
401e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
4025fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            case EVENT_GET_CELL_INFO_LIST: {
4035fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                AsyncResult ar = (AsyncResult) msg.obj;
4045fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                CellInfoResult result = (CellInfoResult) ar.userObj;
4055fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                synchronized(result.lockObj) {
4065fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    if (ar.exception != null) {
4075fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        log("EVENT_GET_CELL_INFO_LIST: error ret null, e=" + ar.exception);
4085fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        result.list = null;
4095fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    } else {
4105fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        result.list = (List<CellInfo>) ar.result;
4115fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
4125fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        if (VDBG) {
4135fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                            log("EVENT_GET_CELL_INFO_LIST: size=" + result.list.size()
4145fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                                    + " list=" + result.list);
4155fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        }
4165fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    }
4170c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    mLastCellInfoListTime = SystemClock.elapsedRealtime();
4185fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    mLastCellInfoList = result.list;
4195fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    result.lockObj.notify();
4205fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                }
4215fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                break;
4225fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            }
4235fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
4245fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            case EVENT_UNSOL_CELL_INFO_LIST: {
4255fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                AsyncResult ar = (AsyncResult) msg.obj;
4265fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                if (ar.exception != null) {
4275fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    log("EVENT_UNSOL_CELL_INFO_LIST: error ignoring, e=" + ar.exception);
4285fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                } else {
4295fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    List<CellInfo> list = (List<CellInfo>) ar.result;
4305fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    if (DBG) {
4315fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        log("EVENT_UNSOL_CELL_INFO_LIST: size=" + list.size()
4325fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                                + " list=" + list);
4335fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    }
4340c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    mLastCellInfoListTime = SystemClock.elapsedRealtime();
4355fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    mLastCellInfoList = list;
4365fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    mPhoneBase.notifyCellInfo(list);
4375fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                }
4385fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                break;
4395fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            }
4405fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("Unhandled message with number: " + msg.what);
4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract Phone getPhone();
4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void handlePollStateResult(int what, AsyncResult ar);
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void updateSpnDisplay();
4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void setPowerStateToDesired();
451e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected abstract void onUpdateIccAvailability();
4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void log(String s);
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void loge(String s);
4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public abstract int getCurrentDataConnectionState();
4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public abstract boolean isConcurrentVoiceAndDataAllowed();
4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into DataConnection attached.
4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForDataConnectionAttached(Handler h, int what, Object obj) {
4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mAttachedRegistrants.add(r);
4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (getCurrentDataConnectionState() == ServiceState.STATE_IN_SERVICE) {
4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
4700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForDataConnectionAttached(Handler h) {
4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mAttachedRegistrants.remove(h);
4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into DataConnection detached.
4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
4810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForDataConnectionDetached(Handler h, int what, Object obj) {
4830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDetachedRegistrants.add(r);
4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (getCurrentDataConnectionState() != ServiceState.STATE_IN_SERVICE) {
4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForDataConnectionDetached(Handler h) {
4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDetachedRegistrants.remove(h);
4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
495203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * Registration for DataConnection RIL Data Radio Technology changing. The
496203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * new radio technology will be returned AsyncResult#result as an Integer Object.
497203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * The AsyncResult will be in the notification Message#obj.
498203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     *
499203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * @param h handler to notify
500203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * @param what what code of message when delivered
501203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * @param obj placed in Message.obj
502203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     */
503203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    public void registerForDataRegStateOrRatChanged(Handler h, int what, Object obj) {
504203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        Registrant r = new Registrant(h, what, obj);
505203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        mDataRegStateOrRatChangedRegistrants.add(r);
506203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        notifyDataRegStateRilRadioTechnologyChanged();
507203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    }
508203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    public void unregisterForDataRegStateOrRatChanged(Handler h) {
509203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        mDataRegStateOrRatChangedRegistrants.remove(h);
510203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    }
511203e588e3c42a81aa8a56f595119c181a63b12caWink Saville
512203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    /**
5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into network attached.
5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj in Message.obj
5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForNetworkAttached(Handler h, int what, Object obj) {
5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNetworkAttachedRegistrants.add(r);
52222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE) {
5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForNetworkAttached(Handler h) {
5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNetworkAttachedRegistrants.remove(h);
5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into packet service restricted zone.
5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForPsRestrictedEnabled(Handler h, int what, Object obj) {
5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictEnabledRegistrants.add(r);
5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mRestrictedState.isPsRestricted()) {
5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForPsRestrictedEnabled(Handler h) {
5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictEnabledRegistrants.remove(h);
5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition out of packet service restricted zone.
5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForPsRestrictedDisabled(Handler h, int what, Object obj) {
5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictDisabledRegistrants.add(r);
5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mRestrictedState.isPsRestricted()) {
5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForPsRestrictedDisabled(Handler h) {
5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictDisabledRegistrants.remove(h);
5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Clean up existing voice and data connection then turn off radio power.
5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Hang up the existing voice calls to decrease call drop rate.
5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
573454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    public void powerOffRadioSafely(DcTrackerBase dcTracker) {
5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (this) {
5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!mPendingRadioPowerOffAfterDataOff) {
5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // To minimize race conditions we call cleanUpAllConnections on
5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // both if else paths instead of before this isDisconnected test.
5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (dcTracker.isDisconnected()) {
5790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // To minimize race conditions we do this after isDisconnected
5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF);
5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) log("Data disconnected, turn off radio right away.");
5820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    hangupAndPowerOff();
5830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF);
5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    Message msg = Message.obtain(this);
5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    msg.what = EVENT_SET_RADIO_POWER_OFF;
5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    msg.arg1 = ++mPendingRadioPowerOffAfterDataOffTag;
5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (sendMessageDelayed(msg, 30000)) {
5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("Wait upto 30s for data to disconnect, then turn off radio.");
5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mPendingRadioPowerOffAfterDataOff = true;
5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("Cannot send delayed Msg, turn off radio right away.");
5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        hangupAndPowerOff();
5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * process the pending request to turn radio off after data is disconnected
6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * return true if there is pending request to process; false otherwise.
6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean processPendingRadioPowerOffAfterDataOff() {
6060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized(this) {
6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mPendingRadioPowerOffAfterDataOff) {
6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("Process pending request to turn radio off.");
6090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPendingRadioPowerOffAfterDataOffTag += 1;
6100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangupAndPowerOff();
6110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPendingRadioPowerOffAfterDataOff = false;
6120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return true;
6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
6195b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam     * send signal-strength-changed notification if changed Called both for
6205b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam     * solicited and unsolicited signal strength updates
621e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville     *
622e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville     * @return true if the signal strength changed and a notification was sent.
6235b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam     */
624e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville    protected boolean onSignalStrengthResult(AsyncResult ar, boolean isGsm) {
6255b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        SignalStrength oldSignalStrength = mSignalStrength;
6265b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam
6275b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        // This signal is used for both voice and data radio signal so parse
6285b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        // all fields
6295b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam
6305b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        if ((ar.exception == null) && (ar.result != null)) {
6315b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            mSignalStrength = (SignalStrength) ar.result;
6325b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            mSignalStrength.validateInput();
6335b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            mSignalStrength.setGsm(isGsm);
6345b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        } else {
6355b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            log("onSignalStrengthResult() Exception from RIL : " + ar.exception);
6365b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            mSignalStrength = new SignalStrength(isGsm);
6375b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        }
6385b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam
639e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville        return notifySignalStrength();
6405b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam    }
6415b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam
6425b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam    /**
6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Hang up all voice call and turn off radio. Implemented by derived class.
6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void hangupAndPowerOff();
6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Cancel a pending (if any) pollState() operation */
6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void cancelPollState() {
6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // This will effectively cancel the rest of the poll requests.
65022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPollingContext = new int[1];
6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Return true if time zone needs fixing.
6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param phoneBase
6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param operatorNumeric
6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param prevOperatorNumeric
6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param needToFixTimeZone
6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if time zone needs to be fixed
6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean shouldFixTimeZoneNow(PhoneBase phoneBase, String operatorNumeric,
6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String prevOperatorNumeric, boolean needToFixTimeZone) {
6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Return false if the mcc isn't valid as we don't know where we are.
6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Return true if we have an IccCard and the mcc changed or we
6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // need to fix it because when the NITZ time came in we didn't
6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // know the country code.
6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If mcc is invalid then we'll return false
6700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int mcc;
6710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mcc = Integer.parseInt(operatorNumeric.substring(0, 3));
6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (Exception e) {
6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("shouldFixTimeZoneNow: no mcc, operatorNumeric=" + operatorNumeric +
6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        " retVal=false");
6770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If prevMcc is invalid will make it different from mcc
6820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // so we'll return true if the card exists.
6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int prevMcc;
6840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
6850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            prevMcc = Integer.parseInt(prevOperatorNumeric.substring(0, 3));
6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (Exception e) {
6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            prevMcc = mcc + 1;
6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Determine if the Icc card exists
691e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        boolean iccCardExist = false;
692e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mUiccApplcation != null) {
693e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            iccCardExist = mUiccApplcation.getState() != AppState.APPSTATE_UNKNOWN;
694e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
6950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Determine retVal
6970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean retVal = ((iccCardExist && (mcc != prevMcc)) || needToFixTimeZone);
6980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
6990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            long ctm = System.currentTimeMillis();
7000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("shouldFixTimeZoneNow: retVal=" + retVal +
7010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " iccCardExist=" + iccCardExist +
7020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " operatorNumeric=" + operatorNumeric + " mcc=" + mcc +
7030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " prevOperatorNumeric=" + prevOperatorNumeric + " prevMcc=" + prevMcc +
7040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " needToFixTimeZone=" + needToFixTimeZone +
7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " ltod=" + TimeUtils.logTimeOfDay(ctm));
7060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return retVal;
7080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
710ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    /**
711ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     * @return all available cell information or null if none.
712ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     */
713ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    public List<CellInfo> getAllCellInfo() {
7145fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        CellInfoResult result = new CellInfoResult();
7155fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        if (VDBG) log("SST.getAllCellInfo(): E");
7165fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        int ver = mCi.getRilVersion();
7175fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        if (ver >= 8) {
7185fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            if (isCallerOnDifferentThread()) {
7190c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                if ((SystemClock.elapsedRealtime() - mLastCellInfoListTime)
7200c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        > LAST_CELL_INFO_LIST_MAX_AGE_MS) {
7210c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    Message msg = obtainMessage(EVENT_GET_CELL_INFO_LIST, result);
7220c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    synchronized(result.lockObj) {
7230c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        mCi.getCellInfoList(msg);
7240c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        try {
7250c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                            result.lockObj.wait();
7260c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        } catch (InterruptedException e) {
7270c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                            e.printStackTrace();
7280c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                            result.list = null;
7290c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        }
7305fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    }
7310c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                } else {
7320c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    if (DBG) log("SST.getAllCellInfo(): return last, back to back calls");
7330c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    result.list = mLastCellInfoList;
7345fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                }
7355fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            } else {
7360c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                if (DBG) log("SST.getAllCellInfo(): return last, same thread can't block");
7375fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                result.list = mLastCellInfoList;
7385fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            }
7395fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        } else {
7400c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville            if (DBG) log("SST.getAllCellInfo(): not implemented");
7415fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            result.list = null;
7425fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        }
7435fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        if (DBG) {
7445fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            if (result.list != null) {
7455fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                log("SST.getAllCellInfo(): X size=" + result.list.size()
7465fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        + " list=" + result.list);
7475fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            } else {
7485fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                log("SST.getAllCellInfo(): X size=0 list=null");
7495fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            }
7505fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        }
7515fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        return result.list;
752ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
753ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
754ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    /**
755ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     * @return signal strength
756ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     */
757ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    public SignalStrength getSignalStrength() {
758ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        synchronized(mCellInfo) {
759ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville            return mSignalStrength;
760ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        }
761ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
762ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
7630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
7640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println("ServiceStateTracker:");
76522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mSS=" + mSS);
76622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mNewSS=" + mNewSS);
767ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        pw.println(" mCellInfo=" + mCellInfo);
7680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mRestrictedState=" + mRestrictedState);
76922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mPollingContext=" + mPollingContext);
7700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mDesiredPowerState=" + mDesiredPowerState);
77122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mDontPollSignalStrength=" + mDontPollSignalStrength);
7720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mPendingRadioPowerOffAfterDataOff=" + mPendingRadioPowerOffAfterDataOff);
7730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mPendingRadioPowerOffAfterDataOffTag=" + mPendingRadioPowerOffAfterDataOffTag);
7740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
775e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
776e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    /**
777e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * Verifies the current thread is the same as the thread originally
778e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * used in the initialization of this instance. Throws RuntimeException
779e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * if not.
780e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     *
781e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * @exception RuntimeException if the current thread is not
782e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * the thread that originally obtained this PhoneBase instance.
783e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     */
784e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected void checkCorrectThread() {
785e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (Thread.currentThread() != getLooper().getThread()) {
786e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            throw new RuntimeException(
787e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                    "ServiceStateTracker must be used from within one thread");
788e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        }
789e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    }
7905fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
7915fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected boolean isCallerOnDifferentThread() {
7925fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        boolean value = Thread.currentThread() != getLooper().getThread();
7935fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        if (VDBG) log("isCallerOnDifferentThread: " + value);
7945fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        return value;
7955fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    }
796b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt
797b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt    protected void updateCarrierMccMncConfiguration(String newOp, String oldOp, Context context) {
798b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt        // if we have a change in operator, notify wifi (even to/from none)
799b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt        if (((newOp == null) && (TextUtils.isEmpty(oldOp) == false)) ||
800b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                ((newOp != null) && (newOp.equals(oldOp) == false))) {
801b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt            MccTable.updateMccMncConfiguration(context, newOp, true);
802b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt        }
803b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt    }
8040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
805