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;
24de2d2034a7df068f3e929ff1d623a80c847b6335Chris Mantonimport android.os.BaseBundle;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Registrant;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.RegistrantList;
290c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Savilleimport android.os.SystemClock;
30ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhaoimport android.os.SystemProperties;
31d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajanimport android.preference.PreferenceManager;
32de2d2034a7df068f3e929ff1d623a80c847b6335Chris Mantonimport android.telephony.CarrierConfigManager;
33ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Savilleimport android.telephony.CellInfo;
3414ad8ce79de28b7e4a1d25bacb4e51ca027159b4Shishir Agrawalimport android.telephony.Rlog;
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.ServiceState;
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.SignalStrength;
373bc32aa4a3f533421f82a6d7991bb1971bf78191Amit Mahajanimport android.telephony.SubscriptionManager;
384b09dff383ae7dfca595aeeea886a594a1947340Wink Savilleimport android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
39a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.TelephonyManager;
40b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwaltimport android.text.TextUtils;
4156dbbcf63e9991ee83945fd10661190d917f700axinheimport android.util.Log;
42203e588e3c42a81aa8a56f595119c181a63b12caWink Savilleimport android.util.Pair;
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.TimeUtils;
440e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singhimport android.net.ConnectivityManager;
450e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singhimport android.net.NetworkInfo;
460e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singhimport android.content.Context;
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.FileDescriptor;
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.PrintWriter;
50de2d2034a7df068f3e929ff1d623a80c847b6335Chris Mantonimport java.util.Arrays;
515fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Savilleimport java.util.ArrayList;
52ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Savilleimport java.util.List;
5340dc777432250ec592696c7e1f395d582edb3b5fRobert Greenwaltimport java.util.concurrent.atomic.AtomicInteger;
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
55454b1dfd508844b42eb775e4ab2359be74d3672bWink Savilleimport com.android.internal.telephony.dataconnection.DcTrackerBase;
56d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
5756dbbcf63e9991ee83945fd10661190d917f700axinheimport com.android.internal.telephony.uicc.IccCardProxy;
58d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccRecords;
59d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.UiccCardApplication;
60e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenkaimport com.android.internal.telephony.uicc.UiccController;
61e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic abstract class ServiceStateTracker extends Handler {
6614ad8ce79de28b7e4a1d25bacb4e51ca027159b4Shishir Agrawal    private static final String LOG_TAG = "SST";
675fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected  static final boolean DBG = true;
685fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected static final boolean VDBG = false;
695fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
7060ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkey    protected static final String PROP_FORCE_ROAMING = "telephony.test.forceRoaming";
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected CommandsInterface mCi;
73e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected UiccController mUiccController = null;
74e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    protected UiccCardApplication mUiccApplcation = null;
75e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected IccRecords mIccRecords = null;
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
77ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected PhoneBase mPhoneBase;
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
79f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville    protected boolean mVoiceCapable;
80f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville
8122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    public ServiceState mSS = new ServiceState();
8222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected ServiceState mNewSS = new ServiceState();
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
840c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville    private static final long LAST_CELL_INFO_LIST_MAX_AGE_MS = 2000;
850c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville    protected long mLastCellInfoListTime;
865fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected List<CellInfo> mLastCellInfoList = null;
87ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
88ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    // This is final as subclasses alias to a more specific type
89ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    // so we don't want the reference to change.
90ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected final CellInfo mCellInfo;
91ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
92ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected SignalStrength mSignalStrength = new SignalStrength();
93ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
94ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    // TODO - this should not be public, right now used externally GsmConnetion.
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public RestrictedState mRestrictedState = new RestrictedState();
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* The otaspMode passed to PhoneStateListener#onOtaspChanged */
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_UNINITIALIZED = 0;
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_UNKNOWN = 1;
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_NEEDED = 2;
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static public final int OTASP_NOT_NEEDED = 3;
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * A unique identifier to track requests associated with a poll
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * and ignore stale responses.  The value is a count-down of
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * expected responses in this pollingContext.
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
10822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected int[] mPollingContext;
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean mDesiredPowerState;
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * By default, strength polling is enabled.  However, if we're
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * getting unsolicited signal strength updates from the radio, set
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * value to true and don't bother polling any more.
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    protected boolean mDontPollSignalStrength = false;
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
118ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    protected RegistrantList mVoiceRoamingOnRegistrants = new RegistrantList();
119ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    protected RegistrantList mVoiceRoamingOffRegistrants = new RegistrantList();
120ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    protected RegistrantList mDataRoamingOnRegistrants = new RegistrantList();
121ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    protected RegistrantList mDataRoamingOffRegistrants = new RegistrantList();
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mAttachedRegistrants = new RegistrantList();
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mDetachedRegistrants = new RegistrantList();
124203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    protected RegistrantList mDataRegStateOrRatChangedRegistrants = new RegistrantList();
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mNetworkAttachedRegistrants = new RegistrantList();
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mPsRestrictEnabledRegistrants = new RegistrantList();
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected RegistrantList mPsRestrictDisabledRegistrants = new RegistrantList();
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* Radio power off pending flag and tag counter */
130a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected boolean mPendingRadioPowerOffAfterDataOff = false;
131a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected int mPendingRadioPowerOffAfterDataOffTag = 0;
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Signal strength poll rate. */
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int POLL_PERIOD_MILLIS = 20 * 1000;
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Waiting period before recheck gprs and voice registration. */
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** GSM events */
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RADIO_STATE_CHANGED               = 1;
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NETWORK_STATE_CHANGED             = 2;
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_SIGNAL_STRENGTH               = 3;
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_REGISTRATION           = 4;
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_GPRS                   = 5;
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_OPERATOR               = 6;
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_SIGNAL_STRENGTH              = 10;
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NITZ_TIME                         = 11;
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SIGNAL_STRENGTH_UPDATE            = 12;
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RADIO_AVAILABLE                   = 13;
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_NETWORK_SELECTION_MODE = 14;
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_LOC_DONE                      = 15;
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SIM_RECORDS_LOADED                = 16;
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SIM_READY                         = 17;
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_LOCATION_UPDATES_ENABLED          = 18;
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_PREFERRED_NETWORK_TYPE        = 19;
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SET_PREFERRED_NETWORK_TYPE        = 20;
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RESET_PREFERRED_NETWORK_TYPE      = 21;
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_CHECK_REPORT_GPRS                 = 22;
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RESTRICTED_STATE_CHANGED          = 23;
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** CDMA events */
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_REGISTRATION_CDMA      = 24;
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_OPERATOR_CDMA          = 25;
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RUIM_READY                        = 26;
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RUIM_RECORDS_LOADED               = 27;
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_SIGNAL_STRENGTH_CDMA         = 28;
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_SIGNAL_STRENGTH_CDMA          = 29;
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NETWORK_STATE_CHANGED_CDMA        = 30;
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_GET_LOC_DONE_CDMA                 = 31;
170ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    //protected static final int EVENT_UNUSED                            = 32;
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NV_LOADED                         = 33;
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_POLL_STATE_CDMA_SUBSCRIPTION      = 34;
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_NV_READY                          = 35;
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_ERI_FILE_LOADED                   = 36;
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_OTA_PROVISION_STATUS_CHANGE       = 37;
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_SET_RADIO_POWER_OFF               = 38;
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED  = 39;
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_CDMA_PRL_VERSION_CHANGED          = 40;
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final int EVENT_RADIO_ON                          = 41;
180a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public static final int EVENT_ICC_CHANGED                          = 42;
1815fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected static final int EVENT_GET_CELL_INFO_LIST                = 43;
1825fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected static final int EVENT_UNSOL_CELL_INFO_LIST              = 44;
183a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected static final int EVENT_CHANGE_IMS_STATE                  = 45;
184bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com    protected static final int EVENT_IMS_STATE_CHANGED                 = 46;
185bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com    protected static final int EVENT_IMS_STATE_DONE                    = 47;
186e51d918511afab905399d9fda7f51442f15bd8a7Pavel Zhamaitsiak    protected static final int EVENT_IMS_CAPABILITY_CHANGED            = 48;
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * List of ISO codes for countries that can have an offset of
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * GMT+0 when not in daylight savings time.  This ignores some
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * small places such as the Canary Islands (Spain) and
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Danmarkshavn (Denmark).  The list must be sorted by code.
1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    */
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String[] GMT_COUNTRY_CODES = {
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "bf", // Burkina Faso
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ci", // Cote d'Ivoire
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "eh", // Western Sahara
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "fo", // Faroe Islands, Denmark
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gb", // United Kingdom of Great Britain and Northern Ireland
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gh", // Ghana
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gm", // Gambia
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gn", // Guinea
2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "gw", // Guinea Bissau
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ie", // Ireland
2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "lr", // Liberia
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "is", // Iceland
2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ma", // Morocco
2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "ml", // Mali
2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "mr", // Mauritania
2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "pt", // Portugal
2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "sl", // Sierra Leone
2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "sn", // Senegal
2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "st", // Sao Tome and Principe
2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "tg", // Togo
2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2195fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    private class CellInfoResult {
2205fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        List<CellInfo> list;
2215fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        Object lockObj = new Object();
2225fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    }
2235fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Reason for registration denial. */
2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String REGISTRATION_DENIED_GEN  = "General";
2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected static final String REGISTRATION_DENIED_AUTH = "Authentication Failure";
2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
228a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected boolean mImsRegistrationOnOff = false;
229a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected boolean mAlarmSwitch = false;
230a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected IntentFilter mIntentFilter = null;
231a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected PendingIntent mRadioOffIntent = null;
232a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected static final String ACTION_RADIO_OFF = "android.intent.action.ACTION_RADIO_OFF";
233a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected boolean mPowerOffDelayNeed = true;
23403586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla    protected boolean mDeviceShuttingDown = false;
23519517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan    /** Keep track of SPN display rules, so we only broadcast intent if something changes. */
23619517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan    protected boolean mSpnUpdatePending = false;
23719517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan    protected String mCurSpn = null;
238519ffa0fab25898c909ed96c10f64b2c23910f88Pavel Zhamaitsiak    protected String mCurDataSpn = null;
23919517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan    protected String mCurPlmn = null;
24019517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan    protected boolean mCurShowPlmn = false;
24119517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan    protected boolean mCurShowSpn = false;
2426c497f695c5c0017c511e471d36bdfc66dbbf605Jack Yu    protected int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
24319517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan
244bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com    private boolean mImsRegistered = false;
24503586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla
2464b09dff383ae7dfca595aeeea886a594a1947340Wink Saville    protected SubscriptionManager mSubscriptionManager;
2470192d7f3f201bce2b513749982577c8ddebe3ea2Jason Monk    protected SubscriptionController mSubscriptionController;
24840dc777432250ec592696c7e1f395d582edb3b5fRobert Greenwalt    protected final SstSubscriptionsChangedListener mOnSubscriptionsChangedListener =
24940dc777432250ec592696c7e1f395d582edb3b5fRobert Greenwalt        new SstSubscriptionsChangedListener();
25040dc777432250ec592696c7e1f395d582edb3b5fRobert Greenwalt
25140dc777432250ec592696c7e1f395d582edb3b5fRobert Greenwalt    protected class SstSubscriptionsChangedListener extends OnSubscriptionsChangedListener {
25240dc777432250ec592696c7e1f395d582edb3b5fRobert Greenwalt        public final AtomicInteger mPreviousSubId = new AtomicInteger(-1); // < 0 is invalid subId
2534b09dff383ae7dfca595aeeea886a594a1947340Wink Saville        /**
2544b09dff383ae7dfca595aeeea886a594a1947340Wink Saville         * Callback invoked when there is any change to any SubscriptionInfo. Typically
2554b09dff383ae7dfca595aeeea886a594a1947340Wink Saville         * this method would invoke {@link SubscriptionManager#getActiveSubscriptionInfoList}
2563bc32aa4a3f533421f82a6d7991bb1971bf78191Amit Mahajan         */
2573bc32aa4a3f533421f82a6d7991bb1971bf78191Amit Mahajan        @Override
2584b09dff383ae7dfca595aeeea886a594a1947340Wink Saville        public void onSubscriptionsChanged() {
2593bc32aa4a3f533421f82a6d7991bb1971bf78191Amit Mahajan            if (DBG) log("SubscriptionListener.onSubscriptionInfoChanged");
2603bc32aa4a3f533421f82a6d7991bb1971bf78191Amit Mahajan            // Set the network type, in case the radio does not restore it.
26156dbbcf63e9991ee83945fd10661190d917f700axinhe            int subId = mPhoneBase.getSubId();
26240dc777432250ec592696c7e1f395d582edb3b5fRobert Greenwalt            if (mPreviousSubId.getAndSet(subId) != subId) {
263b8ec2c1d94a76180871a58e14da06e1f0267e503Amit Mahajan                if (SubscriptionManager.isValidSubscriptionId(subId)) {
264d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                    Context context = mPhoneBase.getContext();
265b41cbe42c6e7c07c039eac2a871b6a772329d8dbAmit Mahajan
266ad8eab8645079b88aeba3c7dc77ce885114a0efcAmit Mahajan                    mPhoneBase.notifyCallForwardingIndicator();
267ad8eab8645079b88aeba3c7dc77ce885114a0efcAmit Mahajan
2680349fc63faa1e63848cba7718c5002d53e6b0451Stuart Scott                    boolean restoreSelection = !context.getResources().getBoolean(
269d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                            com.android.internal.R.bool.skip_restoring_network_selection);
2700349fc63faa1e63848cba7718c5002d53e6b0451Stuart Scott                    mPhoneBase.sendSubscriptionSettings(restoreSelection);
271d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan
272b41cbe42c6e7c07c039eac2a871b6a772329d8dbAmit Mahajan                    mPhoneBase.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
273b41cbe42c6e7c07c039eac2a871b6a772329d8dbAmit Mahajan                        ServiceState.rilRadioTechnologyToString(mSS.getRilDataRadioTechnology()));
27419517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan
27519517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan                    if (mSpnUpdatePending) {
276062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal                        mSubscriptionController.setPlmnSpn(mPhoneBase.getPhoneId(), mCurShowPlmn,
277062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal                                mCurPlmn, mCurShowSpn, mCurSpn);
27819517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan                        mSpnUpdatePending = false;
27919517065ec69bafc5cfc91c8386a7583441ecf6dAmit Mahajan                    }
280d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan
281d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                    // Remove old network selection sharedPreferences since SP key names are now
282d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                    // changed to include subId. This will be done only once when upgrading from an
283d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                    // older build that did not include subId in the names.
284d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                    SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(
285d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                            context);
2860349fc63faa1e63848cba7718c5002d53e6b0451Stuart Scott                    String oldNetworkSelection = sp.getString(
2870349fc63faa1e63848cba7718c5002d53e6b0451Stuart Scott                            PhoneBase.NETWORK_SELECTION_KEY, "");
2880349fc63faa1e63848cba7718c5002d53e6b0451Stuart Scott                    String oldNetworkSelectionName = sp.getString(
2890349fc63faa1e63848cba7718c5002d53e6b0451Stuart Scott                            PhoneBase.NETWORK_SELECTION_NAME_KEY, "");
2900349fc63faa1e63848cba7718c5002d53e6b0451Stuart Scott                    String oldNetworkSelectionShort = sp.getString(
2910349fc63faa1e63848cba7718c5002d53e6b0451Stuart Scott                            PhoneBase.NETWORK_SELECTION_SHORT_KEY, "");
2920349fc63faa1e63848cba7718c5002d53e6b0451Stuart Scott                    if (!TextUtils.isEmpty(oldNetworkSelection) ||
2930349fc63faa1e63848cba7718c5002d53e6b0451Stuart Scott                            !TextUtils.isEmpty(oldNetworkSelectionName) ||
2940349fc63faa1e63848cba7718c5002d53e6b0451Stuart Scott                            !TextUtils.isEmpty(oldNetworkSelectionShort)) {
295d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                        SharedPreferences.Editor editor = sp.edit();
296d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                        editor.putString(PhoneBase.NETWORK_SELECTION_KEY + subId,
297d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                                oldNetworkSelection);
2980349fc63faa1e63848cba7718c5002d53e6b0451Stuart Scott                        editor.putString(PhoneBase.NETWORK_SELECTION_NAME_KEY + subId,
2990349fc63faa1e63848cba7718c5002d53e6b0451Stuart Scott                                oldNetworkSelectionName);
3000349fc63faa1e63848cba7718c5002d53e6b0451Stuart Scott                        editor.putString(PhoneBase.NETWORK_SELECTION_SHORT_KEY + subId,
3010349fc63faa1e63848cba7718c5002d53e6b0451Stuart Scott                                oldNetworkSelectionShort);
302d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                        editor.remove(PhoneBase.NETWORK_SELECTION_KEY);
3030349fc63faa1e63848cba7718c5002d53e6b0451Stuart Scott                        editor.remove(PhoneBase.NETWORK_SELECTION_NAME_KEY);
3040349fc63faa1e63848cba7718c5002d53e6b0451Stuart Scott                        editor.remove(PhoneBase.NETWORK_SELECTION_SHORT_KEY);
305d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                        editor.commit();
306d756a6bcf4fe09b561481eb6ed5368bd7b21ca76Amit Mahajan                    }
3076c497f695c5c0017c511e471d36bdfc66dbbf605Jack Yu
3086c497f695c5c0017c511e471d36bdfc66dbbf605Jack Yu                    // Once sub id becomes valid, we need to update the service provider name
3096c497f695c5c0017c511e471d36bdfc66dbbf605Jack Yu                    // displayed on the UI again. The old SPN update intents sent to
3106c497f695c5c0017c511e471d36bdfc66dbbf605Jack Yu                    // MobileSignalController earlier were actually ignored due to invalid sub id.
3116c497f695c5c0017c511e471d36bdfc66dbbf605Jack Yu                    updateSpnDisplay();
31256dbbcf63e9991ee83945fd10661190d917f700axinhe                }
3133bc32aa4a3f533421f82a6d7991bb1971bf78191Amit Mahajan            }
3143bc32aa4a3f533421f82a6d7991bb1971bf78191Amit Mahajan        }
3153bc32aa4a3f533421f82a6d7991bb1971bf78191Amit Mahajan    };
316a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
317049ab0421f32e6effc5d1277b69bd382cebadb18Wink Saville    protected ServiceStateTracker(PhoneBase phoneBase, CommandsInterface ci, CellInfo cellInfo) {
318ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        mPhoneBase = phoneBase;
319ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        mCellInfo = cellInfo;
32022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi = ci;
321f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville        mVoiceCapable = mPhoneBase.getContext().getResources().getBoolean(
322f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville                com.android.internal.R.bool.config_voice_capable);
323e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        mUiccController = UiccController.getInstance();
324e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
32522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
3265fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        mCi.registerForCellInfoList(this, EVENT_UNSOL_CELL_INFO_LIST, null);
327c4161078eff3305894f1f9f1b2f00952ea0e83d8Kazuya Ohshiro
3280192d7f3f201bce2b513749982577c8ddebe3ea2Jason Monk        mSubscriptionController = SubscriptionController.getInstance();
3294b09dff383ae7dfca595aeeea886a594a1947340Wink Saville        mSubscriptionManager = SubscriptionManager.from(phoneBase.getContext());
3304b09dff383ae7dfca595aeeea886a594a1947340Wink Saville        mSubscriptionManager
33133d14d71f4b43d82d6c1b87d1d30cd86d13c5372Wink Saville            .addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
3323bc32aa4a3f533421f82a6d7991bb1971bf78191Amit Mahajan
333c4161078eff3305894f1f9f1b2f00952ea0e83d8Kazuya Ohshiro        mPhoneBase.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
334c4161078eff3305894f1f9f1b2f00952ea0e83d8Kazuya Ohshiro            ServiceState.rilRadioTechnologyToString(ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN));
335bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com        mCi.registerForImsNetworkStateChanged(this, EVENT_IMS_STATE_CHANGED, null);
336ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
337ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
33803586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla    void requestShutdown() {
33903586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla        if (mDeviceShuttingDown == true) return;
34003586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla        mDeviceShuttingDown = true;
34103586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla        mDesiredPowerState = false;
34203586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla        setPowerStateToDesired();
34303586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla    }
34403586878fb3d870373f2fdf65afb81cc5ae97067Naveen Kalla
345ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    public void dispose() {
34622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unSetOnSignalStrengthUpdate(this);
347c26fb77c4e637466cf0483a4995fe82e6f68b8d3Alex Yakavenka        mUiccController.unregisterForIccChanged(this);
3485fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        mCi.unregisterForCellInfoList(this);
3494b09dff383ae7dfca595aeeea886a594a1947340Wink Saville        mSubscriptionManager
35033d14d71f4b43d82d6c1b87d1d30cd86d13c5372Wink Saville            .removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean getDesiredPowerState() {
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return mDesiredPowerState;
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
357ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    private SignalStrength mLastSignalStrength = null;
358ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    protected boolean notifySignalStrength() {
359ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        boolean notified = false;
360ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        synchronized(mCellInfo) {
361ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville            if (!mSignalStrength.equals(mLastSignalStrength)) {
362ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                try {
363ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                    mPhoneBase.notifySignalStrength();
364ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                    notified = true;
365ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                } catch (NullPointerException ex) {
366ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                    loge("updateSignalStrength() Phone already destroyed: " + ex
367ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                            + "SignalStrength not notified");
368ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville                }
369ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville            }
370ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        }
371ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        return notified;
372ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
373ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
374ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    /**
375203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * Notify all mDataConnectionRatChangeRegistrants using an
376203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * AsyncResult in msg.obj where AsyncResult#result contains the
377203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * new RAT as an Integer Object.
378203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     */
379203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    protected void notifyDataRegStateRilRadioTechnologyChanged() {
380203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        int rat = mSS.getRilDataRadioTechnology();
381203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        int drs = mSS.getDataRegState();
382203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        if (DBG) log("notifyDataRegStateRilRadioTechnologyChanged: drs=" + drs + " rat=" + rat);
383203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        mPhoneBase.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
384203e588e3c42a81aa8a56f595119c181a63b12caWink Saville                ServiceState.rilRadioTechnologyToString(rat));
385203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        mDataRegStateOrRatChangedRegistrants.notifyResult(new Pair<Integer, Integer>(drs, rat));
386203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    }
387203e588e3c42a81aa8a56f595119c181a63b12caWink Saville
388203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    /**
389f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville     * Some operators have been known to report registration failure
390f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville     * data only devices, to fix that use DataRegState.
391f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville     */
392f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville    protected void useDataRegStateForDataOnlyDevices() {
393f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville        if (mVoiceCapable == false) {
394f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville            if (DBG) {
395f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville                log("useDataRegStateForDataOnlyDevice: VoiceRegState=" + mNewSS.getVoiceRegState()
396f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville                    + " DataRegState=" + mNewSS.getDataRegState());
397f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville            }
398f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville            // TODO: Consider not lying and instead have callers know the difference.
399f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville            mNewSS.setVoiceRegState(mNewSS.getDataRegState());
400f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville        }
401f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville    }
402f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville
40303b37b67755a4033c6be32ae2e389c310e06e7d1Amit Mahajan    protected void updatePhoneObject() {
40417a893295d021cd48ad0e2e6ccf9ceda3f97c70cSukanya Rajkhowa        if (mPhoneBase.getContext().getResources().
40517a893295d021cd48ad0e2e6ccf9ceda3f97c70cSukanya Rajkhowa                getBoolean(com.android.internal.R.bool.config_switch_phone_on_voice_reg_state_change)) {
40614ad8ce79de28b7e4a1d25bacb4e51ca027159b4Shishir Agrawal            // If the phone is not registered on a network, no need to update.
40714ad8ce79de28b7e4a1d25bacb4e51ca027159b4Shishir Agrawal            boolean isRegistered = mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE ||
40814ad8ce79de28b7e4a1d25bacb4e51ca027159b4Shishir Agrawal                    mSS.getVoiceRegState() == ServiceState.STATE_EMERGENCY_ONLY;
40914ad8ce79de28b7e4a1d25bacb4e51ca027159b4Shishir Agrawal            if (!isRegistered) {
41014ad8ce79de28b7e4a1d25bacb4e51ca027159b4Shishir Agrawal                Rlog.d(LOG_TAG, "updatePhoneObject: Ignore update");
41114ad8ce79de28b7e4a1d25bacb4e51ca027159b4Shishir Agrawal                return;
41214ad8ce79de28b7e4a1d25bacb4e51ca027159b4Shishir Agrawal            }
41317a893295d021cd48ad0e2e6ccf9ceda3f97c70cSukanya Rajkhowa            mPhoneBase.updatePhoneObject(mSS.getRilVoiceRadioTechnology());
41417a893295d021cd48ad0e2e6ccf9ceda3f97c70cSukanya Rajkhowa        }
41503b37b67755a4033c6be32ae2e389c310e06e7d1Amit Mahajan    }
416f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville
417f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville    /**
418ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * Registration point for combined roaming on of mobile voice
4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * combined roaming is true when roaming is true and ONS differs SPN
4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
425ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    public void registerForVoiceRoamingOn(Handler h, int what, Object obj) {
4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
427ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        mVoiceRoamingOnRegistrants.add(r);
4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
429ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        if (mSS.getVoiceRoaming()) {
4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
434ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    public void unregisterForVoiceRoamingOn(Handler h) {
435ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        mVoiceRoamingOnRegistrants.remove(h);
4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
439ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * Registration point for roaming off of mobile voice
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * combined roaming is true when roaming is true and ONS differs SPN
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
446ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    public void registerForVoiceRoamingOff(Handler h, int what, Object obj) {
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
448ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        mVoiceRoamingOffRegistrants.add(r);
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
450ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        if (!mSS.getVoiceRoaming()) {
4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
455ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    public void unregisterForVoiceRoamingOff(Handler h) {
456ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        mVoiceRoamingOffRegistrants.remove(h);
457ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    }
458ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao
459ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    /**
460ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * Registration point for combined roaming on of mobile data
461ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * combined roaming is true when roaming is true and ONS differs SPN
462ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     *
463ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * @param h handler to notify
464ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * @param what what code of message when delivered
465ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * @param obj placed in Message.obj
466ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     */
467ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    public void registerForDataRoamingOn(Handler h, int what, Object obj) {
468ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        Registrant r = new Registrant(h, what, obj);
469ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        mDataRoamingOnRegistrants.add(r);
470ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao
471ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        if (mSS.getDataRoaming()) {
472ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            r.notifyRegistrant();
473ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        }
474ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    }
475ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao
476ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    public void unregisterForDataRoamingOn(Handler h) {
477ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        mDataRoamingOnRegistrants.remove(h);
478ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    }
479ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao
480ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    /**
481ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * Registration point for roaming off of mobile data
482ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * combined roaming is true when roaming is true and ONS differs SPN
483ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     *
484ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * @param h handler to notify
485ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * @param what what code of message when delivered
486ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * @param obj placed in Message.obj
487ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     */
488ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    public void registerForDataRoamingOff(Handler h, int what, Object obj) {
489ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        Registrant r = new Registrant(h, what, obj);
490ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        mDataRoamingOffRegistrants.add(r);
491ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao
492ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        if (!mSS.getDataRoaming()) {
493ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            r.notifyRegistrant();
494ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        }
495ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    }
496ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao
497ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    public void unregisterForDataRoamingOff(Handler h) {
498ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        mDataRoamingOffRegistrants.remove(h);
4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Re-register network by toggling preferred network type.
5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * This is a work-around to deregister and register network since there is
5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * no ril api to set COPS=2 (deregister) only.
5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param onComplete is dispatched when this is complete.  it will be
5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * an AsyncResult, and onComplete.obj.exception will be non-null
5080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * on failure.
5090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void reRegisterNetwork(Message onComplete) {
51122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.getPreferredNetworkType(
5120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE, onComplete));
5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    setRadioPower(boolean power) {
5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDesiredPowerState = power;
5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        setPowerStateToDesired();
5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * These two flags manage the behavior of the cell lock -- the
5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * lock should be held if either flag is true.  The intention is
5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * to allow temporary acquisition of the lock to get a single
5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * update.  Such a lock grab and release can thus be made to not
5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * interfere with more permanent lock holds -- in other words, the
5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * lock will only be released if both flags are false, and so
5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * releases by temporary users will only affect the lock state if
5300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * there is no continuous user.
5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mWantContinuousLocationUpdates;
5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mWantSingleLocationUpdate;
5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void enableSingleLocationUpdate() {
5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return;
5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantSingleLocationUpdate = true;
53822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED));
5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void enableLocationUpdates() {
5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return;
5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantContinuousLocationUpdates = true;
54422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED));
5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void disableSingleLocationUpdate() {
5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantSingleLocationUpdate = false;
5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) {
55022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.setLocationUpdates(false, null);
5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void disableLocationUpdates() {
5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWantContinuousLocationUpdates = false;
5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) {
55722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.setLocationUpdates(false, null);
5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void handleMessage(Message msg) {
5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (msg.what) {
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SET_RADIO_POWER_OFF:
5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                synchronized(this) {
5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (mPendingRadioPowerOffAfterDataOff &&
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            (msg.arg1 == mPendingRadioPowerOffAfterDataOffTag)) {
5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now.");
5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        hangupAndPowerOff();
5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mPendingRadioPowerOffAfterDataOffTag += 1;
5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mPendingRadioPowerOffAfterDataOff = false;
5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("EVENT_SET_RADIO_OFF is stale arg1=" + msg.arg1 +
5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                "!= tag=" + mPendingRadioPowerOffAfterDataOffTag);
5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
579e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            case EVENT_ICC_CHANGED:
580e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                onUpdateIccAvailability();
581e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                break;
582e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
5835fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            case EVENT_GET_CELL_INFO_LIST: {
5845fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                AsyncResult ar = (AsyncResult) msg.obj;
5855fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                CellInfoResult result = (CellInfoResult) ar.userObj;
5865fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                synchronized(result.lockObj) {
5875fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    if (ar.exception != null) {
5885fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        log("EVENT_GET_CELL_INFO_LIST: error ret null, e=" + ar.exception);
5895fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        result.list = null;
5905fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    } else {
5915fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        result.list = (List<CellInfo>) ar.result;
5925fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
5935fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        if (VDBG) {
5945fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                            log("EVENT_GET_CELL_INFO_LIST: size=" + result.list.size()
5955fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                                    + " list=" + result.list);
5965fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        }
5975fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    }
5980c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    mLastCellInfoListTime = SystemClock.elapsedRealtime();
5995fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    mLastCellInfoList = result.list;
6005fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    result.lockObj.notify();
6015fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                }
6025fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                break;
6035fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            }
6045fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
6055fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            case EVENT_UNSOL_CELL_INFO_LIST: {
6065fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                AsyncResult ar = (AsyncResult) msg.obj;
6075fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                if (ar.exception != null) {
6085fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    log("EVENT_UNSOL_CELL_INFO_LIST: error ignoring, e=" + ar.exception);
6095fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                } else {
6105fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    List<CellInfo> list = (List<CellInfo>) ar.result;
6115fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    if (DBG) {
6125fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        log("EVENT_UNSOL_CELL_INFO_LIST: size=" + list.size()
6135fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                                + " list=" + list);
6145fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    }
6150c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    mLastCellInfoListTime = SystemClock.elapsedRealtime();
6165fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    mLastCellInfoList = list;
6175fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    mPhoneBase.notifyCellInfo(list);
6185fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                }
6195fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                break;
6205fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            }
6215fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
622bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com            case  EVENT_IMS_STATE_CHANGED: // received unsol
623bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com                mCi.getImsRegistrationState(this.obtainMessage(EVENT_IMS_STATE_DONE));
624bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com                break;
625bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com
626bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com            case EVENT_IMS_STATE_DONE:
627bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com                AsyncResult ar = (AsyncResult) msg.obj;
628bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com                if (ar.exception == null) {
629bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com                    int[] responseArray = (int[])ar.result;
630bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com                    mImsRegistered = (responseArray[0] == 1) ? true : false;
631bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com                }
632bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com                break;
633bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com
6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("Unhandled message with number: " + msg.what);
6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
6370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract Phone getPhone();
6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void handlePollStateResult(int what, AsyncResult ar);
6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void updateSpnDisplay();
6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void setPowerStateToDesired();
644e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected abstract void onUpdateIccAvailability();
6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void log(String s);
6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void loge(String s);
6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public abstract int getCurrentDataConnectionState();
6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public abstract boolean isConcurrentVoiceAndDataAllowed();
6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
651a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public abstract void setImsRegistrationState(boolean registered);
652e51d918511afab905399d9fda7f51442f15bd8a7Pavel Zhamaitsiak    public void onImsCapabilityChanged() {}
653b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal    public abstract void pollState();
654a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into DataConnection attached.
6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForDataConnectionAttached(Handler h, int what, Object obj) {
6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mAttachedRegistrants.add(r);
6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (getCurrentDataConnectionState() == ServiceState.STATE_IN_SERVICE) {
6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForDataConnectionAttached(Handler h) {
6700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mAttachedRegistrants.remove(h);
6710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into DataConnection detached.
6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
6770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
6780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForDataConnectionDetached(Handler h, int what, Object obj) {
6800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
6810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDetachedRegistrants.add(r);
6820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (getCurrentDataConnectionState() != ServiceState.STATE_IN_SERVICE) {
6840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
6850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForDataConnectionDetached(Handler h) {
6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDetachedRegistrants.remove(h);
6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
692203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * Registration for DataConnection RIL Data Radio Technology changing. The
693203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * new radio technology will be returned AsyncResult#result as an Integer Object.
694203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * The AsyncResult will be in the notification Message#obj.
695203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     *
696203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * @param h handler to notify
697203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * @param what what code of message when delivered
698203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     * @param obj placed in Message.obj
699203e588e3c42a81aa8a56f595119c181a63b12caWink Saville     */
700203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    public void registerForDataRegStateOrRatChanged(Handler h, int what, Object obj) {
701203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        Registrant r = new Registrant(h, what, obj);
702203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        mDataRegStateOrRatChangedRegistrants.add(r);
703203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        notifyDataRegStateRilRadioTechnologyChanged();
704203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    }
705203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    public void unregisterForDataRegStateOrRatChanged(Handler h) {
706203e588e3c42a81aa8a56f595119c181a63b12caWink Saville        mDataRegStateOrRatChangedRegistrants.remove(h);
707203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    }
708203e588e3c42a81aa8a56f595119c181a63b12caWink Saville
709203e588e3c42a81aa8a56f595119c181a63b12caWink Saville    /**
7100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into network attached.
7110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
7120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
7130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj in Message.obj
7140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
7150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForNetworkAttached(Handler h, int what, Object obj) {
7160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
7170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNetworkAttachedRegistrants.add(r);
71922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE) {
7200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
7210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForNetworkAttached(Handler h) {
7240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNetworkAttachedRegistrants.remove(h);
7250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
7280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition into packet service restricted zone.
7290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
7300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
7310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
7320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
7330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForPsRestrictedEnabled(Handler h, int what, Object obj) {
7340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
7350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictEnabledRegistrants.add(r);
7360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mRestrictedState.isPsRestricted()) {
7380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForPsRestrictedEnabled(Handler h) {
7430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictEnabledRegistrants.remove(h);
7440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
7470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Registration point for transition out of packet service restricted zone.
7480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param h handler to notify
7490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param what what code of message when delivered
7500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param obj placed in Message.obj
7510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
7520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void registerForPsRestrictedDisabled(Handler h, int what, Object obj) {
7530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Registrant r = new Registrant(h, what, obj);
7540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictDisabledRegistrants.add(r);
7550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mRestrictedState.isPsRestricted()) {
7570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            r.notifyRegistrant();
7580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void unregisterForPsRestrictedDisabled(Handler h) {
7620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPsRestrictDisabledRegistrants.remove(h);
7630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
7660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Clean up existing voice and data connection then turn off radio power.
7670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
7680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Hang up the existing voice calls to decrease call drop rate.
7690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
770454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville    public void powerOffRadioSafely(DcTrackerBase dcTracker) {
7710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (this) {
7720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!mPendingRadioPowerOffAfterDataOff) {
77375c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                // In some network, deactivate PDP connection cause releasing of RRC connection,
77475c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                // which MM/IMSI detaching request needs. Without this detaching, network can
77575c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                // not release the network resources previously attached.
77675c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                // So we are avoiding data detaching on these networks.
77775c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                String[] networkNotClearData = mPhoneBase.getContext().getResources()
77875c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                        .getStringArray(com.android.internal.R.array.networks_not_clear_data);
77975c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                String currentNetwork = mSS.getOperatorNumeric();
78075c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                if ((networkNotClearData != null) && (currentNetwork != null)) {
78175c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                    for (int i = 0; i < networkNotClearData.length; i++) {
78275c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                        if (currentNetwork.equals(networkNotClearData[i])) {
78375c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                            // Don't clear data connection for this carrier
78475c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                            if (DBG)
78575c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                                log("Not disconnecting data for " + currentNetwork);
78675c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                            hangupAndPowerOff();
78775c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                            return;
78875c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                        }
78975c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                    }
79075c934492b242f8ba750b11d9dae4304c76bbc07Jing Zhao                }
7910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // To minimize race conditions we call cleanUpAllConnections on
7920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // both if else paths instead of before this isDisconnected test.
7930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (dcTracker.isDisconnected()) {
7940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // To minimize race conditions we do this after isDisconnected
7950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF);
7960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) log("Data disconnected, turn off radio right away.");
7970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    hangupAndPowerOff();
7980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
7990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF);
8000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    Message msg = Message.obtain(this);
8010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    msg.what = EVENT_SET_RADIO_POWER_OFF;
8020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    msg.arg1 = ++mPendingRadioPowerOffAfterDataOffTag;
8030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (sendMessageDelayed(msg, 30000)) {
8040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("Wait upto 30s for data to disconnect, then turn off radio.");
8050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mPendingRadioPowerOffAfterDataOff = true;
8060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
8070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("Cannot send delayed Msg, turn off radio right away.");
8080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        hangupAndPowerOff();
8090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
8100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
8110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
8160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * process the pending request to turn radio off after data is disconnected
8170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
8180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * return true if there is pending request to process; false otherwise.
8190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
8200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean processPendingRadioPowerOffAfterDataOff() {
8210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized(this) {
8220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mPendingRadioPowerOffAfterDataOff) {
8230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("Process pending request to turn radio off.");
8240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPendingRadioPowerOffAfterDataOffTag += 1;
8250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hangupAndPowerOff();
8260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPendingRadioPowerOffAfterDataOff = false;
8270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return true;
8280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
8300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
8345b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam     * send signal-strength-changed notification if changed Called both for
8355b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam     * solicited and unsolicited signal strength updates
836e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville     *
837e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville     * @return true if the signal strength changed and a notification was sent.
8385b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam     */
839e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville    protected boolean onSignalStrengthResult(AsyncResult ar, boolean isGsm) {
8405b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        SignalStrength oldSignalStrength = mSignalStrength;
8415b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam
8425b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        // This signal is used for both voice and data radio signal so parse
8435b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        // all fields
8445b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam
8455b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        if ((ar.exception == null) && (ar.result != null)) {
8465b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            mSignalStrength = (SignalStrength) ar.result;
8475b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            mSignalStrength.validateInput();
8485b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            mSignalStrength.setGsm(isGsm);
8495b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        } else {
8505b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            log("onSignalStrengthResult() Exception from RIL : " + ar.exception);
8515b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam            mSignalStrength = new SignalStrength(isGsm);
8525b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        }
8535b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam
854e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville        return notifySignalStrength();
8555b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam    }
8565b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam
8575b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam    /**
8580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Hang up all voice call and turn off radio. Implemented by derived class.
8590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
8600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void hangupAndPowerOff();
8610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Cancel a pending (if any) pollState() operation */
8630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void cancelPollState() {
8640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // This will effectively cancel the rest of the poll requests.
86522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPollingContext = new int[1];
8660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
8690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Return true if time zone needs fixing.
8700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
8710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param phoneBase
8720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param operatorNumeric
8730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param prevOperatorNumeric
8740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param needToFixTimeZone
8750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if time zone needs to be fixed
8760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
8770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected boolean shouldFixTimeZoneNow(PhoneBase phoneBase, String operatorNumeric,
8780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String prevOperatorNumeric, boolean needToFixTimeZone) {
8790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Return false if the mcc isn't valid as we don't know where we are.
8800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Return true if we have an IccCard and the mcc changed or we
8810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // need to fix it because when the NITZ time came in we didn't
8820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // know the country code.
8830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If mcc is invalid then we'll return false
8850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int mcc;
8860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
8870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mcc = Integer.parseInt(operatorNumeric.substring(0, 3));
8880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (Exception e) {
8890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
8900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("shouldFixTimeZoneNow: no mcc, operatorNumeric=" + operatorNumeric +
8910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        " retVal=false");
8920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
8940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If prevMcc is invalid will make it different from mcc
8970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // so we'll return true if the card exists.
8980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int prevMcc;
8990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
9000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            prevMcc = Integer.parseInt(prevOperatorNumeric.substring(0, 3));
9010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (Exception e) {
9020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            prevMcc = mcc + 1;
9030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Determine if the Icc card exists
906e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        boolean iccCardExist = false;
907e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mUiccApplcation != null) {
908e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            iccCardExist = mUiccApplcation.getState() != AppState.APPSTATE_UNKNOWN;
909e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
9100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Determine retVal
9120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean retVal = ((iccCardExist && (mcc != prevMcc)) || needToFixTimeZone);
9130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
9140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            long ctm = System.currentTimeMillis();
9150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("shouldFixTimeZoneNow: retVal=" + retVal +
9160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " iccCardExist=" + iccCardExist +
9170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " operatorNumeric=" + operatorNumeric + " mcc=" + mcc +
9180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " prevOperatorNumeric=" + prevOperatorNumeric + " prevMcc=" + prevMcc +
9190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " needToFixTimeZone=" + needToFixTimeZone +
9200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    " ltod=" + TimeUtils.logTimeOfDay(ctm));
9210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return retVal;
9230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
9240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
925a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public String getSystemProperty(String property, String defValue) {
9266bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville        return TelephonyManager.getTelephonyProperty(mPhoneBase.getPhoneId(), property, defValue);
927a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
928a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
929ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    /**
930ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     * @return all available cell information or null if none.
931ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     */
932ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    public List<CellInfo> getAllCellInfo() {
9335fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        CellInfoResult result = new CellInfoResult();
9345fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        if (VDBG) log("SST.getAllCellInfo(): E");
9355fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        int ver = mCi.getRilVersion();
9365fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        if (ver >= 8) {
9375fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            if (isCallerOnDifferentThread()) {
9380c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                if ((SystemClock.elapsedRealtime() - mLastCellInfoListTime)
9390c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        > LAST_CELL_INFO_LIST_MAX_AGE_MS) {
9400c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    Message msg = obtainMessage(EVENT_GET_CELL_INFO_LIST, result);
9410c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    synchronized(result.lockObj) {
942bed429d6d0a0dbc6384b04e0641aa1e03e406f42Amit Mahajan                        result.list = null;
9430c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        mCi.getCellInfoList(msg);
9440c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        try {
945bed429d6d0a0dbc6384b04e0641aa1e03e406f42Amit Mahajan                            result.lockObj.wait(5000);
9460c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        } catch (InterruptedException e) {
9470c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                            e.printStackTrace();
9480c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        }
9495fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                    }
9500c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                } else {
9510c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    if (DBG) log("SST.getAllCellInfo(): return last, back to back calls");
9520c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    result.list = mLastCellInfoList;
9535fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                }
9545fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            } else {
9550c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                if (DBG) log("SST.getAllCellInfo(): return last, same thread can't block");
9565fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                result.list = mLastCellInfoList;
9575fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            }
9585fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        } else {
9590c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville            if (DBG) log("SST.getAllCellInfo(): not implemented");
9605fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            result.list = null;
9615fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        }
962bed429d6d0a0dbc6384b04e0641aa1e03e406f42Amit Mahajan        synchronized(result.lockObj) {
9635fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            if (result.list != null) {
964bed429d6d0a0dbc6384b04e0641aa1e03e406f42Amit Mahajan                if (DBG) log("SST.getAllCellInfo(): X size=" + result.list.size()
9655fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville                        + " list=" + result.list);
966bed429d6d0a0dbc6384b04e0641aa1e03e406f42Amit Mahajan                return result.list;
9675fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            } else {
968bed429d6d0a0dbc6384b04e0641aa1e03e406f42Amit Mahajan                if (DBG) log("SST.getAllCellInfo(): X size=0 list=null");
969bed429d6d0a0dbc6384b04e0641aa1e03e406f42Amit Mahajan                return null;
9705fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville            }
9715fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        }
972ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
973ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
974ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    /**
975ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     * @return signal strength
976ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville     */
977ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    public SignalStrength getSignalStrength() {
978ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        synchronized(mCellInfo) {
979ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville            return mSignalStrength;
980ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        }
981ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    }
982ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville
9830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
9840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println("ServiceStateTracker:");
98522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mSS=" + mSS);
98622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mNewSS=" + mNewSS);
987ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        pw.println(" mCellInfo=" + mCellInfo);
9880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mRestrictedState=" + mRestrictedState);
98922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mPollingContext=" + mPollingContext);
9900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mDesiredPowerState=" + mDesiredPowerState);
99122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mDontPollSignalStrength=" + mDontPollSignalStrength);
9920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mPendingRadioPowerOffAfterDataOff=" + mPendingRadioPowerOffAfterDataOff);
9930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mPendingRadioPowerOffAfterDataOffTag=" + mPendingRadioPowerOffAfterDataOffTag);
994e97be3971cb6b55e019433c32524cc60ce0d037bWink Saville        pw.flush();
9950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
996e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
997bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com    public boolean isImsRegistered() {
998bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com        return mImsRegistered;
999bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com    }
1000e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    /**
1001e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * Verifies the current thread is the same as the thread originally
1002e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * used in the initialization of this instance. Throws RuntimeException
1003e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * if not.
1004e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     *
1005e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * @exception RuntimeException if the current thread is not
1006e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     * the thread that originally obtained this PhoneBase instance.
1007e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka     */
1008e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected void checkCorrectThread() {
1009e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (Thread.currentThread() != getLooper().getThread()) {
1010e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            throw new RuntimeException(
1011e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                    "ServiceStateTracker must be used from within one thread");
1012e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        }
1013e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    }
10145fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville
10155fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    protected boolean isCallerOnDifferentThread() {
10165fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        boolean value = Thread.currentThread() != getLooper().getThread();
10175fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        if (VDBG) log("isCallerOnDifferentThread: " + value);
10185fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville        return value;
10195fb811ff076aa6b4a9ceca6edaf504a4c6d9ad20Wink Saville    }
1020b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt
1021b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt    protected void updateCarrierMccMncConfiguration(String newOp, String oldOp, Context context) {
1022b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt        // if we have a change in operator, notify wifi (even to/from none)
1023b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt        if (((newOp == null) && (TextUtils.isEmpty(oldOp) == false)) ||
1024b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                ((newOp != null) && (newOp.equals(oldOp) == false))) {
1025a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("update mccmnc=" + newOp + " fromServiceState=true");
1026b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt            MccTable.updateMccMncConfiguration(context, newOp, true);
1027b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt        }
1028b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt    }
1029ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao
1030ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    /**
1031ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     * Check ISO country by MCC to see if phone is roaming in same registered country
1032ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao     */
1033ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    protected boolean inSameCountry(String operatorNumeric) {
1034ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        if (TextUtils.isEmpty(operatorNumeric) || (operatorNumeric.length() < 5)) {
1035ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            // Not a valid network
1036ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            return false;
1037ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        }
1038ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        final String homeNumeric = getHomeOperatorNumeric();
1039ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        if (TextUtils.isEmpty(homeNumeric) || (homeNumeric.length() < 5)) {
1040ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            // Not a valid SIM MCC
1041ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            return false;
1042ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        }
1043ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        boolean inSameCountry = true;
1044ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        final String networkMCC = operatorNumeric.substring(0, 3);
1045ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        final String homeMCC = homeNumeric.substring(0, 3);
1046ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        final String networkCountry = MccTable.countryCodeForMcc(Integer.parseInt(networkMCC));
1047ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        final String homeCountry = MccTable.countryCodeForMcc(Integer.parseInt(homeMCC));
1048ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        if (networkCountry.isEmpty() || homeCountry.isEmpty()) {
1049ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            // Not a valid country
1050ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            return false;
1051ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        }
1052ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        inSameCountry = homeCountry.equals(networkCountry);
1053ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        if (inSameCountry) {
1054ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            return inSameCountry;
1055ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        }
1056ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        // special same country cases
1057ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        if ("us".equals(homeCountry) && "vi".equals(networkCountry)) {
1058ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            inSameCountry = true;
1059ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        } else if ("vi".equals(homeCountry) && "us".equals(networkCountry)) {
1060ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao            inSameCountry = true;
1061ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        }
1062ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao        return inSameCountry;
1063ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    }
1064ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao
1065ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    protected abstract void setRoamingType(ServiceState currentServiceState);
1066ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao
1067ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    protected String getHomeOperatorNumeric() {
1068e70617d81dcd42350a737b11c25532e1d43df4ffLegler Wu        return ((TelephonyManager) mPhoneBase.getContext().
1069e70617d81dcd42350a737b11c25532e1d43df4ffLegler Wu                getSystemService(Context.TELEPHONY_SERVICE)).
1070e70617d81dcd42350a737b11c25532e1d43df4ffLegler Wu                getSimOperatorNumericForPhone(mPhoneBase.getPhoneId());
1071ffdf8ce51e37e5e45791c9ea11604aa00dffc88eJing Zhao    }
1072062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal
1073062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal    protected int getPhoneId() {
1074062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal        return mPhoneBase.getPhoneId();
1075062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal    }
10760e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh
10770e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh    /* Reset Service state when IWLAN is enabled as polling in airplane mode
10780e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh     * causes state to go to OUT_OF_SERVICE state instead of STATE_OFF
10790e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh     */
10800e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh    protected void resetServiceStateInIwlanMode() {
10810e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        if (mCi.getRadioState() == CommandsInterface.RadioState.RADIO_OFF) {
10820e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            boolean resetIwlanRatVal = false;
10830e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            log("set service state as POWER_OFF");
10840e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            if (ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
10850e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                        == mNewSS.getRilDataRadioTechnology()) {
10860e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                log("pollStateDone: mNewSS = " + mNewSS);
10870e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                log("pollStateDone: reset iwlan RAT value");
10880e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                resetIwlanRatVal = true;
10890e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            }
10900e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            mNewSS.setStateOff();
10910e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            if (resetIwlanRatVal) {
10920e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                mNewSS.setRilDataRadioTechnology(ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN);
10930e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                mNewSS.setDataRegState(ServiceState.STATE_IN_SERVICE);
10940e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh                log("pollStateDone: mNewSS = " + mNewSS);
10950e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh            }
10960e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh        }
10970e42864afb21261d6bd2e9b4aa97f6d01d039a25Yashdev Singh    }
1098de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton
1099de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton    /**
1100cdd0ef910a79d75d60222d97c5f33aa154876bfbChris Manton     * Check if device is non-roaming and always on home network.
1101cdd0ef910a79d75d60222d97c5f33aa154876bfbChris Manton     *
1102cdd0ef910a79d75d60222d97c5f33aa154876bfbChris Manton     * @param b carrier config bundle obtained from CarrierConfigManager
1103cdd0ef910a79d75d60222d97c5f33aa154876bfbChris Manton     * @return true if network is always on home network, false otherwise
1104cdd0ef910a79d75d60222d97c5f33aa154876bfbChris Manton     * @see CarrierConfigManager
1105cdd0ef910a79d75d60222d97c5f33aa154876bfbChris Manton     */
1106cdd0ef910a79d75d60222d97c5f33aa154876bfbChris Manton    protected final boolean alwaysOnHomeNetwork(BaseBundle b) {
1107cdd0ef910a79d75d60222d97c5f33aa154876bfbChris Manton        return b.getBoolean(CarrierConfigManager.KEY_FORCE_HOME_NETWORK_BOOL);
1108cdd0ef910a79d75d60222d97c5f33aa154876bfbChris Manton    }
1109cdd0ef910a79d75d60222d97c5f33aa154876bfbChris Manton
1110cdd0ef910a79d75d60222d97c5f33aa154876bfbChris Manton    /**
1111de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton     * Check if the network identifier has membership in the set of
1112de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton     * network identifiers stored in the carrier config bundle.
1113de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton     *
1114cdd0ef910a79d75d60222d97c5f33aa154876bfbChris Manton     * @param b carrier config bundle obtained from CarrierConfigManager
1115de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton     * @param network The network identifier to check network existence in bundle
1116de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton     * @param key The key to index into the bundle presenting a string array of
1117de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton     *            networks to check membership
1118de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton     * @return true if network has membership in bundle networks, false otherwise
1119de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton     * @see CarrierConfigManager
1120de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton     */
1121de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton    private boolean isInNetwork(BaseBundle b, String network, String key) {
1122de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton        String[] networks = b.getStringArray(key);
1123de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton
1124de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton        if (networks != null && Arrays.asList(networks).contains(network)) {
1125de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton            return true;
1126de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton        }
1127de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton        return false;
1128de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton    }
1129de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton
1130cdd0ef910a79d75d60222d97c5f33aa154876bfbChris Manton    protected final boolean isRoamingInGsmNetwork(BaseBundle b, String network) {
1131de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton        return isInNetwork(b, network, CarrierConfigManager.KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY);
1132de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton    }
1133de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton
1134cdd0ef910a79d75d60222d97c5f33aa154876bfbChris Manton    protected final boolean isNonRoamingInGsmNetwork(BaseBundle b, String network) {
1135de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton        return isInNetwork(b, network, CarrierConfigManager.KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY);
1136de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton    }
1137de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton
1138cdd0ef910a79d75d60222d97c5f33aa154876bfbChris Manton    protected final boolean isRoamingInCdmaNetwork(BaseBundle b, String network) {
1139de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton        return isInNetwork(b, network, CarrierConfigManager.KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY);
1140de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton    }
1141de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton
1142cdd0ef910a79d75d60222d97c5f33aa154876bfbChris Manton    protected final boolean isNonRoamingInCdmaNetwork(BaseBundle b, String network) {
1143de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton        return isInNetwork(b, network, CarrierConfigManager.KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY);
1144de2d2034a7df068f3e929ff1d623a80c847b6335Chris Manton    }
1145211ed45a3500a84a4b102e22d3235f758ac49563Jack Yu
1146211ed45a3500a84a4b102e22d3235f758ac49563Jack Yu    /** Check if the device is shutting down. */
1147211ed45a3500a84a4b102e22d3235f758ac49563Jack Yu    public final boolean isDeviceShuttingDown() {
1148211ed45a3500a84a4b102e22d3235f758ac49563Jack Yu        return mDeviceShuttingDown;
1149211ed45a3500a84a4b102e22d3235f758ac49563Jack Yu    }
11500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
1151