GsmServiceStateTracker.java revision 60ced166cb63c35a0ebbee1fc356cddcb76b956f
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;
40ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Savilleimport android.telephony.CellInfoGsm;
4160ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport android.telephony.Rlog;
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.ServiceState;
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.SignalStrength;
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.gsm.GsmCellLocation;
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.text.TextUtils;
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.EventLog;
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.TimeUtils;
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4960ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.CommandException;
5060ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.CommandsInterface;
5160ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.EventLogTags;
5260ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.MccTable;
5360ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.Phone;
5460ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.RILConstants;
5560ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.RestrictedState;
5660ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.ServiceStateTracker;
5760ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.TelephonyIntents;
5860ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.TelephonyProperties;
5960ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.dataconnection.DcTrackerBase;
6060ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
6160ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.uicc.IccRecords;
6260ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.uicc.SIMRecords;
6360ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.uicc.UiccCardApplication;
6460ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.uicc.UiccController;
6560ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkey
660825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.FileDescriptor;
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.PrintWriter;
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList;
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Arrays;
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Calendar;
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Date;
720825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.TimeZone;
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillefinal class GsmServiceStateTracker extends ServiceStateTracker {
78cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private static final String LOG_TAG = "GsmSST";
79cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private static final boolean VDBG = false;
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    GSMPhone mPhone;
8222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    GsmCellLocation mCellLoc;
8322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    GsmCellLocation mNewCellLoc;
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    int mPreferredNetworkType;
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mMaxDataCalls = 1;
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mNewMaxDataCalls = 1;
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mReasonDataDenied = -1;
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mNewReasonDataDenied = -1;
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * GSM roaming status solely based on TS 27.007 7.2 CREG. Only used by
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * handlePollStateResult to store CREG roaming result.
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mGsmRoaming = false;
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Data roaming status solely based on TS 27.007 10.1.19 CGREG. Only used by
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * handlePollStateResult to store CGREG roaming result.
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mDataRoaming = false;
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Mark when service state is in emergency call only mode
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mEmergencyOnly = false;
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Sometimes we get the NITZ time before we know what country we
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * are in. Keep the time zone information from the NITZ string so
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * we can fix the time zone once know the country.
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mNeedFixZoneAfterNitz = false;
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mZoneOffset;
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mZoneDst;
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private long mZoneTime;
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mGotCountryCode = false;
11822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private ContentResolver mCr;
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Boolean is true is setTimeFromNITZString was called */
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mNitzUpdatedTime = false;
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    String mSavedTimeZone;
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    long mSavedTime;
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    long mSavedAtTime;
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Started the recheck process after finding gprs should registered but not. */
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mStartedGprsRegCheck = false;
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Already sent the event-log for no gprs register. */
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mReportedGprsNoReg = false;
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * The Notification object given to the NotificationManager.
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Notification mNotification;
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Wake lock used while setting time of day. */
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private PowerManager.WakeLock mWakeLock;
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final String WAKELOCK_TAG = "ServiceStateTracker";
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Keep track of SPN display rules, so we only broadcast intent if something changes. */
14322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private String mCurSpn = null;
14422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private String mCurPlmn = null;
14522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private boolean mCurShowPlmn = false;
14622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private boolean mCurShowSpn = false;
14760e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Notification type. */
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int PS_ENABLED = 1001;            // Access Control blocks data service
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int PS_DISABLED = 1002;           // Access Control enables data service
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int CS_ENABLED = 1003;            // Access Control blocks all voice/sms service
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int CS_DISABLED = 1004;           // Access Control enables all voice/sms service
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int CS_NORMAL_ENABLED = 1005;     // Access Control blocks normal voice/sms service
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int CS_EMERGENCY_ENABLED = 1006;  // Access Control blocks emergency call service
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Notification id. */
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int PS_NOTIFICATION = 888;  // Id to update and cancel PS restricted
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int CS_NOTIFICATION = 999;  // Id to update and cancel CS restricted
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        @Override
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        public void onReceive(Context context, Intent intent) {
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (intent.getAction().equals(Intent.ACTION_LOCALE_CHANGED)) {
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // update emergency string whenever locale changed
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                updateSpnDisplay();
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) {
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        @Override
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        public void onChange(boolean selfChange) {
17399c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville            Rlog.i("GsmServiceStateTracker", "Auto time state changed");
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            revertToNitzTime();
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private ContentObserver mAutoTimeZoneObserver = new ContentObserver(new Handler()) {
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        @Override
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        public void onChange(boolean selfChange) {
18199c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville            Rlog.i("GsmServiceStateTracker", "Auto time zone state changed");
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            revertToNitzTimeZone();
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public GsmServiceStateTracker(GSMPhone phone) {
18722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        super(phone, phone.mCi, new CellInfoGsm());
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone = phone;
19022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCellLoc = new GsmCellLocation();
19122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mNewCellLoc = new GsmCellLocation();
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        PowerManager powerManager =
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                (PowerManager)phone.getContext().getSystemService(Context.POWER_SERVICE);
1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG);
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
19722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
19822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForVoiceNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null);
20122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setOnNITZTime(this, EVENT_NITZ_TIME, null);
20222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setOnRestrictedStateChanged(this, EVENT_RESTRICTED_STATE_CHANGED, null);
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // system setting property AIRPLANE_MODE_ON is set in Settings.
205069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate        int airplaneMode = Settings.Global.getInt(
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                phone.getContext().getContentResolver(),
207069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate                Settings.Global.AIRPLANE_MODE_ON, 0);
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDesiredPowerState = ! (airplaneMode > 0);
2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCr = phone.getContext().getContentResolver();
21122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCr.registerContentObserver(
212069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate                Settings.Global.getUriFor(Settings.Global.AUTO_TIME), true,
2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mAutoTimeObserver);
21422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCr.registerContentObserver(
215069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate                Settings.Global.getUriFor(Settings.Global.AUTO_TIME_ZONE), true,
2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mAutoTimeZoneObserver);
2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        setSignalStrengthDefaultValues();
2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Monitor locale change
2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        IntentFilter filter = new IntentFilter();
2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        filter.addAction(Intent.ACTION_LOCALE_CHANGED);
2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.getContext().registerReceiver(mIntentReceiver, filter);
2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Gsm doesn't support OTASP so its not needed
2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.notifyOtaspChanged(OTASP_NOT_NEEDED);
2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
229ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    @Override
2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dispose() {
231e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        checkCorrectThread();
2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Unregister for all events.
23322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unregisterForAvailable(this);
23422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unregisterForRadioStateChanged(this);
23522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unregisterForVoiceNetworkStateChanged(this);
236e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mUiccApplcation != null) {mUiccApplcation.unregisterForReady(this);}
237e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (mIccRecords != null) {mIccRecords.unregisterForRecordsLoaded(this);}
23822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unSetOnRestrictedStateChanged(this);
23922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unSetOnNITZTime(this);
24022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCr.unregisterContentObserver(mAutoTimeObserver);
24122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCr.unregisterContentObserver(mAutoTimeZoneObserver);
24222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.getContext().unregisterReceiver(mIntentReceiver);
243ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        super.dispose();
2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
246cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void finalize() {
2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if(DBG) log("finalize");
2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected Phone getPhone() {
25322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mPhone;
2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
256cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void handleMessage (Message msg) {
2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AsyncResult ar;
2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int[] ints;
2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String[] strings;
2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Message message;
2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
26322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (!mPhone.mIsTheCurrentActivePhone) {
26499c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville            Rlog.e(LOG_TAG, "Received message " + msg +
2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    "[" + msg.what + "] while being destroyed. Ignoring.");
2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (msg.what) {
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RADIO_AVAILABLE:
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                //this is unnecessary
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                //setPowerStateToDesired();
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SIM_READY:
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Set the network type, in case the radio does not restore it.
27622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.setCurrentPreferredNetworkType();
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
27822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                boolean skipRestoringSelection = mPhone.getContext().getResources().getBoolean(
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        com.android.internal.R.bool.skip_restoring_network_selection);
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!skipRestoringSelection) {
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // restore the previous network selection.
28322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPhone.restoreSavedNetworkSelection(null);
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollState();
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Signal strength polling stops when radio is off
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                queueNextSignalStrengthPoll();
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RADIO_STATE_CHANGED:
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // This will do nothing in the radio not
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // available case
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setPowerStateToDesired();
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollState();
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_NETWORK_STATE_CHANGED:
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollState();
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_GET_SIGNAL_STRENGTH:
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // This callback is called when signal strength is polled
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // all by itself
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
30522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (!(mCi.getRadioState().isOn())) {
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Polling will continue when radio turns back on
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return;
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
310e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville                onSignalStrengthResult(ar, true);
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                queueNextSignalStrengthPoll();
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_GET_LOC_DONE:
3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception == null) {
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    String states[] = (String[])ar.result;
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int lac = -1;
3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int cid = -1;
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (states.length >= 3) {
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        try {
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states[1] != null && states[1].length() > 0) {
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                lac = Integer.parseInt(states[1], 16);
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states[2] != null && states[2].length() > 0) {
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                cid = Integer.parseInt(states[2], 16);
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        } catch (NumberFormatException ex) {
33199c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                            Rlog.w(LOG_TAG, "error parsing location: " + ex);
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
33422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mCellLoc.setLacAndCid(lac, cid);
33522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPhone.notifyLocationChanged();
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Release any temporary cell lock, which could have been
3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // acquired to allow a single-shot location update.
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                disableSingleLocationUpdate();
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_STATE_REGISTRATION:
3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_STATE_GPRS:
3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_STATE_OPERATOR:
3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_STATE_NETWORK_SELECTION_MODE:
3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                handlePollStateResult(msg.what, ar);
3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_SIGNAL_STRENGTH:
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Just poll signal strength...not part of pollState()
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
35522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_NITZ_TIME:
3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                String nitzString = (String)((Object[])ar.result)[0];
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                long nitzReceiveTime = ((Long)((Object[])ar.result)[1]).longValue();
3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setTimeFromNITZString(nitzString, nitzReceiveTime);
3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SIGNAL_STRENGTH_UPDATE:
3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // This is a notification from
3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // CommandsInterface.setOnSignalStrengthUpdate
3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // The radio is telling us about signal strength changes
3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // we don't have to ask it
37522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mDontPollSignalStrength = true;
3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
377e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville                onSignalStrengthResult(ar, true);
3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SIM_RECORDS_LOADED:
3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                updateSpnDisplay();
3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_LOCATION_UPDATES_ENABLED:
3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception == null) {
38822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mCi.getVoiceRegistrationState(obtainMessage(EVENT_GET_LOC_DONE, null));
3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SET_PREFERRED_NETWORK_TYPE:
3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Don't care the result, only use for dereg network (COPS=2)
3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                message = obtainMessage(EVENT_RESET_PREFERRED_NETWORK_TYPE, ar.userObj);
39622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.setPreferredNetworkType(mPreferredNetworkType, message);
3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RESET_PREFERRED_NETWORK_TYPE:
4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.userObj != null) {
4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    AsyncResult.forMessage(((Message) ar.userObj)).exception
4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            = ar.exception;
4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ((Message) ar.userObj).sendToTarget();
4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_GET_PREFERRED_NETWORK_TYPE:
4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception == null) {
4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mPreferredNetworkType = ((int[])ar.result)[0];
4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mPreferredNetworkType = RILConstants.NETWORK_MODE_GLOBAL;
4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                message = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE, ar.userObj);
4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                int toggledNetworkType = RILConstants.NETWORK_MODE_GLOBAL;
4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
42022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.setPreferredNetworkType(toggledNetworkType, message);
4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_CHECK_REPORT_GPRS:
42422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (mSS != null && !isGprsConsistent(mSS.getDataRegState(), mSS.getVoiceRegState())) {
4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Can't register data service while voice service is ok
4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // i.e. CREG is ok while CGREG is not
4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // possible a network or baseband side error
42922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    GsmCellLocation loc = ((GsmCellLocation)mPhone.getCellLocation());
4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    EventLog.writeEvent(EventLogTags.DATA_NETWORK_REGISTRATION_FAIL,
43122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            mSS.getOperatorNumeric(), loc != null ? loc.getCid() : -1);
4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mReportedGprsNoReg = true;
4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mStartedGprsRegCheck = false;
4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RESTRICTED_STATE_CHANGED:
4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // This is a notification from
4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // CommandsInterface.setOnRestrictedStateChanged
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("EVENT_RESTRICTED_STATE_CHANGED");
4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                onRestrictedStateChanged(ar);
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                super.handleMessage(msg);
4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
454cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void setPowerStateToDesired() {
4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If we want it on and it's off, turn it on
4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mDesiredPowerState
45822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            && mCi.getRadioState() == CommandsInterface.RadioState.RADIO_OFF) {
45922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.setRadioPower(true, null);
46022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (!mDesiredPowerState && mCi.getRadioState().isOn()) {
4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // If it's on and available and we want it off gracefully
462454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcTrackerBase dcTracker = mPhone.mDcTracker;
4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            powerOffRadioSafely(dcTracker);
4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } // Otherwise, we're in the desired state
4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void hangupAndPowerOff() {
4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // hang up all active voice calls
47022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPhone.isInCall()) {
47122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.mCT.mRingingCall.hangupIfAlive();
47222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.mCT.mBackgroundCall.hangupIfAlive();
47322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.mCT.mForegroundCall.hangupIfAlive();
4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
47622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setRadioPower(false, null);
4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
479f7a8133113daddcc48a41e451193afd3fcb35e16Wink Saville    @Override
4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void updateSpnDisplay() {
48160e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        // The values of plmn/showPlmn change in different scenarios.
48260e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        // 1) No service but emergency call allowed -> expected
48360e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    to show "Emergency call only"
48460e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_SHOW_PLMN = true
48560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_PLMN = "Emergency call only"
48660e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang
48760e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        // 2) No service at all --> expected to show "No service"
48860e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_SHOW_PLMN = true
48960e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_PLMN = "No service"
49060e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang
49160e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        // 3) Normal operation in either home or roaming service
49260e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_SHOW_PLMN = depending on IccRecords rule
49360e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_PLMN = plmn
49460e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang
49560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        // 4) No service due to power off, aka airplane mode
49660e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_SHOW_PLMN = false
49760e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_PLMN = null
49860e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang
499f7a8133113daddcc48a41e451193afd3fcb35e16Wink Saville        IccRecords iccRecords = mIccRecords;
50060e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        String plmn = null;
50160e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        boolean showPlmn = false;
50222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        int rule = (iccRecords != null) ? iccRecords.getDisplayRule(mSS.getOperatorNumeric()) : 0;
50322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mSS.getVoiceRegState() == ServiceState.STATE_OUT_OF_SERVICE
50422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                || mSS.getVoiceRegState() == ServiceState.STATE_EMERGENCY_ONLY) {
50560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            showPlmn = true;
50660e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            if (mEmergencyOnly) {
50760e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                // No service but emergency call allowed
50860e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                plmn = Resources.getSystem().
50960e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                        getText(com.android.internal.R.string.emergency_calls_only).toString();
51060e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            } else {
51160e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                // No service at all
51260e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                plmn = Resources.getSystem().
51360e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                        getText(com.android.internal.R.string.lockscreen_carrier_default).toString();
51460e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            }
51560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            if (DBG) log("updateSpnDisplay: radio is on but out " +
51660e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                    "of service, set plmn='" + plmn + "'");
51722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE) {
51860e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            // In either home or roaming service
51922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            plmn = mSS.getOperatorAlphaLong();
52060e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            showPlmn = !TextUtils.isEmpty(plmn) &&
52160e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                    ((rule & SIMRecords.SPN_RULE_SHOW_PLMN)
52260e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                            == SIMRecords.SPN_RULE_SHOW_PLMN);
52360e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        } else {
52460e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            // Power off state, such as airplane mode
52560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            if (DBG) log("updateSpnDisplay: radio is off w/ showPlmn="
52660e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                    + showPlmn + " plmn=" + plmn);
5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
52960e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        // The value of spn/showSpn are same in different scenarios.
53060e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_SHOW_SPN = depending on IccRecords rule
53160e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_SPN = spn
532f7a8133113daddcc48a41e451193afd3fcb35e16Wink Saville        String spn = (iccRecords != null) ? iccRecords.getServiceProviderName() : "";
53360e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        boolean showSpn = !TextUtils.isEmpty(spn)
53460e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                && ((rule & SIMRecords.SPN_RULE_SHOW_SPN)
53560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                        == SIMRecords.SPN_RULE_SHOW_SPN);
53660e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang
53760e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        // Update SPN_STRINGS_UPDATED_ACTION IFF any value changes
53822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (showPlmn != mCurShowPlmn
53922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                || showSpn != mCurShowSpn
54022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                || !TextUtils.equals(spn, mCurSpn)
54122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                || !TextUtils.equals(plmn, mCurPlmn)) {
5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
54360e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                log(String.format("updateSpnDisplay: changed" +
54460e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                        " sending intent rule=" + rule +
54560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                        " showPlmn='%b' plmn='%s' showSpn='%b' spn='%s'",
54660e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                        showPlmn, plmn, showSpn, spn));
5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Intent intent = new Intent(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
5500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            intent.putExtra(TelephonyIntents.EXTRA_SHOW_SPN, showSpn);
5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            intent.putExtra(TelephonyIntents.EXTRA_SPN, spn);
5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            intent.putExtra(TelephonyIntents.EXTRA_SHOW_PLMN, showPlmn);
5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            intent.putExtra(TelephonyIntents.EXTRA_PLMN, plmn);
55422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.getContext().sendStickyBroadcastAsUser(intent, UserHandle.ALL);
5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
55722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCurShowSpn = showSpn;
55822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCurShowPlmn = showPlmn;
55922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCurSpn = spn;
56022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCurPlmn = plmn;
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Handle the result of one of the pollState()-related requests
5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
566f92cb4bd5519427a0db673709d94683a8baf203aWink Saville    @Override
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void handlePollStateResult (int what, AsyncResult ar) {
5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int ints[];
5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String states[];
5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Ignore stale requests from last poll
57222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (ar.userObj != mPollingContext) return;
5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ar.exception != null) {
5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CommandException.Error err=null;
5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (ar.exception instanceof CommandException) {
5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                err = ((CommandException)(ar.exception)).getCommandError();
5790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (err == CommandException.Error.RADIO_NOT_AVAILABLE) {
5820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Radio has crashed or turned off
5830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cancelPollState();
5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
58722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (!mCi.getRadioState().isOn()) {
5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Radio has crashed or turned off
5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cancelPollState();
5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) {
5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                loge("RIL implementation has returned an error where it must succeed" +
5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ar.exception);
5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else try {
5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            switch (what) {
599f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                case EVENT_POLL_STATE_REGISTRATION: {
6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    states = (String[])ar.result;
6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int lac = -1;
6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int cid = -1;
603f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    int type = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
604f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    int regState = ServiceState.RIL_REG_STATE_UNKNOWN;
6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int reasonRegStateDenied = -1;
6060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int psc = -1;
6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (states.length > 0) {
6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        try {
6090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            regState = Integer.parseInt(states[0]);
6100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states.length >= 3) {
6110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (states[1] != null && states[1].length() > 0) {
6120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    lac = Integer.parseInt(states[1], 16);
6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
6140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (states[2] != null && states[2].length() > 0) {
6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    cid = Integer.parseInt(states[2], 16);
6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
617f92cb4bd5519427a0db673709d94683a8baf203aWink Saville
618f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                                // states[3] (if present) is the current radio technology
619f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                                if (states.length >= 4 && states[3] != null) {
620f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                                    type = Integer.parseInt(states[3]);
621f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                                }
6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
6230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states.length > 14) {
6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (states[14] != null && states[14].length() > 0) {
6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    psc = Integer.parseInt(states[14], 16);
6260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
6270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
6280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        } catch (NumberFormatException ex) {
6290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            loge("error parsing RegistrationState: " + ex);
6300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
6310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
6320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mGsmRoaming = regCodeIsRoaming(regState);
63422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewSS.setState(regCodeToServiceState(regState));
63522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewSS.setRilVoiceRadioTechnology(type);
6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
637f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    if (regState == ServiceState.RIL_REG_STATE_DENIED_EMERGENCY_CALL_ENABLED
638f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                         || regState == ServiceState.RIL_REG_STATE_NOT_REG_EMERGENCY_CALL_ENABLED
639f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                         || regState == ServiceState.RIL_REG_STATE_SEARCHING_EMERGENCY_CALL_ENABLED
640f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                         || regState == ServiceState.RIL_REG_STATE_UNKNOWN_EMERGENCY_CALL_ENABLED) {
6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mEmergencyOnly = true;
6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mEmergencyOnly = false;
6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // LAC and CID are -1 if not avail
64722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewCellLoc.setLacAndCid(lac, cid);
64822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewCellLoc.setPsc(psc);
649f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    break;
650f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                }
6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
652f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                case EVENT_POLL_STATE_GPRS: {
6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    states = (String[])ar.result;
6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int type = 0;
656f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    int regState = ServiceState.RIL_REG_STATE_UNKNOWN;
6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mNewReasonDataDenied = -1;
6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mNewMaxDataCalls = 1;
6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (states.length > 0) {
6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        try {
6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            regState = Integer.parseInt(states[0]);
6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            // states[3] (if present) is the current radio technology
6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states.length >= 4 && states[3] != null) {
6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                type = Integer.parseInt(states[3]);
6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
667f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                            if ((states.length >= 5 ) &&
668f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                                    (regState == ServiceState.RIL_REG_STATE_DENIED)) {
6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                mNewReasonDataDenied = Integer.parseInt(states[4]);
6700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
6710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states.length >= 6) {
6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                mNewMaxDataCalls = Integer.parseInt(states[5]);
6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        } catch (NumberFormatException ex) {
6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            loge("error parsing GprsRegistrationState: " + ex);
6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
6770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
678f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    int dataRegState = regCodeToServiceState(regState);
67922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewSS.setDataRegState(dataRegState);
6800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mDataRoaming = regCodeIsRoaming(regState);
68122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewSS.setRilDataRadioTechnology(type);
682f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    if (DBG) {
683f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                        log("handlPollStateResultMessage: GsmSST setDataRegState=" + dataRegState
684f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                                + " regState=" + regState
685f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                                + " dataRadioTechnology=" + type);
686f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    }
687f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    break;
688f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                }
6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
690f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                case EVENT_POLL_STATE_OPERATOR: {
6910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    String opNames[] = (String[])ar.result;
6920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (opNames != null && opNames.length >= 3) {
69422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                         mNewSS.setOperatorName (opNames[0], opNames[1], opNames[2]);
6950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
696f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    break;
697f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                }
6980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
699f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                case EVENT_POLL_STATE_NETWORK_SELECTION_MODE: {
7000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ints = (int[])ar.result;
70122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewSS.setIsManualSelection(ints[0] == 1);
702f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    break;
703f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                }
7040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (RuntimeException ex) {
7070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("Exception while polling service state. Probably malformed RIL response." + ex);
7080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
71022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPollingContext[0]--;
7110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
71222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPollingContext[0] == 0) {
7130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            /**
7140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             *  Since the roaming states of gsm service (from +CREG) and
7150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             *  data service (from +CGREG) could be different, the new SS
7160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             *  is set roaming while either one is roaming.
7170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             *
7180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             *  There is an exception for the above rule. The new SS is not set
7190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             *  as roaming while gsm service reports roaming but indeed it is
7200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             *  not roaming between operators.
7210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             */
7220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            boolean roaming = (mGsmRoaming || mDataRoaming);
72322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (mGsmRoaming && !isRoamingBetweenOperators(mGsmRoaming, mNewSS)) {
7240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                roaming = false;
7250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
72622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mNewSS.setRoaming(roaming);
72722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mNewSS.setEmergencyOnly(mEmergencyOnly);
7280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pollStateDone();
7290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
732c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void setSignalStrengthDefaultValues() {
7335b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        mSignalStrength = new SignalStrength(true);
7340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
7370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * A complete "service state" from our perspective is
7380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * composed of a handful of separate requests to the radio.
7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
7400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * We make all of these requests at once, but then abandon them
7410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * and start over again if the radio notifies us that some
7420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * event has changed
7430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
7440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void pollState() {
74522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPollingContext = new int[1];
74622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPollingContext[0] = 0;
7470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
74822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        switch (mCi.getRadioState()) {
7490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case RADIO_UNAVAILABLE:
75022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mNewSS.setStateOutOfService();
75122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mNewCellLoc.setStateInvalid();
7520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setSignalStrengthDefaultValues();
7530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mGotCountryCode = false;
7540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNitzUpdatedTime = false;
7550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollStateDone();
7560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
7570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case RADIO_OFF:
75922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mNewSS.setStateOff();
76022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mNewCellLoc.setStateInvalid();
7610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setSignalStrengthDefaultValues();
7620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mGotCountryCode = false;
7630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNitzUpdatedTime = false;
7640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollStateDone();
7650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
7660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
7680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Issue all poll-related commands at once
7690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // then count down the responses, which
7700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // are allowed to arrive out-of-order
7710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
77222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPollingContext[0]++;
77322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.getOperator(
7740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    obtainMessage(
77522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        EVENT_POLL_STATE_OPERATOR, mPollingContext));
7760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
77722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPollingContext[0]++;
77822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.getDataRegistrationState(
7790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    obtainMessage(
78022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        EVENT_POLL_STATE_GPRS, mPollingContext));
7810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
78222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPollingContext[0]++;
78322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.getVoiceRegistrationState(
7840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    obtainMessage(
78522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        EVENT_POLL_STATE_REGISTRATION, mPollingContext));
7860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
78722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPollingContext[0]++;
78822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.getNetworkSelectionMode(
7890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    obtainMessage(
79022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        EVENT_POLL_STATE_NETWORK_SELECTION_MODE, mPollingContext));
7910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
7920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void pollStateDone() {
7960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
7970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("Poll ServiceState done: " +
79822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                " oldSS=[" + mSS + "] newSS=[" + mNewSS + "]" +
7990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                " oldMaxDataCalls=" + mMaxDataCalls +
8000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                " mNewMaxDataCalls=" + mNewMaxDataCalls +
8010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                " oldReasonDataDenied=" + mReasonDataDenied +
802f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                " mNewReasonDataDenied=" + mNewReasonDataDenied);
8030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
80560ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkey        if (Build.IS_DEBUGGABLE && SystemProperties.getBoolean(PROP_FORCE_ROAMING, false)) {
80660ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkey            mNewSS.setRoaming(true);
80760ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkey        }
80860ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkey
8090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasRegistered =
81022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mSS.getVoiceRegState() != ServiceState.STATE_IN_SERVICE
81122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            && mNewSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE;
8120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasDeregistered =
81422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE
81522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            && mNewSS.getVoiceRegState() != ServiceState.STATE_IN_SERVICE;
8160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasGprsAttached =
81822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSS.getDataRegState() != ServiceState.STATE_IN_SERVICE
81922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && mNewSS.getDataRegState() == ServiceState.STATE_IN_SERVICE;
8200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasGprsDetached =
82222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSS.getDataRegState() == ServiceState.STATE_IN_SERVICE
82322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && mNewSS.getDataRegState() != ServiceState.STATE_IN_SERVICE;
8240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
825f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        boolean hasRilVoiceRadioTechnologyChanged =
82622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSS.getRilVoiceRadioTechnology() != mNewSS.getRilVoiceRadioTechnology();
8270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
82822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        boolean hasChanged = !mNewSS.equals(mSS);
8290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
83022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        boolean hasRoamingOn = !mSS.getRoaming() && mNewSS.getRoaming();
8310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
83222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        boolean hasRoamingOff = mSS.getRoaming() && !mNewSS.getRoaming();
8330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
83422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        boolean hasLocationChanged = !mNewCellLoc.equals(mCellLoc);
8350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Add an event log when connection state changes
83722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mSS.getVoiceRegState() != mNewSS.getVoiceRegState()
83822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                || mSS.getDataRegState() != mNewSS.getDataRegState()) {
8390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            EventLog.writeEvent(EventLogTags.GSM_SERVICE_STATE_CHANGE,
84022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSS.getVoiceRegState(), mSS.getDataRegState(),
84122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mNewSS.getVoiceRegState(), mNewSS.getDataRegState());
8420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ServiceState tss;
84522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        tss = mSS;
84622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mSS = mNewSS;
84722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mNewSS = tss;
8480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // clean slate for next time
84922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mNewSS.setStateOutOfService();
8500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
85122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        GsmCellLocation tcl = mCellLoc;
85222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCellLoc = mNewCellLoc;
85322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mNewCellLoc = tcl;
8540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Add an event log when network type switched
8560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // TODO: we may add filtering to reduce the event logged,
8570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // i.e. check preferred network setting, only switch to 2G, etc
858f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        if (hasRilVoiceRadioTechnologyChanged) {
8590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int cid = -1;
86022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            GsmCellLocation loc = ((GsmCellLocation)mPhone.getCellLocation());
8610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (loc != null) cid = loc.getCid();
86222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            EventLog.writeEvent(EventLogTags.GSM_RAT_SWITCHED, cid, mSS.getRilVoiceRadioTechnology(),
86322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewSS.getRilVoiceRadioTechnology());
8640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
865f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                log("RAT switched "
86622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        + ServiceState.rilRadioTechnologyToString(mSS.getRilVoiceRadioTechnology())
867f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                        + " -> "
86822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        + ServiceState.rilRadioTechnologyToString(mNewSS.getRilVoiceRadioTechnology()) +
8690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        " at cell " + cid);
8700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mReasonDataDenied = mNewReasonDataDenied;
8740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mMaxDataCalls = mNewMaxDataCalls;
8750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
87622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mNewSS.setStateOutOfService(); // clean slate for next time
8770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
878f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        if (hasRilVoiceRadioTechnologyChanged) {
87922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
88022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    ServiceState.rilRadioTechnologyToString(mSS.getRilVoiceRadioTechnology()));
8810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasRegistered) {
8840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mNetworkAttachedRegistrants.notifyRegistrants();
8850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
8870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("pollStateDone: registering current mNitzUpdatedTime=" +
8880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mNitzUpdatedTime + " changing to false");
8890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mNitzUpdatedTime = false;
8910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasChanged) {
8940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String operatorNumeric;
8950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            updateSpnDisplay();
8970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
89822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
89922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSS.getOperatorAlphaLong());
9000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String prevOperatorNumeric =
9020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, "");
90322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            operatorNumeric = mSS.getOperatorNumeric();
90422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
9050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (operatorNumeric == null) {
9070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("operatorNumeric is null");
90822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
9090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mGotCountryCode = false;
9100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNitzUpdatedTime = false;
9110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
9120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                String iso = "";
9137c491bb3d140e2579c2c01edca94305701664db5Rekha Kumar                String mcc = "";
9140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                try{
9157c491bb3d140e2579c2c01edca94305701664db5Rekha Kumar                    mcc = operatorNumeric.substring(0, 3);
9160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    iso = MccTable.countryCodeForMcc(Integer.parseInt(mcc));
9170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } catch ( NumberFormatException ex){
9180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    loge("pollStateDone: countryCodeForMcc error" + ex);
9190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } catch ( StringIndexOutOfBoundsException ex) {
9200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    loge("pollStateDone: countryCodeForMcc error" + ex);
9210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
92322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, iso);
9240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mGotCountryCode = true;
9250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                TimeZone zone = null;
9270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!mNitzUpdatedTime && !mcc.equals("000") && !TextUtils.isEmpty(iso) &&
9290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        getAutoTimeZone()) {
9300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Test both paths if ignore nitz is true
9320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    boolean testOneUniqueOffsetPath = SystemProperties.getBoolean(
9330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                TelephonyProperties.PROPERTY_IGNORE_NITZ, false) &&
9340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    ((SystemClock.uptimeMillis() & 1) == 0);
9350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ArrayList<TimeZone> uniqueZones = TimeUtils.getTimeZonesWithUniqueOffsets(iso);
9370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if ((uniqueZones.size() == 1) || testOneUniqueOffsetPath) {
9380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = uniqueZones.get(0);
9390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) {
9400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                           log("pollStateDone: no nitz but one TZ for iso-cc=" + iso +
9410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                   " with zone.getID=" + zone.getID() +
9420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                   " testOneUniqueOffsetPath=" + testOneUniqueOffsetPath);
9430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
9440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        setAndBroadcastNetworkSetTimeZone(zone.getID());
9450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
9460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) {
9470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            log("pollStateDone: there are " + uniqueZones.size() +
9480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                " unique offsets for iso-cc='" + iso +
9490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                " testOneUniqueOffsetPath=" + testOneUniqueOffsetPath +
9500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                "', do nothing");
9510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
9520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
9530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
95522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (shouldFixTimeZoneNow(mPhone, operatorNumeric, prevOperatorNumeric,
9560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mNeedFixZoneAfterNitz)) {
9570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // If the offset is (0, false) and the timezone property
9580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // is set, use the timezone property rather than
9590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // GMT.
9600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    String zoneName = SystemProperties.get(TIMEZONE_PROPERTY);
9610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) {
9620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("pollStateDone: fix time zone zoneName='" + zoneName +
9630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "' mZoneOffset=" + mZoneOffset + " mZoneDst=" + mZoneDst +
9640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            " iso-cc='" + iso +
9650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "' iso-cc-idx=" + Arrays.binarySearch(GMT_COUNTRY_CODES, iso));
9660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
9670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // "(mZoneOffset == 0) && (mZoneDst == false) &&
9690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    //  (Arrays.binarySearch(GMT_COUNTRY_CODES, iso) < 0)"
9700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // means that we received a NITZ string telling
9710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // it is in GMT+0 w/ DST time zone
9720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // BUT iso tells is NOT, e.g, a wrong NITZ reporting
9730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // local time w/ 0 offset.
9740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if ((mZoneOffset == 0) && (mZoneDst == false) &&
9750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        (zoneName != null) && (zoneName.length() > 0) &&
9760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        (Arrays.binarySearch(GMT_COUNTRY_CODES, iso) < 0)) {
9770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = TimeZone.getDefault();
9780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (mNeedFixZoneAfterNitz) {
9790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            // For wrong NITZ reporting local time w/ 0 offset,
9800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            // need adjust time to reflect default timezone setting
9810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            long ctm = System.currentTimeMillis();
9820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            long tzOffset = zone.getOffset(ctm);
9830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (DBG) {
9840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                log("pollStateDone: tzOffset=" + tzOffset + " ltod=" +
9850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        TimeUtils.logTimeOfDay(ctm));
9860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
9870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (getAutoTime()) {
9880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                long adj = ctm - tzOffset;
9890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (DBG) log("pollStateDone: adj ltod=" +
9900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        TimeUtils.logTimeOfDay(adj));
9910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                setAndBroadcastNetworkSetTime(adj);
9920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            } else {
9930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                // Adjust the saved NITZ time to account for tzOffset.
9940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                mSavedTime = mSavedTime - tzOffset;
9950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
9960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
9970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("pollStateDone: using default TimeZone");
9980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else if (iso.equals("")){
9990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Country code not found.  This is likely a test network.
10000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Get a TimeZone based only on the NITZ parameters (best guess).
10010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = getNitzTimeZone(mZoneOffset, mZoneDst, mZoneTime);
10020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("pollStateDone: using NITZ TimeZone");
10030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
10040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = TimeUtils.getTimeZone(mZoneOffset, mZoneDst, mZoneTime, iso);
10050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("pollStateDone: using getTimeZone(off, dst, time, iso)");
10060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
10070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mNeedFixZoneAfterNitz = false;
10090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (zone != null) {
10110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("pollStateDone: zone != null zone.getID=" + zone.getID());
10120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (getAutoTimeZone()) {
10130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            setAndBroadcastNetworkSetTimeZone(zone.getID());
10140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
10150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        saveNitzTimeZone(zone.getID());
10160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
10170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("pollStateDone: zone == null");
10180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
10190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
10200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
10210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
102222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
102322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSS.getRoaming() ? "true" : "false");
10240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
102522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyServiceStateChanged(mSS);
10260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasGprsAttached) {
10290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mAttachedRegistrants.notifyRegistrants();
10300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasGprsDetached) {
10330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mDetachedRegistrants.notifyRegistrants();
10340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1036f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        if (hasRilVoiceRadioTechnologyChanged) {
103722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyDataConnection(Phone.REASON_NW_TYPE_CHANGED);
10380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasRoamingOn) {
10410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mRoamingOnRegistrants.notifyRegistrants();
10420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasRoamingOff) {
10450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mRoamingOffRegistrants.notifyRegistrants();
10460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasLocationChanged) {
104922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyLocationChanged();
10500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
105222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (! isGprsConsistent(mSS.getDataRegState(), mSS.getVoiceRegState())) {
10530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!mStartedGprsRegCheck && !mReportedGprsNoReg) {
10540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mStartedGprsRegCheck = true;
10550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1056b840987a39e7149c1364739696977089cd53814dWink Saville                int check_period = Settings.Global.getInt(
105722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mPhone.getContext().getContentResolver(),
1058b840987a39e7149c1364739696977089cd53814dWink Saville                        Settings.Global.GPRS_REGISTER_CHECK_PERIOD_MS,
10590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        DEFAULT_GPRS_CHECK_PERIOD_MILLIS);
10600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                sendMessageDelayed(obtainMessage(EVENT_CHECK_REPORT_GPRS),
10610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        check_period);
10620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
10630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
10640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mReportedGprsNoReg = false;
10650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1066ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        // TODO: Add GsmCellIdenity updating, see CdmaLteServiceStateTracker.
10670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
10700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Check if GPRS got registered while voice is registered.
10710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
1072cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param dataRegState i.e. CGREG in GSM
1073cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param voiceRegState i.e. CREG in GSM
10740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return false if device only register to voice but not gprs
10750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1076f92cb4bd5519427a0db673709d94683a8baf203aWink Saville    private boolean isGprsConsistent(int dataRegState, int voiceRegState) {
1077f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        return !((voiceRegState == ServiceState.STATE_IN_SERVICE) &&
1078f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                (dataRegState != ServiceState.STATE_IN_SERVICE));
10790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
10820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Returns a TimeZone object based only on parameters from the NITZ string.
10830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
10840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private TimeZone getNitzTimeZone(int offset, boolean dst, long when) {
10850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        TimeZone guess = findTimeZone(offset, dst, when);
10860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (guess == null) {
10870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Couldn't find a proper timezone.  Perhaps the DST data is wrong.
10880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            guess = findTimeZone(offset, !dst, when);
10890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("getNitzTimeZone returning " + (guess == null ? guess : guess.getID()));
10910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return guess;
10920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private TimeZone findTimeZone(int offset, boolean dst, long when) {
10950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int rawOffset = offset;
10960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (dst) {
10970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            rawOffset -= 3600000;
10980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String[] zones = TimeZone.getAvailableIDs(rawOffset);
11000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        TimeZone guess = null;
11010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Date d = new Date(when);
11020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (String zone : zones) {
11030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            TimeZone tz = TimeZone.getTimeZone(zone);
11040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (tz.getOffset(when) == offset &&
11050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                tz.inDaylightTime(d) == dst) {
11060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                guess = tz;
11070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
11080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return guess;
11120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void queueNextSignalStrengthPoll() {
111522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mDontPollSignalStrength) {
11160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // The radio is telling us about signal strength changes
11170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // we don't have to ask it
11180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
11190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Message msg;
11220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        msg = obtainMessage();
11240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        msg.what = EVENT_POLL_SIGNAL_STRENGTH;
11250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        long nextTime;
11270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // TODO Don't poll signal strength if screen is off
11290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        sendMessageDelayed(msg, POLL_PERIOD_MILLIS);
11300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Set restricted state based on the OnRestrictedStateChanged notification
11340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * If any voice or packet restricted state changes, trigger a UI
11350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * notification and notify registrants when sim is ready.
11360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
11370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param ar an int value of RIL_RESTRICTED_STATE_*
11380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void onRestrictedStateChanged(AsyncResult ar) {
11400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        RestrictedState newRs = new RestrictedState();
11410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onRestrictedStateChanged: E rs "+ mRestrictedState);
11430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ar.exception == null) {
11450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int[] ints = (int[])ar.result;
11460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int state = ints[0];
11470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            newRs.setCsEmergencyRestricted(
11490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ((state & RILConstants.RIL_RESTRICTED_STATE_CS_EMERGENCY) != 0) ||
11500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
11510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //ignore the normal call and data restricted state before SIM READY
1152e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mUiccApplcation != null && mUiccApplcation.getState() == AppState.APPSTATE_READY) {
11530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                newRs.setCsNormalRestricted(
11540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ((state & RILConstants.RIL_RESTRICTED_STATE_CS_NORMAL) != 0) ||
11550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
11560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                newRs.setPsRestricted(
11570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        (state & RILConstants.RIL_RESTRICTED_STATE_PS_ALL)!= 0);
11580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("onRestrictedStateChanged: new rs "+ newRs);
11610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!mRestrictedState.isPsRestricted() && newRs.isPsRestricted()) {
11630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPsRestrictEnabledRegistrants.notifyRegistrants();
11640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setNotification(PS_ENABLED);
11650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (mRestrictedState.isPsRestricted() && !newRs.isPsRestricted()) {
11660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPsRestrictDisabledRegistrants.notifyRegistrants();
11670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setNotification(PS_DISABLED);
11680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            /**
11710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             * There are two kind of cs restriction, normal and emergency. So
11720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             * there are 4 x 4 combinations in current and new restricted states
11730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             * and we only need to notify when state is changed.
11740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             */
11750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mRestrictedState.isCsRestricted()) {
11760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!newRs.isCsRestricted()) {
11770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove all restriction
11780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_DISABLED);
11790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (!newRs.isCsNormalRestricted()) {
11800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove normal restriction
11810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_EMERGENCY_ENABLED);
11820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (!newRs.isCsEmergencyRestricted()) {
11830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove emergency restriction
11840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_NORMAL_ENABLED);
11850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
11860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (mRestrictedState.isCsEmergencyRestricted() &&
11870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    !mRestrictedState.isCsNormalRestricted()) {
11880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!newRs.isCsRestricted()) {
11890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove all restriction
11900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_DISABLED);
11910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsRestricted()) {
11920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // enable all restriction
11930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_ENABLED);
11940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsNormalRestricted()) {
11950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove emergency restriction and enable normal restriction
11960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_NORMAL_ENABLED);
11970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
11980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (!mRestrictedState.isCsEmergencyRestricted() &&
11990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mRestrictedState.isCsNormalRestricted()) {
12000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!newRs.isCsRestricted()) {
12010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove all restriction
12020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_DISABLED);
12030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsRestricted()) {
12040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // enable all restriction
12050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_ENABLED);
12060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsEmergencyRestricted()) {
12070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove normal restriction and enable emergency restriction
12080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_EMERGENCY_ENABLED);
12090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
12100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
12110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (newRs.isCsRestricted()) {
12120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // enable all restriction
12130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_ENABLED);
12140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsEmergencyRestricted()) {
12150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // enable emergency restriction
12160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_EMERGENCY_ENABLED);
12170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsNormalRestricted()) {
12180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // enable normal restriction
12190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_NORMAL_ENABLED);
12200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
12210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
12220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mRestrictedState = newRs;
12240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        log("onRestrictedStateChanged: X rs "+ mRestrictedState);
12260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** code is registration state 0-5 from TS 27.007 7.2 */
12290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int regCodeToServiceState(int code) {
12300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (code) {
12310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 0:
12320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 2: // 2 is "searching"
12330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 3: // 3 is "registration denied"
12340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 4: // 4 is "unknown" no vaild in current baseband
12350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 10:// same as 0, but indicates that emergency call is possible.
12360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 12:// same as 2, but indicates that emergency call is possible.
12370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 13:// same as 3, but indicates that emergency call is possible.
12380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 14:// same as 4, but indicates that emergency call is possible.
12390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return ServiceState.STATE_OUT_OF_SERVICE;
12400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 1:
12420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return ServiceState.STATE_IN_SERVICE;
12430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 5:
12450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // in service, roam
12460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return ServiceState.STATE_IN_SERVICE;
12470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
12490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                loge("regCodeToServiceState: unexpected service state " + code);
12500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return ServiceState.STATE_OUT_OF_SERVICE;
12510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * code is registration state 0-5 from TS 27.007 7.2
12570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * returns true if registered roam, false otherwise
12580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean regCodeIsRoaming (int code) {
1260f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        return ServiceState.RIL_REG_STATE_ROAMING == code;
12610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Set roaming state when gsmRoaming is true and, if operator mcc is the
12650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * same as sim mcc, ons is different from spn
12660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param gsmRoaming TS 27.007 7.2 CREG registered roaming
12670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param s ServiceState hold current ons
12680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true for roaming state set
12690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean isRoamingBetweenOperators(boolean gsmRoaming, ServiceState s) {
12710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String spn = SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, "empty");
12720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String onsl = s.getOperatorAlphaLong();
12740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String onss = s.getOperatorAlphaShort();
12750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean equalsOnsl = onsl != null && spn.equals(onsl);
12770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean equalsOnss = onss != null && spn.equals(onss);
12780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String simNumeric = SystemProperties.get(
12800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "");
12810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String  operatorNumeric = s.getOperatorNumeric();
12820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean equalsMcc = true;
12840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
12850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            equalsMcc = simNumeric.substring(0, 3).
12860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    equals(operatorNumeric.substring(0, 3));
12870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (Exception e){
12880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return gsmRoaming && !(equalsMcc && (equalsOnsl || equalsOnss));
12910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return The current GPRS state. IN_SERVICE is the same as "attached"
12950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * and OUT_OF_SERVICE is the same as detached.
12960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1297f92cb4bd5519427a0db673709d94683a8baf203aWink Saville    @Override
12980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public int getCurrentDataConnectionState() {
129922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mSS.getDataRegState();
13000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
13010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
13030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if phone is camping on a technology (eg UMTS)
13040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * that could support voice and data simultaneously.
13050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1306cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
13070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean isConcurrentVoiceAndDataAllowed() {
130822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return (mSS.getRilVoiceRadioTechnology() >= ServiceState.RIL_RADIO_TECHNOLOGY_UMTS);
13090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
13100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
13120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * nitzReceiveTime is time_t that the NITZ time was posted
13130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
13140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void setTimeFromNITZString (String nitz, long nitzReceiveTime) {
13150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // "yy/mm/dd,hh:mm:ss(+/-)tz"
13160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // tz is in number of quarter-hours
13170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        long start = SystemClock.elapsedRealtime();
13190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {log("NITZ: " + nitz + "," + nitzReceiveTime +
13200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        " start=" + start + " delay=" + (start - nitzReceiveTime));
13210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
13220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
13240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            /* NITZ time (hour:min:sec) will be in UTC but it supplies the timezone
13250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             * offset as well (which we won't worry about until later) */
13260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
13270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.clear();
13290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.DST_OFFSET, 0);
13300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String[] nitzSubs = nitz.split("[/:,+-]");
13320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int year = 2000 + Integer.parseInt(nitzSubs[0]);
13340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.YEAR, year);
13350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // month is 0 based!
13370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int month = Integer.parseInt(nitzSubs[1]) - 1;
13380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.MONTH, month);
13390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int date = Integer.parseInt(nitzSubs[2]);
13410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.DATE, date);
13420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int hour = Integer.parseInt(nitzSubs[3]);
13440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.HOUR, hour);
13450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int minute = Integer.parseInt(nitzSubs[4]);
13470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.MINUTE, minute);
13480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int second = Integer.parseInt(nitzSubs[5]);
13500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.SECOND, second);
13510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            boolean sign = (nitz.indexOf('-') == -1);
13530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int tzOffset = Integer.parseInt(nitzSubs[6]);
13550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int dst = (nitzSubs.length >= 8 ) ? Integer.parseInt(nitzSubs[7])
13570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                              : 0;
13580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // The zone offset received from NITZ is for current local time,
13600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // so DST correction is already applied.  Don't add it again.
13610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //
13620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // tzOffset += dst * 4;
13630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //
13640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // We could unapply it if we wanted the raw offset.
13650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            tzOffset = (sign ? 1 : -1) * tzOffset * 15 * 60 * 1000;
13670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            TimeZone    zone = null;
13690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // As a special extension, the Android emulator appends the name of
13710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // the host computer's timezone to the nitz string. this is zoneinfo
13720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // timezone name of the form Area!Location or Area!Location!SubLocation
13730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // so we need to convert the ! into /
13740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (nitzSubs.length >= 9) {
13750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                String  tzname = nitzSubs[8].replace('!','/');
13760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                zone = TimeZone.getTimeZone( tzname );
13770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
13780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String iso = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY);
13800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (zone == null) {
13820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (mGotCountryCode) {
13840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (iso != null && iso.length() > 0) {
13850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = TimeUtils.getTimeZone(tzOffset, dst != 0,
13860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                c.getTimeInMillis(),
13870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                iso);
13880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
13890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // We don't have a valid iso country code.  This is
13900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // most likely because we're on a test network that's
13910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // using a bogus MCC (eg, "001"), so get a TimeZone
13920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // based only on the NITZ parameters.
13930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = getNitzTimeZone(tzOffset, (dst != 0), c.getTimeInMillis());
13940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
13950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
13960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
13970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if ((zone == null) || (mZoneOffset != tzOffset) || (mZoneDst != (dst != 0))){
13990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // We got the time before the country or the zone has changed
14000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // so we don't know how to identify the DST rules yet.  Save
14010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // the information and hope to fix it up later.
14020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNeedFixZoneAfterNitz = true;
14040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mZoneOffset  = tzOffset;
14050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mZoneDst     = dst != 0;
14060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mZoneTime    = c.getTimeInMillis();
14070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
14080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (zone != null) {
14100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (getAutoTimeZone()) {
14110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setAndBroadcastNetworkSetTimeZone(zone.getID());
14120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
14130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                saveNitzTimeZone(zone.getID());
14140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
14150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String ignore = SystemProperties.get("gsm.ignore-nitz");
14170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (ignore != null && ignore.equals("yes")) {
14180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("NITZ: Not setting clock because gsm.ignore-nitz is set");
14190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
14200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
14210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            try {
14230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mWakeLock.acquire();
14240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (getAutoTime()) {
14260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    long millisSinceNitzReceived
14270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            = SystemClock.elapsedRealtime() - nitzReceiveTime;
14280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (millisSinceNitzReceived < 0) {
14300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Sanity check: something is wrong
14310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) {
14320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            log("NITZ: not setting time, clock has rolled "
14330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                            + "backwards since NITZ time was received, "
14340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                            + nitz);
14350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
14360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        return;
14370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
14380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (millisSinceNitzReceived > Integer.MAX_VALUE) {
14400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // If the time is this far off, something is wrong > 24 days!
14410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) {
14420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            log("NITZ: not setting time, processing has taken "
14430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        + (millisSinceNitzReceived / (1000 * 60 * 60 * 24))
14440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        + " days");
14450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
14460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        return;
14470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
14480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Note: with range checks above, cast to int is safe
14500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    c.add(Calendar.MILLISECOND, (int)millisSinceNitzReceived);
14510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) {
14530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("NITZ: Setting time of day to " + c.getTime()
14540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + " NITZ receive delay(ms): " + millisSinceNitzReceived
14550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + " gained(ms): "
14560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + (c.getTimeInMillis() - System.currentTimeMillis())
14570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + " from " + nitz);
14580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
14590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setAndBroadcastNetworkSetTime(c.getTimeInMillis());
146199c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                    Rlog.i(LOG_TAG, "NITZ: after Setting time of day");
14620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
14630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SystemProperties.set("gsm.nitz.time", String.valueOf(c.getTimeInMillis()));
14640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                saveNitzTime(c.getTimeInMillis());
1465cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (VDBG) {
14660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    long end = SystemClock.elapsedRealtime();
14670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("NITZ: end=" + end + " dur=" + (end - start));
14680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
14690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNitzUpdatedTime = true;
14700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } finally {
14710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mWakeLock.release();
14720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
14730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (RuntimeException ex) {
14740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("NITZ: Parsing NITZ time " + nitz + " ex=" + ex);
14750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
14760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean getAutoTime() {
14790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
148022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            return Settings.Global.getInt(mPhone.getContext().getContentResolver(),
1481069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate                    Settings.Global.AUTO_TIME) > 0;
14820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (SettingNotFoundException snfe) {
14830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
14840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
14850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean getAutoTimeZone() {
14880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
148922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            return Settings.Global.getInt(mPhone.getContext().getContentResolver(),
1490069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate                    Settings.Global.AUTO_TIME_ZONE) > 0;
14910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (SettingNotFoundException snfe) {
14920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
14930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
14940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void saveNitzTimeZone(String zoneId) {
14970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mSavedTimeZone = zoneId;
14980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void saveNitzTime(long time) {
15010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mSavedTime = time;
15020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mSavedAtTime = SystemClock.elapsedRealtime();
15030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
15060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Set the timezone and send out a sticky broadcast so the system can
15070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * determine if the timezone was set by the carrier.
15080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
15090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param zoneId timezone set by carrier
15100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
15110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void setAndBroadcastNetworkSetTimeZone(String zoneId) {
15120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setAndBroadcastNetworkSetTimeZone: setTimeZone=" + zoneId);
15130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AlarmManager alarm =
151422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
15150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        alarm.setTimeZone(zoneId);
15160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE);
15170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
15180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.putExtra("time-zone", zoneId);
151922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.getContext().sendStickyBroadcastAsUser(intent, UserHandle.ALL);
15200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
15210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("setAndBroadcastNetworkSetTimeZone: call alarm.setTimeZone and broadcast zoneId=" +
15220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                zoneId);
15230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
15270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Set the time and Send out a sticky broadcast so the system can determine
15280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * if the time was set by the carrier.
15290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
15300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param time time set by network
15310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
15320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void setAndBroadcastNetworkSetTime(long time) {
15330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setAndBroadcastNetworkSetTime: time=" + time + "ms");
15340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SystemClock.setCurrentTimeMillis(time);
15350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME);
15360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
15370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.putExtra("time", time);
153822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.getContext().sendStickyBroadcastAsUser(intent, UserHandle.ALL);
15390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void revertToNitzTime() {
154222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (Settings.Global.getInt(mPhone.getContext().getContentResolver(),
1543069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate                Settings.Global.AUTO_TIME, 0) == 0) {
15440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
15450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
15470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("Reverting to NITZ Time: mSavedTime=" + mSavedTime
15480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                + " mSavedAtTime=" + mSavedAtTime);
15490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mSavedTime != 0 && mSavedAtTime != 0) {
15510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setAndBroadcastNetworkSetTime(mSavedTime
15520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    + (SystemClock.elapsedRealtime() - mSavedAtTime));
15530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void revertToNitzTimeZone() {
155722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (Settings.Global.getInt(mPhone.getContext().getContentResolver(),
1558069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate                Settings.Global.AUTO_TIME_ZONE, 0) == 0) {
15590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
15600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("Reverting to NITZ TimeZone: tz='" + mSavedTimeZone);
15620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mSavedTimeZone != null) {
15630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setAndBroadcastNetworkSetTimeZone(mSavedTimeZone);
15640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
15680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Post a notification to NotificationManager for restricted state
15690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
15700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param notifyType is one state of PS/CS_*_ENABLE/DISABLE
15710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
15720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void setNotification(int notifyType) {
15730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setNotification: create notification " + notifyType);
157522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        Context context = mPhone.getContext();
15760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification = new Notification();
15780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.when = System.currentTimeMillis();
15790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.flags = Notification.FLAG_AUTO_CANCEL;
15800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.icon = com.android.internal.R.drawable.stat_sys_warning;
15810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent();
15820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.contentIntent = PendingIntent
15830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        .getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
15840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CharSequence details = "";
15860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CharSequence title = context.getText(com.android.internal.R.string.RestrictedChangedTitle);
15870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int notificationId = CS_NOTIFICATION;
15880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (notifyType) {
15900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PS_ENABLED:
15910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notificationId = PS_NOTIFICATION;
1592cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            details = context.getText(com.android.internal.R.string.RestrictedOnData);
15930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
15940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PS_DISABLED:
15950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notificationId = PS_NOTIFICATION;
15960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
15970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CS_ENABLED:
1598cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            details = context.getText(com.android.internal.R.string.RestrictedOnAllVoice);
15990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
16000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CS_NORMAL_ENABLED:
1601cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            details = context.getText(com.android.internal.R.string.RestrictedOnNormal);
16020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
16030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CS_EMERGENCY_ENABLED:
1604cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            details = context.getText(com.android.internal.R.string.RestrictedOnEmergency);
16050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
16060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CS_DISABLED:
16070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // do nothing and cancel the notification later
16080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
16090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setNotification: put notification " + title + " / " +details);
16120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.tickerText = title;
16130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.setLatestEventInfo(context, title, details,
16140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNotification.contentIntent);
16150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        NotificationManager notificationManager = (NotificationManager)
16170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            context.getSystemService(Context.NOTIFICATION_SERVICE);
16180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (notifyType == PS_DISABLED || notifyType == CS_DISABLED) {
16200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // cancel previous post notification
16210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notificationManager.cancel(notificationId);
16220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
16230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // update restricted state notification
16240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notificationManager.notify(notificationId, mNotification);
16250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
1629e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected void onUpdateIccAvailability() {
1630e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (mUiccController == null ) {
1631e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            return;
1632e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        }
1633e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
1634e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        UiccCardApplication newUiccApplication =
1635e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccController.getUiccCardApplication(UiccController.APP_FAM_3GPP);
1636e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
1637e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mUiccApplcation != newUiccApplication) {
1638e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mUiccApplcation != null) {
1639e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                log("Removing stale icc objects.");
1640e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplcation.unregisterForReady(this);
1641e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                if (mIccRecords != null) {
1642e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                    mIccRecords.unregisterForRecordsLoaded(this);
1643e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                }
1644e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                mIccRecords = null;
1645e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplcation = null;
1646e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            }
1647e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (newUiccApplication != null) {
1648e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                log("New card found");
1649e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplcation = newUiccApplication;
1650e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mIccRecords = mUiccApplcation.getIccRecords();
1651e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplcation.registerForReady(this, EVENT_SIM_READY, null);
1652e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                if (mIccRecords != null) {
1653e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                    mIccRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
1654e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                }
1655e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            }
1656e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        }
1657e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    }
1658e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    @Override
16590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void log(String s) {
166099c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.d(LOG_TAG, "[GsmSST] " + s);
16610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
16640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void loge(String s) {
166599c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.e(LOG_TAG, "[GsmSST] " + s);
16660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
16690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
16700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println("GsmServiceStateTracker extends:");
16710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        super.dump(fd, pw, args);
167222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mPhone=" + mPhone);
167322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mSS=" + mSS);
167422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mNewSS=" + mNewSS);
167522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mCellLoc=" + mCellLoc);
167622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mNewCellLoc=" + mNewCellLoc);
16770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mPreferredNetworkType=" + mPreferredNetworkType);
16780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mMaxDataCalls=" + mMaxDataCalls);
16790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNewMaxDataCalls=" + mNewMaxDataCalls);
16800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mReasonDataDenied=" + mReasonDataDenied);
16810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNewReasonDataDenied=" + mNewReasonDataDenied);
16820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mGsmRoaming=" + mGsmRoaming);
16830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mDataRoaming=" + mDataRoaming);
16840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mEmergencyOnly=" + mEmergencyOnly);
16850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNeedFixZoneAfterNitz=" + mNeedFixZoneAfterNitz);
16860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mZoneOffset=" + mZoneOffset);
16870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mZoneDst=" + mZoneDst);
16880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mZoneTime=" + mZoneTime);
16890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mGotCountryCode=" + mGotCountryCode);
16900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNitzUpdatedTime=" + mNitzUpdatedTime);
16910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mSavedTimeZone=" + mSavedTimeZone);
16920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mSavedTime=" + mSavedTime);
16930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mSavedAtTime=" + mSavedAtTime);
16940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mStartedGprsRegCheck=" + mStartedGprsRegCheck);
16950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mReportedGprsNoReg=" + mReportedGprsNoReg);
16960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNotification=" + mNotification);
16970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mWakeLock=" + mWakeLock);
169822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mCurSpn=" + mCurSpn);
169922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mCurShowSpn=" + mCurShowSpn);
170022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mCurPlmn=" + mCurPlmn);
170122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mCurShowPlmn=" + mCurShowPlmn);
17020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
17030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
1704