GsmServiceStateTracker.java revision b54cd09892e0676d719e6df00e60c77b663f993c
10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/*
20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2006 The Android Open Source Project
30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License.
60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at
70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software
110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and
140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License.
150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony.gsm;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.AlarmManager;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.Notification;
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.NotificationManager;
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.PendingIntent;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.BroadcastReceiver;
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.ContentResolver;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Context;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Intent;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.IntentFilter;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.res.Resources;
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.database.ContentObserver;
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult;
3160ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport android.os.Build;
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler;
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.PowerManager;
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.SystemClock;
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.SystemProperties;
377eff443d1f090abdbbd93eef9f265c74890920bcDianne Hackbornimport android.os.UserHandle;
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.provider.Settings;
390825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.provider.Settings.SettingNotFoundException;
400c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Savilleimport android.telephony.CellIdentityGsm;
410c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Savilleimport android.telephony.CellIdentityLte;
420c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Savilleimport android.telephony.CellIdentityWcdma;
430c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Savilleimport android.telephony.CellInfo;
44ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Savilleimport android.telephony.CellInfoGsm;
450c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Savilleimport android.telephony.CellInfoLte;
460c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Savilleimport android.telephony.CellInfoWcdma;
470c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Savilleimport android.telephony.CellLocation;
4860ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport android.telephony.Rlog;
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.ServiceState;
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.SignalStrength;
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.gsm.GsmCellLocation;
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.text.TextUtils;
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.EventLog;
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.TimeUtils;
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5660ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.CommandException;
5760ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.CommandsInterface;
5860ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.EventLogTags;
5960ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.MccTable;
6060ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.Phone;
6160ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.RILConstants;
6260ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.RestrictedState;
6360ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.ServiceStateTracker;
6460ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.TelephonyIntents;
6560ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.TelephonyProperties;
6660ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.dataconnection.DcTrackerBase;
6760ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
6860ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.uicc.IccRecords;
6960ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.uicc.SIMRecords;
7060ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.uicc.UiccCardApplication;
7160ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkeyimport com.android.internal.telephony.uicc.UiccController;
7260ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkey
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.FileDescriptor;
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.PrintWriter;
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList;
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Arrays;
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Calendar;
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Date;
790c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Savilleimport java.util.List;
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.TimeZone;
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillefinal class GsmServiceStateTracker extends ServiceStateTracker {
86cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private static final String LOG_TAG = "GsmSST";
87cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private static final boolean VDBG = false;
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    GSMPhone mPhone;
9022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    GsmCellLocation mCellLoc;
9122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    GsmCellLocation mNewCellLoc;
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    int mPreferredNetworkType;
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mMaxDataCalls = 1;
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mNewMaxDataCalls = 1;
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mReasonDataDenied = -1;
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mNewReasonDataDenied = -1;
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * GSM roaming status solely based on TS 27.007 7.2 CREG. Only used by
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * handlePollStateResult to store CREG roaming result.
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mGsmRoaming = false;
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Data roaming status solely based on TS 27.007 10.1.19 CGREG. Only used by
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * handlePollStateResult to store CGREG roaming result.
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mDataRoaming = false;
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Mark when service state is in emergency call only mode
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mEmergencyOnly = false;
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Sometimes we get the NITZ time before we know what country we
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * are in. Keep the time zone information from the NITZ string so
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * we can fix the time zone once know the country.
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mNeedFixZoneAfterNitz = false;
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mZoneOffset;
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mZoneDst;
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private long mZoneTime;
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mGotCountryCode = false;
12622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private ContentResolver mCr;
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Boolean is true is setTimeFromNITZString was called */
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mNitzUpdatedTime = false;
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    String mSavedTimeZone;
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    long mSavedTime;
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    long mSavedAtTime;
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Started the recheck process after finding gprs should registered but not. */
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mStartedGprsRegCheck = false;
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Already sent the event-log for no gprs register. */
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mReportedGprsNoReg = false;
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * The Notification object given to the NotificationManager.
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Notification mNotification;
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Wake lock used while setting time of day. */
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private PowerManager.WakeLock mWakeLock;
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final String WAKELOCK_TAG = "ServiceStateTracker";
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Keep track of SPN display rules, so we only broadcast intent if something changes. */
15122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private String mCurSpn = null;
15222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private String mCurPlmn = null;
15322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private boolean mCurShowPlmn = false;
15422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private boolean mCurShowSpn = false;
15560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Notification type. */
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int PS_ENABLED = 1001;            // Access Control blocks data service
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int PS_DISABLED = 1002;           // Access Control enables data service
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int CS_ENABLED = 1003;            // Access Control blocks all voice/sms service
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int CS_DISABLED = 1004;           // Access Control enables all voice/sms service
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int CS_NORMAL_ENABLED = 1005;     // Access Control blocks normal voice/sms service
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int CS_EMERGENCY_ENABLED = 1006;  // Access Control blocks emergency call service
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Notification id. */
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int PS_NOTIFICATION = 888;  // Id to update and cancel PS restricted
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int CS_NOTIFICATION = 999;  // Id to update and cancel CS restricted
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        @Override
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        public void onReceive(Context context, Intent intent) {
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (intent.getAction().equals(Intent.ACTION_LOCALE_CHANGED)) {
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // update emergency string whenever locale changed
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                updateSpnDisplay();
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) {
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        @Override
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        public void onChange(boolean selfChange) {
18199c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville            Rlog.i("GsmServiceStateTracker", "Auto time state changed");
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            revertToNitzTime();
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private ContentObserver mAutoTimeZoneObserver = new ContentObserver(new Handler()) {
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        @Override
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        public void onChange(boolean selfChange) {
18999c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville            Rlog.i("GsmServiceStateTracker", "Auto time zone state changed");
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            revertToNitzTimeZone();
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public GsmServiceStateTracker(GSMPhone phone) {
19522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        super(phone, phone.mCi, new CellInfoGsm());
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
19722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone = phone;
19822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCellLoc = new GsmCellLocation();
19922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mNewCellLoc = new GsmCellLocation();
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        PowerManager powerManager =
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                (PowerManager)phone.getContext().getSystemService(Context.POWER_SERVICE);
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG);
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
20622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.registerForVoiceNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null);
20922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setOnNITZTime(this, EVENT_NITZ_TIME, null);
21022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setOnRestrictedStateChanged(this, EVENT_RESTRICTED_STATE_CHANGED, null);
2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // system setting property AIRPLANE_MODE_ON is set in Settings.
213069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate        int airplaneMode = Settings.Global.getInt(
2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                phone.getContext().getContentResolver(),
215069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate                Settings.Global.AIRPLANE_MODE_ON, 0);
2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDesiredPowerState = ! (airplaneMode > 0);
2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCr = phone.getContext().getContentResolver();
21922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCr.registerContentObserver(
220069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate                Settings.Global.getUriFor(Settings.Global.AUTO_TIME), true,
2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mAutoTimeObserver);
22222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCr.registerContentObserver(
223069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate                Settings.Global.getUriFor(Settings.Global.AUTO_TIME_ZONE), true,
2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mAutoTimeZoneObserver);
2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        setSignalStrengthDefaultValues();
2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Monitor locale change
2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        IntentFilter filter = new IntentFilter();
2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        filter.addAction(Intent.ACTION_LOCALE_CHANGED);
2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.getContext().registerReceiver(mIntentReceiver, filter);
2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Gsm doesn't support OTASP so its not needed
2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.notifyOtaspChanged(OTASP_NOT_NEEDED);
2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
237ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    @Override
2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dispose() {
239e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        checkCorrectThread();
2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Unregister for all events.
24122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unregisterForAvailable(this);
24222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unregisterForRadioStateChanged(this);
24322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unregisterForVoiceNetworkStateChanged(this);
244e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mUiccApplcation != null) {mUiccApplcation.unregisterForReady(this);}
245e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (mIccRecords != null) {mIccRecords.unregisterForRecordsLoaded(this);}
24622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unSetOnRestrictedStateChanged(this);
24722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.unSetOnNITZTime(this);
24822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCr.unregisterContentObserver(mAutoTimeObserver);
24922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCr.unregisterContentObserver(mAutoTimeZoneObserver);
25022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.getContext().unregisterReceiver(mIntentReceiver);
251ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        super.dispose();
2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void finalize() {
2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if(DBG) log("finalize");
2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected Phone getPhone() {
26122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mPhone;
2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
264cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void handleMessage (Message msg) {
2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AsyncResult ar;
2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int[] ints;
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String[] strings;
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Message message;
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
27122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (!mPhone.mIsTheCurrentActivePhone) {
27299c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville            Rlog.e(LOG_TAG, "Received message " + msg +
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    "[" + msg.what + "] while being destroyed. Ignoring.");
2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (msg.what) {
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RADIO_AVAILABLE:
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                //this is unnecessary
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                //setPowerStateToDesired();
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SIM_READY:
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Set the network type, in case the radio does not restore it.
28422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.setCurrentPreferredNetworkType();
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
28622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                boolean skipRestoringSelection = mPhone.getContext().getResources().getBoolean(
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        com.android.internal.R.bool.skip_restoring_network_selection);
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!skipRestoringSelection) {
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // restore the previous network selection.
29122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPhone.restoreSavedNetworkSelection(null);
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollState();
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Signal strength polling stops when radio is off
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                queueNextSignalStrengthPoll();
2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RADIO_STATE_CHANGED:
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // This will do nothing in the radio not
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // available case
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setPowerStateToDesired();
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollState();
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_NETWORK_STATE_CHANGED:
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollState();
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_GET_SIGNAL_STRENGTH:
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // This callback is called when signal strength is polled
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // all by itself
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
31322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (!(mCi.getRadioState().isOn())) {
3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Polling will continue when radio turns back on
3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return;
3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
318e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville                onSignalStrengthResult(ar, true);
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                queueNextSignalStrengthPoll();
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_GET_LOC_DONE:
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception == null) {
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    String states[] = (String[])ar.result;
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int lac = -1;
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int cid = -1;
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (states.length >= 3) {
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        try {
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states[1] != null && states[1].length() > 0) {
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                lac = Integer.parseInt(states[1], 16);
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states[2] != null && states[2].length() > 0) {
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                cid = Integer.parseInt(states[2], 16);
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        } catch (NumberFormatException ex) {
33999c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                            Rlog.w(LOG_TAG, "error parsing location: " + ex);
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
34222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mCellLoc.setLacAndCid(lac, cid);
34322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPhone.notifyLocationChanged();
3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Release any temporary cell lock, which could have been
3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // acquired to allow a single-shot location update.
3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                disableSingleLocationUpdate();
3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_STATE_REGISTRATION:
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_STATE_GPRS:
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_STATE_OPERATOR:
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_STATE_NETWORK_SELECTION_MODE:
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                handlePollStateResult(msg.what, ar);
3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_SIGNAL_STRENGTH:
3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Just poll signal strength...not part of pollState()
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
36322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_NITZ_TIME:
3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                String nitzString = (String)((Object[])ar.result)[0];
3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                long nitzReceiveTime = ((Long)((Object[])ar.result)[1]).longValue();
3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setTimeFromNITZString(nitzString, nitzReceiveTime);
3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SIGNAL_STRENGTH_UPDATE:
3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // This is a notification from
3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // CommandsInterface.setOnSignalStrengthUpdate
3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // The radio is telling us about signal strength changes
3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // we don't have to ask it
38322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mDontPollSignalStrength = true;
3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
385e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville                onSignalStrengthResult(ar, true);
3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SIM_RECORDS_LOADED:
389b54cd09892e0676d719e6df00e60c77b663f993cWink Saville                log("EVENT_SIM_RECORDS_LOADED: what=" + msg.what);
390b54cd09892e0676d719e6df00e60c77b663f993cWink Saville
391b54cd09892e0676d719e6df00e60c77b663f993cWink Saville                updatePhoneObject();
3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                updateSpnDisplay();
3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_LOCATION_UPDATES_ENABLED:
3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception == null) {
39922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mCi.getVoiceRegistrationState(obtainMessage(EVENT_GET_LOC_DONE, null));
4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SET_PREFERRED_NETWORK_TYPE:
4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Don't care the result, only use for dereg network (COPS=2)
4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                message = obtainMessage(EVENT_RESET_PREFERRED_NETWORK_TYPE, ar.userObj);
40722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.setPreferredNetworkType(mPreferredNetworkType, message);
4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RESET_PREFERRED_NETWORK_TYPE:
4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.userObj != null) {
4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    AsyncResult.forMessage(((Message) ar.userObj)).exception
4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            = ar.exception;
4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ((Message) ar.userObj).sendToTarget();
4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_GET_PREFERRED_NETWORK_TYPE:
4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception == null) {
4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mPreferredNetworkType = ((int[])ar.result)[0];
4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mPreferredNetworkType = RILConstants.NETWORK_MODE_GLOBAL;
4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                message = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE, ar.userObj);
4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                int toggledNetworkType = RILConstants.NETWORK_MODE_GLOBAL;
4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
43122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.setPreferredNetworkType(toggledNetworkType, message);
4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_CHECK_REPORT_GPRS:
43522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (mSS != null && !isGprsConsistent(mSS.getDataRegState(), mSS.getVoiceRegState())) {
4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Can't register data service while voice service is ok
4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // i.e. CREG is ok while CGREG is not
4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // possible a network or baseband side error
44022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    GsmCellLocation loc = ((GsmCellLocation)mPhone.getCellLocation());
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    EventLog.writeEvent(EventLogTags.DATA_NETWORK_REGISTRATION_FAIL,
44222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            mSS.getOperatorNumeric(), loc != null ? loc.getCid() : -1);
4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mReportedGprsNoReg = true;
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mStartedGprsRegCheck = false;
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RESTRICTED_STATE_CHANGED:
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // This is a notification from
4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // CommandsInterface.setOnRestrictedStateChanged
4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("EVENT_RESTRICTED_STATE_CHANGED");
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                onRestrictedStateChanged(ar);
4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                super.handleMessage(msg);
4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
465cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void setPowerStateToDesired() {
4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If we want it on and it's off, turn it on
4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mDesiredPowerState
46922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            && mCi.getRadioState() == CommandsInterface.RadioState.RADIO_OFF) {
47022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCi.setRadioPower(true, null);
47122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (!mDesiredPowerState && mCi.getRadioState().isOn()) {
4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // If it's on and available and we want it off gracefully
473454b1dfd508844b42eb775e4ab2359be74d3672bWink Saville            DcTrackerBase dcTracker = mPhone.mDcTracker;
4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            powerOffRadioSafely(dcTracker);
4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } // Otherwise, we're in the desired state
4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void hangupAndPowerOff() {
4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // hang up all active voice calls
48122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPhone.isInCall()) {
48222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.mCT.mRingingCall.hangupIfAlive();
48322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.mCT.mBackgroundCall.hangupIfAlive();
48422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.mCT.mForegroundCall.hangupIfAlive();
4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
48722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCi.setRadioPower(false, null);
4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
490f7a8133113daddcc48a41e451193afd3fcb35e16Wink Saville    @Override
4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void updateSpnDisplay() {
49260e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        // The values of plmn/showPlmn change in different scenarios.
49360e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        // 1) No service but emergency call allowed -> expected
49460e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    to show "Emergency call only"
49560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_SHOW_PLMN = true
49660e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_PLMN = "Emergency call only"
49760e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang
49860e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        // 2) No service at all --> expected to show "No service"
49960e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_SHOW_PLMN = true
50060e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_PLMN = "No service"
50160e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang
50260e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        // 3) Normal operation in either home or roaming service
50360e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_SHOW_PLMN = depending on IccRecords rule
50460e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_PLMN = plmn
50560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang
50660e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        // 4) No service due to power off, aka airplane mode
50760e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_SHOW_PLMN = false
50860e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_PLMN = null
50960e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang
510f7a8133113daddcc48a41e451193afd3fcb35e16Wink Saville        IccRecords iccRecords = mIccRecords;
51160e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        String plmn = null;
51260e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        boolean showPlmn = false;
51322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        int rule = (iccRecords != null) ? iccRecords.getDisplayRule(mSS.getOperatorNumeric()) : 0;
51422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mSS.getVoiceRegState() == ServiceState.STATE_OUT_OF_SERVICE
51522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                || mSS.getVoiceRegState() == ServiceState.STATE_EMERGENCY_ONLY) {
51660e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            showPlmn = true;
51760e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            if (mEmergencyOnly) {
51860e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                // No service but emergency call allowed
51960e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                plmn = Resources.getSystem().
52060e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                        getText(com.android.internal.R.string.emergency_calls_only).toString();
52160e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            } else {
52260e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                // No service at all
52360e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                plmn = Resources.getSystem().
52460e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                        getText(com.android.internal.R.string.lockscreen_carrier_default).toString();
52560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            }
52660e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            if (DBG) log("updateSpnDisplay: radio is on but out " +
52760e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                    "of service, set plmn='" + plmn + "'");
52822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE) {
52960e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            // In either home or roaming service
53022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            plmn = mSS.getOperatorAlphaLong();
53160e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            showPlmn = !TextUtils.isEmpty(plmn) &&
53260e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                    ((rule & SIMRecords.SPN_RULE_SHOW_PLMN)
53360e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                            == SIMRecords.SPN_RULE_SHOW_PLMN);
53460e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        } else {
53560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            // Power off state, such as airplane mode
53660e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang            if (DBG) log("updateSpnDisplay: radio is off w/ showPlmn="
53760e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                    + showPlmn + " plmn=" + plmn);
5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
54060e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        // The value of spn/showSpn are same in different scenarios.
54160e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_SHOW_SPN = depending on IccRecords rule
54260e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        //    EXTRA_SPN = spn
543f7a8133113daddcc48a41e451193afd3fcb35e16Wink Saville        String spn = (iccRecords != null) ? iccRecords.getServiceProviderName() : "";
54460e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        boolean showSpn = !TextUtils.isEmpty(spn)
54560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                && ((rule & SIMRecords.SPN_RULE_SHOW_SPN)
54660e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                        == SIMRecords.SPN_RULE_SHOW_SPN);
54760e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang
54860e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang        // Update SPN_STRINGS_UPDATED_ACTION IFF any value changes
54922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (showPlmn != mCurShowPlmn
55022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                || showSpn != mCurShowSpn
55122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                || !TextUtils.equals(spn, mCurSpn)
55222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                || !TextUtils.equals(plmn, mCurPlmn)) {
5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
55460e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                log(String.format("updateSpnDisplay: changed" +
55560e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                        " sending intent rule=" + rule +
55660e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                        " showPlmn='%b' plmn='%s' showSpn='%b' spn='%s'",
55760e7f68c5f73b06fd5b603c331fc24b9d329de6bJohn Wang                        showPlmn, plmn, showSpn, spn));
5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Intent intent = new Intent(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            intent.putExtra(TelephonyIntents.EXTRA_SHOW_SPN, showSpn);
5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            intent.putExtra(TelephonyIntents.EXTRA_SPN, spn);
5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            intent.putExtra(TelephonyIntents.EXTRA_SHOW_PLMN, showPlmn);
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            intent.putExtra(TelephonyIntents.EXTRA_PLMN, plmn);
56522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.getContext().sendStickyBroadcastAsUser(intent, UserHandle.ALL);
5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
56822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCurShowSpn = showSpn;
56922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCurShowPlmn = showPlmn;
57022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCurSpn = spn;
57122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCurPlmn = plmn;
5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Handle the result of one of the pollState()-related requests
5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
577f92cb4bd5519427a0db673709d94683a8baf203aWink Saville    @Override
5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void handlePollStateResult (int what, AsyncResult ar) {
5790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int ints[];
5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String states[];
5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Ignore stale requests from last poll
58322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (ar.userObj != mPollingContext) return;
5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ar.exception != null) {
5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CommandException.Error err=null;
5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (ar.exception instanceof CommandException) {
5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                err = ((CommandException)(ar.exception)).getCommandError();
5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (err == CommandException.Error.RADIO_NOT_AVAILABLE) {
5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Radio has crashed or turned off
5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cancelPollState();
5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
59822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (!mCi.getRadioState().isOn()) {
5990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Radio has crashed or turned off
6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cancelPollState();
6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) {
6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                loge("RIL implementation has returned an error where it must succeed" +
6060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ar.exception);
6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else try {
6090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            switch (what) {
610f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                case EVENT_POLL_STATE_REGISTRATION: {
6110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    states = (String[])ar.result;
6120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int lac = -1;
6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int cid = -1;
614f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    int type = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
615f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    int regState = ServiceState.RIL_REG_STATE_UNKNOWN;
6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int reasonRegStateDenied = -1;
6170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int psc = -1;
6180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (states.length > 0) {
6190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        try {
6200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            regState = Integer.parseInt(states[0]);
6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states.length >= 3) {
6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (states[1] != null && states[1].length() > 0) {
6230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    lac = Integer.parseInt(states[1], 16);
6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (states[2] != null && states[2].length() > 0) {
6260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    cid = Integer.parseInt(states[2], 16);
6270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
628f92cb4bd5519427a0db673709d94683a8baf203aWink Saville
629f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                                // states[3] (if present) is the current radio technology
630f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                                if (states.length >= 4 && states[3] != null) {
631f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                                    type = Integer.parseInt(states[3]);
632f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                                }
6330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states.length > 14) {
6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (states[14] != null && states[14].length() > 0) {
6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    psc = Integer.parseInt(states[14], 16);
6370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
6380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
6390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        } catch (NumberFormatException ex) {
6400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            loge("error parsing RegistrationState: " + ex);
6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mGsmRoaming = regCodeIsRoaming(regState);
64522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewSS.setState(regCodeToServiceState(regState));
64622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewSS.setRilVoiceRadioTechnology(type);
6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6489c430a4d72c8c962caefb916e82a4c82eca7068cWink Saville                    boolean isVoiceCapable = mPhoneBase.getContext().getResources()
6499c430a4d72c8c962caefb916e82a4c82eca7068cWink Saville                            .getBoolean(com.android.internal.R.bool.config_voice_capable);
6509c430a4d72c8c962caefb916e82a4c82eca7068cWink Saville                    if ((regState == ServiceState.RIL_REG_STATE_DENIED_EMERGENCY_CALL_ENABLED
651f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                         || regState == ServiceState.RIL_REG_STATE_NOT_REG_EMERGENCY_CALL_ENABLED
652f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                         || regState == ServiceState.RIL_REG_STATE_SEARCHING_EMERGENCY_CALL_ENABLED
6539c430a4d72c8c962caefb916e82a4c82eca7068cWink Saville                         || regState == ServiceState.RIL_REG_STATE_UNKNOWN_EMERGENCY_CALL_ENABLED)
6549c430a4d72c8c962caefb916e82a4c82eca7068cWink Saville                         && isVoiceCapable) {
6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mEmergencyOnly = true;
6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mEmergencyOnly = false;
6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // LAC and CID are -1 if not avail
66122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewCellLoc.setLacAndCid(lac, cid);
66222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewCellLoc.setPsc(psc);
663f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    break;
664f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                }
6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
666f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                case EVENT_POLL_STATE_GPRS: {
6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    states = (String[])ar.result;
6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int type = 0;
670f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    int regState = ServiceState.RIL_REG_STATE_UNKNOWN;
6710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mNewReasonDataDenied = -1;
6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mNewMaxDataCalls = 1;
6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (states.length > 0) {
6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        try {
6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            regState = Integer.parseInt(states[0]);
6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            // states[3] (if present) is the current radio technology
6780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states.length >= 4 && states[3] != null) {
6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                type = Integer.parseInt(states[3]);
6800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
681f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                            if ((states.length >= 5 ) &&
682f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                                    (regState == ServiceState.RIL_REG_STATE_DENIED)) {
6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                mNewReasonDataDenied = Integer.parseInt(states[4]);
6840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
6850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states.length >= 6) {
6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                mNewMaxDataCalls = Integer.parseInt(states[5]);
6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        } catch (NumberFormatException ex) {
6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            loge("error parsing GprsRegistrationState: " + ex);
6900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
6910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
692f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    int dataRegState = regCodeToServiceState(regState);
69322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewSS.setDataRegState(dataRegState);
6940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mDataRoaming = regCodeIsRoaming(regState);
69522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewSS.setRilDataRadioTechnology(type);
696f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    if (DBG) {
697f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                        log("handlPollStateResultMessage: GsmSST setDataRegState=" + dataRegState
698f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                                + " regState=" + regState
699f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                                + " dataRadioTechnology=" + type);
700f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    }
701f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    break;
702f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                }
7030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
704f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                case EVENT_POLL_STATE_OPERATOR: {
7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    String opNames[] = (String[])ar.result;
7060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (opNames != null && opNames.length >= 3) {
70822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                         mNewSS.setOperatorName (opNames[0], opNames[1], opNames[2]);
7090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
710f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    break;
711f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                }
7120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
713f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                case EVENT_POLL_STATE_NETWORK_SELECTION_MODE: {
7140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ints = (int[])ar.result;
71522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewSS.setIsManualSelection(ints[0] == 1);
716f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                    break;
717f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                }
7180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (RuntimeException ex) {
7210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("Exception while polling service state. Probably malformed RIL response." + ex);
7220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
72422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPollingContext[0]--;
7250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
72622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mPollingContext[0] == 0) {
7270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            /**
728a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi             * Since the roaming state of gsm service (from +CREG) and
729a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi             * data service (from +CGREG) could be different, the new SS
730a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi             * is set to roaming when either is true.
7310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             *
732a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi             * There are exceptions for the above rule.
733a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi             * The new SS is not set as roaming while gsm service reports
734a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi             * roaming but indeed it is same operator.
735a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi             * And the operator is considered non roaming.
7367ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi             *
737a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi             * The test for the operators is to handle special roaming
738a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi             * agreements and MVNO's.
7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             */
740a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi            boolean roaming = (mGsmRoaming || mDataRoaming);
741a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi            if ((mGsmRoaming && isSameNamedOperators(mNewSS))
742a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi                    || isOperatorConsideredNonRoaming(mNewSS)) {
743a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi                roaming = false;
744a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi            }
745a23d86f400fe029aa05592b963b2c10988545a55Sungmin Choi            mNewSS.setRoaming(roaming);
74622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mNewSS.setEmergencyOnly(mEmergencyOnly);
7470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pollStateDone();
7480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
751c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void setSignalStrengthDefaultValues() {
7525b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        mSignalStrength = new SignalStrength(true);
7530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
7560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * A complete "service state" from our perspective is
7570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * composed of a handful of separate requests to the radio.
7580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
7590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * We make all of these requests at once, but then abandon them
7600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * and start over again if the radio notifies us that some
7610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * event has changed
7620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
7630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void pollState() {
76422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPollingContext = new int[1];
76522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPollingContext[0] = 0;
7660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
76722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        switch (mCi.getRadioState()) {
7680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case RADIO_UNAVAILABLE:
76922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mNewSS.setStateOutOfService();
77022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mNewCellLoc.setStateInvalid();
7710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setSignalStrengthDefaultValues();
7720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mGotCountryCode = false;
7730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNitzUpdatedTime = false;
7740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollStateDone();
7750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
7760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case RADIO_OFF:
77822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mNewSS.setStateOff();
77922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mNewCellLoc.setStateInvalid();
7800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setSignalStrengthDefaultValues();
7810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mGotCountryCode = false;
7820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNitzUpdatedTime = false;
7830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollStateDone();
7840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
7850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
7870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Issue all poll-related commands at once
7880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // then count down the responses, which
7890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // are allowed to arrive out-of-order
7900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
79122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPollingContext[0]++;
79222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.getOperator(
7930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    obtainMessage(
79422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        EVENT_POLL_STATE_OPERATOR, mPollingContext));
7950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
79622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPollingContext[0]++;
79722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.getDataRegistrationState(
7980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    obtainMessage(
79922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        EVENT_POLL_STATE_GPRS, mPollingContext));
8000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
80122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPollingContext[0]++;
80222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.getVoiceRegistrationState(
8030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    obtainMessage(
80422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        EVENT_POLL_STATE_REGISTRATION, mPollingContext));
8050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
80622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPollingContext[0]++;
80722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCi.getNetworkSelectionMode(
8080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    obtainMessage(
80922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        EVENT_POLL_STATE_NETWORK_SELECTION_MODE, mPollingContext));
8100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
8110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void pollStateDone() {
8150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
8160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("Poll ServiceState done: " +
81722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                " oldSS=[" + mSS + "] newSS=[" + mNewSS + "]" +
8180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                " oldMaxDataCalls=" + mMaxDataCalls +
8190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                " mNewMaxDataCalls=" + mNewMaxDataCalls +
8200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                " oldReasonDataDenied=" + mReasonDataDenied +
821f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                " mNewReasonDataDenied=" + mNewReasonDataDenied);
8220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
82460ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkey        if (Build.IS_DEBUGGABLE && SystemProperties.getBoolean(PROP_FORCE_ROAMING, false)) {
82560ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkey            mNewSS.setRoaming(true);
82660ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkey        }
82760ced166cb63c35a0ebbee1fc356cddcb76b956fJeff Sharkey
828f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville        useDataRegStateForDataOnlyDevices();
829f1317a4b3492218ac2e449ee990948bac0295b65Wink Saville
8300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasRegistered =
83122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mSS.getVoiceRegState() != ServiceState.STATE_IN_SERVICE
83222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            && mNewSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE;
8330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasDeregistered =
83522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE
83622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            && mNewSS.getVoiceRegState() != ServiceState.STATE_IN_SERVICE;
8370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasGprsAttached =
83922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSS.getDataRegState() != ServiceState.STATE_IN_SERVICE
84022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && mNewSS.getDataRegState() == ServiceState.STATE_IN_SERVICE;
8410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasGprsDetached =
84322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSS.getDataRegState() == ServiceState.STATE_IN_SERVICE
84422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                && mNewSS.getDataRegState() != ServiceState.STATE_IN_SERVICE;
8450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
846a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville        boolean hasDataRegStateChanged =
847a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville                mSS.getDataRegState() != mNewSS.getDataRegState();
848a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville
849a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville        boolean hasVoiceRegStateChanged =
850a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville                mSS.getVoiceRegState() != mNewSS.getVoiceRegState();
851a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville
852f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        boolean hasRilVoiceRadioTechnologyChanged =
85322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSS.getRilVoiceRadioTechnology() != mNewSS.getRilVoiceRadioTechnology();
8540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
855a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville        boolean hasRilDataRadioTechnologyChanged =
856a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville                mSS.getRilDataRadioTechnology() != mNewSS.getRilDataRadioTechnology();
857a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville
85822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        boolean hasChanged = !mNewSS.equals(mSS);
8590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
86022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        boolean hasRoamingOn = !mSS.getRoaming() && mNewSS.getRoaming();
8610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
86222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        boolean hasRoamingOff = mSS.getRoaming() && !mNewSS.getRoaming();
8630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
86422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        boolean hasLocationChanged = !mNewCellLoc.equals(mCellLoc);
8650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Add an event log when connection state changes
867a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville        if (hasVoiceRegStateChanged || hasDataRegStateChanged) {
8680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            EventLog.writeEvent(EventLogTags.GSM_SERVICE_STATE_CHANGE,
86922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSS.getVoiceRegState(), mSS.getDataRegState(),
87022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mNewSS.getVoiceRegState(), mNewSS.getDataRegState());
8710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Add an event log when network type switched
8740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // TODO: we may add filtering to reduce the event logged,
8750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // i.e. check preferred network setting, only switch to 2G, etc
876f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        if (hasRilVoiceRadioTechnologyChanged) {
8770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int cid = -1;
878385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby            GsmCellLocation loc = mNewCellLoc;
8790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (loc != null) cid = loc.getCid();
880385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby            // NOTE: this code was previously located after mSS and mNewSS are swapped, so
881385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby            // existing logs were incorrectly using the new state for "network_from"
882385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby            // and STATE_OUT_OF_SERVICE for "network_to". To avoid confusion, use a new log tag
883385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby            // to record the correct states.
884385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby            EventLog.writeEvent(EventLogTags.GSM_RAT_SWITCHED_NEW, cid,
885385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby                    mSS.getRilVoiceRadioTechnology(),
88622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mNewSS.getRilVoiceRadioTechnology());
8870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
888f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                log("RAT switched "
88922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        + ServiceState.rilRadioTechnologyToString(mSS.getRilVoiceRadioTechnology())
890f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                        + " -> "
891385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby                        + ServiceState.rilRadioTechnologyToString(
892385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby                                mNewSS.getRilVoiceRadioTechnology()) + " at cell " + cid);
8930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
896385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby        // swap mSS and mNewSS to put new state in mSS
897385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby        ServiceState tss = mSS;
898385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby        mSS = mNewSS;
899385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby        mNewSS = tss;
900385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby        // clean slate for next time
901385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby        mNewSS.setStateOutOfService();
902385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby
903385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby        // swap mCellLoc and mNewCellLoc to put new state in mCellLoc
904385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby        GsmCellLocation tcl = mCellLoc;
905385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby        mCellLoc = mNewCellLoc;
906385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby        mNewCellLoc = tcl;
907385051afecde7a16a08b2aebb2025c3a2bbac279Jake Hamby
9080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mReasonDataDenied = mNewReasonDataDenied;
9090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mMaxDataCalls = mNewMaxDataCalls;
9100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
911b54cd09892e0676d719e6df00e60c77b663f993cWink Saville        if (hasRilVoiceRadioTechnologyChanged) {
912b54cd09892e0676d719e6df00e60c77b663f993cWink Saville            updatePhoneObject();
913b54cd09892e0676d719e6df00e60c77b663f993cWink Saville        }
914b54cd09892e0676d719e6df00e60c77b663f993cWink Saville
915a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville        if (hasRilDataRadioTechnologyChanged) {
91622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
91722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    ServiceState.rilRadioTechnologyToString(mSS.getRilVoiceRadioTechnology()));
9180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasRegistered) {
9210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mNetworkAttachedRegistrants.notifyRegistrants();
9220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
9240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("pollStateDone: registering current mNitzUpdatedTime=" +
9250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mNitzUpdatedTime + " changing to false");
9260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
9270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mNitzUpdatedTime = false;
9280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasChanged) {
9310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String operatorNumeric;
9320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            updateSpnDisplay();
9340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
93522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
93622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSS.getOperatorAlphaLong());
9370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String prevOperatorNumeric =
9390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, "");
94022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            operatorNumeric = mSS.getOperatorNumeric();
94122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
9420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (operatorNumeric == null) {
9440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("operatorNumeric is null");
94522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
9460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mGotCountryCode = false;
9470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNitzUpdatedTime = false;
9480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
9490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                String iso = "";
9507c491bb3d140e2579c2c01edca94305701664db5Rekha Kumar                String mcc = "";
9510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                try{
9527c491bb3d140e2579c2c01edca94305701664db5Rekha Kumar                    mcc = operatorNumeric.substring(0, 3);
9530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    iso = MccTable.countryCodeForMcc(Integer.parseInt(mcc));
9540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } catch ( NumberFormatException ex){
9550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    loge("pollStateDone: countryCodeForMcc error" + ex);
9560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } catch ( StringIndexOutOfBoundsException ex) {
9570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    loge("pollStateDone: countryCodeForMcc error" + ex);
9580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
96022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, iso);
9610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mGotCountryCode = true;
9620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                TimeZone zone = null;
9640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!mNitzUpdatedTime && !mcc.equals("000") && !TextUtils.isEmpty(iso) &&
9660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        getAutoTimeZone()) {
9670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Test both paths if ignore nitz is true
9690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    boolean testOneUniqueOffsetPath = SystemProperties.getBoolean(
9700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                TelephonyProperties.PROPERTY_IGNORE_NITZ, false) &&
9710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    ((SystemClock.uptimeMillis() & 1) == 0);
9720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ArrayList<TimeZone> uniqueZones = TimeUtils.getTimeZonesWithUniqueOffsets(iso);
9740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if ((uniqueZones.size() == 1) || testOneUniqueOffsetPath) {
9750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = uniqueZones.get(0);
9760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) {
9770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                           log("pollStateDone: no nitz but one TZ for iso-cc=" + iso +
9780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                   " with zone.getID=" + zone.getID() +
9790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                   " testOneUniqueOffsetPath=" + testOneUniqueOffsetPath);
9800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
9810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        setAndBroadcastNetworkSetTimeZone(zone.getID());
9820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
9830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) {
9840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            log("pollStateDone: there are " + uniqueZones.size() +
9850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                " unique offsets for iso-cc='" + iso +
9860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                " testOneUniqueOffsetPath=" + testOneUniqueOffsetPath +
9870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                "', do nothing");
9880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
9890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
9900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
99222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (shouldFixTimeZoneNow(mPhone, operatorNumeric, prevOperatorNumeric,
9930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mNeedFixZoneAfterNitz)) {
9940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // If the offset is (0, false) and the timezone property
9950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // is set, use the timezone property rather than
9960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // GMT.
9970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    String zoneName = SystemProperties.get(TIMEZONE_PROPERTY);
9980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) {
9990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("pollStateDone: fix time zone zoneName='" + zoneName +
10000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "' mZoneOffset=" + mZoneOffset + " mZoneDst=" + mZoneDst +
10010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            " iso-cc='" + iso +
10020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "' iso-cc-idx=" + Arrays.binarySearch(GMT_COUNTRY_CODES, iso));
10030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
10040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // "(mZoneOffset == 0) && (mZoneDst == false) &&
10060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    //  (Arrays.binarySearch(GMT_COUNTRY_CODES, iso) < 0)"
10070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // means that we received a NITZ string telling
10080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // it is in GMT+0 w/ DST time zone
10090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // BUT iso tells is NOT, e.g, a wrong NITZ reporting
10100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // local time w/ 0 offset.
10110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if ((mZoneOffset == 0) && (mZoneDst == false) &&
10120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        (zoneName != null) && (zoneName.length() > 0) &&
10130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        (Arrays.binarySearch(GMT_COUNTRY_CODES, iso) < 0)) {
10140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = TimeZone.getDefault();
10150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (mNeedFixZoneAfterNitz) {
10160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            // For wrong NITZ reporting local time w/ 0 offset,
10170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            // need adjust time to reflect default timezone setting
10180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            long ctm = System.currentTimeMillis();
10190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            long tzOffset = zone.getOffset(ctm);
10200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (DBG) {
10210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                log("pollStateDone: tzOffset=" + tzOffset + " ltod=" +
10220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        TimeUtils.logTimeOfDay(ctm));
10230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
10240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (getAutoTime()) {
10250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                long adj = ctm - tzOffset;
10260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (DBG) log("pollStateDone: adj ltod=" +
10270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        TimeUtils.logTimeOfDay(adj));
10280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                setAndBroadcastNetworkSetTime(adj);
10290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            } else {
10300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                // Adjust the saved NITZ time to account for tzOffset.
10310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                mSavedTime = mSavedTime - tzOffset;
10320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
10330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
10340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("pollStateDone: using default TimeZone");
10350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else if (iso.equals("")){
10360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Country code not found.  This is likely a test network.
10370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Get a TimeZone based only on the NITZ parameters (best guess).
10380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = getNitzTimeZone(mZoneOffset, mZoneDst, mZoneTime);
10390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("pollStateDone: using NITZ TimeZone");
10400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
10410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = TimeUtils.getTimeZone(mZoneOffset, mZoneDst, mZoneTime, iso);
10420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("pollStateDone: using getTimeZone(off, dst, time, iso)");
10430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
10440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mNeedFixZoneAfterNitz = false;
10460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (zone != null) {
10480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("pollStateDone: zone != null zone.getID=" + zone.getID());
10490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (getAutoTimeZone()) {
10500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            setAndBroadcastNetworkSetTimeZone(zone.getID());
10510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
10520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        saveNitzTimeZone(zone.getID());
10530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
10540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("pollStateDone: zone == null");
10550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
10560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
10570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
10580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
105922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
106022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSS.getRoaming() ? "true" : "false");
10610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
106222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyServiceStateChanged(mSS);
10630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasGprsAttached) {
10660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mAttachedRegistrants.notifyRegistrants();
10670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasGprsDetached) {
10700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mDetachedRegistrants.notifyRegistrants();
10710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1073a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville        if (hasDataRegStateChanged || hasRilDataRadioTechnologyChanged) {
1074203e588e3c42a81aa8a56f595119c181a63b12caWink Saville            notifyDataRegStateRilRadioTechnologyChanged();
1075a0f04ae3f07c686ddbc4d83edf0f1b7d8d1b4a0aWink Saville            mPhone.notifyDataConnection(null);
10760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasRoamingOn) {
10790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mRoamingOnRegistrants.notifyRegistrants();
10800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasRoamingOff) {
10830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mRoamingOffRegistrants.notifyRegistrants();
10840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasLocationChanged) {
108722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.notifyLocationChanged();
10880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
109022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (! isGprsConsistent(mSS.getDataRegState(), mSS.getVoiceRegState())) {
10910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!mStartedGprsRegCheck && !mReportedGprsNoReg) {
10920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mStartedGprsRegCheck = true;
10930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1094b840987a39e7149c1364739696977089cd53814dWink Saville                int check_period = Settings.Global.getInt(
109522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mPhone.getContext().getContentResolver(),
1096b840987a39e7149c1364739696977089cd53814dWink Saville                        Settings.Global.GPRS_REGISTER_CHECK_PERIOD_MS,
10970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        DEFAULT_GPRS_CHECK_PERIOD_MILLIS);
10980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                sendMessageDelayed(obtainMessage(EVENT_CHECK_REPORT_GPRS),
10990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        check_period);
11000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
11020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mReportedGprsNoReg = false;
11030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1104ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        // TODO: Add GsmCellIdenity updating, see CdmaLteServiceStateTracker.
11050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Check if GPRS got registered while voice is registered.
11090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
1110cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param dataRegState i.e. CGREG in GSM
1111cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @param voiceRegState i.e. CREG in GSM
11120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return false if device only register to voice but not gprs
11130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1114f92cb4bd5519427a0db673709d94683a8baf203aWink Saville    private boolean isGprsConsistent(int dataRegState, int voiceRegState) {
1115f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        return !((voiceRegState == ServiceState.STATE_IN_SERVICE) &&
1116f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                (dataRegState != ServiceState.STATE_IN_SERVICE));
11170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Returns a TimeZone object based only on parameters from the NITZ string.
11210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private TimeZone getNitzTimeZone(int offset, boolean dst, long when) {
11230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        TimeZone guess = findTimeZone(offset, dst, when);
11240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (guess == null) {
11250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Couldn't find a proper timezone.  Perhaps the DST data is wrong.
11260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            guess = findTimeZone(offset, !dst, when);
11270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("getNitzTimeZone returning " + (guess == null ? guess : guess.getID()));
11290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return guess;
11300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private TimeZone findTimeZone(int offset, boolean dst, long when) {
11330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int rawOffset = offset;
11340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (dst) {
11350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            rawOffset -= 3600000;
11360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String[] zones = TimeZone.getAvailableIDs(rawOffset);
11380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        TimeZone guess = null;
11390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Date d = new Date(when);
11400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (String zone : zones) {
11410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            TimeZone tz = TimeZone.getTimeZone(zone);
11420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (tz.getOffset(when) == offset &&
11430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                tz.inDaylightTime(d) == dst) {
11440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                guess = tz;
11450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
11460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return guess;
11500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void queueNextSignalStrengthPoll() {
115322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mDontPollSignalStrength) {
11540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // The radio is telling us about signal strength changes
11550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // we don't have to ask it
11560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
11570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Message msg;
11600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        msg = obtainMessage();
11620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        msg.what = EVENT_POLL_SIGNAL_STRENGTH;
11630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        long nextTime;
11650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // TODO Don't poll signal strength if screen is off
11670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        sendMessageDelayed(msg, POLL_PERIOD_MILLIS);
11680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Set restricted state based on the OnRestrictedStateChanged notification
11720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * If any voice or packet restricted state changes, trigger a UI
11730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * notification and notify registrants when sim is ready.
11740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
11750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param ar an int value of RIL_RESTRICTED_STATE_*
11760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void onRestrictedStateChanged(AsyncResult ar) {
11780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        RestrictedState newRs = new RestrictedState();
11790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onRestrictedStateChanged: E rs "+ mRestrictedState);
11810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ar.exception == null) {
11830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int[] ints = (int[])ar.result;
11840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int state = ints[0];
11850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            newRs.setCsEmergencyRestricted(
11870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ((state & RILConstants.RIL_RESTRICTED_STATE_CS_EMERGENCY) != 0) ||
11880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
11890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //ignore the normal call and data restricted state before SIM READY
1190e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mUiccApplcation != null && mUiccApplcation.getState() == AppState.APPSTATE_READY) {
11910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                newRs.setCsNormalRestricted(
11920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ((state & RILConstants.RIL_RESTRICTED_STATE_CS_NORMAL) != 0) ||
11930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
11940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                newRs.setPsRestricted(
11950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        (state & RILConstants.RIL_RESTRICTED_STATE_PS_ALL)!= 0);
11960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("onRestrictedStateChanged: new rs "+ newRs);
11990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!mRestrictedState.isPsRestricted() && newRs.isPsRestricted()) {
12010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPsRestrictEnabledRegistrants.notifyRegistrants();
12020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setNotification(PS_ENABLED);
12030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (mRestrictedState.isPsRestricted() && !newRs.isPsRestricted()) {
12040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPsRestrictDisabledRegistrants.notifyRegistrants();
12050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setNotification(PS_DISABLED);
12060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
12070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            /**
12090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             * There are two kind of cs restriction, normal and emergency. So
12100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             * there are 4 x 4 combinations in current and new restricted states
12110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             * and we only need to notify when state is changed.
12120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             */
12130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mRestrictedState.isCsRestricted()) {
12140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!newRs.isCsRestricted()) {
12150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove all restriction
12160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_DISABLED);
12170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (!newRs.isCsNormalRestricted()) {
12180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove normal restriction
12190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_EMERGENCY_ENABLED);
12200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (!newRs.isCsEmergencyRestricted()) {
12210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove emergency restriction
12220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_NORMAL_ENABLED);
12230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
12240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (mRestrictedState.isCsEmergencyRestricted() &&
12250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    !mRestrictedState.isCsNormalRestricted()) {
12260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!newRs.isCsRestricted()) {
12270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove all restriction
12280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_DISABLED);
12290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsRestricted()) {
12300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // enable all restriction
12310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_ENABLED);
12320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsNormalRestricted()) {
12330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove emergency restriction and enable normal restriction
12340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_NORMAL_ENABLED);
12350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
12360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (!mRestrictedState.isCsEmergencyRestricted() &&
12370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mRestrictedState.isCsNormalRestricted()) {
12380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!newRs.isCsRestricted()) {
12390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove all restriction
12400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_DISABLED);
12410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsRestricted()) {
12420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // enable all restriction
12430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_ENABLED);
12440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsEmergencyRestricted()) {
12450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove normal restriction and enable emergency restriction
12460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_EMERGENCY_ENABLED);
12470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
12480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
12490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (newRs.isCsRestricted()) {
12500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // enable all restriction
12510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_ENABLED);
12520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsEmergencyRestricted()) {
12530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // enable emergency restriction
12540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_EMERGENCY_ENABLED);
12550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsNormalRestricted()) {
12560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // enable normal restriction
12570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_NORMAL_ENABLED);
12580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
12590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
12600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mRestrictedState = newRs;
12620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        log("onRestrictedStateChanged: X rs "+ mRestrictedState);
12640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** code is registration state 0-5 from TS 27.007 7.2 */
12670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int regCodeToServiceState(int code) {
12680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (code) {
12690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 0:
12700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 2: // 2 is "searching"
12710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 3: // 3 is "registration denied"
12720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 4: // 4 is "unknown" no vaild in current baseband
12730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 10:// same as 0, but indicates that emergency call is possible.
12740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 12:// same as 2, but indicates that emergency call is possible.
12750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 13:// same as 3, but indicates that emergency call is possible.
12760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 14:// same as 4, but indicates that emergency call is possible.
12770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return ServiceState.STATE_OUT_OF_SERVICE;
12780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 1:
12800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return ServiceState.STATE_IN_SERVICE;
12810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 5:
12830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // in service, roam
12840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return ServiceState.STATE_IN_SERVICE;
12850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
12870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                loge("regCodeToServiceState: unexpected service state " + code);
12880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return ServiceState.STATE_OUT_OF_SERVICE;
12890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * code is registration state 0-5 from TS 27.007 7.2
12950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * returns true if registered roam, false otherwise
12960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean regCodeIsRoaming (int code) {
1298f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        return ServiceState.RIL_REG_STATE_ROAMING == code;
12990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
13000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
13027ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * Set roaming state if operator mcc is the same as sim mcc
13037ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * and ons is different from spn
13047ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     *
13050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param s ServiceState hold current ons
13067ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * @return true if same operator
13070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
13087ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi    private boolean isSameNamedOperators(ServiceState s) {
13090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String spn = SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, "empty");
13100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String onsl = s.getOperatorAlphaLong();
13120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String onss = s.getOperatorAlphaShort();
13130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean equalsOnsl = onsl != null && spn.equals(onsl);
13150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean equalsOnss = onss != null && spn.equals(onss);
13160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13177ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi        return currentMccEqualsSimMcc(s) && (equalsOnsl || equalsOnss);
13187ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi    }
13197ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi
13207ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi    /**
13217ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * Compare SIM MCC with Operator MCC
13227ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     *
13237ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * @param s ServiceState hold current ons
13247ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * @return true if both are same
13257ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     */
13267ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi    private boolean currentMccEqualsSimMcc(ServiceState s) {
13270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String simNumeric = SystemProperties.get(
13280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "");
13297ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi        String operatorNumeric = s.getOperatorNumeric();
13300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean equalsMcc = true;
13317ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi
13320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
13330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            equalsMcc = simNumeric.substring(0, 3).
13340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    equals(operatorNumeric.substring(0, 3));
13350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (Exception e){
13360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
13377ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi        return equalsMcc;
13387ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi    }
13390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13407ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi    /**
13417ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * Do not set roaming state in case of oprators considered non-roaming.
13427ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     *
13437ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     + Can use mcc or mcc+mnc as item of config_operatorConsideredNonRoaming.
13447ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * For example, 302 or 21407. If mcc or mcc+mnc match with operator,
13457ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * don't set roaming state.
13467ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     *
13477ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * @param s ServiceState hold current ons
13487ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     * @return false for roaming state set
13497ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi     */
13507ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi    private boolean isOperatorConsideredNonRoaming(ServiceState s) {
13517ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi        String operatorNumeric = s.getOperatorNumeric();
13527ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi        String[] numericArray = mPhone.getContext().getResources().getStringArray(
13537ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi                    com.android.internal.R.array.config_operatorConsideredNonRoaming);
13547ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi
13557ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi        if (numericArray.length == 0 || operatorNumeric == null)
13567ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi            return false;
13577ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi
13587ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi        for (String numeric : numericArray) {
13597ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi            if (operatorNumeric.startsWith(numeric))
13607ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi                return true;
13617ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi            else
13627ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi                return false;
13637ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi        }
13647ed57239eb9eff4a4afa722948db93ea288f0505Sungmin Choi        return false;
13650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
13660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
13680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return The current GPRS state. IN_SERVICE is the same as "attached"
13690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * and OUT_OF_SERVICE is the same as detached.
13700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1371f92cb4bd5519427a0db673709d94683a8baf203aWink Saville    @Override
13720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public int getCurrentDataConnectionState() {
137322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mSS.getDataRegState();
13740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
13750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
13770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if phone is camping on a technology (eg UMTS)
13780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * that could support voice and data simultaneously.
13790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1380cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
13810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean isConcurrentVoiceAndDataAllowed() {
138222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return (mSS.getRilVoiceRadioTechnology() >= ServiceState.RIL_RADIO_TECHNOLOGY_UMTS);
13830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
13840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
13860c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville     * @return the current cell location information. Prefer Gsm location
13870c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville     * information if available otherwise return LTE location information
13880c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville     */
13890c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville    public CellLocation getCellLocation() {
13900c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville        if ((mCellLoc.getLac() >= 0) && (mCellLoc.getCid() >= 0)) {
13910c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville            if (DBG) log("getCellLocation(): X good mCellLoc=" + mCellLoc);
13920c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville            return mCellLoc;
13930c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville        } else {
13940c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville            List<CellInfo> result = getAllCellInfo();
13950c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville            if (result != null) {
13960c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                // A hack to allow tunneling of LTE information via GsmCellLocation
13970c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                // so that older Network Location Providers can return some information
13980c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                // on LTE only networks, see bug 9228974.
13990c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                //
14000c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                // We'll search the return CellInfo array preferring GSM/WCDMA
14010c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                // data, but if there is none we'll tunnel the first LTE information
14020c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                // in the list.
14030c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                //
14040c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                // The tunnel'd LTE information is returned as follows:
14050c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                //   LAC = TAC field
14060c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                //   CID = CI field
14070c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                //   PSC = 0.
14080c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                GsmCellLocation cellLocOther = new GsmCellLocation();
14090c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                for (CellInfo ci : result) {
14100c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    if (ci instanceof CellInfoGsm) {
14110c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        CellInfoGsm cellInfoGsm = (CellInfoGsm)ci;
14120c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        CellIdentityGsm cellIdentityGsm = cellInfoGsm.getCellIdentity();
14130c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        cellLocOther.setLacAndCid(cellIdentityGsm.getLac(),
14140c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                                cellIdentityGsm.getCid());
14150c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        cellLocOther.setPsc(cellIdentityGsm.getPsc());
14160c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        if (DBG) log("getCellLocation(): X ret GSM info=" + cellLocOther);
14170c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        return cellLocOther;
14180c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    } else if (ci instanceof CellInfoWcdma) {
14190c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        CellInfoWcdma cellInfoWcdma = (CellInfoWcdma)ci;
14200c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        CellIdentityWcdma cellIdentityWcdma = cellInfoWcdma.getCellIdentity();
14210c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        cellLocOther.setLacAndCid(cellIdentityWcdma.getLac(),
14220c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                                cellIdentityWcdma.getCid());
14230c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        cellLocOther.setPsc(cellIdentityWcdma.getPsc());
14240c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        if (DBG) log("getCellLocation(): X ret WCDMA info=" + cellLocOther);
14250c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        return cellLocOther;
14260c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    } else if ((ci instanceof CellInfoLte) &&
14270c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                            ((cellLocOther.getLac() < 0) || (cellLocOther.getCid() < 0))) {
14280c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        // We'll return the first good LTE info we get if there is no better answer
14290c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        CellInfoLte cellInfoLte = (CellInfoLte)ci;
14300c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        CellIdentityLte cellIdentityLte = cellInfoLte.getCellIdentity();
14310c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        if ((cellIdentityLte.getTac() != Integer.MAX_VALUE)
14320c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                                && (cellIdentityLte.getCi() != Integer.MAX_VALUE)) {
14330c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                            cellLocOther.setLacAndCid(cellIdentityLte.getTac(),
14340c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                                    cellIdentityLte.getCi());
14350c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                            cellLocOther.setPsc(0);
14360c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                            if (DBG) {
14370c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                                log("getCellLocation(): possible LTE cellLocOther=" + cellLocOther);
14380c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                            }
14390c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                        }
14400c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    }
14410c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                }
14420c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                if (DBG) {
14430c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    log("getCellLocation(): X ret best answer cellLocOther=" + cellLocOther);
14440c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                }
14450c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                return cellLocOther;
14460c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville            } else {
14470c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                if (DBG) {
14480c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                    log("getCellLocation(): X empty mCellLoc and CellInfo mCellLoc=" + mCellLoc);
14490c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                }
14500c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville                return mCellLoc;
14510c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville            }
14520c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville        }
14530c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville    }
14540c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville
14550c5a2697697b49228bd2e23dc8d8217877a0fd7bWink Saville    /**
14560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * nitzReceiveTime is time_t that the NITZ time was posted
14570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
14580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void setTimeFromNITZString (String nitz, long nitzReceiveTime) {
14590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // "yy/mm/dd,hh:mm:ss(+/-)tz"
14600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // tz is in number of quarter-hours
14610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        long start = SystemClock.elapsedRealtime();
14630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {log("NITZ: " + nitz + "," + nitzReceiveTime +
14640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        " start=" + start + " delay=" + (start - nitzReceiveTime));
14650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
14660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
14680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            /* NITZ time (hour:min:sec) will be in UTC but it supplies the timezone
14690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             * offset as well (which we won't worry about until later) */
14700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
14710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.clear();
14730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.DST_OFFSET, 0);
14740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String[] nitzSubs = nitz.split("[/:,+-]");
14760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int year = 2000 + Integer.parseInt(nitzSubs[0]);
14780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.YEAR, year);
14790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // month is 0 based!
14810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int month = Integer.parseInt(nitzSubs[1]) - 1;
14820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.MONTH, month);
14830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int date = Integer.parseInt(nitzSubs[2]);
14850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.DATE, date);
14860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int hour = Integer.parseInt(nitzSubs[3]);
14880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.HOUR, hour);
14890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int minute = Integer.parseInt(nitzSubs[4]);
14910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.MINUTE, minute);
14920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int second = Integer.parseInt(nitzSubs[5]);
14940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.SECOND, second);
14950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            boolean sign = (nitz.indexOf('-') == -1);
14970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int tzOffset = Integer.parseInt(nitzSubs[6]);
14990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int dst = (nitzSubs.length >= 8 ) ? Integer.parseInt(nitzSubs[7])
15010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                              : 0;
15020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // The zone offset received from NITZ is for current local time,
15040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // so DST correction is already applied.  Don't add it again.
15050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //
15060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // tzOffset += dst * 4;
15070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //
15080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // We could unapply it if we wanted the raw offset.
15090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            tzOffset = (sign ? 1 : -1) * tzOffset * 15 * 60 * 1000;
15110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            TimeZone    zone = null;
15130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // As a special extension, the Android emulator appends the name of
15150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // the host computer's timezone to the nitz string. this is zoneinfo
15160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // timezone name of the form Area!Location or Area!Location!SubLocation
15170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // so we need to convert the ! into /
15180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (nitzSubs.length >= 9) {
15190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                String  tzname = nitzSubs[8].replace('!','/');
15200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                zone = TimeZone.getTimeZone( tzname );
15210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
15220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String iso = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY);
15240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (zone == null) {
15260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (mGotCountryCode) {
15280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (iso != null && iso.length() > 0) {
15290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = TimeUtils.getTimeZone(tzOffset, dst != 0,
15300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                c.getTimeInMillis(),
15310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                iso);
15320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
15330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // We don't have a valid iso country code.  This is
15340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // most likely because we're on a test network that's
15350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // using a bogus MCC (eg, "001"), so get a TimeZone
15360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // based only on the NITZ parameters.
15370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = getNitzTimeZone(tzOffset, (dst != 0), c.getTimeInMillis());
15380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
15390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
15400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
15410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if ((zone == null) || (mZoneOffset != tzOffset) || (mZoneDst != (dst != 0))){
15430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // We got the time before the country or the zone has changed
15440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // so we don't know how to identify the DST rules yet.  Save
15450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // the information and hope to fix it up later.
15460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNeedFixZoneAfterNitz = true;
15480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mZoneOffset  = tzOffset;
15490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mZoneDst     = dst != 0;
15500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mZoneTime    = c.getTimeInMillis();
15510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
15520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (zone != null) {
15540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (getAutoTimeZone()) {
15550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setAndBroadcastNetworkSetTimeZone(zone.getID());
15560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
15570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                saveNitzTimeZone(zone.getID());
15580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
15590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String ignore = SystemProperties.get("gsm.ignore-nitz");
15610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (ignore != null && ignore.equals("yes")) {
15620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("NITZ: Not setting clock because gsm.ignore-nitz is set");
15630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
15640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
15650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            try {
15670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mWakeLock.acquire();
15680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (getAutoTime()) {
15700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    long millisSinceNitzReceived
15710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            = SystemClock.elapsedRealtime() - nitzReceiveTime;
15720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (millisSinceNitzReceived < 0) {
15740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Sanity check: something is wrong
15750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) {
15760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            log("NITZ: not setting time, clock has rolled "
15770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                            + "backwards since NITZ time was received, "
15780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                            + nitz);
15790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
15800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        return;
15810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
15820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (millisSinceNitzReceived > Integer.MAX_VALUE) {
15840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // If the time is this far off, something is wrong > 24 days!
15850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) {
15860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            log("NITZ: not setting time, processing has taken "
15870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        + (millisSinceNitzReceived / (1000 * 60 * 60 * 24))
15880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        + " days");
15890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
15900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        return;
15910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
15920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Note: with range checks above, cast to int is safe
15940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    c.add(Calendar.MILLISECOND, (int)millisSinceNitzReceived);
15950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) {
15970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("NITZ: Setting time of day to " + c.getTime()
15980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + " NITZ receive delay(ms): " + millisSinceNitzReceived
15990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + " gained(ms): "
16000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + (c.getTimeInMillis() - System.currentTimeMillis())
16010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + " from " + nitz);
16020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
16030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setAndBroadcastNetworkSetTime(c.getTimeInMillis());
160599c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                    Rlog.i(LOG_TAG, "NITZ: after Setting time of day");
16060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
16070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SystemProperties.set("gsm.nitz.time", String.valueOf(c.getTimeInMillis()));
16080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                saveNitzTime(c.getTimeInMillis());
1609cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (VDBG) {
16100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    long end = SystemClock.elapsedRealtime();
16110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("NITZ: end=" + end + " dur=" + (end - start));
16120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
16130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNitzUpdatedTime = true;
16140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } finally {
16150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mWakeLock.release();
16160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
16170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (RuntimeException ex) {
16180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("NITZ: Parsing NITZ time " + nitz + " ex=" + ex);
16190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean getAutoTime() {
16230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
162422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            return Settings.Global.getInt(mPhone.getContext().getContentResolver(),
1625069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate                    Settings.Global.AUTO_TIME) > 0;
16260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (SettingNotFoundException snfe) {
16270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
16280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean getAutoTimeZone() {
16320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
163322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            return Settings.Global.getInt(mPhone.getContext().getContentResolver(),
1634069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate                    Settings.Global.AUTO_TIME_ZONE) > 0;
16350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (SettingNotFoundException snfe) {
16360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
16370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void saveNitzTimeZone(String zoneId) {
16410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mSavedTimeZone = zoneId;
16420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void saveNitzTime(long time) {
16450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mSavedTime = time;
16460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mSavedAtTime = SystemClock.elapsedRealtime();
16470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
16500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Set the timezone and send out a sticky broadcast so the system can
16510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * determine if the timezone was set by the carrier.
16520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
16530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param zoneId timezone set by carrier
16540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
16550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void setAndBroadcastNetworkSetTimeZone(String zoneId) {
16560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setAndBroadcastNetworkSetTimeZone: setTimeZone=" + zoneId);
16570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AlarmManager alarm =
165822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
16590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        alarm.setTimeZone(zoneId);
16600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE);
16610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
16620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.putExtra("time-zone", zoneId);
166322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.getContext().sendStickyBroadcastAsUser(intent, UserHandle.ALL);
16640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
16650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("setAndBroadcastNetworkSetTimeZone: call alarm.setTimeZone and broadcast zoneId=" +
16660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                zoneId);
16670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
16710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Set the time and Send out a sticky broadcast so the system can determine
16720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * if the time was set by the carrier.
16730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
16740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param time time set by network
16750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
16760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void setAndBroadcastNetworkSetTime(long time) {
16770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setAndBroadcastNetworkSetTime: time=" + time + "ms");
16780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SystemClock.setCurrentTimeMillis(time);
16790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME);
16800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
16810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.putExtra("time", time);
168222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.getContext().sendStickyBroadcastAsUser(intent, UserHandle.ALL);
16830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void revertToNitzTime() {
168622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (Settings.Global.getInt(mPhone.getContext().getContentResolver(),
1687069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate                Settings.Global.AUTO_TIME, 0) == 0) {
16880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
16890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
16910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("Reverting to NITZ Time: mSavedTime=" + mSavedTime
16920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                + " mSavedAtTime=" + mSavedAtTime);
16930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mSavedTime != 0 && mSavedAtTime != 0) {
16950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setAndBroadcastNetworkSetTime(mSavedTime
16960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    + (SystemClock.elapsedRealtime() - mSavedAtTime));
16970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void revertToNitzTimeZone() {
170122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (Settings.Global.getInt(mPhone.getContext().getContentResolver(),
1702069488059d9619a2b8bd070e85d6d657bddcf65aChristopher Tate                Settings.Global.AUTO_TIME_ZONE, 0) == 0) {
17030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
17040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("Reverting to NITZ TimeZone: tz='" + mSavedTimeZone);
17060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mSavedTimeZone != null) {
17070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setAndBroadcastNetworkSetTimeZone(mSavedTimeZone);
17080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
17100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
17120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Post a notification to NotificationManager for restricted state
17130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
17140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param notifyType is one state of PS/CS_*_ENABLE/DISABLE
17150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
17160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void setNotification(int notifyType) {
17170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setNotification: create notification " + notifyType);
171922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        Context context = mPhone.getContext();
17200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification = new Notification();
17220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.when = System.currentTimeMillis();
17230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.flags = Notification.FLAG_AUTO_CANCEL;
17240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.icon = com.android.internal.R.drawable.stat_sys_warning;
17250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent();
17260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.contentIntent = PendingIntent
17270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        .getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
17280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CharSequence details = "";
17300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CharSequence title = context.getText(com.android.internal.R.string.RestrictedChangedTitle);
17310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int notificationId = CS_NOTIFICATION;
17320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (notifyType) {
17340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PS_ENABLED:
17350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notificationId = PS_NOTIFICATION;
1736cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            details = context.getText(com.android.internal.R.string.RestrictedOnData);
17370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
17380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PS_DISABLED:
17390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notificationId = PS_NOTIFICATION;
17400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
17410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CS_ENABLED:
1742cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            details = context.getText(com.android.internal.R.string.RestrictedOnAllVoice);
17430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
17440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CS_NORMAL_ENABLED:
1745cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            details = context.getText(com.android.internal.R.string.RestrictedOnNormal);
17460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
17470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CS_EMERGENCY_ENABLED:
1748cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            details = context.getText(com.android.internal.R.string.RestrictedOnEmergency);
17490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
17500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CS_DISABLED:
17510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // do nothing and cancel the notification later
17520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
17530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setNotification: put notification " + title + " / " +details);
17560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.tickerText = title;
17570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.setLatestEventInfo(context, title, details,
17580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNotification.contentIntent);
17590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        NotificationManager notificationManager = (NotificationManager)
17610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            context.getSystemService(Context.NOTIFICATION_SERVICE);
17620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (notifyType == PS_DISABLED || notifyType == CS_DISABLED) {
17640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // cancel previous post notification
17650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notificationManager.cancel(notificationId);
17660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
17670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // update restricted state notification
17680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notificationManager.notify(notificationId, mNotification);
17690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
17700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
17710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
1773e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected void onUpdateIccAvailability() {
1774e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (mUiccController == null ) {
1775e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            return;
1776e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        }
1777e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
1778e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        UiccCardApplication newUiccApplication =
1779e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccController.getUiccCardApplication(UiccController.APP_FAM_3GPP);
1780e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
1781e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mUiccApplcation != newUiccApplication) {
1782e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mUiccApplcation != null) {
1783e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                log("Removing stale icc objects.");
1784e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplcation.unregisterForReady(this);
1785e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                if (mIccRecords != null) {
1786e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                    mIccRecords.unregisterForRecordsLoaded(this);
1787e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                }
1788e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                mIccRecords = null;
1789e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplcation = null;
1790e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            }
1791e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (newUiccApplication != null) {
1792e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                log("New card found");
1793e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplcation = newUiccApplication;
1794e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mIccRecords = mUiccApplcation.getIccRecords();
1795e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplcation.registerForReady(this, EVENT_SIM_READY, null);
1796e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                if (mIccRecords != null) {
1797e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                    mIccRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
1798e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                }
1799e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            }
1800e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        }
1801e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    }
1802e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    @Override
18030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void log(String s) {
180499c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.d(LOG_TAG, "[GsmSST] " + s);
18050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
18060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
18080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void loge(String s) {
180999c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.e(LOG_TAG, "[GsmSST] " + s);
18100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
18110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
18130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
18140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println("GsmServiceStateTracker extends:");
18150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        super.dump(fd, pw, args);
181622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mPhone=" + mPhone);
181722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mSS=" + mSS);
181822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mNewSS=" + mNewSS);
181922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mCellLoc=" + mCellLoc);
182022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mNewCellLoc=" + mNewCellLoc);
18210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mPreferredNetworkType=" + mPreferredNetworkType);
18220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mMaxDataCalls=" + mMaxDataCalls);
18230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNewMaxDataCalls=" + mNewMaxDataCalls);
18240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mReasonDataDenied=" + mReasonDataDenied);
18250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNewReasonDataDenied=" + mNewReasonDataDenied);
18260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mGsmRoaming=" + mGsmRoaming);
18270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mDataRoaming=" + mDataRoaming);
18280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mEmergencyOnly=" + mEmergencyOnly);
18290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNeedFixZoneAfterNitz=" + mNeedFixZoneAfterNitz);
18300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mZoneOffset=" + mZoneOffset);
18310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mZoneDst=" + mZoneDst);
18320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mZoneTime=" + mZoneTime);
18330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mGotCountryCode=" + mGotCountryCode);
18340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNitzUpdatedTime=" + mNitzUpdatedTime);
18350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mSavedTimeZone=" + mSavedTimeZone);
18360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mSavedTime=" + mSavedTime);
18370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mSavedAtTime=" + mSavedAtTime);
18380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mStartedGprsRegCheck=" + mStartedGprsRegCheck);
18390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mReportedGprsNoReg=" + mReportedGprsNoReg);
18400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNotification=" + mNotification);
18410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mWakeLock=" + mWakeLock);
184222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mCurSpn=" + mCurSpn);
184322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mCurShowSpn=" + mCurShowSpn);
184422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mCurPlmn=" + mCurPlmn);
184522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mCurShowPlmn=" + mCurShowPlmn);
18460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
18470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
1848