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.gsm;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.AlarmManager;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.Notification;
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.NotificationManager;
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.PendingIntent;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.BroadcastReceiver;
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.ContentResolver;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Context;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Intent;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.IntentFilter;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.res.Resources;
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.database.ContentObserver;
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult;
3160ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport android.os.Build;
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler;
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.PowerManager;
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.SystemClock;
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.SystemProperties;
377eff443d1f090abdbbd93eef9f265c74890920bcDianne Hackbornimport android.os.UserHandle;
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.provider.Settings;
390825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.provider.Settings.SettingNotFoundException;
400c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Savilleimport android.telephony.CellIdentityGsm;
410c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Savilleimport android.telephony.CellIdentityLte;
420c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Savilleimport android.telephony.CellIdentityWcdma;
430c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Savilleimport android.telephony.CellInfo;
44ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Savilleimport android.telephony.CellInfoGsm;
450c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Savilleimport android.telephony.CellInfoLte;
460c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Savilleimport android.telephony.CellInfoWcdma;
470c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Savilleimport android.telephony.CellLocation;
4860ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport android.telephony.Rlog;
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.ServiceState;
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.SignalStrength;
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.gsm.GsmCellLocation;
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.text.TextUtils;
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.EventLog;
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.TimeUtils;
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5660ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.CommandException;
5760ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.CommandsInterface;
5860ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.EventLogTags;
5960ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.MccTable;
6060ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.Phone;
6160ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.RILConstants;
6260ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.RestrictedState;
6360ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.ServiceStateTracker;
6460ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.TelephonyIntents;
6560ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.TelephonyProperties;
6660ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.dataconnection.DcTrackerBase;
6760ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
6860ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.uicc.IccRecords;
6960ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.uicc.SIMRecords;
7060ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.uicc.UiccCardApplication;
7160ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.uicc.UiccController;
7260ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkey
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.FileDescriptor;
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.PrintWriter;
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList;
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Arrays;
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Calendar;
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Date;
790c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Savilleimport java.util.List;
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.TimeZone;
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillefinal class GsmServiceStateTracker extends ServiceStateTracker {
86cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private static final String LOG_TAG = "GsmSST";
87cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private static final boolean VDBG = false;
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    GSMPhone mPhone;
9022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    GsmCellLocation mCellLoc;
9122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    GsmCellLocation mNewCellLoc;
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    int mPreferredNetworkType;
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mMaxDataCalls = 1;
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mNewMaxDataCalls = 1;
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mReasonDataDenied = -1;
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mNewReasonDataDenied = -1;
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * GSM roaming status solely based on TS 27.007 7.2 CREG. Only used by
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * handlePollStateResult to store CREG roaming result.
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mGsmRoaming = false;
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Data roaming status solely based on TS 27.007 10.1.19 CGREG. Only used by
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * handlePollStateResult to store CGREG roaming result.
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mDataRoaming = false;
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Mark when service state is in emergency call only mode
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mEmergencyOnly = false;
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Sometimes we get the NITZ time before we know what country we
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * are in. Keep the time zone information from the NITZ string so
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * we can fix the time zone once know the country.
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mNeedFixZoneAfterNitz = false;
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mZoneOffset;
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mZoneDst;
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private long mZoneTime;
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mGotCountryCode = false;
12622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private ContentResolver mCr;
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Boolean is true is setTimeFromNITZString was called */
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mNitzUpdatedTime = false;
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    String mSavedTimeZone;
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    long mSavedTime;
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    long mSavedAtTime;
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Started the recheck process after finding gprs should registered but not. */
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mStartedGprsRegCheck = false;
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Already sent the event-log for no gprs register. */
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mReportedGprsNoReg = false;
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * The Notification object given to the NotificationManager.
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Notification mNotification;
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Wake lock used while setting time of day. */
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private PowerManager.WakeLock mWakeLock;
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final String WAKELOCK_TAG = "ServiceStateTracker";
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Keep track of SPN display rules, so we only broadcast intent if something changes. */
15122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private String mCurSpn = null;
15222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private String mCurPlmn = null;
15322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private boolean mCurShowPlmn = false;
15422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private boolean mCurShowSpn = false;
15560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Notification type. */
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int PS_ENABLED = 1001;            // Access Control blocks data service
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int PS_DISABLED = 1002;           // Access Control enables data service
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int CS_ENABLED = 1003;            // Access Control blocks all voice/sms service
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int CS_DISABLED = 1004;           // Access Control enables all voice/sms service
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int CS_NORMAL_ENABLED = 1005;     // Access Control blocks normal voice/sms service
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int CS_EMERGENCY_ENABLED = 1006;  // Access Control blocks emergency call service
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Notification id. */
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int PS_NOTIFICATION = 888;  // Id to update and cancel PS restricted
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int CS_NOTIFICATION = 999;  // Id to update and cancel CS restricted
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        @Override
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        public void onReceive(Context context, Intent intent) {
1715e2000b856a7959609e8f15148a3584ec372f865Wink Saville            if (!mPhone.mIsTheCurrentActivePhone) {
1725e2000b856a7959609e8f15148a3584ec372f865Wink Saville                Rlog.e(LOG_TAG, "Received Intent " + intent +
1735e2000b856a7959609e8f15148a3584ec372f865Wink Saville                        " while being destroyed. Ignoring.");
1745e2000b856a7959609e8f15148a3584ec372f865Wink Saville                return;
1755e2000b856a7959609e8f15148a3584ec372f865Wink Saville            }
1765e2000b856a7959609e8f15148a3584ec372f865Wink Saville
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (intent.getAction().equals(Intent.ACTION_LOCALE_CHANGED)) {
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // update emergency string whenever locale changed
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                updateSpnDisplay();
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) {
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        @Override
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        public void onChange(boolean selfChange) {
18799c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville            Rlog.i("GsmServiceStateTracker", "Auto time state changed");
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            revertToNitzTime();
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private ContentObserver mAutoTimeZoneObserver = new ContentObserver(new Handler()) {
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        @Override
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        public void onChange(boolean selfChange) {
19599c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville            Rlog.i("GsmServiceStateTracker", "Auto time zone state changed");
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            revertToNitzTimeZone();
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public GsmServiceStateTracker(GSMPhone phone) {
20122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        super(phone, phone.mCi, new CellInfoGsm());
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone = phone;
20422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCellLoc = new GsmCellLocation();
20522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mNewCellLoc = new GsmCellLocation();
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        PowerManager powerManager =
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                (PowerManager)phone.getContext().getSystemService(Context.POWER_SERVICE);
2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG);
2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
21222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForVoiceNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null);
21522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setOnNITZTime(this, EVENT_NITZ_TIME, null);
21622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setOnRestrictedStateChanged(this, EVENT_RESTRICTED_STATE_CHANGED, null);
2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // system setting property AIRPLANE_MODE_ON is set in Settings.
219069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate        int airplaneMode = Settings.Global.getInt(
2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                phone.getContext().getContentResolver(),
221069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate                Settings.Global.AIRPLANE_MODE_ON, 0);
2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDesiredPowerState = ! (airplaneMode > 0);
2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCr = phone.getContext().getContentResolver();
22522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCr.registerContentObserver(
226069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate                Settings.Global.getUriFor(Settings.Global.AUTO_TIME), true,
2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mAutoTimeObserver);
22822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCr.registerContentObserver(
229069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate                Settings.Global.getUriFor(Settings.Global.AUTO_TIME_ZONE), true,
2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mAutoTimeZoneObserver);
2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        setSignalStrengthDefaultValues();
2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Monitor locale change
2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        IntentFilter filter = new IntentFilter();
2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        filter.addAction(Intent.ACTION_LOCALE_CHANGED);
2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.getContext().registerReceiver(mIntentReceiver, filter);
2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Gsm doesn't support OTASP so its not needed
2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.notifyOtaspChanged(OTASP_NOT_NEEDED);
2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
243ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    @Override
2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dispose() {
245e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        checkCorrectThread();
2465e2000b856a7959609e8f15148a3584ec372f865Wink Saville        log("ServiceStateTracker dispose");
2475e2000b856a7959609e8f15148a3584ec372f865Wink Saville
2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Unregister for all events.
24922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unregisterForAvailable(this);
25022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unregisterForRadioStateChanged(this);
25122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unregisterForVoiceNetworkStateChanged(this);
252e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mUiccApplcation != null) {mUiccApplcation.unregisterForReady(this);}
253e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (mIccRecords != null) {mIccRecords.unregisterForRecordsLoaded(this);}
25422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unSetOnRestrictedStateChanged(this);
25522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unSetOnNITZTime(this);
25622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCr.unregisterContentObserver(mAutoTimeObserver);
25722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCr.unregisterContentObserver(mAutoTimeZoneObserver);
25822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.getContext().unregisterReceiver(mIntentReceiver);
259ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        super.dispose();
2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
262cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void finalize() {
2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if(DBG) log("finalize");
2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected Phone getPhone() {
26922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mPhone;
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
272cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void handleMessage (Message msg) {
2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AsyncResult ar;
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int[] ints;
2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String[] strings;
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Message message;
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
27922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (!mPhone.mIsTheCurrentActivePhone) {
28099c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville            Rlog.e(LOG_TAG, "Received message " + msg +
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    "[" + msg.what + "] while being destroyed. Ignoring.");
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (msg.what) {
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RADIO_AVAILABLE:
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                //this is unnecessary
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                //setPowerStateToDesired();
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SIM_READY:
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Set the network type, in case the radio does not restore it.
29222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.setCurrentPreferredNetworkType();
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
29422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                boolean skipRestoringSelection = mPhone.getContext().getResources().getBoolean(
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        com.android.internal.R.bool.skip_restoring_network_selection);
2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!skipRestoringSelection) {
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // restore the previous network selection.
29922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPhone.restoreSavedNetworkSelection(null);
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollState();
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Signal strength polling stops when radio is off
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                queueNextSignalStrengthPoll();
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RADIO_STATE_CHANGED:
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // This will do nothing in the radio not
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // available case
3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setPowerStateToDesired();
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollState();
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_NETWORK_STATE_CHANGED:
3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollState();
3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_GET_SIGNAL_STRENGTH:
3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // This callback is called when signal strength is polled
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // all by itself
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
32122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (!(mCi.getRadioState().isOn())) {
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Polling will continue when radio turns back on
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return;
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
326e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville                onSignalStrengthResult(ar, true);
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                queueNextSignalStrengthPoll();
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_GET_LOC_DONE:
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception == null) {
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    String states[] = (String[])ar.result;
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int lac = -1;
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int cid = -1;
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (states.length >= 3) {
3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        try {
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states[1] != null && states[1].length() > 0) {
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                lac = Integer.parseInt(states[1], 16);
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states[2] != null && states[2].length() > 0) {
3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                cid = Integer.parseInt(states[2], 16);
3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        } catch (NumberFormatException ex) {
34799c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                            Rlog.w(LOG_TAG, "error parsing location: " + ex);
3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
35022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mCellLoc.setLacAndCid(lac, cid);
35122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPhone.notifyLocationChanged();
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Release any temporary cell lock, which could have been
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // acquired to allow a single-shot location update.
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                disableSingleLocationUpdate();
3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_STATE_REGISTRATION:
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_STATE_GPRS:
3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_STATE_OPERATOR:
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_STATE_NETWORK_SELECTION_MODE:
3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                handlePollStateResult(msg.what, ar);
3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_SIGNAL_STRENGTH:
3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Just poll signal strength...not part of pollState()
3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
37122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_NITZ_TIME:
3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                String nitzString = (String)((Object[])ar.result)[0];
3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                long nitzReceiveTime = ((Long)((Object[])ar.result)[1]).longValue();
3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setTimeFromNITZString(nitzString, nitzReceiveTime);
3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SIGNAL_STRENGTH_UPDATE:
3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // This is a notification from
3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // CommandsInterface.setOnSignalStrengthUpdate
3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // The radio is telling us about signal strength changes
3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // we don't have to ask it
39122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mDontPollSignalStrength = true;
3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
393e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville                onSignalStrengthResult(ar, true);
3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SIM_RECORDS_LOADED:
397b54cd09892e0676d719e6df00e60c77b663f993cWink Saville                log("EVENT_SIM_RECORDS_LOADED: what=" + msg.what);
398b54cd09892e0676d719e6df00e60c77b663f993cWink Saville
399b54cd09892e0676d719e6df00e60c77b663f993cWink Saville                updatePhoneObject();
4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                updateSpnDisplay();
4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_LOCATION_UPDATES_ENABLED:
4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception == null) {
40722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mCi.getVoiceRegistrationState(obtainMessage(EVENT_GET_LOC_DONE, null));
4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SET_PREFERRED_NETWORK_TYPE:
4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Don't care the result, only use for dereg network (COPS=2)
4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                message = obtainMessage(EVENT_RESET_PREFERRED_NETWORK_TYPE, ar.userObj);
41522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.setPreferredNetworkType(mPreferredNetworkType, message);
4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RESET_PREFERRED_NETWORK_TYPE:
4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.userObj != null) {
4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    AsyncResult.forMessage(((Message) ar.userObj)).exception
4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            = ar.exception;
4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ((Message) ar.userObj).sendToTarget();
4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_GET_PREFERRED_NETWORK_TYPE:
4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception == null) {
4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mPreferredNetworkType = ((int[])ar.result)[0];
4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mPreferredNetworkType = RILConstants.NETWORK_MODE_GLOBAL;
4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                message = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE, ar.userObj);
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                int toggledNetworkType = RILConstants.NETWORK_MODE_GLOBAL;
4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
43922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.setPreferredNetworkType(toggledNetworkType, message);
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_CHECK_REPORT_GPRS:
44322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (mSS != null && !isGprsConsistent(mSS.getDataRegState(), mSS.getVoiceRegState())) {
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Can't register data service while voice service is ok
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // i.e. CREG is ok while CGREG is not
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // possible a network or baseband side error
44822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    GsmCellLocation loc = ((GsmCellLocation)mPhone.getCellLocation());
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    EventLog.writeEvent(EventLogTags.DATA_NETWORK_REGISTRATION_FAIL,
45022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            mSS.getOperatorNumeric(), loc != null ? loc.getCid() : -1);
4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mReportedGprsNoReg = true;
4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mStartedGprsRegCheck = false;
4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RESTRICTED_STATE_CHANGED:
4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // This is a notification from
4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // CommandsInterface.setOnRestrictedStateChanged
4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("EVENT_RESTRICTED_STATE_CHANGED");
4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                onRestrictedStateChanged(ar);
4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                super.handleMessage(msg);
4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
4700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
473cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void setPowerStateToDesired() {
4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If we want it on and it's off, turn it on
4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mDesiredPowerState
47722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            && mCi.getRadioState() == CommandsInterface.RadioState.RADIO_OFF) {
47822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.setRadioPower(true, null);
47922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (!mDesiredPowerState && mCi.getRadioState().isOn()) {
4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // If it's on and available and we want it off gracefully
481454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcTrackerBase dcTracker = mPhone.mDcTracker;
4820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            powerOffRadioSafely(dcTracker);
4830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } // Otherwise, we're in the desired state
4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void hangupAndPowerOff() {
4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // hang up all active voice calls
48922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPhone.isInCall()) {
49022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.mCT.mRingingCall.hangupIfAlive();
49122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.mCT.mBackgroundCall.hangupIfAlive();
49222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.mCT.mForegroundCall.hangupIfAlive();
4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
49522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setRadioPower(false, null);
4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
498f7a8133113daddcc48a41e451193afd3fcb35e16Wink Saville    @Override
4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void updateSpnDisplay() {
50060e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        // The values of plmn/showPlmn change in different scenarios.
50160e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        // 1) No service but emergency call allowed -> expected
50260e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    to show "Emergency call only"
50360e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_SHOW_PLMN = true
50460e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_PLMN = "Emergency call only"
50560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang
50660e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        // 2) No service at all --> expected to show "No service"
50760e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_SHOW_PLMN = true
50860e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_PLMN = "No service"
50960e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang
51060e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        // 3) Normal operation in either home or roaming service
51160e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_SHOW_PLMN = depending on IccRecords rule
51260e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_PLMN = plmn
51360e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang
51460e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        // 4) No service due to power off, aka airplane mode
51560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_SHOW_PLMN = false
51660e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_PLMN = null
51760e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang
518f7a8133113daddcc48a41e451193afd3fcb35e16Wink Saville        IccRecords iccRecords = mIccRecords;
51960e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        String plmn = null;
52060e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        boolean showPlmn = false;
52122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        int rule = (iccRecords != null) ? iccRecords.getDisplayRule(mSS.getOperatorNumeric()) : 0;
52222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mSS.getVoiceRegState() == ServiceState.STATE_OUT_OF_SERVICE
52322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                || mSS.getVoiceRegState() == ServiceState.STATE_EMERGENCY_ONLY) {
52460e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            showPlmn = true;
52560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            if (mEmergencyOnly) {
52660e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                // No service but emergency call allowed
52760e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                plmn = Resources.getSystem().
52860e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                        getText(com.android.internal.R.string.emergency_calls_only).toString();
52960e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            } else {
53060e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                // No service at all
53160e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                plmn = Resources.getSystem().
53260e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                        getText(com.android.internal.R.string.lockscreen_carrier_default).toString();
53360e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            }
53460e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            if (DBG) log("updateSpnDisplay: radio is on but out " +
53560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                    "of service, set plmn='" + plmn + "'");
53622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE) {
53760e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            // In either home or roaming service
53822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            plmn = mSS.getOperatorAlphaLong();
53960e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            showPlmn = !TextUtils.isEmpty(plmn) &&
54060e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                    ((rule & SIMRecords.SPN_RULE_SHOW_PLMN)
54160e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                            == SIMRecords.SPN_RULE_SHOW_PLMN);
54260e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        } else {
54360e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            // Power off state, such as airplane mode
54460e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            if (DBG) log("updateSpnDisplay: radio is off w/ showPlmn="
54560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                    + showPlmn + " plmn=" + plmn);
5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
54860e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        // The value of spn/showSpn are same in different scenarios.
54960e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_SHOW_SPN = depending on IccRecords rule
55060e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_SPN = spn
551f7a8133113daddcc48a41e451193afd3fcb35e16Wink Saville        String spn = (iccRecords != null) ? iccRecords.getServiceProviderName() : "";
55260e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        boolean showSpn = !TextUtils.isEmpty(spn)
55360e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                && ((rule & SIMRecords.SPN_RULE_SHOW_SPN)
55460e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                        == SIMRecords.SPN_RULE_SHOW_SPN);
55560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang
55660e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        // Update SPN_STRINGS_UPDATED_ACTION IFF any value changes
55722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (showPlmn != mCurShowPlmn
55822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                || showSpn != mCurShowSpn
55922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                || !TextUtils.equals(spn, mCurSpn)
56022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                || !TextUtils.equals(plmn, mCurPlmn)) {
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
56260e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                log(String.format("updateSpnDisplay: changed" +
56360e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                        " sending intent rule=" + rule +
56460e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                        " showPlmn='%b' plmn='%s' showSpn='%b' spn='%s'",
56560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                        showPlmn, plmn, showSpn, spn));
5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Intent intent = new Intent(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            intent.putExtra(TelephonyIntents.EXTRA_SHOW_SPN, showSpn);
5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            intent.putExtra(TelephonyIntents.EXTRA_SPN, spn);
5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            intent.putExtra(TelephonyIntents.EXTRA_SHOW_PLMN, showPlmn);
5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            intent.putExtra(TelephonyIntents.EXTRA_PLMN, plmn);
57322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.getContext().sendStickyBroadcastAsUser(intent, UserHandle.ALL);
5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
57622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCurShowSpn = showSpn;
57722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCurShowPlmn = showPlmn;
57822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCurSpn = spn;
57922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCurPlmn = plmn;
5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Handle the result of one of the pollState()-related requests
5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
585f92cb4bd5519427a0db673709d94683a8baf203aWink Saville    @Override
5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void handlePollStateResult (int what, AsyncResult ar) {
5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int ints[];
5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String states[];
5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Ignore stale requests from last poll
59122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (ar.userObj != mPollingContext) return;
5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ar.exception != null) {
5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CommandException.Error err=null;
5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (ar.exception instanceof CommandException) {
5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                err = ((CommandException)(ar.exception)).getCommandError();
5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (err == CommandException.Error.RADIO_NOT_AVAILABLE) {
6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Radio has crashed or turned off
6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cancelPollState();
6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
60622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (!mCi.getRadioState().isOn()) {
6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Radio has crashed or turned off
6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cancelPollState();
6090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
6100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) {
6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                loge("RIL implementation has returned an error where it must succeed" +
6140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ar.exception);
6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else try {
6170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            switch (what) {
618f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                case EVENT_POLL_STATE_REGISTRATION: {
6190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    states = (String[])ar.result;
6200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int lac = -1;
6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int cid = -1;
622f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    int type = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
623f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    int regState = ServiceState.RIL_REG_STATE_UNKNOWN;
6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int reasonRegStateDenied = -1;
6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int psc = -1;
6260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (states.length > 0) {
6270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        try {
6280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            regState = Integer.parseInt(states[0]);
6290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states.length >= 3) {
6300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (states[1] != null && states[1].length() > 0) {
6310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    lac = Integer.parseInt(states[1], 16);
6320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
6330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (states[2] != null && states[2].length() > 0) {
6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    cid = Integer.parseInt(states[2], 16);
6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
636f92cb4bd5519427a0db673709d94683a8baf203aWink Saville
637f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                                // states[3] (if present) is the current radio technology
638f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                                if (states.length >= 4 && states[3] != null) {
639f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                                    type = Integer.parseInt(states[3]);
640f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                                }
6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states.length > 14) {
6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (states[14] != null && states[14].length() > 0) {
6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    psc = Integer.parseInt(states[14], 16);
6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        } catch (NumberFormatException ex) {
6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            loge("error parsing RegistrationState: " + ex);
6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mGsmRoaming = regCodeIsRoaming(regState);
65322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewSS.setState(regCodeToServiceState(regState));
65422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewSS.setRilVoiceRadioTechnology(type);
6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6569c430a4d72c8c962caefb916e82a4c82eca7068cWink Saville                    boolean isVoiceCapable = mPhoneBase.getContext().getResources()
6579c430a4d72c8c962caefb916e82a4c82eca7068cWink Saville                            .getBoolean(com.android.internal.R.bool.config_voice_capable);
6589c430a4d72c8c962caefb916e82a4c82eca7068cWink Saville                    if ((regState == ServiceState.RIL_REG_STATE_DENIED_EMERGENCY_CALL_ENABLED
659f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                         || regState == ServiceState.RIL_REG_STATE_NOT_REG_EMERGENCY_CALL_ENABLED
660f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                         || regState == ServiceState.RIL_REG_STATE_SEARCHING_EMERGENCY_CALL_ENABLED
6619c430a4d72c8c962caefb916e82a4c82eca7068cWink Saville                         || regState == ServiceState.RIL_REG_STATE_UNKNOWN_EMERGENCY_CALL_ENABLED)
6629c430a4d72c8c962caefb916e82a4c82eca7068cWink Saville                         && isVoiceCapable) {
6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mEmergencyOnly = true;
6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mEmergencyOnly = false;
6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // LAC and CID are -1 if not avail
66922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewCellLoc.setLacAndCid(lac, cid);
67022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewCellLoc.setPsc(psc);
671f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    break;
672f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                }
6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
674f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                case EVENT_POLL_STATE_GPRS: {
6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    states = (String[])ar.result;
6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int type = 0;
678f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    int regState = ServiceState.RIL_REG_STATE_UNKNOWN;
6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mNewReasonDataDenied = -1;
6800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mNewMaxDataCalls = 1;
6810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (states.length > 0) {
6820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        try {
6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            regState = Integer.parseInt(states[0]);
6840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            // states[3] (if present) is the current radio technology
6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states.length >= 4 && states[3] != null) {
6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                type = Integer.parseInt(states[3]);
6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
689f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                            if ((states.length >= 5 ) &&
690f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                                    (regState == ServiceState.RIL_REG_STATE_DENIED)) {
6910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                mNewReasonDataDenied = Integer.parseInt(states[4]);
6920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
6930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states.length >= 6) {
6940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                mNewMaxDataCalls = Integer.parseInt(states[5]);
6950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
6960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        } catch (NumberFormatException ex) {
6970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            loge("error parsing GprsRegistrationState: " + ex);
6980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
6990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
700f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    int dataRegState = regCodeToServiceState(regState);
70122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewSS.setDataRegState(dataRegState);
7020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mDataRoaming = regCodeIsRoaming(regState);
70322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewSS.setRilDataRadioTechnology(type);
704f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    if (DBG) {
705f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                        log("handlPollStateResultMessage: GsmSST setDataRegState=" + dataRegState
706f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                                + " regState=" + regState
707f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                                + " dataRadioTechnology=" + type);
708f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    }
709f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    break;
710f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                }
7110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
712f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                case EVENT_POLL_STATE_OPERATOR: {
7130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    String opNames[] = (String[])ar.result;
7140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (opNames != null && opNames.length >= 3) {
71622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                         mNewSS.setOperatorName (opNames[0], opNames[1], opNames[2]);
7170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
718f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    break;
719f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                }
7200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
721f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                case EVENT_POLL_STATE_NETWORK_SELECTION_MODE: {
7220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ints = (int[])ar.result;
72322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewSS.setIsManualSelection(ints[0] == 1);
724f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    break;
725f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                }
7260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (RuntimeException ex) {
7290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("Exception while polling service state. Probably malformed RIL response." + ex);
7300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
73222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPollingContext[0]--;
7330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
73422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPollingContext[0] == 0) {
7350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            /**
736a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi             * Since the roaming state of gsm service (from +CREG) and
737a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi             * data service (from +CGREG) could be different, the new SS
738a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi             * is set to roaming when either is true.
7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             *
740a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi             * There are exceptions for the above rule.
741a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi             * The new SS is not set as roaming while gsm service reports
742a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi             * roaming but indeed it is same operator.
743a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi             * And the operator is considered non roaming.
7447ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi             *
745a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi             * The test for the operators is to handle special roaming
746a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi             * agreements and MVNO's.
7470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             */
748a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi            boolean roaming = (mGsmRoaming || mDataRoaming);
7491110f0fd89337adc1b09fe866750b8721ef882cfVineeta Srivastava            if ((mGsmRoaming && isSameNamedOperators(mNewSS)
7501110f0fd89337adc1b09fe866750b8721ef882cfVineeta Srivastava                        && !isSameNamedOperatorConsideredRoaming(mNewSS))
751a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi                    || isOperatorConsideredNonRoaming(mNewSS)) {
752a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi                roaming = false;
753a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi            }
754a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi            mNewSS.setRoaming(roaming);
75522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mNewSS.setEmergencyOnly(mEmergencyOnly);
7560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pollStateDone();
7570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
760c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void setSignalStrengthDefaultValues() {
7615b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        mSignalStrength = new SignalStrength(true);
7620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
7650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * A complete "service state" from our perspective is
7660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * composed of a handful of separate requests to the radio.
7670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
7680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * We make all of these requests at once, but then abandon them
7690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * and start over again if the radio notifies us that some
7700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * event has changed
7710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
7720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void pollState() {
77322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPollingContext = new int[1];
77422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPollingContext[0] = 0;
7750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
77622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        switch (mCi.getRadioState()) {
7770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case RADIO_UNAVAILABLE:
77822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mNewSS.setStateOutOfService();
77922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mNewCellLoc.setStateInvalid();
7800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setSignalStrengthDefaultValues();
7810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mGotCountryCode = false;
7820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNitzUpdatedTime = false;
7830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollStateDone();
7840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
7850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case RADIO_OFF:
78722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mNewSS.setStateOff();
78822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mNewCellLoc.setStateInvalid();
7890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setSignalStrengthDefaultValues();
7900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mGotCountryCode = false;
7910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNitzUpdatedTime = false;
7920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollStateDone();
7930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
7940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
7960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Issue all poll-related commands at once
7970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // then count down the responses, which
7980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // are allowed to arrive out-of-order
7990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
80022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPollingContext[0]++;
80122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.getOperator(
8020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    obtainMessage(
80322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        EVENT_POLL_STATE_OPERATOR, mPollingContext));
8040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
80522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPollingContext[0]++;
80622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.getDataRegistrationState(
8070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    obtainMessage(
80822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        EVENT_POLL_STATE_GPRS, mPollingContext));
8090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
81022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPollingContext[0]++;
81122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.getVoiceRegistrationState(
8120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    obtainMessage(
81322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        EVENT_POLL_STATE_REGISTRATION, mPollingContext));
8140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
81522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPollingContext[0]++;
81622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.getNetworkSelectionMode(
8170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    obtainMessage(
81822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        EVENT_POLL_STATE_NETWORK_SELECTION_MODE, mPollingContext));
8190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
8200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void pollStateDone() {
8240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
8250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("Poll ServiceState done: " +
82622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                " oldSS=[" + mSS + "] newSS=[" + mNewSS + "]" +
8270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                " oldMaxDataCalls=" + mMaxDataCalls +
8280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                " mNewMaxDataCalls=" + mNewMaxDataCalls +
8290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                " oldReasonDataDenied=" + mReasonDataDenied +
830f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                " mNewReasonDataDenied=" + mNewReasonDataDenied);
8310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
83360ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkey        if (Build.IS_DEBUGGABLE && SystemProperties.getBoolean(PROP_FORCE_ROAMING, false)) {
83460ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkey            mNewSS.setRoaming(true);
83560ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkey        }
83660ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkey
837f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville        useDataRegStateForDataOnlyDevices();
838f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville
8390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasRegistered =
84022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mSS.getVoiceRegState() != ServiceState.STATE_IN_SERVICE
84122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            && mNewSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE;
8420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasDeregistered =
84422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE
84522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            && mNewSS.getVoiceRegState() != ServiceState.STATE_IN_SERVICE;
8460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasGprsAttached =
84822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSS.getDataRegState() != ServiceState.STATE_IN_SERVICE
84922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && mNewSS.getDataRegState() == ServiceState.STATE_IN_SERVICE;
8500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasGprsDetached =
85222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSS.getDataRegState() == ServiceState.STATE_IN_SERVICE
85322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && mNewSS.getDataRegState() != ServiceState.STATE_IN_SERVICE;
8540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
855a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville        boolean hasDataRegStateChanged =
856a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville                mSS.getDataRegState() != mNewSS.getDataRegState();
857a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville
858a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville        boolean hasVoiceRegStateChanged =
859a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville                mSS.getVoiceRegState() != mNewSS.getVoiceRegState();
860a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville
861f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        boolean hasRilVoiceRadioTechnologyChanged =
86222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSS.getRilVoiceRadioTechnology() != mNewSS.getRilVoiceRadioTechnology();
8630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
864a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville        boolean hasRilDataRadioTechnologyChanged =
865a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville                mSS.getRilDataRadioTechnology() != mNewSS.getRilDataRadioTechnology();
866a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville
86722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        boolean hasChanged = !mNewSS.equals(mSS);
8680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
86922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        boolean hasRoamingOn = !mSS.getRoaming() && mNewSS.getRoaming();
8700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
87122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        boolean hasRoamingOff = mSS.getRoaming() && !mNewSS.getRoaming();
8720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
87322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        boolean hasLocationChanged = !mNewCellLoc.equals(mCellLoc);
8740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Add an event log when connection state changes
876a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville        if (hasVoiceRegStateChanged || hasDataRegStateChanged) {
8770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            EventLog.writeEvent(EventLogTags.GSM_SERVICE_STATE_CHANGE,
87822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSS.getVoiceRegState(), mSS.getDataRegState(),
87922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mNewSS.getVoiceRegState(), mNewSS.getDataRegState());
8800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Add an event log when network type switched
8830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // TODO: we may add filtering to reduce the event logged,
8840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // i.e. check preferred network setting, only switch to 2G, etc
885f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        if (hasRilVoiceRadioTechnologyChanged) {
8860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int cid = -1;
887385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby            GsmCellLocation loc = mNewCellLoc;
8880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (loc != null) cid = loc.getCid();
889385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby            // NOTE: this code was previously located after mSS and mNewSS are swapped, so
890385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby            // existing logs were incorrectly using the new state for "network_from"
891385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby            // and STATE_OUT_OF_SERVICE for "network_to". To avoid confusion, use a new log tag
892385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby            // to record the correct states.
893385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby            EventLog.writeEvent(EventLogTags.GSM_RAT_SWITCHED_NEW, cid,
894385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby                    mSS.getRilVoiceRadioTechnology(),
89522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewSS.getRilVoiceRadioTechnology());
8960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
897f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                log("RAT switched "
89822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        + ServiceState.rilRadioTechnologyToString(mSS.getRilVoiceRadioTechnology())
899f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                        + " -> "
900385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby                        + ServiceState.rilRadioTechnologyToString(
901385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby                                mNewSS.getRilVoiceRadioTechnology()) + " at cell " + cid);
9020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
9030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
905385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby        // swap mSS and mNewSS to put new state in mSS
906385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby        ServiceState tss = mSS;
907385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby        mSS = mNewSS;
908385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby        mNewSS = tss;
909385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby        // clean slate for next time
910385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby        mNewSS.setStateOutOfService();
911385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby
912385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby        // swap mCellLoc and mNewCellLoc to put new state in mCellLoc
913385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby        GsmCellLocation tcl = mCellLoc;
914385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby        mCellLoc = mNewCellLoc;
915385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby        mNewCellLoc = tcl;
916385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby
9170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mReasonDataDenied = mNewReasonDataDenied;
9180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mMaxDataCalls = mNewMaxDataCalls;
9190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
920b54cd09892e0676d719e6df00e60c77b663f993cWink Saville        if (hasRilVoiceRadioTechnologyChanged) {
921b54cd09892e0676d719e6df00e60c77b663f993cWink Saville            updatePhoneObject();
922b54cd09892e0676d719e6df00e60c77b663f993cWink Saville        }
923b54cd09892e0676d719e6df00e60c77b663f993cWink Saville
924a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville        if (hasRilDataRadioTechnologyChanged) {
92522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
92622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    ServiceState.rilRadioTechnologyToString(mSS.getRilVoiceRadioTechnology()));
9270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasRegistered) {
9300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mNetworkAttachedRegistrants.notifyRegistrants();
9310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
9330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("pollStateDone: registering current mNitzUpdatedTime=" +
9340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mNitzUpdatedTime + " changing to false");
9350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
9360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mNitzUpdatedTime = false;
9370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasChanged) {
9400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String operatorNumeric;
9410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            updateSpnDisplay();
9430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
94422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
94522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSS.getOperatorAlphaLong());
9460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String prevOperatorNumeric =
9480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, "");
94922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            operatorNumeric = mSS.getOperatorNumeric();
95022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
9510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (operatorNumeric == null) {
9530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("operatorNumeric is null");
95422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
9550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mGotCountryCode = false;
9560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNitzUpdatedTime = false;
9570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
9580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                String iso = "";
9597c491bb3d140e2579c2c01edca94305701664db5Rekha Kumar                String mcc = "";
9600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                try{
9617c491bb3d140e2579c2c01edca94305701664db5Rekha Kumar                    mcc = operatorNumeric.substring(0, 3);
9620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    iso = MccTable.countryCodeForMcc(Integer.parseInt(mcc));
9630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } catch ( NumberFormatException ex){
9640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    loge("pollStateDone: countryCodeForMcc error" + ex);
9650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } catch ( StringIndexOutOfBoundsException ex) {
9660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    loge("pollStateDone: countryCodeForMcc error" + ex);
9670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
96922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, iso);
9700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mGotCountryCode = true;
9710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                TimeZone zone = null;
9730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!mNitzUpdatedTime && !mcc.equals("000") && !TextUtils.isEmpty(iso) &&
9750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        getAutoTimeZone()) {
9760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Test both paths if ignore nitz is true
9780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    boolean testOneUniqueOffsetPath = SystemProperties.getBoolean(
9790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                TelephonyProperties.PROPERTY_IGNORE_NITZ, false) &&
9800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    ((SystemClock.uptimeMillis() & 1) == 0);
9810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ArrayList<TimeZone> uniqueZones = TimeUtils.getTimeZonesWithUniqueOffsets(iso);
9830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if ((uniqueZones.size() == 1) || testOneUniqueOffsetPath) {
9840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = uniqueZones.get(0);
9850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) {
9860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                           log("pollStateDone: no nitz but one TZ for iso-cc=" + iso +
9870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                   " with zone.getID=" + zone.getID() +
9880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                   " testOneUniqueOffsetPath=" + testOneUniqueOffsetPath);
9890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
9900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        setAndBroadcastNetworkSetTimeZone(zone.getID());
9910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
9920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) {
9930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            log("pollStateDone: there are " + uniqueZones.size() +
9940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                " unique offsets for iso-cc='" + iso +
9950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                " testOneUniqueOffsetPath=" + testOneUniqueOffsetPath +
9960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                "', do nothing");
9970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
9980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
9990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
10000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
100122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (shouldFixTimeZoneNow(mPhone, operatorNumeric, prevOperatorNumeric,
10020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mNeedFixZoneAfterNitz)) {
10030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // If the offset is (0, false) and the timezone property
10040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // is set, use the timezone property rather than
10050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // GMT.
10060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    String zoneName = SystemProperties.get(TIMEZONE_PROPERTY);
10070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) {
10080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("pollStateDone: fix time zone zoneName='" + zoneName +
10090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "' mZoneOffset=" + mZoneOffset + " mZoneDst=" + mZoneDst +
10100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            " iso-cc='" + iso +
10110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "' iso-cc-idx=" + Arrays.binarySearch(GMT_COUNTRY_CODES, iso));
10120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
10130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // "(mZoneOffset == 0) && (mZoneDst == false) &&
10150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    //  (Arrays.binarySearch(GMT_COUNTRY_CODES, iso) < 0)"
10160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // means that we received a NITZ string telling
10170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // it is in GMT+0 w/ DST time zone
10180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // BUT iso tells is NOT, e.g, a wrong NITZ reporting
10190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // local time w/ 0 offset.
10200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if ((mZoneOffset == 0) && (mZoneDst == false) &&
10210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        (zoneName != null) && (zoneName.length() > 0) &&
10220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        (Arrays.binarySearch(GMT_COUNTRY_CODES, iso) < 0)) {
10230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = TimeZone.getDefault();
10240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (mNeedFixZoneAfterNitz) {
10250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            // For wrong NITZ reporting local time w/ 0 offset,
10260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            // need adjust time to reflect default timezone setting
10270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            long ctm = System.currentTimeMillis();
10280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            long tzOffset = zone.getOffset(ctm);
10290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (DBG) {
10300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                log("pollStateDone: tzOffset=" + tzOffset + " ltod=" +
10310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        TimeUtils.logTimeOfDay(ctm));
10320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
10330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (getAutoTime()) {
10340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                long adj = ctm - tzOffset;
10350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (DBG) log("pollStateDone: adj ltod=" +
10360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        TimeUtils.logTimeOfDay(adj));
10370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                setAndBroadcastNetworkSetTime(adj);
10380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            } else {
10390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                // Adjust the saved NITZ time to account for tzOffset.
10400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                mSavedTime = mSavedTime - tzOffset;
10410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
10420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
10430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("pollStateDone: using default TimeZone");
10440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else if (iso.equals("")){
10450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Country code not found.  This is likely a test network.
10460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Get a TimeZone based only on the NITZ parameters (best guess).
10470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = getNitzTimeZone(mZoneOffset, mZoneDst, mZoneTime);
10480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("pollStateDone: using NITZ TimeZone");
10490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
10500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = TimeUtils.getTimeZone(mZoneOffset, mZoneDst, mZoneTime, iso);
10510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("pollStateDone: using getTimeZone(off, dst, time, iso)");
10520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
10530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mNeedFixZoneAfterNitz = false;
10550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (zone != null) {
10570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("pollStateDone: zone != null zone.getID=" + zone.getID());
10580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (getAutoTimeZone()) {
10590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            setAndBroadcastNetworkSetTimeZone(zone.getID());
10600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
10610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        saveNitzTimeZone(zone.getID());
10620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
10630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("pollStateDone: zone == null");
10640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
10650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
10660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
10670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
106822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
106922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSS.getRoaming() ? "true" : "false");
10700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
107122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyServiceStateChanged(mSS);
10720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasGprsAttached) {
10750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mAttachedRegistrants.notifyRegistrants();
10760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasGprsDetached) {
10790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mDetachedRegistrants.notifyRegistrants();
10800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1082a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville        if (hasDataRegStateChanged || hasRilDataRadioTechnologyChanged) {
1083203e588e3c42a81aa8a56f595119c181a63b12caWink Saville            notifyDataRegStateRilRadioTechnologyChanged();
1084a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville            mPhone.notifyDataConnection(null);
10850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasRoamingOn) {
10880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mRoamingOnRegistrants.notifyRegistrants();
10890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasRoamingOff) {
10920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mRoamingOffRegistrants.notifyRegistrants();
10930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasLocationChanged) {
109622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyLocationChanged();
10970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
109922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (! isGprsConsistent(mSS.getDataRegState(), mSS.getVoiceRegState())) {
11000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!mStartedGprsRegCheck && !mReportedGprsNoReg) {
11010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mStartedGprsRegCheck = true;
11020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1103b840987a39e7149c1364739696977089cd53814dWink Saville                int check_period = Settings.Global.getInt(
110422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mPhone.getContext().getContentResolver(),
1105b840987a39e7149c1364739696977089cd53814dWink Saville                        Settings.Global.GPRS_REGISTER_CHECK_PERIOD_MS,
11060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        DEFAULT_GPRS_CHECK_PERIOD_MILLIS);
11070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                sendMessageDelayed(obtainMessage(EVENT_CHECK_REPORT_GPRS),
11080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        check_period);
11090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
11110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mReportedGprsNoReg = false;
11120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1113ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        // TODO: Add GsmCellIdenity updating, see CdmaLteServiceStateTracker.
11140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Check if GPRS got registered while voice is registered.
11180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
1119cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param dataRegState i.e. CGREG in GSM
1120cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param voiceRegState i.e. CREG in GSM
11210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return false if device only register to voice but not gprs
11220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1123f92cb4bd5519427a0db673709d94683a8baf203aWink Saville    private boolean isGprsConsistent(int dataRegState, int voiceRegState) {
1124f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        return !((voiceRegState == ServiceState.STATE_IN_SERVICE) &&
1125f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                (dataRegState != ServiceState.STATE_IN_SERVICE));
11260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Returns a TimeZone object based only on parameters from the NITZ string.
11300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private TimeZone getNitzTimeZone(int offset, boolean dst, long when) {
11320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        TimeZone guess = findTimeZone(offset, dst, when);
11330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (guess == null) {
11340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Couldn't find a proper timezone.  Perhaps the DST data is wrong.
11350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            guess = findTimeZone(offset, !dst, when);
11360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("getNitzTimeZone returning " + (guess == null ? guess : guess.getID()));
11380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return guess;
11390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private TimeZone findTimeZone(int offset, boolean dst, long when) {
11420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int rawOffset = offset;
11430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (dst) {
11440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            rawOffset -= 3600000;
11450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String[] zones = TimeZone.getAvailableIDs(rawOffset);
11470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        TimeZone guess = null;
11480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Date d = new Date(when);
11490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (String zone : zones) {
11500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            TimeZone tz = TimeZone.getTimeZone(zone);
11510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (tz.getOffset(when) == offset &&
11520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                tz.inDaylightTime(d) == dst) {
11530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                guess = tz;
11540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
11550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return guess;
11590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void queueNextSignalStrengthPoll() {
116222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mDontPollSignalStrength) {
11630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // The radio is telling us about signal strength changes
11640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // we don't have to ask it
11650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
11660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Message msg;
11690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        msg = obtainMessage();
11710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        msg.what = EVENT_POLL_SIGNAL_STRENGTH;
11720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        long nextTime;
11740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // TODO Don't poll signal strength if screen is off
11760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        sendMessageDelayed(msg, POLL_PERIOD_MILLIS);
11770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Set restricted state based on the OnRestrictedStateChanged notification
11810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * If any voice or packet restricted state changes, trigger a UI
11820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * notification and notify registrants when sim is ready.
11830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
11840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param ar an int value of RIL_RESTRICTED_STATE_*
11850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void onRestrictedStateChanged(AsyncResult ar) {
11870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        RestrictedState newRs = new RestrictedState();
11880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onRestrictedStateChanged: E rs "+ mRestrictedState);
11900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ar.exception == null) {
11920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int[] ints = (int[])ar.result;
11930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int state = ints[0];
11940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            newRs.setCsEmergencyRestricted(
11960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ((state & RILConstants.RIL_RESTRICTED_STATE_CS_EMERGENCY) != 0) ||
11970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
11980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //ignore the normal call and data restricted state before SIM READY
1199e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mUiccApplcation != null && mUiccApplcation.getState() == AppState.APPSTATE_READY) {
12000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                newRs.setCsNormalRestricted(
12010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ((state & RILConstants.RIL_RESTRICTED_STATE_CS_NORMAL) != 0) ||
12020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
12030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                newRs.setPsRestricted(
12040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        (state & RILConstants.RIL_RESTRICTED_STATE_PS_ALL)!= 0);
12050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
12060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("onRestrictedStateChanged: new rs "+ newRs);
12080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!mRestrictedState.isPsRestricted() && newRs.isPsRestricted()) {
12100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPsRestrictEnabledRegistrants.notifyRegistrants();
12110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setNotification(PS_ENABLED);
12120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (mRestrictedState.isPsRestricted() && !newRs.isPsRestricted()) {
12130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPsRestrictDisabledRegistrants.notifyRegistrants();
12140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setNotification(PS_DISABLED);
12150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
12160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            /**
12180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             * There are two kind of cs restriction, normal and emergency. So
12190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             * there are 4 x 4 combinations in current and new restricted states
12200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             * and we only need to notify when state is changed.
12210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             */
12220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mRestrictedState.isCsRestricted()) {
12230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!newRs.isCsRestricted()) {
12240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove all restriction
12250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_DISABLED);
12260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (!newRs.isCsNormalRestricted()) {
12270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove normal restriction
12280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_EMERGENCY_ENABLED);
12290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (!newRs.isCsEmergencyRestricted()) {
12300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove emergency restriction
12310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_NORMAL_ENABLED);
12320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
12330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (mRestrictedState.isCsEmergencyRestricted() &&
12340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    !mRestrictedState.isCsNormalRestricted()) {
12350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!newRs.isCsRestricted()) {
12360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove all restriction
12370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_DISABLED);
12380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsRestricted()) {
12390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // enable all restriction
12400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_ENABLED);
12410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsNormalRestricted()) {
12420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove emergency restriction and enable normal restriction
12430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_NORMAL_ENABLED);
12440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
12450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (!mRestrictedState.isCsEmergencyRestricted() &&
12460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mRestrictedState.isCsNormalRestricted()) {
12470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!newRs.isCsRestricted()) {
12480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove all restriction
12490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_DISABLED);
12500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsRestricted()) {
12510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // enable all restriction
12520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_ENABLED);
12530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsEmergencyRestricted()) {
12540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove normal restriction and enable emergency restriction
12550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_EMERGENCY_ENABLED);
12560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
12570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
12580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (newRs.isCsRestricted()) {
12590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // enable all restriction
12600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_ENABLED);
12610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsEmergencyRestricted()) {
12620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // enable emergency restriction
12630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_EMERGENCY_ENABLED);
12640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsNormalRestricted()) {
12650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // enable normal restriction
12660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_NORMAL_ENABLED);
12670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
12680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
12690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mRestrictedState = newRs;
12710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        log("onRestrictedStateChanged: X rs "+ mRestrictedState);
12730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** code is registration state 0-5 from TS 27.007 7.2 */
12760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int regCodeToServiceState(int code) {
12770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (code) {
12780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 0:
12790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 2: // 2 is "searching"
12800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 3: // 3 is "registration denied"
12810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 4: // 4 is "unknown" no vaild in current baseband
12820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 10:// same as 0, but indicates that emergency call is possible.
12830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 12:// same as 2, but indicates that emergency call is possible.
12840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 13:// same as 3, but indicates that emergency call is possible.
12850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 14:// same as 4, but indicates that emergency call is possible.
12860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return ServiceState.STATE_OUT_OF_SERVICE;
12870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 1:
12890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return ServiceState.STATE_IN_SERVICE;
12900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 5:
12920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // in service, roam
12930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return ServiceState.STATE_IN_SERVICE;
12940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
12960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                loge("regCodeToServiceState: unexpected service state " + code);
12970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return ServiceState.STATE_OUT_OF_SERVICE;
12980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
13000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
13030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * code is registration state 0-5 from TS 27.007 7.2
13040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * returns true if registered roam, false otherwise
13050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
13060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean regCodeIsRoaming (int code) {
1307f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        return ServiceState.RIL_REG_STATE_ROAMING == code;
13080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
13090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
13117ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * Set roaming state if operator mcc is the same as sim mcc
13127ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * and ons is different from spn
13137ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     *
13140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param s ServiceState hold current ons
13157ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * @return true if same operator
13160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
13177ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi    private boolean isSameNamedOperators(ServiceState s) {
13180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String spn = SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, "empty");
13190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String onsl = s.getOperatorAlphaLong();
13210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String onss = s.getOperatorAlphaShort();
13220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean equalsOnsl = onsl != null && spn.equals(onsl);
13240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean equalsOnss = onss != null && spn.equals(onss);
13250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13267ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi        return currentMccEqualsSimMcc(s) && (equalsOnsl || equalsOnss);
13277ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi    }
13287ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi
13297ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi    /**
13307ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * Compare SIM MCC with Operator MCC
13317ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     *
13327ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * @param s ServiceState hold current ons
13337ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * @return true if both are same
13347ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     */
13357ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi    private boolean currentMccEqualsSimMcc(ServiceState s) {
13360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String simNumeric = SystemProperties.get(
13370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "");
13387ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi        String operatorNumeric = s.getOperatorNumeric();
13390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean equalsMcc = true;
13407ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi
13410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
13420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            equalsMcc = simNumeric.substring(0, 3).
13430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    equals(operatorNumeric.substring(0, 3));
13440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (Exception e){
13450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
13467ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi        return equalsMcc;
13477ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi    }
13480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13497ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi    /**
13507ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * Do not set roaming state in case of oprators considered non-roaming.
13517ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     *
13527ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     + Can use mcc or mcc+mnc as item of config_operatorConsideredNonRoaming.
13537ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * For example, 302 or 21407. If mcc or mcc+mnc match with operator,
13547ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * don't set roaming state.
13557ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     *
13567ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * @param s ServiceState hold current ons
13577ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * @return false for roaming state set
13587ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     */
13597ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi    private boolean isOperatorConsideredNonRoaming(ServiceState s) {
13607ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi        String operatorNumeric = s.getOperatorNumeric();
13617ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi        String[] numericArray = mPhone.getContext().getResources().getStringArray(
13627ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi                    com.android.internal.R.array.config_operatorConsideredNonRoaming);
13637ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi
13647ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi        if (numericArray.length == 0 || operatorNumeric == null)
13657ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi            return false;
13667ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi
13677ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi        for (String numeric : numericArray) {
13687ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi            if (operatorNumeric.startsWith(numeric))
13697ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi                return true;
13707ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi            else
13717ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi                return false;
13727ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi        }
13737ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi        return false;
13740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
13750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13761110f0fd89337adc1b09fe866750b8721ef882cfVineeta Srivastava    private boolean isSameNamedOperatorConsideredRoaming(ServiceState s) {
13771110f0fd89337adc1b09fe866750b8721ef882cfVineeta Srivastava        String operatorNumeric = s.getOperatorNumeric();
13781110f0fd89337adc1b09fe866750b8721ef882cfVineeta Srivastava        String[] numericArray = mPhone.getContext().getResources().getStringArray(
13791110f0fd89337adc1b09fe866750b8721ef882cfVineeta Srivastava                    com.android.internal.R.array.config_sameNamedOperatorConsideredRoaming);
13801110f0fd89337adc1b09fe866750b8721ef882cfVineeta Srivastava
13811110f0fd89337adc1b09fe866750b8721ef882cfVineeta Srivastava        if (numericArray.length == 0 || operatorNumeric == null)
13821110f0fd89337adc1b09fe866750b8721ef882cfVineeta Srivastava            return false;
13831110f0fd89337adc1b09fe866750b8721ef882cfVineeta Srivastava
13841110f0fd89337adc1b09fe866750b8721ef882cfVineeta Srivastava        for (String numeric : numericArray) {
13851110f0fd89337adc1b09fe866750b8721ef882cfVineeta Srivastava            if (operatorNumeric.startsWith(numeric))
13861110f0fd89337adc1b09fe866750b8721ef882cfVineeta Srivastava                return true;
13871110f0fd89337adc1b09fe866750b8721ef882cfVineeta Srivastava            else
13881110f0fd89337adc1b09fe866750b8721ef882cfVineeta Srivastava                return false;
13891110f0fd89337adc1b09fe866750b8721ef882cfVineeta Srivastava        }
13901110f0fd89337adc1b09fe866750b8721ef882cfVineeta Srivastava        return false;
13911110f0fd89337adc1b09fe866750b8721ef882cfVineeta Srivastava    }
13921110f0fd89337adc1b09fe866750b8721ef882cfVineeta Srivastava
13930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
13940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return The current GPRS state. IN_SERVICE is the same as "attached"
13950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * and OUT_OF_SERVICE is the same as detached.
13960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1397f92cb4bd5519427a0db673709d94683a8baf203aWink Saville    @Override
13980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public int getCurrentDataConnectionState() {
139922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mSS.getDataRegState();
14000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
14030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if phone is camping on a technology (eg UMTS)
14040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * that could support voice and data simultaneously.
14050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1406cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
14070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean isConcurrentVoiceAndDataAllowed() {
140822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return (mSS.getRilVoiceRadioTechnology() >= ServiceState.RIL_RADIO_TECHNOLOGY_UMTS);
14090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
14120c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville     * @return the current cell location information. Prefer Gsm location
14130c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville     * information if available otherwise return LTE location information
14140c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville     */
14150c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville    public CellLocation getCellLocation() {
14160c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville        if ((mCellLoc.getLac() >= 0) && (mCellLoc.getCid() >= 0)) {
14170c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville            if (DBG) log("getCellLocation(): X good mCellLoc=" + mCellLoc);
14180c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville            return mCellLoc;
14190c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville        } else {
14200c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville            List<CellInfo> result = getAllCellInfo();
14210c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville            if (result != null) {
14220c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                // A hack to allow tunneling of LTE information via GsmCellLocation
14230c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                // so that older Network Location Providers can return some information
14240c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                // on LTE only networks, see bug 9228974.
14250c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                //
14260c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                // We'll search the return CellInfo array preferring GSM/WCDMA
14270c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                // data, but if there is none we'll tunnel the first LTE information
14280c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                // in the list.
14290c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                //
14300c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                // The tunnel'd LTE information is returned as follows:
14310c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                //   LAC = TAC field
14320c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                //   CID = CI field
14330c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                //   PSC = 0.
14340c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                GsmCellLocation cellLocOther = new GsmCellLocation();
14350c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                for (CellInfo ci : result) {
14360c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    if (ci instanceof CellInfoGsm) {
14370c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        CellInfoGsm cellInfoGsm = (CellInfoGsm)ci;
14380c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        CellIdentityGsm cellIdentityGsm = cellInfoGsm.getCellIdentity();
14390c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        cellLocOther.setLacAndCid(cellIdentityGsm.getLac(),
14400c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                                cellIdentityGsm.getCid());
14410c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        cellLocOther.setPsc(cellIdentityGsm.getPsc());
14420c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        if (DBG) log("getCellLocation(): X ret GSM info=" + cellLocOther);
14430c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        return cellLocOther;
14440c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    } else if (ci instanceof CellInfoWcdma) {
14450c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        CellInfoWcdma cellInfoWcdma = (CellInfoWcdma)ci;
14460c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        CellIdentityWcdma cellIdentityWcdma = cellInfoWcdma.getCellIdentity();
14470c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        cellLocOther.setLacAndCid(cellIdentityWcdma.getLac(),
14480c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                                cellIdentityWcdma.getCid());
14490c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        cellLocOther.setPsc(cellIdentityWcdma.getPsc());
14500c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        if (DBG) log("getCellLocation(): X ret WCDMA info=" + cellLocOther);
14510c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        return cellLocOther;
14520c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    } else if ((ci instanceof CellInfoLte) &&
14530c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                            ((cellLocOther.getLac() < 0) || (cellLocOther.getCid() < 0))) {
14540c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        // We'll return the first good LTE info we get if there is no better answer
14550c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        CellInfoLte cellInfoLte = (CellInfoLte)ci;
14560c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        CellIdentityLte cellIdentityLte = cellInfoLte.getCellIdentity();
14570c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        if ((cellIdentityLte.getTac() != Integer.MAX_VALUE)
14580c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                                && (cellIdentityLte.getCi() != Integer.MAX_VALUE)) {
14590c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                            cellLocOther.setLacAndCid(cellIdentityLte.getTac(),
14600c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                                    cellIdentityLte.getCi());
14610c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                            cellLocOther.setPsc(0);
14620c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                            if (DBG) {
14630c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                                log("getCellLocation(): possible LTE cellLocOther=" + cellLocOther);
14640c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                            }
14650c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        }
14660c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    }
14670c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                }
14680c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                if (DBG) {
14690c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    log("getCellLocation(): X ret best answer cellLocOther=" + cellLocOther);
14700c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                }
14710c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                return cellLocOther;
14720c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville            } else {
14730c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                if (DBG) {
14740c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    log("getCellLocation(): X empty mCellLoc and CellInfo mCellLoc=" + mCellLoc);
14750c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                }
14760c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                return mCellLoc;
14770c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville            }
14780c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville        }
14790c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville    }
14800c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville
14810c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville    /**
14820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * nitzReceiveTime is time_t that the NITZ time was posted
14830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
14840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void setTimeFromNITZString (String nitz, long nitzReceiveTime) {
14850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // "yy/mm/dd,hh:mm:ss(+/-)tz"
14860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // tz is in number of quarter-hours
14870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        long start = SystemClock.elapsedRealtime();
14890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {log("NITZ: " + nitz + "," + nitzReceiveTime +
14900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        " start=" + start + " delay=" + (start - nitzReceiveTime));
14910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
14920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
14940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            /* NITZ time (hour:min:sec) will be in UTC but it supplies the timezone
14950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             * offset as well (which we won't worry about until later) */
14960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
14970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.clear();
14990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.DST_OFFSET, 0);
15000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String[] nitzSubs = nitz.split("[/:,+-]");
15020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int year = 2000 + Integer.parseInt(nitzSubs[0]);
15040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.YEAR, year);
15050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // month is 0 based!
15070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int month = Integer.parseInt(nitzSubs[1]) - 1;
15080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.MONTH, month);
15090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int date = Integer.parseInt(nitzSubs[2]);
15110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.DATE, date);
15120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int hour = Integer.parseInt(nitzSubs[3]);
15140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.HOUR, hour);
15150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int minute = Integer.parseInt(nitzSubs[4]);
15170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.MINUTE, minute);
15180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int second = Integer.parseInt(nitzSubs[5]);
15200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.SECOND, second);
15210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            boolean sign = (nitz.indexOf('-') == -1);
15230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int tzOffset = Integer.parseInt(nitzSubs[6]);
15250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int dst = (nitzSubs.length >= 8 ) ? Integer.parseInt(nitzSubs[7])
15270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                              : 0;
15280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // The zone offset received from NITZ is for current local time,
15300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // so DST correction is already applied.  Don't add it again.
15310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //
15320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // tzOffset += dst * 4;
15330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //
15340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // We could unapply it if we wanted the raw offset.
15350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            tzOffset = (sign ? 1 : -1) * tzOffset * 15 * 60 * 1000;
15370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            TimeZone    zone = null;
15390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // As a special extension, the Android emulator appends the name of
15410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // the host computer's timezone to the nitz string. this is zoneinfo
15420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // timezone name of the form Area!Location or Area!Location!SubLocation
15430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // so we need to convert the ! into /
15440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (nitzSubs.length >= 9) {
15450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                String  tzname = nitzSubs[8].replace('!','/');
15460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                zone = TimeZone.getTimeZone( tzname );
15470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
15480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String iso = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY);
15500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (zone == null) {
15520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (mGotCountryCode) {
15540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (iso != null && iso.length() > 0) {
15550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = TimeUtils.getTimeZone(tzOffset, dst != 0,
15560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                c.getTimeInMillis(),
15570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                iso);
15580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
15590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // We don't have a valid iso country code.  This is
15600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // most likely because we're on a test network that's
15610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // using a bogus MCC (eg, "001"), so get a TimeZone
15620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // based only on the NITZ parameters.
15630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = getNitzTimeZone(tzOffset, (dst != 0), c.getTimeInMillis());
15640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
15650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
15660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
15670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if ((zone == null) || (mZoneOffset != tzOffset) || (mZoneDst != (dst != 0))){
15690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // We got the time before the country or the zone has changed
15700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // so we don't know how to identify the DST rules yet.  Save
15710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // the information and hope to fix it up later.
15720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNeedFixZoneAfterNitz = true;
15740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mZoneOffset  = tzOffset;
15750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mZoneDst     = dst != 0;
15760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mZoneTime    = c.getTimeInMillis();
15770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
15780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (zone != null) {
15800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (getAutoTimeZone()) {
15810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setAndBroadcastNetworkSetTimeZone(zone.getID());
15820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
15830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                saveNitzTimeZone(zone.getID());
15840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
15850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String ignore = SystemProperties.get("gsm.ignore-nitz");
15870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (ignore != null && ignore.equals("yes")) {
15880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("NITZ: Not setting clock because gsm.ignore-nitz is set");
15890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
15900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
15910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            try {
15930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mWakeLock.acquire();
15940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (getAutoTime()) {
15960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    long millisSinceNitzReceived
15970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            = SystemClock.elapsedRealtime() - nitzReceiveTime;
15980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (millisSinceNitzReceived < 0) {
16000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Sanity check: something is wrong
16010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) {
16020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            log("NITZ: not setting time, clock has rolled "
16030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                            + "backwards since NITZ time was received, "
16040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                            + nitz);
16050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
16060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        return;
16070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
16080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (millisSinceNitzReceived > Integer.MAX_VALUE) {
16100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // If the time is this far off, something is wrong > 24 days!
16110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) {
16120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            log("NITZ: not setting time, processing has taken "
16130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        + (millisSinceNitzReceived / (1000 * 60 * 60 * 24))
16140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        + " days");
16150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
16160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        return;
16170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
16180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Note: with range checks above, cast to int is safe
16200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    c.add(Calendar.MILLISECOND, (int)millisSinceNitzReceived);
16210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) {
16230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("NITZ: Setting time of day to " + c.getTime()
16240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + " NITZ receive delay(ms): " + millisSinceNitzReceived
16250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + " gained(ms): "
16260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + (c.getTimeInMillis() - System.currentTimeMillis())
16270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + " from " + nitz);
16280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
16290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setAndBroadcastNetworkSetTime(c.getTimeInMillis());
163199c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                    Rlog.i(LOG_TAG, "NITZ: after Setting time of day");
16320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
16330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SystemProperties.set("gsm.nitz.time", String.valueOf(c.getTimeInMillis()));
16340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                saveNitzTime(c.getTimeInMillis());
1635cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (VDBG) {
16360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    long end = SystemClock.elapsedRealtime();
16370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("NITZ: end=" + end + " dur=" + (end - start));
16380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
16390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNitzUpdatedTime = true;
16400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } finally {
16410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mWakeLock.release();
16420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
16430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (RuntimeException ex) {
16440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("NITZ: Parsing NITZ time " + nitz + " ex=" + ex);
16450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean getAutoTime() {
16490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
165022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            return Settings.Global.getInt(mPhone.getContext().getContentResolver(),
1651069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate                    Settings.Global.AUTO_TIME) > 0;
16520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (SettingNotFoundException snfe) {
16530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
16540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean getAutoTimeZone() {
16580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
165922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            return Settings.Global.getInt(mPhone.getContext().getContentResolver(),
1660069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate                    Settings.Global.AUTO_TIME_ZONE) > 0;
16610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (SettingNotFoundException snfe) {
16620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
16630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void saveNitzTimeZone(String zoneId) {
16670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mSavedTimeZone = zoneId;
16680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void saveNitzTime(long time) {
16710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mSavedTime = time;
16720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mSavedAtTime = SystemClock.elapsedRealtime();
16730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
16760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Set the timezone and send out a sticky broadcast so the system can
16770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * determine if the timezone was set by the carrier.
16780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
16790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param zoneId timezone set by carrier
16800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
16810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void setAndBroadcastNetworkSetTimeZone(String zoneId) {
16820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setAndBroadcastNetworkSetTimeZone: setTimeZone=" + zoneId);
16830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AlarmManager alarm =
168422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
16850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        alarm.setTimeZone(zoneId);
16860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE);
16870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
16880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.putExtra("time-zone", zoneId);
168922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.getContext().sendStickyBroadcastAsUser(intent, UserHandle.ALL);
16900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
16910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("setAndBroadcastNetworkSetTimeZone: call alarm.setTimeZone and broadcast zoneId=" +
16920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                zoneId);
16930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
16970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Set the time and Send out a sticky broadcast so the system can determine
16980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * if the time was set by the carrier.
16990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
17000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param time time set by network
17010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
17020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void setAndBroadcastNetworkSetTime(long time) {
17030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setAndBroadcastNetworkSetTime: time=" + time + "ms");
17040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SystemClock.setCurrentTimeMillis(time);
17050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME);
17060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
17070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.putExtra("time", time);
170822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.getContext().sendStickyBroadcastAsUser(intent, UserHandle.ALL);
17090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
17100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void revertToNitzTime() {
171222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (Settings.Global.getInt(mPhone.getContext().getContentResolver(),
1713069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate                Settings.Global.AUTO_TIME, 0) == 0) {
17140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
17150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
17170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("Reverting to NITZ Time: mSavedTime=" + mSavedTime
17180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                + " mSavedAtTime=" + mSavedAtTime);
17190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mSavedTime != 0 && mSavedAtTime != 0) {
17210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setAndBroadcastNetworkSetTime(mSavedTime
17220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    + (SystemClock.elapsedRealtime() - mSavedAtTime));
17230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
17250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void revertToNitzTimeZone() {
172722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (Settings.Global.getInt(mPhone.getContext().getContentResolver(),
1728069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate                Settings.Global.AUTO_TIME_ZONE, 0) == 0) {
17290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
17300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("Reverting to NITZ TimeZone: tz='" + mSavedTimeZone);
17320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mSavedTimeZone != null) {
17330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setAndBroadcastNetworkSetTimeZone(mSavedTimeZone);
17340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
17360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
17380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Post a notification to NotificationManager for restricted state
17390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
17400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param notifyType is one state of PS/CS_*_ENABLE/DISABLE
17410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
17420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void setNotification(int notifyType) {
17430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setNotification: create notification " + notifyType);
174522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        Context context = mPhone.getContext();
17460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification = new Notification();
17480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.when = System.currentTimeMillis();
17490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.flags = Notification.FLAG_AUTO_CANCEL;
17500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.icon = com.android.internal.R.drawable.stat_sys_warning;
17510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent();
17520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.contentIntent = PendingIntent
17530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        .getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
17540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CharSequence details = "";
17560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CharSequence title = context.getText(com.android.internal.R.string.RestrictedChangedTitle);
17570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int notificationId = CS_NOTIFICATION;
17580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (notifyType) {
17600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PS_ENABLED:
17610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notificationId = PS_NOTIFICATION;
1762cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            details = context.getText(com.android.internal.R.string.RestrictedOnData);
17630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
17640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PS_DISABLED:
17650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notificationId = PS_NOTIFICATION;
17660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
17670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CS_ENABLED:
1768cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            details = context.getText(com.android.internal.R.string.RestrictedOnAllVoice);
17690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
17700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CS_NORMAL_ENABLED:
1771cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            details = context.getText(com.android.internal.R.string.RestrictedOnNormal);
17720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
17730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CS_EMERGENCY_ENABLED:
1774cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            details = context.getText(com.android.internal.R.string.RestrictedOnEmergency);
17750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
17760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CS_DISABLED:
17770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // do nothing and cancel the notification later
17780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
17790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setNotification: put notification " + title + " / " +details);
17820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.tickerText = title;
17830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.setLatestEventInfo(context, title, details,
17840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNotification.contentIntent);
17850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        NotificationManager notificationManager = (NotificationManager)
17870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            context.getSystemService(Context.NOTIFICATION_SERVICE);
17880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (notifyType == PS_DISABLED || notifyType == CS_DISABLED) {
17900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // cancel previous post notification
17910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notificationManager.cancel(notificationId);
17920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
17930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // update restricted state notification
17940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notificationManager.notify(notificationId, mNotification);
17950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
17970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
1799e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected void onUpdateIccAvailability() {
1800e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (mUiccController == null ) {
1801e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            return;
1802e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        }
1803e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
1804e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        UiccCardApplication newUiccApplication =
1805e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccController.getUiccCardApplication(UiccController.APP_FAM_3GPP);
1806e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
1807e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mUiccApplcation != newUiccApplication) {
1808e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mUiccApplcation != null) {
1809e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                log("Removing stale icc objects.");
1810e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplcation.unregisterForReady(this);
1811e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                if (mIccRecords != null) {
1812e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                    mIccRecords.unregisterForRecordsLoaded(this);
1813e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                }
1814e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                mIccRecords = null;
1815e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplcation = null;
1816e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            }
1817e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (newUiccApplication != null) {
1818e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                log("New card found");
1819e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplcation = newUiccApplication;
1820e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mIccRecords = mUiccApplcation.getIccRecords();
1821e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplcation.registerForReady(this, EVENT_SIM_READY, null);
1822e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                if (mIccRecords != null) {
1823e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                    mIccRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
1824e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                }
1825e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            }
1826e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        }
1827e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    }
1828e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    @Override
18290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void log(String s) {
183099c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.d(LOG_TAG, "[GsmSST] " + s);
18310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
18320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
18340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void loge(String s) {
183599c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.e(LOG_TAG, "[GsmSST] " + s);
18360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
18370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
18390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
18400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println("GsmServiceStateTracker extends:");
18410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        super.dump(fd, pw, args);
184222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mPhone=" + mPhone);
184322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mSS=" + mSS);
184422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mNewSS=" + mNewSS);
184522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mCellLoc=" + mCellLoc);
184622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mNewCellLoc=" + mNewCellLoc);
18470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mPreferredNetworkType=" + mPreferredNetworkType);
18480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mMaxDataCalls=" + mMaxDataCalls);
18490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNewMaxDataCalls=" + mNewMaxDataCalls);
18500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mReasonDataDenied=" + mReasonDataDenied);
18510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNewReasonDataDenied=" + mNewReasonDataDenied);
18520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mGsmRoaming=" + mGsmRoaming);
18530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mDataRoaming=" + mDataRoaming);
18540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mEmergencyOnly=" + mEmergencyOnly);
18550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNeedFixZoneAfterNitz=" + mNeedFixZoneAfterNitz);
18560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mZoneOffset=" + mZoneOffset);
18570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mZoneDst=" + mZoneDst);
18580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mZoneTime=" + mZoneTime);
18590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mGotCountryCode=" + mGotCountryCode);
18600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNitzUpdatedTime=" + mNitzUpdatedTime);
18610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mSavedTimeZone=" + mSavedTimeZone);
18620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mSavedTime=" + mSavedTime);
18630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mSavedAtTime=" + mSavedAtTime);
18640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mStartedGprsRegCheck=" + mStartedGprsRegCheck);
18650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mReportedGprsNoReg=" + mReportedGprsNoReg);
18660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNotification=" + mNotification);
18670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mWakeLock=" + mWakeLock);
186822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mCurSpn=" + mCurSpn);
186922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mCurShowSpn=" + mCurShowSpn);
187022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mCurPlmn=" + mCurPlmn);
187122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mCurShowPlmn=" + mCurShowPlmn);
18720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
18730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
1874