ServiceStateTracker.java revision ef1d4bff9bbf7d967dbcace73f08910e14e367d0
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;
24ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Savilleimport android.os.SystemClock;
25ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Savilleimport android.telephony.CellInfo;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.ServiceState;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.SignalStrength;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.TimeUtils;
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.FileDescriptor;
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.PrintWriter;
32ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Savilleimport java.util.List;
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic abstract class ServiceStateTracker extends Handler {
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected CommandsInterface cm;
400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
41ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected PhoneBase mPhoneBase;
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
43ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    public ServiceState ss = new ServiceState();
44ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected ServiceState newSS = new ServiceState();
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
46ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected CellInfo mLastCellInfo = null;
47ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
48ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    // This is final as subclasses alias to a more specific type
49ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    // so we don't want the reference to change.
50ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected final CellInfo mCellInfo;
51ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
52ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected SignalStrength mSignalStrength = new SignalStrength();
53ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
54ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    // TODO - this should not be public, right now used externally GsmConnetion.
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public RestrictedState mRestrictedState = new RestrictedState();
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* The otaspMode passed to PhoneStateListener#onOtaspChanged */
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_UNINITIALIZED = 0;
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_UNKNOWN = 1;
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_NEEDED = 2;
610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_NOT_NEEDED = 3;
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * A unique identifier to track requests associated with a poll
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * and ignore stale responses.  The value is a count-down of
660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * expected responses in this pollingContext.
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected int[] pollingContext;
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean mDesiredPowerState;
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  Values correspond to ServiceState.RIL_RADIO_TECHNOLOGY_ definitions.
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected int mRilRadioTechnology = 0;
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected int mNewRilRadioTechnology = 0;
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * By default, strength polling is enabled.  However, if we're
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * getting unsolicited signal strength updates from the radio, set
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * value to true and don't bother polling any more.
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean dontPollSignalStrength = false;
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mRoamingOnRegistrants = new RegistrantList();
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mRoamingOffRegistrants = new RegistrantList();
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mAttachedRegistrants = new RegistrantList();
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mDetachedRegistrants = new RegistrantList();
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mNetworkAttachedRegistrants = new RegistrantList();
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mPsRestrictEnabledRegistrants = new RegistrantList();
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mPsRestrictDisabledRegistrants = new RegistrantList();
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* Radio power off pending flag and tag counter */
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mPendingRadioPowerOffAfterDataOff = false;
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mPendingRadioPowerOffAfterDataOffTag = 0;
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected  static final boolean DBG = true;
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Signal strength poll rate. */
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int POLL_PERIOD_MILLIS = 20 * 1000;
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Waiting period before recheck gprs and voice registration. */
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** GSM events */
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RADIO_STATE_CHANGED               = 1;
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NETWORK_STATE_CHANGED             = 2;
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_SIGNAL_STRENGTH               = 3;
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_REGISTRATION           = 4;
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_GPRS                   = 5;
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_OPERATOR               = 6;
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_SIGNAL_STRENGTH              = 10;
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NITZ_TIME                         = 11;
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SIGNAL_STRENGTH_UPDATE            = 12;
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RADIO_AVAILABLE                   = 13;
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_NETWORK_SELECTION_MODE = 14;
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_LOC_DONE                      = 15;
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SIM_RECORDS_LOADED                = 16;
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SIM_READY                         = 17;
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_LOCATION_UPDATES_ENABLED          = 18;
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_PREFERRED_NETWORK_TYPE        = 19;
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SET_PREFERRED_NETWORK_TYPE        = 20;
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RESET_PREFERRED_NETWORK_TYPE      = 21;
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_CHECK_REPORT_GPRS                 = 22;
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RESTRICTED_STATE_CHANGED          = 23;
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** CDMA events */
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_REGISTRATION_CDMA      = 24;
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_OPERATOR_CDMA          = 25;
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RUIM_READY                        = 26;
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RUIM_RECORDS_LOADED               = 27;
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_SIGNAL_STRENGTH_CDMA         = 28;
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_SIGNAL_STRENGTH_CDMA          = 29;
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NETWORK_STATE_CHANGED_CDMA        = 30;
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_LOC_DONE_CDMA                 = 31;
135ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    //protected static final int EVENT_UNUSED                            = 32;
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NV_LOADED                         = 33;
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_CDMA_SUBSCRIPTION      = 34;
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NV_READY                          = 35;
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_ERI_FILE_LOADED                   = 36;
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_OTA_PROVISION_STATUS_CHANGE       = 37;
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SET_RADIO_POWER_OFF               = 38;
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED  = 39;
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_CDMA_PRL_VERSION_CHANGED          = 40;
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RADIO_ON                          = 41;
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * List of ISO codes for countries that can have an offset of
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * GMT+0 when not in daylight savings time.  This ignores some
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * small places such as the Canary Islands (Spain) and
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Danmarkshavn (Denmark).  The list must be sorted by code.
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    */
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String[] GMT_COUNTRY_CODES = {
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "bf", // Burkina Faso
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ci", // Cote d'Ivoire
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "eh", // Western Sahara
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "fo", // Faroe Islands, Denmark
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gb", // United Kingdom of Great Britain and Northern Ireland
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gh", // Ghana
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gm", // Gambia
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gn", // Guinea
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gw", // Guinea Bissau
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ie", // Ireland
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "lr", // Liberia
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "is", // Iceland
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ma", // Morocco
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ml", // Mali
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "mr", // Mauritania
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "pt", // Portugal
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "sl", // Sierra Leone
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "sn", // Senegal
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "st", // Sao Tome and Principe
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "tg", // Togo
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Reason for registration denial. */
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String REGISTRATION_DENIED_GEN  = "General";
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String REGISTRATION_DENIED_AUTH = "Authentication Failure";
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
182ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected ServiceStateTracker(PhoneBase phoneBase, CellInfo cellInfo) {
183ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        mPhoneBase = phoneBase;
184ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        mCellInfo = cellInfo;
185ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        cm = mPhoneBase.mCM;
186ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
187ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
188ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
189ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    public void dispose() {
190ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        cm.unSetOnSignalStrengthUpdate(this);
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean getDesiredPowerState() {
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return mDesiredPowerState;
1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
197ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    private SignalStrength mLastSignalStrength = null;
198ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected boolean notifySignalStrength() {
199ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        boolean notified = false;
200ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        synchronized(mCellInfo) {
201ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville            if (!mSignalStrength.equals(mLastSignalStrength)) {
202ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                try {
203ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                    mPhoneBase.notifySignalStrength();
204ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                    notified = true;
205ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                } catch (NullPointerException ex) {
206ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                    loge("updateSignalStrength() Phone already destroyed: " + ex
207ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                            + "SignalStrength not notified");
208ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                }
209ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville            }
210ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        }
211ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        return notified;
212ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
213ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
214ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    /**
215ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     * Set the mCellInfo.signalStrength to its default values
216ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     */
217ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected void setSignalStrengthDefaultValues() {
218ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        setSignalStrengthDefaultValues(mSignalStrength);
219ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
220ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
221ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    /**
222ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     * Set the signal strength default values
223ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     */
224ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected void setSignalStrengthDefaultValues(SignalStrength signalStrength) {
225ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        signalStrength.initialize(99, -1, -1, -1, -1, -1, -1,
226ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                -1, -1, -1, SignalStrength.INVALID_SNR, -1, isGsmSignalStrength());
227ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
228ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
229ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    /**
230ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     * Return true if this SST is a GSM category device.
231ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     */
232ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected abstract boolean isGsmSignalStrength();
233ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for combined roaming on
2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * combined roaming is true when roaming is true and ONS differs SPN
2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public  void registerForRoamingOn(Handler h, int what, Object obj) {
2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mRoamingOnRegistrants.add(r);
2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ss.getRoaming()) {
2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public  void unregisterForRoamingOn(Handler h) {
2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mRoamingOnRegistrants.remove(h);
2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for combined roaming off
2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * combined roaming is true when roaming is true and ONS differs SPN
2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public  void registerForRoamingOff(Handler h, int what, Object obj) {
2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mRoamingOffRegistrants.add(r);
2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!ss.getRoaming()) {
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public  void unregisterForRoamingOff(Handler h) {
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mRoamingOffRegistrants.remove(h);
2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Re-register network by toggling preferred network type.
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * This is a work-around to deregister and register network since there is
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * no ril api to set COPS=2 (deregister) only.
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param onComplete is dispatched when this is complete.  it will be
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * an AsyncResult, and onComplete.obj.exception will be non-null
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * on failure.
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void reRegisterNetwork(Message onComplete) {
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.getPreferredNetworkType(
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE, onComplete));
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    setRadioPower(boolean power) {
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDesiredPowerState = power;
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        setPowerStateToDesired();
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * These two flags manage the behavior of the cell lock -- the
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * lock should be held if either flag is true.  The intention is
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * to allow temporary acquisition of the lock to get a single
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * update.  Such a lock grab and release can thus be made to not
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * interfere with more permanent lock holds -- in other words, the
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * lock will only be released if both flags are false, and so
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * releases by temporary users will only affect the lock state if
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * there is no continuous user.
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mWantContinuousLocationUpdates;
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mWantSingleLocationUpdate;
3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void enableSingleLocationUpdate() {
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return;
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantSingleLocationUpdate = true;
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED));
3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void enableLocationUpdates() {
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return;
3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantContinuousLocationUpdates = true;
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED));
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void disableSingleLocationUpdate() {
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantSingleLocationUpdate = false;
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) {
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cm.setLocationUpdates(false, null);
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void disableLocationUpdates() {
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantContinuousLocationUpdates = false;
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) {
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cm.setLocationUpdates(false, null);
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void handleMessage(Message msg) {
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (msg.what) {
3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SET_RADIO_POWER_OFF:
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                synchronized(this) {
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (mPendingRadioPowerOffAfterDataOff &&
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            (msg.arg1 == mPendingRadioPowerOffAfterDataOffTag)) {
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now.");
3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        hangupAndPowerOff();
3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mPendingRadioPowerOffAfterDataOffTag += 1;
3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mPendingRadioPowerOffAfterDataOff = false;
3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("EVENT_SET_RADIO_OFF is stale arg1=" + msg.arg1 +
3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                "!= tag=" + mPendingRadioPowerOffAfterDataOffTag);
3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("Unhandled message with number: " + msg.what);
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract Phone getPhone();
3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void handlePollStateResult(int what, AsyncResult ar);
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void updateSpnDisplay();
3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void setPowerStateToDesired();
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void log(String s);
3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void loge(String s);
3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public abstract int getCurrentDataConnectionState();
3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public abstract boolean isConcurrentVoiceAndDataAllowed();
3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into DataConnection attached.
3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForDataConnectionAttached(Handler h, int what, Object obj) {
3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mAttachedRegistrants.add(r);
3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (getCurrentDataConnectionState() == ServiceState.STATE_IN_SERVICE) {
3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForDataConnectionAttached(Handler h) {
3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mAttachedRegistrants.remove(h);
3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into DataConnection detached.
3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForDataConnectionDetached(Handler h, int what, Object obj) {
3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDetachedRegistrants.add(r);
3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (getCurrentDataConnectionState() != ServiceState.STATE_IN_SERVICE) {
3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForDataConnectionDetached(Handler h) {
4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDetachedRegistrants.remove(h);
4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into network attached.
4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj in Message.obj
4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForNetworkAttached(Handler h, int what, Object obj) {
4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNetworkAttachedRegistrants.add(r);
4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ss.getState() == ServiceState.STATE_IN_SERVICE) {
4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForNetworkAttached(Handler h) {
4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNetworkAttachedRegistrants.remove(h);
4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into packet service restricted zone.
4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForPsRestrictedEnabled(Handler h, int what, Object obj) {
4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictEnabledRegistrants.add(r);
4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mRestrictedState.isPsRestricted()) {
4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForPsRestrictedEnabled(Handler h) {
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictEnabledRegistrants.remove(h);
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition out of packet service restricted zone.
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForPsRestrictedDisabled(Handler h, int what, Object obj) {
4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictDisabledRegistrants.add(r);
4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mRestrictedState.isPsRestricted()) {
4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForPsRestrictedDisabled(Handler h) {
4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictDisabledRegistrants.remove(h);
4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Clean up existing voice and data connection then turn off radio power.
4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Hang up the existing voice calls to decrease call drop rate.
4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void powerOffRadioSafely(DataConnectionTracker dcTracker) {
4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (this) {
4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!mPendingRadioPowerOffAfterDataOff) {
4700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // To minimize race conditions we call cleanUpAllConnections on
4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // both if else paths instead of before this isDisconnected test.
4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (dcTracker.isDisconnected()) {
4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // To minimize race conditions we do this after isDisconnected
4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF);
4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) log("Data disconnected, turn off radio right away.");
4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    hangupAndPowerOff();
4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF);
4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    Message msg = Message.obtain(this);
4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    msg.what = EVENT_SET_RADIO_POWER_OFF;
4810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    msg.arg1 = ++mPendingRadioPowerOffAfterDataOffTag;
4820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (sendMessageDelayed(msg, 30000)) {
4830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("Wait upto 30s for data to disconnect, then turn off radio.");
4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mPendingRadioPowerOffAfterDataOff = true;
4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("Cannot send delayed Msg, turn off radio right away.");
4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        hangupAndPowerOff();
4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * process the pending request to turn radio off after data is disconnected
4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * return true if there is pending request to process; false otherwise.
4980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean processPendingRadioPowerOffAfterDataOff() {
5000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized(this) {
5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mPendingRadioPowerOffAfterDataOff) {
5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("Process pending request to turn radio off.");
5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPendingRadioPowerOffAfterDataOffTag += 1;
5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangupAndPowerOff();
5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPendingRadioPowerOffAfterDataOff = false;
5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return true;
5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
5090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Hang up all voice call and turn off radio. Implemented by derived class.
5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void hangupAndPowerOff();
5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Cancel a pending (if any) pollState() operation */
5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void cancelPollState() {
5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // This will effectively cancel the rest of the poll requests.
5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pollingContext = new int[1];
5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Return true if time zone needs fixing.
5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param phoneBase
5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param operatorNumeric
5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param prevOperatorNumeric
5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param needToFixTimeZone
5300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if time zone needs to be fixed
5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean shouldFixTimeZoneNow(PhoneBase phoneBase, String operatorNumeric,
5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String prevOperatorNumeric, boolean needToFixTimeZone) {
5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Return false if the mcc isn't valid as we don't know where we are.
5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Return true if we have an IccCard and the mcc changed or we
5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // need to fix it because when the NITZ time came in we didn't
5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // know the country code.
5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If mcc is invalid then we'll return false
5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int mcc;
5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mcc = Integer.parseInt(operatorNumeric.substring(0, 3));
5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (Exception e) {
5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("shouldFixTimeZoneNow: no mcc, operatorNumeric=" + operatorNumeric +
5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        " retVal=false");
5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If prevMcc is invalid will make it different from mcc
5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // so we'll return true if the card exists.
5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int prevMcc;
5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            prevMcc = Integer.parseInt(prevOperatorNumeric.substring(0, 3));
5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (Exception e) {
5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            prevMcc = mcc + 1;
5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Determine if the Icc card exists
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        IccCard iccCard = phoneBase.getIccCard();
5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean iccCardExist = (iccCard != null) && iccCard.getState().iccCardExist();
5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Determine retVal
5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean retVal = ((iccCardExist && (mcc != prevMcc)) || needToFixTimeZone);
5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            long ctm = System.currentTimeMillis();
5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("shouldFixTimeZoneNow: retVal=" + retVal +
5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " iccCard=" + iccCard +
5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " iccCard.state=" + (iccCard == null ? "null" : iccCard.getState().toString()) +
5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " iccCardExist=" + iccCardExist +
5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " operatorNumeric=" + operatorNumeric + " mcc=" + mcc +
5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " prevOperatorNumeric=" + prevOperatorNumeric + " prevMcc=" + prevMcc +
5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " needToFixTimeZone=" + needToFixTimeZone +
5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " ltod=" + TimeUtils.logTimeOfDay(ctm));
5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return retVal;
5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
580ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    /**
581ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     * @return all available cell information or null if none.
582ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     */
583ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    public List<CellInfo> getAllCellInfo() {
584ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        return null;
585ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
586ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
587ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    /**
588ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     * @return signal strength
589ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     */
590ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    public SignalStrength getSignalStrength() {
591ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        synchronized(mCellInfo) {
592ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville            return mSignalStrength;
593ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        }
594ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
595ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println("ServiceStateTracker:");
5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" ss=" + ss);
5990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" newSS=" + newSS);
600ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        pw.println(" mCellInfo=" + mCellInfo);
6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mRestrictedState=" + mRestrictedState);
6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" pollingContext=" + pollingContext);
6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mDesiredPowerState=" + mDesiredPowerState);
6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mRilRadioTechnology=" + mRilRadioTechnology);
6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNewRilRadioTechnology=" + mNewRilRadioTechnology);
6060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" dontPollSignalStrength=" + dontPollSignalStrength);
6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mPendingRadioPowerOffAfterDataOff=" + mPendingRadioPowerOffAfterDataOff);
6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mPendingRadioPowerOffAfterDataOffTag=" + mPendingRadioPowerOffAfterDataOffTag);
6090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
611