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
19a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.app.PendingIntent;
20b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwaltimport android.content.Context;
21a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.content.IntentFilter;
22d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajanimport android.content.SharedPreferences;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult;
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Registrant;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.RegistrantList;
280c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Savilleimport android.os.SystemClock;
29ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhaoimport android.os.SystemProperties;
30d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajanimport android.preference.PreferenceManager;
31ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Savilleimport android.telephony.CellInfo;
3214ad8ce79de28b7e4a1d25bacb4e51ca027159b4Shishir Agrawalimport android.telephony.Rlog;
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.ServiceState;
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.SignalStrength;
353bc32aa4a3f533421f82a6d7991bb1971bf78191Amit Mahajanimport android.telephony.SubscriptionManager;
364b09dff383ae7dfca595aeeea886a594a1947340Wink Savilleimport android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
37a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.TelephonyManager;
38b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwaltimport android.text.TextUtils;
3956dbbcf63e9991ee83945fd10661190d917f700axinheimport android.util.Log;
40203e588e3c42a81aa8a56f595119c181a63b12caWink Savilleimport android.util.Pair;
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.TimeUtils;
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.FileDescriptor;
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.PrintWriter;
455fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Savilleimport java.util.ArrayList;
46ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Savilleimport java.util.List;
4740dc777432250ec592696c7e1f395d582edb3b5fRobert Greenwaltimport java.util.concurrent.atomic.AtomicInteger;
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
49454b1dfd508844b42eb775e4ab2359be74d3672bWink Savilleimport com.android.internal.telephony.dataconnection.DcTrackerBase;
50d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
5156dbbcf63e9991ee83945fd10661190d917f700axinheimport com.android.internal.telephony.uicc.IccCardProxy;
52d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccRecords;
53d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.UiccCardApplication;
54e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenkaimport com.android.internal.telephony.uicc.UiccController;
55e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic abstract class ServiceStateTracker extends Handler {
6014ad8ce79de28b7e4a1d25bacb4e51ca027159b4Shishir Agrawal    private static final String LOG_TAG = "SST";
615fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected  static final boolean DBG = true;
625fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected static final boolean VDBG = false;
635fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
6460ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkey    protected static final String PROP_FORCE_ROAMING = "telephony.test.forceRoaming";
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected CommandsInterface mCi;
67e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected UiccController mUiccController = null;
68e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    protected UiccCardApplication mUiccApplcation = null;
69e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected IccRecords mIccRecords = null;
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
71ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected PhoneBase mPhoneBase;
720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
73f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville    protected boolean mVoiceCapable;
74f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville
7522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    public ServiceState mSS = new ServiceState();
7622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected ServiceState mNewSS = new ServiceState();
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
780c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville    private static final long LAST_CELL_INFO_LIST_MAX_AGE_MS = 2000;
790c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville    protected long mLastCellInfoListTime;
805fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected List<CellInfo> mLastCellInfoList = null;
81ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
82ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    // This is final as subclasses alias to a more specific type
83ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    // so we don't want the reference to change.
84ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected final CellInfo mCellInfo;
85ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
86ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected SignalStrength mSignalStrength = new SignalStrength();
87ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
88ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    // TODO - this should not be public, right now used externally GsmConnetion.
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public RestrictedState mRestrictedState = new RestrictedState();
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* The otaspMode passed to PhoneStateListener#onOtaspChanged */
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_UNINITIALIZED = 0;
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_UNKNOWN = 1;
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_NEEDED = 2;
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_NOT_NEEDED = 3;
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * A unique identifier to track requests associated with a poll
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * and ignore stale responses.  The value is a count-down of
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * expected responses in this pollingContext.
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
10222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected int[] mPollingContext;
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean mDesiredPowerState;
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * By default, strength polling is enabled.  However, if we're
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * getting unsolicited signal strength updates from the radio, set
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * value to true and don't bother polling any more.
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected boolean mDontPollSignalStrength = false;
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
112ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    protected RegistrantList mVoiceRoamingOnRegistrants = new RegistrantList();
113ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    protected RegistrantList mVoiceRoamingOffRegistrants = new RegistrantList();
114ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    protected RegistrantList mDataRoamingOnRegistrants = new RegistrantList();
115ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    protected RegistrantList mDataRoamingOffRegistrants = new RegistrantList();
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mAttachedRegistrants = new RegistrantList();
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mDetachedRegistrants = new RegistrantList();
118203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    protected RegistrantList mDataRegStateOrRatChangedRegistrants = new RegistrantList();
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mNetworkAttachedRegistrants = new RegistrantList();
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mPsRestrictEnabledRegistrants = new RegistrantList();
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mPsRestrictDisabledRegistrants = new RegistrantList();
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* Radio power off pending flag and tag counter */
124a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected boolean mPendingRadioPowerOffAfterDataOff = false;
125a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected int mPendingRadioPowerOffAfterDataOffTag = 0;
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Signal strength poll rate. */
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int POLL_PERIOD_MILLIS = 20 * 1000;
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Waiting period before recheck gprs and voice registration. */
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** GSM events */
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RADIO_STATE_CHANGED               = 1;
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NETWORK_STATE_CHANGED             = 2;
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_SIGNAL_STRENGTH               = 3;
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_REGISTRATION           = 4;
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_GPRS                   = 5;
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_OPERATOR               = 6;
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_SIGNAL_STRENGTH              = 10;
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NITZ_TIME                         = 11;
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SIGNAL_STRENGTH_UPDATE            = 12;
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RADIO_AVAILABLE                   = 13;
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_NETWORK_SELECTION_MODE = 14;
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_LOC_DONE                      = 15;
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SIM_RECORDS_LOADED                = 16;
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SIM_READY                         = 17;
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_LOCATION_UPDATES_ENABLED          = 18;
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_PREFERRED_NETWORK_TYPE        = 19;
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SET_PREFERRED_NETWORK_TYPE        = 20;
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RESET_PREFERRED_NETWORK_TYPE      = 21;
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_CHECK_REPORT_GPRS                 = 22;
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RESTRICTED_STATE_CHANGED          = 23;
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** CDMA events */
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_REGISTRATION_CDMA      = 24;
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_OPERATOR_CDMA          = 25;
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RUIM_READY                        = 26;
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RUIM_RECORDS_LOADED               = 27;
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_SIGNAL_STRENGTH_CDMA         = 28;
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_SIGNAL_STRENGTH_CDMA          = 29;
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NETWORK_STATE_CHANGED_CDMA        = 30;
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_LOC_DONE_CDMA                 = 31;
164ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    //protected static final int EVENT_UNUSED                            = 32;
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NV_LOADED                         = 33;
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_CDMA_SUBSCRIPTION      = 34;
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NV_READY                          = 35;
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_ERI_FILE_LOADED                   = 36;
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_OTA_PROVISION_STATUS_CHANGE       = 37;
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SET_RADIO_POWER_OFF               = 38;
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED  = 39;
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_CDMA_PRL_VERSION_CHANGED          = 40;
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RADIO_ON                          = 41;
174a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public static final int EVENT_ICC_CHANGED                          = 42;
1755fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected static final int EVENT_GET_CELL_INFO_LIST                = 43;
1765fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected static final int EVENT_UNSOL_CELL_INFO_LIST              = 44;
177a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected static final int EVENT_CHANGE_IMS_STATE                  = 45;
178bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com    protected static final int EVENT_IMS_STATE_CHANGED                 = 46;
179bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com    protected static final int EVENT_IMS_STATE_DONE                    = 47;
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * List of ISO codes for countries that can have an offset of
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * GMT+0 when not in daylight savings time.  This ignores some
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * small places such as the Canary Islands (Spain) and
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Danmarkshavn (Denmark).  The list must be sorted by code.
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    */
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String[] GMT_COUNTRY_CODES = {
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "bf", // Burkina Faso
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ci", // Cote d'Ivoire
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "eh", // Western Sahara
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "fo", // Faroe Islands, Denmark
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gb", // United Kingdom of Great Britain and Northern Ireland
1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gh", // Ghana
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gm", // Gambia
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gn", // Guinea
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gw", // Guinea Bissau
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ie", // Ireland
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "lr", // Liberia
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "is", // Iceland
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ma", // Morocco
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ml", // Mali
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "mr", // Mauritania
2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "pt", // Portugal
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "sl", // Sierra Leone
2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "sn", // Senegal
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "st", // Sao Tome and Principe
2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "tg", // Togo
2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2125fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    private class CellInfoResult {
2135fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        List<CellInfo> list;
2145fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        Object lockObj = new Object();
2155fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    }
2165fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Reason for registration denial. */
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String REGISTRATION_DENIED_GEN  = "General";
2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String REGISTRATION_DENIED_AUTH = "Authentication Failure";
2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
221a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected boolean mImsRegistrationOnOff = false;
222a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected boolean mAlarmSwitch = false;
223a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected IntentFilter mIntentFilter = null;
224a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected PendingIntent mRadioOffIntent = null;
225a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected static final String ACTION_RADIO_OFF = "android.intent.action.ACTION_RADIO_OFF";
226a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected boolean mPowerOffDelayNeed = true;
22703586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla    protected boolean mDeviceShuttingDown = false;
22819517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan    /** Keep track of SPN display rules, so we only broadcast intent if something changes. */
22919517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan    protected boolean mSpnUpdatePending = false;
23019517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan    protected String mCurSpn = null;
23119517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan    protected String mCurPlmn = null;
23219517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan    protected boolean mCurShowPlmn = false;
23319517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan    protected boolean mCurShowSpn = false;
23419517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan
23519517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan
236bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com    private boolean mImsRegistered = false;
23703586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla
2384b09dff383ae7dfca595aeeea886a594a1947340Wink Saville    protected SubscriptionManager mSubscriptionManager;
2390192d7f3f201bce2b513749982577c8ddebe3ea2Jason Monk    protected SubscriptionController mSubscriptionController;
24040dc777432250ec592696c7e1f395d582edb3b5fRobert Greenwalt    protected final SstSubscriptionsChangedListener mOnSubscriptionsChangedListener =
24140dc777432250ec592696c7e1f395d582edb3b5fRobert Greenwalt        new SstSubscriptionsChangedListener();
24240dc777432250ec592696c7e1f395d582edb3b5fRobert Greenwalt
24340dc777432250ec592696c7e1f395d582edb3b5fRobert Greenwalt    protected class SstSubscriptionsChangedListener extends OnSubscriptionsChangedListener {
24440dc777432250ec592696c7e1f395d582edb3b5fRobert Greenwalt        public final AtomicInteger mPreviousSubId = new AtomicInteger(-1); // < 0 is invalid subId
2454b09dff383ae7dfca595aeeea886a594a1947340Wink Saville        /**
2464b09dff383ae7dfca595aeeea886a594a1947340Wink Saville         * Callback invoked when there is any change to any SubscriptionInfo. Typically
2474b09dff383ae7dfca595aeeea886a594a1947340Wink Saville         * this method would invoke {@link SubscriptionManager#getActiveSubscriptionInfoList}
2483bc32aa4a3f533421f82a6d7991bb1971bf78191Amit Mahajan         */
2493bc32aa4a3f533421f82a6d7991bb1971bf78191Amit Mahajan        @Override
2504b09dff383ae7dfca595aeeea886a594a1947340Wink Saville        public void onSubscriptionsChanged() {
2513bc32aa4a3f533421f82a6d7991bb1971bf78191Amit Mahajan            if (DBG) log("SubscriptionListener.onSubscriptionInfoChanged");
2523bc32aa4a3f533421f82a6d7991bb1971bf78191Amit Mahajan            // Set the network type, in case the radio does not restore it.
25356dbbcf63e9991ee83945fd10661190d917f700axinhe            int subId = mPhoneBase.getSubId();
25440dc777432250ec592696c7e1f395d582edb3b5fRobert Greenwalt            if (mPreviousSubId.getAndSet(subId) != subId) {
255b8ec2c1d94a76180871a58e14da06e1f0267e503Amit Mahajan                if (SubscriptionManager.isValidSubscriptionId(subId)) {
256d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                    Context context = mPhoneBase.getContext();
257d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                    int networkType = PhoneFactory.calculatePreferredNetworkType(context, subId);
258b41cbe42c6e7c07c039eac2a871b6a772329d8dbAmit Mahajan                    mCi.setPreferredNetworkType(networkType, null);
259b41cbe42c6e7c07c039eac2a871b6a772329d8dbAmit Mahajan
260ad8eab8645079b88aeba3c7dc77ce885114a0efcAmit Mahajan                    mPhoneBase.notifyCallForwardingIndicator();
261ad8eab8645079b88aeba3c7dc77ce885114a0efcAmit Mahajan
262d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                    boolean skipRestoringSelection = context.getResources().getBoolean(
263d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                            com.android.internal.R.bool.skip_restoring_network_selection);
264d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                    if (!skipRestoringSelection) {
265d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                        // restore the previous network selection.
266d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                        mPhoneBase.restoreSavedNetworkSelection(null);
267d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                    }
268d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan
269b41cbe42c6e7c07c039eac2a871b6a772329d8dbAmit Mahajan                    mPhoneBase.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
270b41cbe42c6e7c07c039eac2a871b6a772329d8dbAmit Mahajan                        ServiceState.rilRadioTechnologyToString(mSS.getRilDataRadioTechnology()));
27119517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan
27219517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan                    if (mSpnUpdatePending) {
273062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal                        mSubscriptionController.setPlmnSpn(mPhoneBase.getPhoneId(), mCurShowPlmn,
274062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal                                mCurPlmn, mCurShowSpn, mCurSpn);
27519517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan                        mSpnUpdatePending = false;
27619517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan                    }
277d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan
278d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                    // Remove old network selection sharedPreferences since SP key names are now
279d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                    // changed to include subId. This will be done only once when upgrading from an
280d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                    // older build that did not include subId in the names.
281d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                    SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(
282d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                            context);
283d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                    String oldNetworkSelectionName = sp.getString(PhoneBase.
284d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                            NETWORK_SELECTION_NAME_KEY, "");
285d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                    String oldNetworkSelection = sp.getString(PhoneBase.NETWORK_SELECTION_KEY,
286d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                            "");
287d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                    if (!TextUtils.isEmpty(oldNetworkSelectionName) ||
288d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                            !TextUtils.isEmpty(oldNetworkSelection)) {
289d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                        SharedPreferences.Editor editor = sp.edit();
290d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                        editor.putString(PhoneBase.NETWORK_SELECTION_NAME_KEY + subId,
291d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                                oldNetworkSelectionName);
292d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                        editor.putString(PhoneBase.NETWORK_SELECTION_KEY + subId,
293d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                                oldNetworkSelection);
294d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                        editor.remove(PhoneBase.NETWORK_SELECTION_NAME_KEY);
295d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                        editor.remove(PhoneBase.NETWORK_SELECTION_KEY);
296d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                        editor.commit();
297d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                    }
29856dbbcf63e9991ee83945fd10661190d917f700axinhe                }
2993bc32aa4a3f533421f82a6d7991bb1971bf78191Amit Mahajan            }
3003bc32aa4a3f533421f82a6d7991bb1971bf78191Amit Mahajan        }
3013bc32aa4a3f533421f82a6d7991bb1971bf78191Amit Mahajan    };
302a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
303049ab0421f32e6effc5d1277b69bd382cebadb18Wink Saville    protected ServiceStateTracker(PhoneBase phoneBase, CommandsInterface ci, CellInfo cellInfo) {
304ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        mPhoneBase = phoneBase;
305ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        mCellInfo = cellInfo;
30622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi = ci;
307f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville        mVoiceCapable = mPhoneBase.getContext().getResources().getBoolean(
308f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville                com.android.internal.R.bool.config_voice_capable);
309e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        mUiccController = UiccController.getInstance();
310e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
31122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
3125fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        mCi.registerForCellInfoList(this, EVENT_UNSOL_CELL_INFO_LIST, null);
313c4161078eff3305894f1f9f1b2f00952ea0e83d8Kazuya Ohshiro
3140192d7f3f201bce2b513749982577c8ddebe3ea2Jason Monk        mSubscriptionController = SubscriptionController.getInstance();
3154b09dff383ae7dfca595aeeea886a594a1947340Wink Saville        mSubscriptionManager = SubscriptionManager.from(phoneBase.getContext());
3164b09dff383ae7dfca595aeeea886a594a1947340Wink Saville        mSubscriptionManager
31733d14d71f4b43d82d6c1b87d1d30cd86d13c5372Wink Saville            .addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
3183bc32aa4a3f533421f82a6d7991bb1971bf78191Amit Mahajan
319c4161078eff3305894f1f9f1b2f00952ea0e83d8Kazuya Ohshiro        mPhoneBase.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
320c4161078eff3305894f1f9f1b2f00952ea0e83d8Kazuya Ohshiro            ServiceState.rilRadioTechnologyToString(ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN));
321bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com        mCi.registerForImsNetworkStateChanged(this, EVENT_IMS_STATE_CHANGED, null);
322ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
323ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
32403586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla    void requestShutdown() {
32503586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla        if (mDeviceShuttingDown == true) return;
32603586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla        mDeviceShuttingDown = true;
32703586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla        mDesiredPowerState = false;
32803586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla        setPowerStateToDesired();
32903586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla    }
33003586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla
331ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    public void dispose() {
33222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unSetOnSignalStrengthUpdate(this);
333c26fb77c4e637466cf0483a4995fe82e6f68b8d3Alex Yakavenka        mUiccController.unregisterForIccChanged(this);
3345fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        mCi.unregisterForCellInfoList(this);
3354b09dff383ae7dfca595aeeea886a594a1947340Wink Saville        mSubscriptionManager
33633d14d71f4b43d82d6c1b87d1d30cd86d13c5372Wink Saville            .removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean getDesiredPowerState() {
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return mDesiredPowerState;
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
343ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    private SignalStrength mLastSignalStrength = null;
344ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected boolean notifySignalStrength() {
345ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        boolean notified = false;
346ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        synchronized(mCellInfo) {
347ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville            if (!mSignalStrength.equals(mLastSignalStrength)) {
348ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                try {
349ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                    mPhoneBase.notifySignalStrength();
350ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                    notified = true;
351ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                } catch (NullPointerException ex) {
352ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                    loge("updateSignalStrength() Phone already destroyed: " + ex
353ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                            + "SignalStrength not notified");
354ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                }
355ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville            }
356ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        }
357ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        return notified;
358ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
359ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
360ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    /**
361203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * Notify all mDataConnectionRatChangeRegistrants using an
362203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * AsyncResult in msg.obj where AsyncResult#result contains the
363203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * new RAT as an Integer Object.
364203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     */
365203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    protected void notifyDataRegStateRilRadioTechnologyChanged() {
366203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        int rat = mSS.getRilDataRadioTechnology();
367203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        int drs = mSS.getDataRegState();
368203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        if (DBG) log("notifyDataRegStateRilRadioTechnologyChanged: drs=" + drs + " rat=" + rat);
369203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        mPhoneBase.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
370203e588e3c42a81aa8a56f595119c181a63b12caWink Saville                ServiceState.rilRadioTechnologyToString(rat));
371203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        mDataRegStateOrRatChangedRegistrants.notifyResult(new Pair<Integer, Integer>(drs, rat));
372203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    }
373203e588e3c42a81aa8a56f595119c181a63b12caWink Saville
374203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    /**
375f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville     * Some operators have been known to report registration failure
376f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville     * data only devices, to fix that use DataRegState.
377f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville     */
378f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville    protected void useDataRegStateForDataOnlyDevices() {
379f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville        if (mVoiceCapable == false) {
380f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville            if (DBG) {
381f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville                log("useDataRegStateForDataOnlyDevice: VoiceRegState=" + mNewSS.getVoiceRegState()
382f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville                    + " DataRegState=" + mNewSS.getDataRegState());
383f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville            }
384f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville            // TODO: Consider not lying and instead have callers know the difference.
385f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville            mNewSS.setVoiceRegState(mNewSS.getDataRegState());
386f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville        }
387f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville    }
388f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville
38903b37b67755a4033c6be32ae2e389c310e06e7d1Amit Mahajan    protected void updatePhoneObject() {
39017a893295d021cd48ad0e2e6ccf9ceda3f97c70cSukanya Rajkhowa        if (mPhoneBase.getContext().getResources().
39117a893295d021cd48ad0e2e6ccf9ceda3f97c70cSukanya Rajkhowa                getBoolean(com.android.internal.R.bool.config_switch_phone_on_voice_reg_state_change)) {
39214ad8ce79de28b7e4a1d25bacb4e51ca027159b4Shishir Agrawal            // If the phone is not registered on a network, no need to update.
39314ad8ce79de28b7e4a1d25bacb4e51ca027159b4Shishir Agrawal            boolean isRegistered = mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE ||
39414ad8ce79de28b7e4a1d25bacb4e51ca027159b4Shishir Agrawal                    mSS.getVoiceRegState() == ServiceState.STATE_EMERGENCY_ONLY;
39514ad8ce79de28b7e4a1d25bacb4e51ca027159b4Shishir Agrawal            if (!isRegistered) {
39614ad8ce79de28b7e4a1d25bacb4e51ca027159b4Shishir Agrawal                Rlog.d(LOG_TAG, "updatePhoneObject: Ignore update");
39714ad8ce79de28b7e4a1d25bacb4e51ca027159b4Shishir Agrawal                return;
39814ad8ce79de28b7e4a1d25bacb4e51ca027159b4Shishir Agrawal            }
39917a893295d021cd48ad0e2e6ccf9ceda3f97c70cSukanya Rajkhowa            mPhoneBase.updatePhoneObject(mSS.getRilVoiceRadioTechnology());
40017a893295d021cd48ad0e2e6ccf9ceda3f97c70cSukanya Rajkhowa        }
40103b37b67755a4033c6be32ae2e389c310e06e7d1Amit Mahajan    }
402f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville
403f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville    /**
404ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * Registration point for combined roaming on of mobile voice
4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * combined roaming is true when roaming is true and ONS differs SPN
4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
411ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    public void registerForVoiceRoamingOn(Handler h, int what, Object obj) {
4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
413ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        mVoiceRoamingOnRegistrants.add(r);
4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
415ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        if (mSS.getVoiceRoaming()) {
4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
420ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    public void unregisterForVoiceRoamingOn(Handler h) {
421ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        mVoiceRoamingOnRegistrants.remove(h);
4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
425ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * Registration point for roaming off of mobile voice
4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * combined roaming is true when roaming is true and ONS differs SPN
4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
432ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    public void registerForVoiceRoamingOff(Handler h, int what, Object obj) {
4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
434ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        mVoiceRoamingOffRegistrants.add(r);
4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
436ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        if (!mSS.getVoiceRoaming()) {
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
441ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    public void unregisterForVoiceRoamingOff(Handler h) {
442ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        mVoiceRoamingOffRegistrants.remove(h);
443ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    }
444ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao
445ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    /**
446ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * Registration point for combined roaming on of mobile data
447ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * combined roaming is true when roaming is true and ONS differs SPN
448ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     *
449ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * @param h handler to notify
450ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * @param what what code of message when delivered
451ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * @param obj placed in Message.obj
452ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     */
453ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    public void registerForDataRoamingOn(Handler h, int what, Object obj) {
454ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        Registrant r = new Registrant(h, what, obj);
455ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        mDataRoamingOnRegistrants.add(r);
456ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao
457ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        if (mSS.getDataRoaming()) {
458ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            r.notifyRegistrant();
459ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        }
460ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    }
461ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao
462ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    public void unregisterForDataRoamingOn(Handler h) {
463ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        mDataRoamingOnRegistrants.remove(h);
464ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    }
465ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao
466ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    /**
467ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * Registration point for roaming off of mobile data
468ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * combined roaming is true when roaming is true and ONS differs SPN
469ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     *
470ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * @param h handler to notify
471ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * @param what what code of message when delivered
472ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * @param obj placed in Message.obj
473ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     */
474ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    public void registerForDataRoamingOff(Handler h, int what, Object obj) {
475ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        Registrant r = new Registrant(h, what, obj);
476ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        mDataRoamingOffRegistrants.add(r);
477ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao
478ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        if (!mSS.getDataRoaming()) {
479ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            r.notifyRegistrant();
480ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        }
481ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    }
482ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao
483ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    public void unregisterForDataRoamingOff(Handler h) {
484ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        mDataRoamingOffRegistrants.remove(h);
4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Re-register network by toggling preferred network type.
4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * This is a work-around to deregister and register network since there is
4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * no ril api to set COPS=2 (deregister) only.
4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param onComplete is dispatched when this is complete.  it will be
4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * an AsyncResult, and onComplete.obj.exception will be non-null
4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * on failure.
4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void reRegisterNetwork(Message onComplete) {
49722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.getPreferredNetworkType(
4980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE, onComplete));
4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    setRadioPower(boolean power) {
5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDesiredPowerState = power;
5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        setPowerStateToDesired();
5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * These two flags manage the behavior of the cell lock -- the
5100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * lock should be held if either flag is true.  The intention is
5110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * to allow temporary acquisition of the lock to get a single
5120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * update.  Such a lock grab and release can thus be made to not
5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * interfere with more permanent lock holds -- in other words, the
5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * lock will only be released if both flags are false, and so
5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * releases by temporary users will only affect the lock state if
5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * there is no continuous user.
5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mWantContinuousLocationUpdates;
5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mWantSingleLocationUpdate;
5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void enableSingleLocationUpdate() {
5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return;
5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantSingleLocationUpdate = true;
52422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED));
5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void enableLocationUpdates() {
5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return;
5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantContinuousLocationUpdates = true;
53022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED));
5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void disableSingleLocationUpdate() {
5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantSingleLocationUpdate = false;
5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) {
53622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.setLocationUpdates(false, null);
5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void disableLocationUpdates() {
5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantContinuousLocationUpdates = false;
5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) {
54322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.setLocationUpdates(false, null);
5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void handleMessage(Message msg) {
5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (msg.what) {
5500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SET_RADIO_POWER_OFF:
5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                synchronized(this) {
5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (mPendingRadioPowerOffAfterDataOff &&
5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            (msg.arg1 == mPendingRadioPowerOffAfterDataOffTag)) {
5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now.");
5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        hangupAndPowerOff();
5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mPendingRadioPowerOffAfterDataOffTag += 1;
5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mPendingRadioPowerOffAfterDataOff = false;
5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("EVENT_SET_RADIO_OFF is stale arg1=" + msg.arg1 +
5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                "!= tag=" + mPendingRadioPowerOffAfterDataOffTag);
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
565e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            case EVENT_ICC_CHANGED:
566e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                onUpdateIccAvailability();
567e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                break;
568e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
5695fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            case EVENT_GET_CELL_INFO_LIST: {
5705fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                AsyncResult ar = (AsyncResult) msg.obj;
5715fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                CellInfoResult result = (CellInfoResult) ar.userObj;
5725fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                synchronized(result.lockObj) {
5735fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    if (ar.exception != null) {
5745fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        log("EVENT_GET_CELL_INFO_LIST: error ret null, e=" + ar.exception);
5755fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        result.list = null;
5765fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    } else {
5775fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        result.list = (List<CellInfo>) ar.result;
5785fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
5795fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        if (VDBG) {
5805fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                            log("EVENT_GET_CELL_INFO_LIST: size=" + result.list.size()
5815fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                                    + " list=" + result.list);
5825fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        }
5835fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    }
5840c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    mLastCellInfoListTime = SystemClock.elapsedRealtime();
5855fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    mLastCellInfoList = result.list;
5865fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    result.lockObj.notify();
5875fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                }
5885fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                break;
5895fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            }
5905fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
5915fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            case EVENT_UNSOL_CELL_INFO_LIST: {
5925fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                AsyncResult ar = (AsyncResult) msg.obj;
5935fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                if (ar.exception != null) {
5945fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    log("EVENT_UNSOL_CELL_INFO_LIST: error ignoring, e=" + ar.exception);
5955fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                } else {
5965fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    List<CellInfo> list = (List<CellInfo>) ar.result;
5975fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    if (DBG) {
5985fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        log("EVENT_UNSOL_CELL_INFO_LIST: size=" + list.size()
5995fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                                + " list=" + list);
6005fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    }
6010c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    mLastCellInfoListTime = SystemClock.elapsedRealtime();
6025fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    mLastCellInfoList = list;
6035fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    mPhoneBase.notifyCellInfo(list);
6045fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                }
6055fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                break;
6065fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            }
6075fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
608bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com            case  EVENT_IMS_STATE_CHANGED: // received unsol
609bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com                mCi.getImsRegistrationState(this.obtainMessage(EVENT_IMS_STATE_DONE));
610bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com                break;
611bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com
612bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com            case EVENT_IMS_STATE_DONE:
613bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com                AsyncResult ar = (AsyncResult) msg.obj;
614bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com                if (ar.exception == null) {
615bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com                    int[] responseArray = (int[])ar.result;
616bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com                    mImsRegistered = (responseArray[0] == 1) ? true : false;
617bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com                }
618bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com                break;
619bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com
6200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("Unhandled message with number: " + msg.what);
6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
6230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract Phone getPhone();
6270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void handlePollStateResult(int what, AsyncResult ar);
6280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void updateSpnDisplay();
6290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void setPowerStateToDesired();
630e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected abstract void onUpdateIccAvailability();
6310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void log(String s);
6320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void loge(String s);
6330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public abstract int getCurrentDataConnectionState();
6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public abstract boolean isConcurrentVoiceAndDataAllowed();
6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
637a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public abstract void setImsRegistrationState(boolean registered);
638b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal    public abstract void pollState();
639a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
6400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into DataConnection attached.
6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForDataConnectionAttached(Handler h, int what, Object obj) {
6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mAttachedRegistrants.add(r);
6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (getCurrentDataConnectionState() == ServiceState.STATE_IN_SERVICE) {
6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
6520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForDataConnectionAttached(Handler h) {
6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mAttachedRegistrants.remove(h);
6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into DataConnection detached.
6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForDataConnectionDetached(Handler h, int what, Object obj) {
6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDetachedRegistrants.add(r);
6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (getCurrentDataConnectionState() != ServiceState.STATE_IN_SERVICE) {
6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
6700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForDataConnectionDetached(Handler h) {
6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDetachedRegistrants.remove(h);
6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
677203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * Registration for DataConnection RIL Data Radio Technology changing. The
678203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * new radio technology will be returned AsyncResult#result as an Integer Object.
679203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * The AsyncResult will be in the notification Message#obj.
680203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     *
681203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * @param h handler to notify
682203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * @param what what code of message when delivered
683203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * @param obj placed in Message.obj
684203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     */
685203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    public void registerForDataRegStateOrRatChanged(Handler h, int what, Object obj) {
686203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        Registrant r = new Registrant(h, what, obj);
687203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        mDataRegStateOrRatChangedRegistrants.add(r);
688203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        notifyDataRegStateRilRadioTechnologyChanged();
689203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    }
690203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    public void unregisterForDataRegStateOrRatChanged(Handler h) {
691203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        mDataRegStateOrRatChangedRegistrants.remove(h);
692203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    }
693203e588e3c42a81aa8a56f595119c181a63b12caWink Saville
694203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    /**
6950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into network attached.
6960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
6970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
6980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj in Message.obj
6990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
7000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForNetworkAttached(Handler h, int what, Object obj) {
7010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
7020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNetworkAttachedRegistrants.add(r);
70422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE) {
7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
7060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForNetworkAttached(Handler h) {
7090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNetworkAttachedRegistrants.remove(h);
7100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
7130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into packet service restricted zone.
7140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
7150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
7160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
7170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
7180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForPsRestrictedEnabled(Handler h, int what, Object obj) {
7190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
7200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictEnabledRegistrants.add(r);
7210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mRestrictedState.isPsRestricted()) {
7230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
7240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForPsRestrictedEnabled(Handler h) {
7280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictEnabledRegistrants.remove(h);
7290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
7320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition out of packet service restricted zone.
7330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
7340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
7350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
7360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
7370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForPsRestrictedDisabled(Handler h, int what, Object obj) {
7380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictDisabledRegistrants.add(r);
7400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mRestrictedState.isPsRestricted()) {
7420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
7430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForPsRestrictedDisabled(Handler h) {
7470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictDisabledRegistrants.remove(h);
7480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
7510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Clean up existing voice and data connection then turn off radio power.
7520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
7530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Hang up the existing voice calls to decrease call drop rate.
7540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
755454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    public void powerOffRadioSafely(DcTrackerBase dcTracker) {
7560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (this) {
7570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!mPendingRadioPowerOffAfterDataOff) {
75875c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                // In some network, deactivate PDP connection cause releasing of RRC connection,
75975c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                // which MM/IMSI detaching request needs. Without this detaching, network can
76075c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                // not release the network resources previously attached.
76175c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                // So we are avoiding data detaching on these networks.
76275c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                String[] networkNotClearData = mPhoneBase.getContext().getResources()
76375c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                        .getStringArray(com.android.internal.R.array.networks_not_clear_data);
76475c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                String currentNetwork = mSS.getOperatorNumeric();
76575c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                if ((networkNotClearData != null) && (currentNetwork != null)) {
76675c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                    for (int i = 0; i < networkNotClearData.length; i++) {
76775c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                        if (currentNetwork.equals(networkNotClearData[i])) {
76875c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                            // Don't clear data connection for this carrier
76975c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                            if (DBG)
77075c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                                log("Not disconnecting data for " + currentNetwork);
77175c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                            hangupAndPowerOff();
77275c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                            return;
77375c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                        }
77475c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                    }
77575c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                }
7760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // To minimize race conditions we call cleanUpAllConnections on
7770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // both if else paths instead of before this isDisconnected test.
7780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (dcTracker.isDisconnected()) {
7790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // To minimize race conditions we do this after isDisconnected
7800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF);
7810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) log("Data disconnected, turn off radio right away.");
7820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    hangupAndPowerOff();
7830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
7840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF);
7850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    Message msg = Message.obtain(this);
7860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    msg.what = EVENT_SET_RADIO_POWER_OFF;
7870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    msg.arg1 = ++mPendingRadioPowerOffAfterDataOffTag;
7880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (sendMessageDelayed(msg, 30000)) {
7890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("Wait upto 30s for data to disconnect, then turn off radio.");
7900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mPendingRadioPowerOffAfterDataOff = true;
7910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
7920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("Cannot send delayed Msg, turn off radio right away.");
7930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        hangupAndPowerOff();
7940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
7950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
7960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
8010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * process the pending request to turn radio off after data is disconnected
8020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
8030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * return true if there is pending request to process; false otherwise.
8040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
8050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean processPendingRadioPowerOffAfterDataOff() {
8060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized(this) {
8070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mPendingRadioPowerOffAfterDataOff) {
8080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("Process pending request to turn radio off.");
8090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPendingRadioPowerOffAfterDataOffTag += 1;
8100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangupAndPowerOff();
8110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPendingRadioPowerOffAfterDataOff = false;
8120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return true;
8130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
8150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
8195b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam     * send signal-strength-changed notification if changed Called both for
8205b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam     * solicited and unsolicited signal strength updates
821e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville     *
822e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville     * @return true if the signal strength changed and a notification was sent.
8235b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam     */
824e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville    protected boolean onSignalStrengthResult(AsyncResult ar, boolean isGsm) {
8255b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        SignalStrength oldSignalStrength = mSignalStrength;
8265b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam
8275b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        // This signal is used for both voice and data radio signal so parse
8285b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        // all fields
8295b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam
8305b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        if ((ar.exception == null) && (ar.result != null)) {
8315b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            mSignalStrength = (SignalStrength) ar.result;
8325b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            mSignalStrength.validateInput();
8335b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            mSignalStrength.setGsm(isGsm);
8345b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        } else {
8355b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            log("onSignalStrengthResult() Exception from RIL : " + ar.exception);
8365b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            mSignalStrength = new SignalStrength(isGsm);
8375b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        }
8385b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam
839e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville        return notifySignalStrength();
8405b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam    }
8415b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam
8425b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam    /**
8430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Hang up all voice call and turn off radio. Implemented by derived class.
8440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
8450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void hangupAndPowerOff();
8460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Cancel a pending (if any) pollState() operation */
8480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void cancelPollState() {
8490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // This will effectively cancel the rest of the poll requests.
85022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPollingContext = new int[1];
8510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
8540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Return true if time zone needs fixing.
8550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
8560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param phoneBase
8570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param operatorNumeric
8580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param prevOperatorNumeric
8590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param needToFixTimeZone
8600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if time zone needs to be fixed
8610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
8620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean shouldFixTimeZoneNow(PhoneBase phoneBase, String operatorNumeric,
8630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String prevOperatorNumeric, boolean needToFixTimeZone) {
8640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Return false if the mcc isn't valid as we don't know where we are.
8650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Return true if we have an IccCard and the mcc changed or we
8660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // need to fix it because when the NITZ time came in we didn't
8670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // know the country code.
8680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If mcc is invalid then we'll return false
8700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int mcc;
8710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
8720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mcc = Integer.parseInt(operatorNumeric.substring(0, 3));
8730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (Exception e) {
8740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
8750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("shouldFixTimeZoneNow: no mcc, operatorNumeric=" + operatorNumeric +
8760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        " retVal=false");
8770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
8790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If prevMcc is invalid will make it different from mcc
8820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // so we'll return true if the card exists.
8830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int prevMcc;
8840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
8850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            prevMcc = Integer.parseInt(prevOperatorNumeric.substring(0, 3));
8860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (Exception e) {
8870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            prevMcc = mcc + 1;
8880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Determine if the Icc card exists
891e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        boolean iccCardExist = false;
892e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mUiccApplcation != null) {
893e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            iccCardExist = mUiccApplcation.getState() != AppState.APPSTATE_UNKNOWN;
894e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
8950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Determine retVal
8970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean retVal = ((iccCardExist && (mcc != prevMcc)) || needToFixTimeZone);
8980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
8990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            long ctm = System.currentTimeMillis();
9000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("shouldFixTimeZoneNow: retVal=" + retVal +
9010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " iccCardExist=" + iccCardExist +
9020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " operatorNumeric=" + operatorNumeric + " mcc=" + mcc +
9030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " prevOperatorNumeric=" + prevOperatorNumeric + " prevMcc=" + prevMcc +
9040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " needToFixTimeZone=" + needToFixTimeZone +
9050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " ltod=" + TimeUtils.logTimeOfDay(ctm));
9060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return retVal;
9080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
910a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public String getSystemProperty(String property, String defValue) {
9116bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        return TelephonyManager.getTelephonyProperty(mPhoneBase.getPhoneId(), property, defValue);
912a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
913a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
914ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    /**
915ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     * @return all available cell information or null if none.
916ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     */
917ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    public List<CellInfo> getAllCellInfo() {
9185fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        CellInfoResult result = new CellInfoResult();
9195fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        if (VDBG) log("SST.getAllCellInfo(): E");
9205fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        int ver = mCi.getRilVersion();
9215fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        if (ver >= 8) {
9225fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            if (isCallerOnDifferentThread()) {
9230c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                if ((SystemClock.elapsedRealtime() - mLastCellInfoListTime)
9240c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        > LAST_CELL_INFO_LIST_MAX_AGE_MS) {
9250c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    Message msg = obtainMessage(EVENT_GET_CELL_INFO_LIST, result);
9260c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    synchronized(result.lockObj) {
927bed429d6d0a0dbc6384b04e0641aa1e03e406f42Amit Mahajan                        result.list = null;
9280c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        mCi.getCellInfoList(msg);
9290c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        try {
930bed429d6d0a0dbc6384b04e0641aa1e03e406f42Amit Mahajan                            result.lockObj.wait(5000);
9310c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        } catch (InterruptedException e) {
9320c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                            e.printStackTrace();
9330c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        }
9345fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    }
9350c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                } else {
9360c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    if (DBG) log("SST.getAllCellInfo(): return last, back to back calls");
9370c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    result.list = mLastCellInfoList;
9385fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                }
9395fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            } else {
9400c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                if (DBG) log("SST.getAllCellInfo(): return last, same thread can't block");
9415fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                result.list = mLastCellInfoList;
9425fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            }
9435fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        } else {
9440c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville            if (DBG) log("SST.getAllCellInfo(): not implemented");
9455fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            result.list = null;
9465fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        }
947bed429d6d0a0dbc6384b04e0641aa1e03e406f42Amit Mahajan        synchronized(result.lockObj) {
9485fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            if (result.list != null) {
949bed429d6d0a0dbc6384b04e0641aa1e03e406f42Amit Mahajan                if (DBG) log("SST.getAllCellInfo(): X size=" + result.list.size()
9505fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        + " list=" + result.list);
951bed429d6d0a0dbc6384b04e0641aa1e03e406f42Amit Mahajan                return result.list;
9525fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            } else {
953bed429d6d0a0dbc6384b04e0641aa1e03e406f42Amit Mahajan                if (DBG) log("SST.getAllCellInfo(): X size=0 list=null");
954bed429d6d0a0dbc6384b04e0641aa1e03e406f42Amit Mahajan                return null;
9555fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            }
9565fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        }
957ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
958ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
959ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    /**
960ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     * @return signal strength
961ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     */
962ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    public SignalStrength getSignalStrength() {
963ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        synchronized(mCellInfo) {
964ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville            return mSignalStrength;
965ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        }
966ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
967ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
9680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
9690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println("ServiceStateTracker:");
97022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mSS=" + mSS);
97122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mNewSS=" + mNewSS);
972ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        pw.println(" mCellInfo=" + mCellInfo);
9730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mRestrictedState=" + mRestrictedState);
97422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mPollingContext=" + mPollingContext);
9750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mDesiredPowerState=" + mDesiredPowerState);
97622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mDontPollSignalStrength=" + mDontPollSignalStrength);
9770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mPendingRadioPowerOffAfterDataOff=" + mPendingRadioPowerOffAfterDataOff);
9780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mPendingRadioPowerOffAfterDataOffTag=" + mPendingRadioPowerOffAfterDataOffTag);
979e97be3971cb6b55e019433c32524cc60ce0d037bWink Saville        pw.flush();
9800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
981e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
982bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com    public boolean isImsRegistered() {
983bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com        return mImsRegistered;
984bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com    }
985e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    /**
986e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * Verifies the current thread is the same as the thread originally
987e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * used in the initialization of this instance. Throws RuntimeException
988e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * if not.
989e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     *
990e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * @exception RuntimeException if the current thread is not
991e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * the thread that originally obtained this PhoneBase instance.
992e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     */
993e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected void checkCorrectThread() {
994e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (Thread.currentThread() != getLooper().getThread()) {
995e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            throw new RuntimeException(
996e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                    "ServiceStateTracker must be used from within one thread");
997e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        }
998e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    }
9995fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
10005fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected boolean isCallerOnDifferentThread() {
10015fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        boolean value = Thread.currentThread() != getLooper().getThread();
10025fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        if (VDBG) log("isCallerOnDifferentThread: " + value);
10035fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        return value;
10045fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    }
1005b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt
1006b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt    protected void updateCarrierMccMncConfiguration(String newOp, String oldOp, Context context) {
1007b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt        // if we have a change in operator, notify wifi (even to/from none)
1008b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt        if (((newOp == null) && (TextUtils.isEmpty(oldOp) == false)) ||
1009b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                ((newOp != null) && (newOp.equals(oldOp) == false))) {
1010a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("update mccmnc=" + newOp + " fromServiceState=true");
1011b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt            MccTable.updateMccMncConfiguration(context, newOp, true);
1012b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt        }
1013b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt    }
1014ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao
1015ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    /**
1016ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * Check ISO country by MCC to see if phone is roaming in same registered country
1017ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     */
1018ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    protected boolean inSameCountry(String operatorNumeric) {
1019ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        if (TextUtils.isEmpty(operatorNumeric) || (operatorNumeric.length() < 5)) {
1020ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            // Not a valid network
1021ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            return false;
1022ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        }
1023ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        final String homeNumeric = getHomeOperatorNumeric();
1024ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        if (TextUtils.isEmpty(homeNumeric) || (homeNumeric.length() < 5)) {
1025ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            // Not a valid SIM MCC
1026ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            return false;
1027ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        }
1028ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        boolean inSameCountry = true;
1029ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        final String networkMCC = operatorNumeric.substring(0, 3);
1030ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        final String homeMCC = homeNumeric.substring(0, 3);
1031ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        final String networkCountry = MccTable.countryCodeForMcc(Integer.parseInt(networkMCC));
1032ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        final String homeCountry = MccTable.countryCodeForMcc(Integer.parseInt(homeMCC));
1033ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        if (networkCountry.isEmpty() || homeCountry.isEmpty()) {
1034ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            // Not a valid country
1035ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            return false;
1036ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        }
1037ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        inSameCountry = homeCountry.equals(networkCountry);
1038ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        if (inSameCountry) {
1039ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            return inSameCountry;
1040ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        }
1041ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        // special same country cases
1042ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        if ("us".equals(homeCountry) && "vi".equals(networkCountry)) {
1043ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            inSameCountry = true;
1044ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        } else if ("vi".equals(homeCountry) && "us".equals(networkCountry)) {
1045ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            inSameCountry = true;
1046ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        }
1047ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        return inSameCountry;
1048ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    }
1049ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao
1050ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    protected abstract void setRoamingType(ServiceState currentServiceState);
1051ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao
1052ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    protected String getHomeOperatorNumeric() {
1053e70617d81dcd42350a737b11c25532e1d43df4ffLegler Wu        return ((TelephonyManager) mPhoneBase.getContext().
1054e70617d81dcd42350a737b11c25532e1d43df4ffLegler Wu                getSystemService(Context.TELEPHONY_SERVICE)).
1055e70617d81dcd42350a737b11c25532e1d43df4ffLegler Wu                getSimOperatorNumericForPhone(mPhoneBase.getPhoneId());
1056ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    }
1057062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal
1058062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal    protected int getPhoneId() {
1059062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal        return mPhoneBase.getPhoneId();
1060062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal    }
10610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
1062