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
190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler;
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Registrant;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.RegistrantList;
240c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Savilleimport android.os.SystemClock;
25ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Savilleimport android.telephony.CellInfo;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.ServiceState;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.SignalStrength;
28203e588e3c42a81aa8a56f595119c181a63b12caWink Savilleimport android.util.Pair;
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.TimeUtils;
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.FileDescriptor;
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.PrintWriter;
335fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Savilleimport java.util.ArrayList;
34ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Savilleimport java.util.List;
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
36454b1dfd508844b42eb775e4ab2359be74d3672bWink Savilleimport com.android.internal.telephony.dataconnection.DcTrackerBase;
37d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
38d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccRecords;
39d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.UiccCardApplication;
40e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenkaimport com.android.internal.telephony.uicc.UiccController;
41e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic abstract class ServiceStateTracker extends Handler {
465fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected  static final boolean DBG = true;
475fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected static final boolean VDBG = false;
485fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
4960ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkey    protected static final String PROP_FORCE_ROAMING = "telephony.test.forceRoaming";
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected CommandsInterface mCi;
52e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected UiccController mUiccController = null;
53e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    protected UiccCardApplication mUiccApplcation = null;
54e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected IccRecords mIccRecords = null;
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
56ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected PhoneBase mPhoneBase;
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
58f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville    protected boolean mVoiceCapable;
59f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville
6022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    public ServiceState mSS = new ServiceState();
6122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected ServiceState mNewSS = new ServiceState();
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
630c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville    private static final long LAST_CELL_INFO_LIST_MAX_AGE_MS = 2000;
640c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville    protected long mLastCellInfoListTime;
655fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected List<CellInfo> mLastCellInfoList = null;
66ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
67ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    // This is final as subclasses alias to a more specific type
68ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    // so we don't want the reference to change.
69ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected final CellInfo mCellInfo;
70ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
71ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected SignalStrength mSignalStrength = new SignalStrength();
72ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
73ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    // TODO - this should not be public, right now used externally GsmConnetion.
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public RestrictedState mRestrictedState = new RestrictedState();
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* The otaspMode passed to PhoneStateListener#onOtaspChanged */
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_UNINITIALIZED = 0;
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_UNKNOWN = 1;
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_NEEDED = 2;
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_NOT_NEEDED = 3;
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * A unique identifier to track requests associated with a poll
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * and ignore stale responses.  The value is a count-down of
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * expected responses in this pollingContext.
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
8722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected int[] mPollingContext;
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean mDesiredPowerState;
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * By default, strength polling is enabled.  However, if we're
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * getting unsolicited signal strength updates from the radio, set
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * value to true and don't bother polling any more.
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
9522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected boolean mDontPollSignalStrength = false;
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mRoamingOnRegistrants = new RegistrantList();
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mRoamingOffRegistrants = new RegistrantList();
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mAttachedRegistrants = new RegistrantList();
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mDetachedRegistrants = new RegistrantList();
101203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    protected RegistrantList mDataRegStateOrRatChangedRegistrants = new RegistrantList();
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mNetworkAttachedRegistrants = new RegistrantList();
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mPsRestrictEnabledRegistrants = new RegistrantList();
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mPsRestrictDisabledRegistrants = new RegistrantList();
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* Radio power off pending flag and tag counter */
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mPendingRadioPowerOffAfterDataOff = false;
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mPendingRadioPowerOffAfterDataOffTag = 0;
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Signal strength poll rate. */
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int POLL_PERIOD_MILLIS = 20 * 1000;
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Waiting period before recheck gprs and voice registration. */
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** GSM events */
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RADIO_STATE_CHANGED               = 1;
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NETWORK_STATE_CHANGED             = 2;
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_SIGNAL_STRENGTH               = 3;
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_REGISTRATION           = 4;
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_GPRS                   = 5;
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_OPERATOR               = 6;
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_SIGNAL_STRENGTH              = 10;
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NITZ_TIME                         = 11;
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SIGNAL_STRENGTH_UPDATE            = 12;
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RADIO_AVAILABLE                   = 13;
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_NETWORK_SELECTION_MODE = 14;
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_LOC_DONE                      = 15;
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SIM_RECORDS_LOADED                = 16;
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SIM_READY                         = 17;
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_LOCATION_UPDATES_ENABLED          = 18;
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_PREFERRED_NETWORK_TYPE        = 19;
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SET_PREFERRED_NETWORK_TYPE        = 20;
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RESET_PREFERRED_NETWORK_TYPE      = 21;
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_CHECK_REPORT_GPRS                 = 22;
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RESTRICTED_STATE_CHANGED          = 23;
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** CDMA events */
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_REGISTRATION_CDMA      = 24;
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_OPERATOR_CDMA          = 25;
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RUIM_READY                        = 26;
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RUIM_RECORDS_LOADED               = 27;
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_SIGNAL_STRENGTH_CDMA         = 28;
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_SIGNAL_STRENGTH_CDMA          = 29;
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NETWORK_STATE_CHANGED_CDMA        = 30;
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_LOC_DONE_CDMA                 = 31;
147ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    //protected static final int EVENT_UNUSED                            = 32;
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NV_LOADED                         = 33;
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_CDMA_SUBSCRIPTION      = 34;
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NV_READY                          = 35;
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_ERI_FILE_LOADED                   = 36;
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_OTA_PROVISION_STATUS_CHANGE       = 37;
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SET_RADIO_POWER_OFF               = 38;
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED  = 39;
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_CDMA_PRL_VERSION_CHANGED          = 40;
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RADIO_ON                          = 41;
157e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected static final int EVENT_ICC_CHANGED                       = 42;
1585fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected static final int EVENT_GET_CELL_INFO_LIST                = 43;
1595fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected static final int EVENT_UNSOL_CELL_INFO_LIST              = 44;
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * List of ISO codes for countries that can have an offset of
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * GMT+0 when not in daylight savings time.  This ignores some
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * small places such as the Canary Islands (Spain) and
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Danmarkshavn (Denmark).  The list must be sorted by code.
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    */
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String[] GMT_COUNTRY_CODES = {
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "bf", // Burkina Faso
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ci", // Cote d'Ivoire
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "eh", // Western Sahara
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "fo", // Faroe Islands, Denmark
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gb", // United Kingdom of Great Britain and Northern Ireland
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gh", // Ghana
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gm", // Gambia
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gn", // Guinea
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gw", // Guinea Bissau
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ie", // Ireland
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "lr", // Liberia
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "is", // Iceland
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ma", // Morocco
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ml", // Mali
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "mr", // Mauritania
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "pt", // Portugal
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "sl", // Sierra Leone
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "sn", // Senegal
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "st", // Sao Tome and Principe
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "tg", // Togo
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1925fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    private class CellInfoResult {
1935fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        List<CellInfo> list;
1945fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        Object lockObj = new Object();
1955fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    }
1965fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Reason for registration denial. */
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String REGISTRATION_DENIED_GEN  = "General";
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String REGISTRATION_DENIED_AUTH = "Authentication Failure";
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
201049ab0421f32e6effc5d1277b69bd382cebadb18Wink Saville    protected ServiceStateTracker(PhoneBase phoneBase, CommandsInterface ci, CellInfo cellInfo) {
202ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        mPhoneBase = phoneBase;
203ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        mCellInfo = cellInfo;
20422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi = ci;
205f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville        mVoiceCapable = mPhoneBase.getContext().getResources().getBoolean(
206f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville                com.android.internal.R.bool.config_voice_capable);
207e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        mUiccController = UiccController.getInstance();
208e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
20922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
2105fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        mCi.registerForCellInfoList(this, EVENT_UNSOL_CELL_INFO_LIST, null);
211c4161078eff3305894f1f9f1b2f00952ea0e83d8Kazuya Ohshiro
212c4161078eff3305894f1f9f1b2f00952ea0e83d8Kazuya Ohshiro        mPhoneBase.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
213c4161078eff3305894f1f9f1b2f00952ea0e83d8Kazuya Ohshiro            ServiceState.rilRadioTechnologyToString(ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN));
214ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
215ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
216ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    public void dispose() {
21722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unSetOnSignalStrengthUpdate(this);
218c26fb77c4e637466cf0483a4995fe82e6f68b8d3Alex Yakavenka        mUiccController.unregisterForIccChanged(this);
2195fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        mCi.unregisterForCellInfoList(this);
2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean getDesiredPowerState() {
2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return mDesiredPowerState;
2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
226ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    private SignalStrength mLastSignalStrength = null;
227ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected boolean notifySignalStrength() {
228ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        boolean notified = false;
229ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        synchronized(mCellInfo) {
230ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville            if (!mSignalStrength.equals(mLastSignalStrength)) {
231ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                try {
232ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                    mPhoneBase.notifySignalStrength();
233ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                    notified = true;
234ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                } catch (NullPointerException ex) {
235ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                    loge("updateSignalStrength() Phone already destroyed: " + ex
236ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                            + "SignalStrength not notified");
237ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                }
238ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville            }
239ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        }
240ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        return notified;
241ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
242ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
243ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    /**
244203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * Notify all mDataConnectionRatChangeRegistrants using an
245203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * AsyncResult in msg.obj where AsyncResult#result contains the
246203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * new RAT as an Integer Object.
247203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     */
248203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    protected void notifyDataRegStateRilRadioTechnologyChanged() {
249203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        int rat = mSS.getRilDataRadioTechnology();
250203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        int drs = mSS.getDataRegState();
251203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        if (DBG) log("notifyDataRegStateRilRadioTechnologyChanged: drs=" + drs + " rat=" + rat);
252203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        mPhoneBase.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
253203e588e3c42a81aa8a56f595119c181a63b12caWink Saville                ServiceState.rilRadioTechnologyToString(rat));
254203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        mDataRegStateOrRatChangedRegistrants.notifyResult(new Pair<Integer, Integer>(drs, rat));
255203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    }
256203e588e3c42a81aa8a56f595119c181a63b12caWink Saville
257203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    /**
258f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville     * Some operators have been known to report registration failure
259f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville     * data only devices, to fix that use DataRegState.
260f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville     */
261f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville    protected void useDataRegStateForDataOnlyDevices() {
262f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville        if (mVoiceCapable == false) {
263f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville            if (DBG) {
264f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville                log("useDataRegStateForDataOnlyDevice: VoiceRegState=" + mNewSS.getVoiceRegState()
265f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville                    + " DataRegState=" + mNewSS.getDataRegState());
266f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville            }
267f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville            // TODO: Consider not lying and instead have callers know the difference.
268f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville            mNewSS.setVoiceRegState(mNewSS.getDataRegState());
269f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville        }
270f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville    }
271f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville
272b54cd09892e0676d719e6df00e60c77b663f993cWink Saville    protected void updatePhoneObject() {
273b54cd09892e0676d719e6df00e60c77b663f993cWink Saville        mPhoneBase.updatePhoneObject(mSS.getRilVoiceRadioTechnology());
274b54cd09892e0676d719e6df00e60c77b663f993cWink Saville    }
275f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville
276f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville    /**
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for combined roaming on
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * combined roaming is true when roaming is true and ONS differs SPN
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public  void registerForRoamingOn(Handler h, int what, Object obj) {
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mRoamingOnRegistrants.add(r);
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
28822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mSS.getRoaming()) {
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public  void unregisterForRoamingOn(Handler h) {
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mRoamingOnRegistrants.remove(h);
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for combined roaming off
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * combined roaming is true when roaming is true and ONS differs SPN
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public  void registerForRoamingOff(Handler h, int what, Object obj) {
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mRoamingOffRegistrants.add(r);
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
30922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (!mSS.getRoaming()) {
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public  void unregisterForRoamingOff(Handler h) {
3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mRoamingOffRegistrants.remove(h);
3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Re-register network by toggling preferred network type.
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * This is a work-around to deregister and register network since there is
3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * no ril api to set COPS=2 (deregister) only.
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param onComplete is dispatched when this is complete.  it will be
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * an AsyncResult, and onComplete.obj.exception will be non-null
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * on failure.
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void reRegisterNetwork(Message onComplete) {
32822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.getPreferredNetworkType(
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE, onComplete));
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    setRadioPower(boolean power) {
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDesiredPowerState = power;
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        setPowerStateToDesired();
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * These two flags manage the behavior of the cell lock -- the
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * lock should be held if either flag is true.  The intention is
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * to allow temporary acquisition of the lock to get a single
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * update.  Such a lock grab and release can thus be made to not
3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * interfere with more permanent lock holds -- in other words, the
3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * lock will only be released if both flags are false, and so
3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * releases by temporary users will only affect the lock state if
3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * there is no continuous user.
3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mWantContinuousLocationUpdates;
3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mWantSingleLocationUpdate;
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void enableSingleLocationUpdate() {
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return;
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantSingleLocationUpdate = true;
35522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED));
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void enableLocationUpdates() {
3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return;
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantContinuousLocationUpdates = true;
36122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED));
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void disableSingleLocationUpdate() {
3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantSingleLocationUpdate = false;
3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) {
36722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.setLocationUpdates(false, null);
3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void disableLocationUpdates() {
3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantContinuousLocationUpdates = false;
3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) {
37422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.setLocationUpdates(false, null);
3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void handleMessage(Message msg) {
3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (msg.what) {
3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SET_RADIO_POWER_OFF:
3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                synchronized(this) {
3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (mPendingRadioPowerOffAfterDataOff &&
3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            (msg.arg1 == mPendingRadioPowerOffAfterDataOffTag)) {
3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now.");
3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        hangupAndPowerOff();
3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mPendingRadioPowerOffAfterDataOffTag += 1;
3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mPendingRadioPowerOffAfterDataOff = false;
3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("EVENT_SET_RADIO_OFF is stale arg1=" + msg.arg1 +
3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                "!= tag=" + mPendingRadioPowerOffAfterDataOffTag);
3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
396e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            case EVENT_ICC_CHANGED:
397e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                onUpdateIccAvailability();
398e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                break;
399e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
4005fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            case EVENT_GET_CELL_INFO_LIST: {
4015fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                AsyncResult ar = (AsyncResult) msg.obj;
4025fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                CellInfoResult result = (CellInfoResult) ar.userObj;
4035fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                synchronized(result.lockObj) {
4045fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    if (ar.exception != null) {
4055fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        log("EVENT_GET_CELL_INFO_LIST: error ret null, e=" + ar.exception);
4065fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        result.list = null;
4075fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    } else {
4085fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        result.list = (List<CellInfo>) ar.result;
4095fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
4105fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        if (VDBG) {
4115fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                            log("EVENT_GET_CELL_INFO_LIST: size=" + result.list.size()
4125fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                                    + " list=" + result.list);
4135fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        }
4145fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    }
4150c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    mLastCellInfoListTime = SystemClock.elapsedRealtime();
4165fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    mLastCellInfoList = result.list;
4175fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    result.lockObj.notify();
4185fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                }
4195fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                break;
4205fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            }
4215fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
4225fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            case EVENT_UNSOL_CELL_INFO_LIST: {
4235fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                AsyncResult ar = (AsyncResult) msg.obj;
4245fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                if (ar.exception != null) {
4255fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    log("EVENT_UNSOL_CELL_INFO_LIST: error ignoring, e=" + ar.exception);
4265fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                } else {
4275fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    List<CellInfo> list = (List<CellInfo>) ar.result;
4285fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    if (DBG) {
4295fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        log("EVENT_UNSOL_CELL_INFO_LIST: size=" + list.size()
4305fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                                + " list=" + list);
4315fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    }
4320c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    mLastCellInfoListTime = SystemClock.elapsedRealtime();
4335fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    mLastCellInfoList = list;
4345fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    mPhoneBase.notifyCellInfo(list);
4355fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                }
4365fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                break;
4375fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            }
4385fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("Unhandled message with number: " + msg.what);
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract Phone getPhone();
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void handlePollStateResult(int what, AsyncResult ar);
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void updateSpnDisplay();
4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void setPowerStateToDesired();
449e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected abstract void onUpdateIccAvailability();
4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void log(String s);
4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void loge(String s);
4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public abstract int getCurrentDataConnectionState();
4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public abstract boolean isConcurrentVoiceAndDataAllowed();
4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into DataConnection attached.
4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForDataConnectionAttached(Handler h, int what, Object obj) {
4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mAttachedRegistrants.add(r);
4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (getCurrentDataConnectionState() == ServiceState.STATE_IN_SERVICE) {
4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForDataConnectionAttached(Handler h) {
4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mAttachedRegistrants.remove(h);
4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into DataConnection detached.
4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForDataConnectionDetached(Handler h, int what, Object obj) {
4810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
4820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDetachedRegistrants.add(r);
4830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (getCurrentDataConnectionState() != ServiceState.STATE_IN_SERVICE) {
4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForDataConnectionDetached(Handler h) {
4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDetachedRegistrants.remove(h);
4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
493203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * Registration for DataConnection RIL Data Radio Technology changing. The
494203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * new radio technology will be returned AsyncResult#result as an Integer Object.
495203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * The AsyncResult will be in the notification Message#obj.
496203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     *
497203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * @param h handler to notify
498203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * @param what what code of message when delivered
499203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * @param obj placed in Message.obj
500203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     */
501203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    public void registerForDataRegStateOrRatChanged(Handler h, int what, Object obj) {
502203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        Registrant r = new Registrant(h, what, obj);
503203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        mDataRegStateOrRatChangedRegistrants.add(r);
504203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        notifyDataRegStateRilRadioTechnologyChanged();
505203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    }
506203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    public void unregisterForDataRegStateOrRatChanged(Handler h) {
507203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        mDataRegStateOrRatChangedRegistrants.remove(h);
508203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    }
509203e588e3c42a81aa8a56f595119c181a63b12caWink Saville
510203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    /**
5110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into network attached.
5120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj in Message.obj
5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForNetworkAttached(Handler h, int what, Object obj) {
5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNetworkAttachedRegistrants.add(r);
52022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE) {
5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForNetworkAttached(Handler h) {
5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNetworkAttachedRegistrants.remove(h);
5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into packet service restricted zone.
5300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForPsRestrictedEnabled(Handler h, int what, Object obj) {
5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictEnabledRegistrants.add(r);
5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mRestrictedState.isPsRestricted()) {
5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForPsRestrictedEnabled(Handler h) {
5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictEnabledRegistrants.remove(h);
5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition out of packet service restricted zone.
5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
5500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForPsRestrictedDisabled(Handler h, int what, Object obj) {
5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictDisabledRegistrants.add(r);
5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mRestrictedState.isPsRestricted()) {
5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForPsRestrictedDisabled(Handler h) {
5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictDisabledRegistrants.remove(h);
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Clean up existing voice and data connection then turn off radio power.
5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Hang up the existing voice calls to decrease call drop rate.
5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
571454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    public void powerOffRadioSafely(DcTrackerBase dcTracker) {
5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (this) {
5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!mPendingRadioPowerOffAfterDataOff) {
5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // To minimize race conditions we call cleanUpAllConnections on
5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // both if else paths instead of before this isDisconnected test.
5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (dcTracker.isDisconnected()) {
5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // To minimize race conditions we do this after isDisconnected
5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF);
5790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) log("Data disconnected, turn off radio right away.");
5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    hangupAndPowerOff();
5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
5820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF);
5830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    Message msg = Message.obtain(this);
5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    msg.what = EVENT_SET_RADIO_POWER_OFF;
5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    msg.arg1 = ++mPendingRadioPowerOffAfterDataOffTag;
5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (sendMessageDelayed(msg, 30000)) {
5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("Wait upto 30s for data to disconnect, then turn off radio.");
5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mPendingRadioPowerOffAfterDataOff = true;
5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("Cannot send delayed Msg, turn off radio right away.");
5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        hangupAndPowerOff();
5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * process the pending request to turn radio off after data is disconnected
6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * return true if there is pending request to process; false otherwise.
6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean processPendingRadioPowerOffAfterDataOff() {
6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized(this) {
6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mPendingRadioPowerOffAfterDataOff) {
6060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("Process pending request to turn radio off.");
6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPendingRadioPowerOffAfterDataOffTag += 1;
6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangupAndPowerOff();
6090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPendingRadioPowerOffAfterDataOff = false;
6100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return true;
6110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
6175b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam     * send signal-strength-changed notification if changed Called both for
6185b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam     * solicited and unsolicited signal strength updates
619e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville     *
620e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville     * @return true if the signal strength changed and a notification was sent.
6215b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam     */
622e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville    protected boolean onSignalStrengthResult(AsyncResult ar, boolean isGsm) {
6235b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        SignalStrength oldSignalStrength = mSignalStrength;
6245b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam
6255b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        // This signal is used for both voice and data radio signal so parse
6265b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        // all fields
6275b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam
6285b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        if ((ar.exception == null) && (ar.result != null)) {
6295b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            mSignalStrength = (SignalStrength) ar.result;
6305b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            mSignalStrength.validateInput();
6315b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            mSignalStrength.setGsm(isGsm);
6325b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        } else {
6335b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            log("onSignalStrengthResult() Exception from RIL : " + ar.exception);
6345b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            mSignalStrength = new SignalStrength(isGsm);
6355b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        }
6365b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam
637e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville        return notifySignalStrength();
6385b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam    }
6395b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam
6405b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam    /**
6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Hang up all voice call and turn off radio. Implemented by derived class.
6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void hangupAndPowerOff();
6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Cancel a pending (if any) pollState() operation */
6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void cancelPollState() {
6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // This will effectively cancel the rest of the poll requests.
64822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPollingContext = new int[1];
6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
6520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Return true if time zone needs fixing.
6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param phoneBase
6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param operatorNumeric
6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param prevOperatorNumeric
6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param needToFixTimeZone
6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if time zone needs to be fixed
6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean shouldFixTimeZoneNow(PhoneBase phoneBase, String operatorNumeric,
6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String prevOperatorNumeric, boolean needToFixTimeZone) {
6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Return false if the mcc isn't valid as we don't know where we are.
6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Return true if we have an IccCard and the mcc changed or we
6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // need to fix it because when the NITZ time came in we didn't
6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // know the country code.
6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If mcc is invalid then we'll return false
6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int mcc;
6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
6700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mcc = Integer.parseInt(operatorNumeric.substring(0, 3));
6710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (Exception e) {
6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("shouldFixTimeZoneNow: no mcc, operatorNumeric=" + operatorNumeric +
6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        " retVal=false");
6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
6770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If prevMcc is invalid will make it different from mcc
6800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // so we'll return true if the card exists.
6810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int prevMcc;
6820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            prevMcc = Integer.parseInt(prevOperatorNumeric.substring(0, 3));
6840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (Exception e) {
6850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            prevMcc = mcc + 1;
6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Determine if the Icc card exists
689e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        boolean iccCardExist = false;
690e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mUiccApplcation != null) {
691e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            iccCardExist = mUiccApplcation.getState() != AppState.APPSTATE_UNKNOWN;
692e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
6930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Determine retVal
6950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean retVal = ((iccCardExist && (mcc != prevMcc)) || needToFixTimeZone);
6960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
6970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            long ctm = System.currentTimeMillis();
6980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("shouldFixTimeZoneNow: retVal=" + retVal +
6990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " iccCardExist=" + iccCardExist +
7000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " operatorNumeric=" + operatorNumeric + " mcc=" + mcc +
7010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " prevOperatorNumeric=" + prevOperatorNumeric + " prevMcc=" + prevMcc +
7020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " needToFixTimeZone=" + needToFixTimeZone +
7030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " ltod=" + TimeUtils.logTimeOfDay(ctm));
7040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return retVal;
7060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
708ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    /**
709ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     * @return all available cell information or null if none.
710ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     */
711ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    public List<CellInfo> getAllCellInfo() {
7125fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        CellInfoResult result = new CellInfoResult();
7135fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        if (VDBG) log("SST.getAllCellInfo(): E");
7145fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        int ver = mCi.getRilVersion();
7155fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        if (ver >= 8) {
7165fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            if (isCallerOnDifferentThread()) {
7170c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                if ((SystemClock.elapsedRealtime() - mLastCellInfoListTime)
7180c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        > LAST_CELL_INFO_LIST_MAX_AGE_MS) {
7190c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    Message msg = obtainMessage(EVENT_GET_CELL_INFO_LIST, result);
7200c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    synchronized(result.lockObj) {
7210c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        mCi.getCellInfoList(msg);
7220c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        try {
7230c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                            result.lockObj.wait();
7240c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        } catch (InterruptedException e) {
7250c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                            e.printStackTrace();
7260c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                            result.list = null;
7270c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        }
7285fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    }
7290c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                } else {
7300c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    if (DBG) log("SST.getAllCellInfo(): return last, back to back calls");
7310c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    result.list = mLastCellInfoList;
7325fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                }
7335fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            } else {
7340c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                if (DBG) log("SST.getAllCellInfo(): return last, same thread can't block");
7355fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                result.list = mLastCellInfoList;
7365fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            }
7375fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        } else {
7380c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville            if (DBG) log("SST.getAllCellInfo(): not implemented");
7395fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            result.list = null;
7405fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        }
7415fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        if (DBG) {
7425fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            if (result.list != null) {
7435fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                log("SST.getAllCellInfo(): X size=" + result.list.size()
7445fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        + " list=" + result.list);
7455fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            } else {
7465fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                log("SST.getAllCellInfo(): X size=0 list=null");
7475fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            }
7485fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        }
7495fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        return result.list;
750ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
751ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
752ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    /**
753ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     * @return signal strength
754ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     */
755ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    public SignalStrength getSignalStrength() {
756ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        synchronized(mCellInfo) {
757ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville            return mSignalStrength;
758ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        }
759ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
760ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
7610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
7620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println("ServiceStateTracker:");
76322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mSS=" + mSS);
76422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mNewSS=" + mNewSS);
765ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        pw.println(" mCellInfo=" + mCellInfo);
7660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mRestrictedState=" + mRestrictedState);
76722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mPollingContext=" + mPollingContext);
7680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mDesiredPowerState=" + mDesiredPowerState);
76922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mDontPollSignalStrength=" + mDontPollSignalStrength);
7700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mPendingRadioPowerOffAfterDataOff=" + mPendingRadioPowerOffAfterDataOff);
7710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mPendingRadioPowerOffAfterDataOffTag=" + mPendingRadioPowerOffAfterDataOffTag);
7720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
773e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
774e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    /**
775e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * Verifies the current thread is the same as the thread originally
776e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * used in the initialization of this instance. Throws RuntimeException
777e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * if not.
778e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     *
779e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * @exception RuntimeException if the current thread is not
780e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * the thread that originally obtained this PhoneBase instance.
781e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     */
782e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected void checkCorrectThread() {
783e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (Thread.currentThread() != getLooper().getThread()) {
784e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            throw new RuntimeException(
785e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                    "ServiceStateTracker must be used from within one thread");
786e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        }
787e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    }
7885fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
7895fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected boolean isCallerOnDifferentThread() {
7905fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        boolean value = Thread.currentThread() != getLooper().getThread();
7915fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        if (VDBG) log("isCallerOnDifferentThread: " + value);
7925fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        return value;
7935fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    }
7940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
795