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
19e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.content.Context;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult;
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler;
22e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenkaimport android.os.Looper;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Registrant;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.RegistrantList;
26ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Savilleimport android.os.SystemClock;
27ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Savilleimport android.telephony.CellInfo;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.ServiceState;
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.SignalStrength;
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.TimeUtils;
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.FileDescriptor;
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.PrintWriter;
34ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Savilleimport java.util.List;
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
36e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.IccCardApplicationStatus.AppState;
37e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenkaimport com.android.internal.telephony.uicc.UiccController;
38e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic abstract class ServiceStateTracker extends Handler {
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected CommandsInterface cm;
45e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected UiccController mUiccController = null;
46e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    protected UiccCardApplication mUiccApplcation = null;
47e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected IccRecords mIccRecords = null;
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
49ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected PhoneBase mPhoneBase;
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
51ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    public ServiceState ss = new ServiceState();
52ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected ServiceState newSS = new ServiceState();
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
54ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected CellInfo mLastCellInfo = null;
55ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
56ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    // This is final as subclasses alias to a more specific type
57ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    // so we don't want the reference to change.
58ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected final CellInfo mCellInfo;
59ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
60ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected SignalStrength mSignalStrength = new SignalStrength();
61ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
62ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    // TODO - this should not be public, right now used externally GsmConnetion.
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public RestrictedState mRestrictedState = new RestrictedState();
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* The otaspMode passed to PhoneStateListener#onOtaspChanged */
660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_UNINITIALIZED = 0;
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_UNKNOWN = 1;
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_NEEDED = 2;
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_NOT_NEEDED = 3;
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * A unique identifier to track requests associated with a poll
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * and ignore stale responses.  The value is a count-down of
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * expected responses in this pollingContext.
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected int[] pollingContext;
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean mDesiredPowerState;
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  Values correspond to ServiceState.RIL_RADIO_TECHNOLOGY_ definitions.
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected int mRilRadioTechnology = 0;
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected int mNewRilRadioTechnology = 0;
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * By default, strength polling is enabled.  However, if we're
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * getting unsolicited signal strength updates from the radio, set
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * value to true and don't bother polling any more.
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean dontPollSignalStrength = false;
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mRoamingOnRegistrants = new RegistrantList();
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mRoamingOffRegistrants = new RegistrantList();
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mAttachedRegistrants = new RegistrantList();
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mDetachedRegistrants = new RegistrantList();
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mNetworkAttachedRegistrants = new RegistrantList();
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mPsRestrictEnabledRegistrants = new RegistrantList();
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mPsRestrictDisabledRegistrants = new RegistrantList();
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* Radio power off pending flag and tag counter */
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mPendingRadioPowerOffAfterDataOff = false;
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mPendingRadioPowerOffAfterDataOffTag = 0;
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected  static final boolean DBG = true;
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Signal strength poll rate. */
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int POLL_PERIOD_MILLIS = 20 * 1000;
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Waiting period before recheck gprs and voice registration. */
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** GSM events */
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RADIO_STATE_CHANGED               = 1;
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NETWORK_STATE_CHANGED             = 2;
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_SIGNAL_STRENGTH               = 3;
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_REGISTRATION           = 4;
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_GPRS                   = 5;
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_OPERATOR               = 6;
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_SIGNAL_STRENGTH              = 10;
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NITZ_TIME                         = 11;
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SIGNAL_STRENGTH_UPDATE            = 12;
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RADIO_AVAILABLE                   = 13;
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_NETWORK_SELECTION_MODE = 14;
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_LOC_DONE                      = 15;
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SIM_RECORDS_LOADED                = 16;
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SIM_READY                         = 17;
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_LOCATION_UPDATES_ENABLED          = 18;
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_PREFERRED_NETWORK_TYPE        = 19;
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SET_PREFERRED_NETWORK_TYPE        = 20;
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RESET_PREFERRED_NETWORK_TYPE      = 21;
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_CHECK_REPORT_GPRS                 = 22;
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RESTRICTED_STATE_CHANGED          = 23;
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** CDMA events */
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_REGISTRATION_CDMA      = 24;
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_OPERATOR_CDMA          = 25;
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RUIM_READY                        = 26;
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RUIM_RECORDS_LOADED               = 27;
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_SIGNAL_STRENGTH_CDMA         = 28;
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_SIGNAL_STRENGTH_CDMA          = 29;
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NETWORK_STATE_CHANGED_CDMA        = 30;
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_LOC_DONE_CDMA                 = 31;
143ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    //protected static final int EVENT_UNUSED                            = 32;
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NV_LOADED                         = 33;
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_CDMA_SUBSCRIPTION      = 34;
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NV_READY                          = 35;
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_ERI_FILE_LOADED                   = 36;
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_OTA_PROVISION_STATUS_CHANGE       = 37;
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SET_RADIO_POWER_OFF               = 38;
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED  = 39;
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_CDMA_PRL_VERSION_CHANGED          = 40;
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RADIO_ON                          = 41;
153e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected static final int EVENT_ICC_CHANGED                       = 42;
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * List of ISO codes for countries that can have an offset of
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * GMT+0 when not in daylight savings time.  This ignores some
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * small places such as the Canary Islands (Spain) and
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Danmarkshavn (Denmark).  The list must be sorted by code.
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    */
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String[] GMT_COUNTRY_CODES = {
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "bf", // Burkina Faso
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ci", // Cote d'Ivoire
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "eh", // Western Sahara
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "fo", // Faroe Islands, Denmark
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gb", // United Kingdom of Great Britain and Northern Ireland
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gh", // Ghana
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gm", // Gambia
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gn", // Guinea
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gw", // Guinea Bissau
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ie", // Ireland
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "lr", // Liberia
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "is", // Iceland
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ma", // Morocco
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ml", // Mali
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "mr", // Mauritania
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "pt", // Portugal
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "sl", // Sierra Leone
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "sn", // Senegal
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "st", // Sao Tome and Principe
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "tg", // Togo
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Reason for registration denial. */
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String REGISTRATION_DENIED_GEN  = "General";
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String REGISTRATION_DENIED_AUTH = "Authentication Failure";
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
190049ab0421f32e6effc5d1277b69bd382cebadb18Wink Saville    protected ServiceStateTracker(PhoneBase phoneBase, CommandsInterface ci, CellInfo cellInfo) {
191ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        mPhoneBase = phoneBase;
192ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        mCellInfo = cellInfo;
193e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        cm = ci;
194e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        mUiccController = UiccController.getInstance();
195e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
196ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
197ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
198ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
199ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    public void dispose() {
200ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        cm.unSetOnSignalStrengthUpdate(this);
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean getDesiredPowerState() {
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return mDesiredPowerState;
2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
207ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    private SignalStrength mLastSignalStrength = null;
208ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected boolean notifySignalStrength() {
209ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        boolean notified = false;
210ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        synchronized(mCellInfo) {
211ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville            if (!mSignalStrength.equals(mLastSignalStrength)) {
212ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                try {
213ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                    mPhoneBase.notifySignalStrength();
214ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                    notified = true;
215ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                } catch (NullPointerException ex) {
216ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                    loge("updateSignalStrength() Phone already destroyed: " + ex
217ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                            + "SignalStrength not notified");
218ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                }
219ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville            }
220ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        }
221ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        return notified;
222ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
223ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
224ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    /**
2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for combined roaming on
2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * combined roaming is true when roaming is true and ONS differs SPN
2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public  void registerForRoamingOn(Handler h, int what, Object obj) {
2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mRoamingOnRegistrants.add(r);
2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ss.getRoaming()) {
2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public  void unregisterForRoamingOn(Handler h) {
2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mRoamingOnRegistrants.remove(h);
2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for combined roaming off
2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * combined roaming is true when roaming is true and ONS differs SPN
2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public  void registerForRoamingOff(Handler h, int what, Object obj) {
2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mRoamingOffRegistrants.add(r);
2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!ss.getRoaming()) {
2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public  void unregisterForRoamingOff(Handler h) {
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mRoamingOffRegistrants.remove(h);
2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Re-register network by toggling preferred network type.
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * This is a work-around to deregister and register network since there is
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * no ril api to set COPS=2 (deregister) only.
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param onComplete is dispatched when this is complete.  it will be
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * an AsyncResult, and onComplete.obj.exception will be non-null
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * on failure.
2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void reRegisterNetwork(Message onComplete) {
2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.getPreferredNetworkType(
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE, onComplete));
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    setRadioPower(boolean power) {
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDesiredPowerState = power;
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        setPowerStateToDesired();
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * These two flags manage the behavior of the cell lock -- the
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * lock should be held if either flag is true.  The intention is
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * to allow temporary acquisition of the lock to get a single
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * update.  Such a lock grab and release can thus be made to not
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * interfere with more permanent lock holds -- in other words, the
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * lock will only be released if both flags are false, and so
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * releases by temporary users will only affect the lock state if
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * there is no continuous user.
2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mWantContinuousLocationUpdates;
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mWantSingleLocationUpdate;
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void enableSingleLocationUpdate() {
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return;
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantSingleLocationUpdate = true;
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED));
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void enableLocationUpdates() {
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return;
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantContinuousLocationUpdates = true;
3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED));
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void disableSingleLocationUpdate() {
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantSingleLocationUpdate = false;
3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) {
3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cm.setLocationUpdates(false, null);
3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void disableLocationUpdates() {
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantContinuousLocationUpdates = false;
3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) {
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cm.setLocationUpdates(false, null);
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void handleMessage(Message msg) {
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (msg.what) {
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SET_RADIO_POWER_OFF:
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                synchronized(this) {
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (mPendingRadioPowerOffAfterDataOff &&
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            (msg.arg1 == mPendingRadioPowerOffAfterDataOffTag)) {
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now.");
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        hangupAndPowerOff();
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mPendingRadioPowerOffAfterDataOffTag += 1;
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mPendingRadioPowerOffAfterDataOff = false;
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("EVENT_SET_RADIO_OFF is stale arg1=" + msg.arg1 +
3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                "!= tag=" + mPendingRadioPowerOffAfterDataOffTag);
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
344e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            case EVENT_ICC_CHANGED:
345e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                onUpdateIccAvailability();
346e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                break;
347e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("Unhandled message with number: " + msg.what);
3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract Phone getPhone();
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void handlePollStateResult(int what, AsyncResult ar);
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void updateSpnDisplay();
3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void setPowerStateToDesired();
358e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected abstract void onUpdateIccAvailability();
3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void log(String s);
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void loge(String s);
3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public abstract int getCurrentDataConnectionState();
3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public abstract boolean isConcurrentVoiceAndDataAllowed();
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into DataConnection attached.
3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForDataConnectionAttached(Handler h, int what, Object obj) {
3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mAttachedRegistrants.add(r);
3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (getCurrentDataConnectionState() == ServiceState.STATE_IN_SERVICE) {
3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForDataConnectionAttached(Handler h) {
3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mAttachedRegistrants.remove(h);
3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into DataConnection detached.
3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForDataConnectionDetached(Handler h, int what, Object obj) {
3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDetachedRegistrants.add(r);
3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (getCurrentDataConnectionState() != ServiceState.STATE_IN_SERVICE) {
3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForDataConnectionDetached(Handler h) {
3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDetachedRegistrants.remove(h);
3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into network attached.
4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj in Message.obj
4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForNetworkAttached(Handler h, int what, Object obj) {
4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNetworkAttachedRegistrants.add(r);
4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ss.getState() == ServiceState.STATE_IN_SERVICE) {
4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForNetworkAttached(Handler h) {
4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNetworkAttachedRegistrants.remove(h);
4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into packet service restricted zone.
4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForPsRestrictedEnabled(Handler h, int what, Object obj) {
4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictEnabledRegistrants.add(r);
4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mRestrictedState.isPsRestricted()) {
4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForPsRestrictedEnabled(Handler h) {
4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictEnabledRegistrants.remove(h);
4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition out of packet service restricted zone.
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForPsRestrictedDisabled(Handler h, int what, Object obj) {
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictDisabledRegistrants.add(r);
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mRestrictedState.isPsRestricted()) {
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForPsRestrictedDisabled(Handler h) {
4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictDisabledRegistrants.remove(h);
4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Clean up existing voice and data connection then turn off radio power.
4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Hang up the existing voice calls to decrease call drop rate.
4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void powerOffRadioSafely(DataConnectionTracker dcTracker) {
4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (this) {
4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!mPendingRadioPowerOffAfterDataOff) {
4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // To minimize race conditions we call cleanUpAllConnections on
4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // both if else paths instead of before this isDisconnected test.
4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (dcTracker.isDisconnected()) {
4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // To minimize race conditions we do this after isDisconnected
4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF);
4700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) log("Data disconnected, turn off radio right away.");
4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    hangupAndPowerOff();
4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF);
4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    Message msg = Message.obtain(this);
4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    msg.what = EVENT_SET_RADIO_POWER_OFF;
4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    msg.arg1 = ++mPendingRadioPowerOffAfterDataOffTag;
4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (sendMessageDelayed(msg, 30000)) {
4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("Wait upto 30s for data to disconnect, then turn off radio.");
4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mPendingRadioPowerOffAfterDataOff = true;
4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
4810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("Cannot send delayed Msg, turn off radio right away.");
4820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        hangupAndPowerOff();
4830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * process the pending request to turn radio off after data is disconnected
4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * return true if there is pending request to process; false otherwise.
4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean processPendingRadioPowerOffAfterDataOff() {
4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized(this) {
4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mPendingRadioPowerOffAfterDataOff) {
4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("Process pending request to turn radio off.");
4980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPendingRadioPowerOffAfterDataOffTag += 1;
4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangupAndPowerOff();
5000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPendingRadioPowerOffAfterDataOff = false;
5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return true;
5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5085b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam     * send signal-strength-changed notification if changed Called both for
5095b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam     * solicited and unsolicited signal strength updates
510e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville     *
511e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville     * @return true if the signal strength changed and a notification was sent.
5125b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam     */
513e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville    protected boolean onSignalStrengthResult(AsyncResult ar, boolean isGsm) {
5145b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        SignalStrength oldSignalStrength = mSignalStrength;
5155b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam
5165b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        // This signal is used for both voice and data radio signal so parse
5175b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        // all fields
5185b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam
5195b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        if ((ar.exception == null) && (ar.result != null)) {
5205b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            mSignalStrength = (SignalStrength) ar.result;
5215b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            mSignalStrength.validateInput();
5225b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            mSignalStrength.setGsm(isGsm);
5235b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        } else {
5245b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            log("onSignalStrengthResult() Exception from RIL : " + ar.exception);
5255b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            mSignalStrength = new SignalStrength(isGsm);
5265b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        }
5275b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam
528e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville        return notifySignalStrength();
5295b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam    }
5305b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam
5315b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam    /**
5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Hang up all voice call and turn off radio. Implemented by derived class.
5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void hangupAndPowerOff();
5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Cancel a pending (if any) pollState() operation */
5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void cancelPollState() {
5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // This will effectively cancel the rest of the poll requests.
5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pollingContext = new int[1];
5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Return true if time zone needs fixing.
5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param phoneBase
5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param operatorNumeric
5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param prevOperatorNumeric
5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param needToFixTimeZone
5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if time zone needs to be fixed
5500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean shouldFixTimeZoneNow(PhoneBase phoneBase, String operatorNumeric,
5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String prevOperatorNumeric, boolean needToFixTimeZone) {
5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Return false if the mcc isn't valid as we don't know where we are.
5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Return true if we have an IccCard and the mcc changed or we
5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // need to fix it because when the NITZ time came in we didn't
5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // know the country code.
5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If mcc is invalid then we'll return false
5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int mcc;
5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mcc = Integer.parseInt(operatorNumeric.substring(0, 3));
5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (Exception e) {
5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("shouldFixTimeZoneNow: no mcc, operatorNumeric=" + operatorNumeric +
5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        " retVal=false");
5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If prevMcc is invalid will make it different from mcc
5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // so we'll return true if the card exists.
5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int prevMcc;
5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            prevMcc = Integer.parseInt(prevOperatorNumeric.substring(0, 3));
5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (Exception e) {
5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            prevMcc = mcc + 1;
5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Determine if the Icc card exists
580e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        boolean iccCardExist = false;
581e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mUiccApplcation != null) {
582e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            iccCardExist = mUiccApplcation.getState() != AppState.APPSTATE_UNKNOWN;
583e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Determine retVal
5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean retVal = ((iccCardExist && (mcc != prevMcc)) || needToFixTimeZone);
5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            long ctm = System.currentTimeMillis();
5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("shouldFixTimeZoneNow: retVal=" + retVal +
5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " iccCardExist=" + iccCardExist +
5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " operatorNumeric=" + operatorNumeric + " mcc=" + mcc +
5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " prevOperatorNumeric=" + prevOperatorNumeric + " prevMcc=" + prevMcc +
5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " needToFixTimeZone=" + needToFixTimeZone +
5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " ltod=" + TimeUtils.logTimeOfDay(ctm));
5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return retVal;
5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
599ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    /**
600ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     * @return all available cell information or null if none.
601ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     */
602ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    public List<CellInfo> getAllCellInfo() {
603ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        return null;
604ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
605ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
606ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    /**
607ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     * @return signal strength
608ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     */
609ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    public SignalStrength getSignalStrength() {
610ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        synchronized(mCellInfo) {
611ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville            return mSignalStrength;
612ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        }
613ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
614ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println("ServiceStateTracker:");
6170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" ss=" + ss);
6180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" newSS=" + newSS);
619ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        pw.println(" mCellInfo=" + mCellInfo);
6200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mRestrictedState=" + mRestrictedState);
6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" pollingContext=" + pollingContext);
6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mDesiredPowerState=" + mDesiredPowerState);
6230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mRilRadioTechnology=" + mRilRadioTechnology);
6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNewRilRadioTechnology=" + mNewRilRadioTechnology);
6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" dontPollSignalStrength=" + dontPollSignalStrength);
6260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mPendingRadioPowerOffAfterDataOff=" + mPendingRadioPowerOffAfterDataOff);
6270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mPendingRadioPowerOffAfterDataOffTag=" + mPendingRadioPowerOffAfterDataOffTag);
6280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
629e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
630e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    /**
631e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * Verifies the current thread is the same as the thread originally
632e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * used in the initialization of this instance. Throws RuntimeException
633e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * if not.
634e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     *
635e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * @exception RuntimeException if the current thread is not
636e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * the thread that originally obtained this PhoneBase instance.
637e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     */
638e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected void checkCorrectThread() {
639e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (Thread.currentThread() != getLooper().getThread()) {
640e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            throw new RuntimeException(
641e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                    "ServiceStateTracker must be used from within one thread");
642e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        }
643e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    }
6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
645