GsmServiceStateTracker.java revision e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4
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 com.android.internal.telephony.CommandException;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CommandsInterface;
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.DataConnectionTracker;
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.EventLogTags;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.IccCard;
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.IccCardConstants;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.IccCardStatus;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.MccTable;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.Phone;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.RestrictedState;
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.RILConstants;
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.ServiceStateTracker;
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.TelephonyIntents;
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.TelephonyProperties;
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.AlarmManager;
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.Notification;
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.NotificationManager;
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.PendingIntent;
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.BroadcastReceiver;
390825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.ContentResolver;
400825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Context;
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Intent;
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.IntentFilter;
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.res.Resources;
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.database.ContentObserver;
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult;
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler;
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.PowerManager;
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Registrant;
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.RegistrantList;
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.SystemClock;
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.SystemProperties;
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.provider.Settings;
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.provider.Settings.SettingNotFoundException;
55ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Savilleimport android.telephony.CellInfo;
56ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Savilleimport android.telephony.CellInfoGsm;
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.ServiceState;
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.SignalStrength;
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.gsm.GsmCellLocation;
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.text.TextUtils;
610825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.EventLog;
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.Log;
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.TimeUtils;
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.FileDescriptor;
660825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.PrintWriter;
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList;
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Arrays;
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Calendar;
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Collection;
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Date;
720825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.HashSet;
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.TimeZone;
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillefinal class GsmServiceStateTracker extends ServiceStateTracker {
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final String LOG_TAG = "GSM";
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final boolean DBG = true;
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    GSMPhone phone;
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    GsmCellLocation cellLoc;
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    GsmCellLocation newCellLoc;
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    int mPreferredNetworkType;
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int gprsState = ServiceState.STATE_OUT_OF_SERVICE;
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int newGPRSState = ServiceState.STATE_OUT_OF_SERVICE;
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mMaxDataCalls = 1;
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mNewMaxDataCalls = 1;
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mReasonDataDenied = -1;
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mNewReasonDataDenied = -1;
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * GSM roaming status solely based on TS 27.007 7.2 CREG. Only used by
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * handlePollStateResult to store CREG roaming result.
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mGsmRoaming = false;
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Data roaming status solely based on TS 27.007 10.1.19 CGREG. Only used by
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * handlePollStateResult to store CGREG roaming result.
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mDataRoaming = false;
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Mark when service state is in emergency call only mode
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mEmergencyOnly = false;
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Sometimes we get the NITZ time before we know what country we
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * are in. Keep the time zone information from the NITZ string so
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * we can fix the time zone once know the country.
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mNeedFixZoneAfterNitz = false;
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int mZoneOffset;
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mZoneDst;
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private long mZoneTime;
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mGotCountryCode = false;
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private ContentResolver cr;
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Boolean is true is setTimeFromNITZString was called */
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mNitzUpdatedTime = false;
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    String mSavedTimeZone;
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    long mSavedTime;
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    long mSavedAtTime;
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Started the recheck process after finding gprs should registered but not. */
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mStartedGprsRegCheck = false;
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Already sent the event-log for no gprs register. */
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean mReportedGprsNoReg = false;
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * The Notification object given to the NotificationManager.
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Notification mNotification;
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Wake lock used while setting time of day. */
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private PowerManager.WakeLock mWakeLock;
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final String WAKELOCK_TAG = "ServiceStateTracker";
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Keep track of SPN display rules, so we only broadcast intent if something changes. */
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private String curSpn = null;
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private String curPlmn = null;
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int curSpnRule = 0;
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** waiting period before recheck gprs and voice registration. */
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Notification type. */
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int PS_ENABLED = 1001;            // Access Control blocks data service
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int PS_DISABLED = 1002;           // Access Control enables data service
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int CS_ENABLED = 1003;            // Access Control blocks all voice/sms service
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int CS_DISABLED = 1004;           // Access Control enables all voice/sms service
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int CS_NORMAL_ENABLED = 1005;     // Access Control blocks normal voice/sms service
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int CS_EMERGENCY_ENABLED = 1006;  // Access Control blocks emergency call service
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Notification id. */
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int PS_NOTIFICATION = 888;  // Id to update and cancel PS restricted
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int CS_NOTIFICATION = 999;  // Id to update and cancel CS restricted
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        @Override
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        public void onReceive(Context context, Intent intent) {
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (intent.getAction().equals(Intent.ACTION_LOCALE_CHANGED)) {
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // update emergency string whenever locale changed
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                updateSpnDisplay();
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) {
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        @Override
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        public void onChange(boolean selfChange) {
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.i("GsmServiceStateTracker", "Auto time state changed");
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            revertToNitzTime();
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private ContentObserver mAutoTimeZoneObserver = new ContentObserver(new Handler()) {
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        @Override
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        public void onChange(boolean selfChange) {
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.i("GsmServiceStateTracker", "Auto time zone state changed");
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            revertToNitzTimeZone();
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public GsmServiceStateTracker(GSMPhone phone) {
192049ab0421f32e6effc5d1277b69bd382cebadb18Wink Saville        super(phone, phone.mCM, new CellInfoGsm());
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.phone = phone;
1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cellLoc = new GsmCellLocation();
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        newCellLoc = new GsmCellLocation();
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        PowerManager powerManager =
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                (PowerManager)phone.getContext().getSystemService(Context.POWER_SERVICE);
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG);
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.registerForVoiceNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null);
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.setOnNITZTime(this, EVENT_NITZ_TIME, null);
2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.setOnRestrictedStateChanged(this, EVENT_RESTRICTED_STATE_CHANGED, null);
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // system setting property AIRPLANE_MODE_ON is set in Settings.
2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int airplaneMode = Settings.System.getInt(
2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                phone.getContext().getContentResolver(),
2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Settings.System.AIRPLANE_MODE_ON, 0);
2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDesiredPowerState = ! (airplaneMode > 0);
2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cr = phone.getContext().getContentResolver();
2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cr.registerContentObserver(
2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Settings.System.getUriFor(Settings.System.AUTO_TIME), true,
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mAutoTimeObserver);
2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cr.registerContentObserver(
2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Settings.System.getUriFor(Settings.System.AUTO_TIME_ZONE), true,
2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mAutoTimeZoneObserver);
2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        setSignalStrengthDefaultValues();
2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Monitor locale change
2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        IntentFilter filter = new IntentFilter();
2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        filter.addAction(Intent.ACTION_LOCALE_CHANGED);
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.getContext().registerReceiver(mIntentReceiver, filter);
2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Gsm doesn't support OTASP so its not needed
2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.notifyOtaspChanged(OTASP_NOT_NEEDED);
2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
234ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville    @Override
2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dispose() {
236e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        checkCorrectThread();
2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Unregister for all events.
2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.unregisterForAvailable(this);
2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.unregisterForRadioStateChanged(this);
2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.unregisterForVoiceNetworkStateChanged(this);
241e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (mIccCard != null) {mIccCard.unregisterForReady(this);}
242e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (mIccRecords != null) {mIccRecords.unregisterForRecordsLoaded(this);}
2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.unSetOnRestrictedStateChanged(this);
2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.unSetOnNITZTime(this);
2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cr.unregisterContentObserver(this.mAutoTimeObserver);
2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cr.unregisterContentObserver(this.mAutoTimeZoneObserver);
247ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        super.dispose();
2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void finalize() {
2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if(DBG) log("finalize");
2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected Phone getPhone() {
2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return phone;
2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void handleMessage (Message msg) {
2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AsyncResult ar;
2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int[] ints;
2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String[] strings;
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Message message;
2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!phone.mIsTheCurrentActivePhone) {
2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.e(LOG_TAG, "Received message " + msg +
2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    "[" + msg.what + "] while being destroyed. Ignoring.");
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (msg.what) {
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RADIO_AVAILABLE:
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                //this is unnecessary
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                //setPowerStateToDesired();
2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SIM_READY:
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Set the network type, in case the radio does not restore it.
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cm.setCurrentPreferredNetworkType();
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                boolean skipRestoringSelection = phone.getContext().getResources().getBoolean(
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        com.android.internal.R.bool.skip_restoring_network_selection);
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!skipRestoringSelection) {
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // restore the previous network selection.
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    phone.restoreSavedNetworkSelection(null);
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollState();
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Signal strength polling stops when radio is off
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                queueNextSignalStrengthPoll();
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RADIO_STATE_CHANGED:
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // This will do nothing in the radio not
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // available case
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setPowerStateToDesired();
2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollState();
2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_NETWORK_STATE_CHANGED:
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollState();
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_GET_SIGNAL_STRENGTH:
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // This callback is called when signal strength is polled
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // all by itself
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!(cm.getRadioState().isOn())) {
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Polling will continue when radio turns back on
3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return;
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
312e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville                onSignalStrengthResult(ar, true);
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                queueNextSignalStrengthPoll();
3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_GET_LOC_DONE:
3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception == null) {
3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    String states[] = (String[])ar.result;
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int lac = -1;
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int cid = -1;
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (states.length >= 3) {
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        try {
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states[1] != null && states[1].length() > 0) {
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                lac = Integer.parseInt(states[1], 16);
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states[2] != null && states[2].length() > 0) {
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                cid = Integer.parseInt(states[2], 16);
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        } catch (NumberFormatException ex) {
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            Log.w(LOG_TAG, "error parsing location: " + ex);
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    cellLoc.setLacAndCid(lac, cid);
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    phone.notifyLocationChanged();
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Release any temporary cell lock, which could have been
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // acquired to allow a single-shot location update.
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                disableSingleLocationUpdate();
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_STATE_REGISTRATION:
3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_STATE_GPRS:
3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_STATE_OPERATOR:
3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_STATE_NETWORK_SELECTION_MODE:
3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                handlePollStateResult(msg.what, ar);
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_POLL_SIGNAL_STRENGTH:
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Just poll signal strength...not part of pollState()
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cm.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_NITZ_TIME:
3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                String nitzString = (String)((Object[])ar.result)[0];
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                long nitzReceiveTime = ((Long)((Object[])ar.result)[1]).longValue();
3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setTimeFromNITZString(nitzString, nitzReceiveTime);
3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SIGNAL_STRENGTH_UPDATE:
3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // This is a notification from
3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // CommandsInterface.setOnSignalStrengthUpdate
3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // The radio is telling us about signal strength changes
3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // we don't have to ask it
3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                dontPollSignalStrength = true;
3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
379e0e2ceb1ae025e6dd2adda75c32dba93c6dfeea4Wink Saville                onSignalStrengthResult(ar, true);
3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SIM_RECORDS_LOADED:
3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                updateSpnDisplay();
3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_LOCATION_UPDATES_ENABLED:
3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception == null) {
3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    cm.getVoiceRegistrationState(obtainMessage(EVENT_GET_LOC_DONE, null));
3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_SET_PREFERRED_NETWORK_TYPE:
3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Don't care the result, only use for dereg network (COPS=2)
3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                message = obtainMessage(EVENT_RESET_PREFERRED_NETWORK_TYPE, ar.userObj);
3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cm.setPreferredNetworkType(mPreferredNetworkType, message);
3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RESET_PREFERRED_NETWORK_TYPE:
4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.userObj != null) {
4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    AsyncResult.forMessage(((Message) ar.userObj)).exception
4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            = ar.exception;
4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ((Message) ar.userObj).sendToTarget();
4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_GET_PREFERRED_NETWORK_TYPE:
4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ar.exception == null) {
4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mPreferredNetworkType = ((int[])ar.result)[0];
4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mPreferredNetworkType = RILConstants.NETWORK_MODE_GLOBAL;
4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                message = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE, ar.userObj);
4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                int toggledNetworkType = RILConstants.NETWORK_MODE_GLOBAL;
4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cm.setPreferredNetworkType(toggledNetworkType, message);
4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_CHECK_REPORT_GPRS:
4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (ss != null && !isGprsConsistent(gprsState, ss.getState())) {
4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Can't register data service while voice service is ok
4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // i.e. CREG is ok while CGREG is not
4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // possible a network or baseband side error
4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    EventLog.writeEvent(EventLogTags.DATA_NETWORK_REGISTRATION_FAIL,
4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            ss.getOperatorNumeric(), loc != null ? loc.getCid() : -1);
4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mReportedGprsNoReg = true;
4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mStartedGprsRegCheck = false;
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_RESTRICTED_STATE_CHANGED:
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // This is a notification from
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // CommandsInterface.setOnRestrictedStateChanged
4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("EVENT_RESTRICTED_STATE_CHANGED");
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ar = (AsyncResult) msg.obj;
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                onRestrictedStateChanged(ar);
4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                super.handleMessage(msg);
4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void setPowerStateToDesired() {
4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // If we want it on and it's off, turn it on
4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mDesiredPowerState
4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            && cm.getRadioState() == CommandsInterface.RadioState.RADIO_OFF) {
4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cm.setRadioPower(true, null);
4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (!mDesiredPowerState && cm.getRadioState().isOn()) {
4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // If it's on and available and we want it off gracefully
4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            DataConnectionTracker dcTracker = phone.mDataConnectionTracker;
4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            powerOffRadioSafely(dcTracker);
4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } // Otherwise, we're in the desired state
4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void hangupAndPowerOff() {
4700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // hang up all active voice calls
4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (phone.isInCall()) {
4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.mCT.ringingCall.hangupIfAlive();
4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.mCT.backgroundCall.hangupIfAlive();
4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.mCT.foregroundCall.hangupIfAlive();
4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cm.setRadioPower(false, null);
4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void updateSpnDisplay() {
481e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (mIccRecords == null) {
482e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            return;
483e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        }
484e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        int rule = mIccRecords.getDisplayRule(ss.getOperatorNumeric());
485e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        String spn = mIccRecords.getServiceProviderName();
4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String plmn = ss.getOperatorAlphaLong();
4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // For emergency calls only, pass the EmergencyCallsOnly string via EXTRA_PLMN
4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mEmergencyOnly && cm.getRadioState().isOn()) {
4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            plmn = Resources.getSystem().
4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                getText(com.android.internal.R.string.emergency_calls_only).toString();
4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("updateSpnDisplay: emergency only and radio is on plmn='" + plmn + "'");
4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (rule != curSpnRule
4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                || !TextUtils.equals(spn, curSpn)
4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                || !TextUtils.equals(plmn, curPlmn)) {
4980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            boolean showSpn = !mEmergencyOnly && !TextUtils.isEmpty(spn)
4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                && (rule & SIMRecords.SPN_RULE_SHOW_SPN) == SIMRecords.SPN_RULE_SHOW_SPN;
5000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            boolean showPlmn = !TextUtils.isEmpty(plmn) &&
5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                (rule & SIMRecords.SPN_RULE_SHOW_PLMN) == SIMRecords.SPN_RULE_SHOW_PLMN;
5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log(String.format("updateSpnDisplay: changed sending intent" + " rule=" + rule +
5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            " showPlmn='%b' plmn='%s' showSpn='%b' spn='%s'",
5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            showPlmn, plmn, showSpn, spn));
5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Intent intent = new Intent(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
5090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
5100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            intent.putExtra(TelephonyIntents.EXTRA_SHOW_SPN, showSpn);
5110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            intent.putExtra(TelephonyIntents.EXTRA_SPN, spn);
5120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            intent.putExtra(TelephonyIntents.EXTRA_SHOW_PLMN, showPlmn);
5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            intent.putExtra(TelephonyIntents.EXTRA_PLMN, plmn);
5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.getContext().sendStickyBroadcast(intent);
5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        curSpnRule = rule;
5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        curSpn = spn;
5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        curPlmn = plmn;
5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Handle the result of one of the pollState()-related requests
5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void handlePollStateResult (int what, AsyncResult ar) {
5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int ints[];
5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String states[];
5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Ignore stale requests from last poll
5300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ar.userObj != pollingContext) return;
5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ar.exception != null) {
5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CommandException.Error err=null;
5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (ar.exception instanceof CommandException) {
5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                err = ((CommandException)(ar.exception)).getCommandError();
5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (err == CommandException.Error.RADIO_NOT_AVAILABLE) {
5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Radio has crashed or turned off
5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cancelPollState();
5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!cm.getRadioState().isOn()) {
5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Radio has crashed or turned off
5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cancelPollState();
5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) {
5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                loge("RIL implementation has returned an error where it must succeed" +
5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ar.exception);
5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else try {
5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            switch (what) {
5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_POLL_STATE_REGISTRATION:
5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    states = (String[])ar.result;
5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int lac = -1;
5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int cid = -1;
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int regState = -1;
5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int reasonRegStateDenied = -1;
5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int psc = -1;
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (states.length > 0) {
5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        try {
5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            regState = Integer.parseInt(states[0]);
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states.length >= 3) {
5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (states[1] != null && states[1].length() > 0) {
5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    lac = Integer.parseInt(states[1], 16);
5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (states[2] != null && states[2].length() > 0) {
5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    cid = Integer.parseInt(states[2], 16);
5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states.length > 14) {
5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (states[14] != null && states[14].length() > 0) {
5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    psc = Integer.parseInt(states[14], 16);
5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                }
5790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        } catch (NumberFormatException ex) {
5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            loge("error parsing RegistrationState: " + ex);
5820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
5830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mGsmRoaming = regCodeIsRoaming(regState);
5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    newSS.setState (regCodeToServiceState(regState));
5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (regState == 10 || regState == 12 || regState == 13 || regState == 14) {
5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mEmergencyOnly = true;
5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mEmergencyOnly = false;
5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // LAC and CID are -1 if not avail
5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    newCellLoc.setLacAndCid(lac, cid);
5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    newCellLoc.setPsc(psc);
5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_POLL_STATE_GPRS:
6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    states = (String[])ar.result;
6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int type = 0;
6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    regState = -1;
6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mNewReasonDataDenied = -1;
6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mNewMaxDataCalls = 1;
6060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (states.length > 0) {
6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        try {
6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            regState = Integer.parseInt(states[0]);
6090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            // states[3] (if present) is the current radio technology
6110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states.length >= 4 && states[3] != null) {
6120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                type = Integer.parseInt(states[3]);
6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
6140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if ((states.length >= 5 ) && (regState == 3)) {
6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                mNewReasonDataDenied = Integer.parseInt(states[4]);
6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
6170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (states.length >= 6) {
6180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                mNewMaxDataCalls = Integer.parseInt(states[5]);
6190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
6200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        } catch (NumberFormatException ex) {
6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            loge("error parsing GprsRegistrationState: " + ex);
6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
6230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    newGPRSState = regCodeToServiceState(regState);
6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mDataRoaming = regCodeIsRoaming(regState);
6260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mNewRilRadioTechnology = type;
6270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    newSS.setRadioTechnology(type);
6280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
6290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_POLL_STATE_OPERATOR:
6310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    String opNames[] = (String[])ar.result;
6320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (opNames != null && opNames.length >= 3) {
6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                         newSS.setOperatorName (opNames[0], opNames[1], opNames[2]);
6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
6370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_POLL_STATE_NETWORK_SELECTION_MODE:
6390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ints = (int[])ar.result;
6400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    newSS.setIsManualSelection(ints[0] == 1);
6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (RuntimeException ex) {
6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("Exception while polling service state. Probably malformed RIL response." + ex);
6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pollingContext[0]--;
6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (pollingContext[0] == 0) {
6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            /**
6520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             *  Since the roaming states of gsm service (from +CREG) and
6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             *  data service (from +CGREG) could be different, the new SS
6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             *  is set roaming while either one is roaming.
6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             *
6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             *  There is an exception for the above rule. The new SS is not set
6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             *  as roaming while gsm service reports roaming but indeed it is
6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             *  not roaming between operators.
6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             */
6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            boolean roaming = (mGsmRoaming || mDataRoaming);
6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mGsmRoaming && !isRoamingBetweenOperators(mGsmRoaming, newSS)) {
6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                roaming = false;
6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            newSS.setRoaming(roaming);
6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            newSS.setEmergencyOnly(mEmergencyOnly);
6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            pollStateDone();
6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
670c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void setSignalStrengthDefaultValues() {
6715b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        mSignalStrength = new SignalStrength(true);
6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * A complete "service state" from our perspective is
6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * composed of a handful of separate requests to the radio.
6770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
6780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * We make all of these requests at once, but then abandon them
6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * and start over again if the radio notifies us that some
6800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * event has changed
6810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
6820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void pollState() {
6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pollingContext = new int[1];
6840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pollingContext[0] = 0;
6850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (cm.getRadioState()) {
6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case RADIO_UNAVAILABLE:
6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                newSS.setStateOutOfService();
6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                newCellLoc.setStateInvalid();
6900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setSignalStrengthDefaultValues();
6910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mGotCountryCode = false;
6920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNitzUpdatedTime = false;
6930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollStateDone();
6940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
6950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case RADIO_OFF:
6970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                newSS.setStateOff();
6980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                newCellLoc.setStateInvalid();
6990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setSignalStrengthDefaultValues();
7000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mGotCountryCode = false;
7010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNitzUpdatedTime = false;
7020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollStateDone();
7030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
7040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
7060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Issue all poll-related commands at once
7070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // then count down the responses, which
7080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // are allowed to arrive out-of-order
7090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollingContext[0]++;
7110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cm.getOperator(
7120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    obtainMessage(
7130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        EVENT_POLL_STATE_OPERATOR, pollingContext));
7140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollingContext[0]++;
7160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cm.getDataRegistrationState(
7170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    obtainMessage(
7180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        EVENT_POLL_STATE_GPRS, pollingContext));
7190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollingContext[0]++;
7210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cm.getVoiceRegistrationState(
7220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    obtainMessage(
7230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        EVENT_POLL_STATE_REGISTRATION, pollingContext));
7240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                pollingContext[0]++;
7260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cm.getNetworkSelectionMode(
7270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    obtainMessage(
7280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        EVENT_POLL_STATE_NETWORK_SELECTION_MODE, pollingContext));
7290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
7300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void pollStateDone() {
7340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
7350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("Poll ServiceState done: " +
7360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                " oldSS=[" + ss + "] newSS=[" + newSS +
7370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                "] oldGprs=" + gprsState + " newData=" + newGPRSState +
7380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                " oldMaxDataCalls=" + mMaxDataCalls +
7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                " mNewMaxDataCalls=" + mNewMaxDataCalls +
7400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                " oldReasonDataDenied=" + mReasonDataDenied +
7410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                " mNewReasonDataDenied=" + mNewReasonDataDenied +
7420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                " oldType=" + ServiceState.rilRadioTechnologyToString(mRilRadioTechnology) +
7430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                " newType=" + ServiceState.rilRadioTechnologyToString(mNewRilRadioTechnology));
7440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasRegistered =
7470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ss.getState() != ServiceState.STATE_IN_SERVICE
7480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            && newSS.getState() == ServiceState.STATE_IN_SERVICE;
7490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasDeregistered =
7510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ss.getState() == ServiceState.STATE_IN_SERVICE
7520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            && newSS.getState() != ServiceState.STATE_IN_SERVICE;
7530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasGprsAttached =
7550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                gprsState != ServiceState.STATE_IN_SERVICE
7560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                && newGPRSState == ServiceState.STATE_IN_SERVICE;
7570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasGprsDetached =
7590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                gprsState == ServiceState.STATE_IN_SERVICE
7600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                && newGPRSState != ServiceState.STATE_IN_SERVICE;
7610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasRadioTechnologyChanged = mRilRadioTechnology != mNewRilRadioTechnology;
7630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasChanged = !newSS.equals(ss);
7650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasRoamingOn = !ss.getRoaming() && newSS.getRoaming();
7670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasRoamingOff = ss.getRoaming() && !newSS.getRoaming();
7690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasLocationChanged = !newCellLoc.equals(cellLoc);
7710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Add an event log when connection state changes
7730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ss.getState() != newSS.getState() || gprsState != newGPRSState) {
7740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            EventLog.writeEvent(EventLogTags.GSM_SERVICE_STATE_CHANGE,
7750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ss.getState(), gprsState, newSS.getState(), newGPRSState);
7760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ServiceState tss;
7790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        tss = ss;
7800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ss = newSS;
7810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        newSS = tss;
7820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // clean slate for next time
7830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        newSS.setStateOutOfService();
7840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        GsmCellLocation tcl = cellLoc;
7860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cellLoc = newCellLoc;
7870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        newCellLoc = tcl;
7880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Add an event log when network type switched
7900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // TODO: we may add filtering to reduce the event logged,
7910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // i.e. check preferred network setting, only switch to 2G, etc
7920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasRadioTechnologyChanged) {
7930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int cid = -1;
7940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
7950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (loc != null) cid = loc.getCid();
7960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            EventLog.writeEvent(EventLogTags.GSM_RAT_SWITCHED, cid, mRilRadioTechnology,
7970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mNewRilRadioTechnology);
7980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
7990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("RAT switched " + ServiceState.rilRadioTechnologyToString(mRilRadioTechnology) +
8000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        " -> " + ServiceState.rilRadioTechnologyToString(mNewRilRadioTechnology) +
8010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        " at cell " + cid);
8020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        gprsState = newGPRSState;
8060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mReasonDataDenied = mNewReasonDataDenied;
8070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mMaxDataCalls = mNewMaxDataCalls;
8080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mRilRadioTechnology = mNewRilRadioTechnology;
8090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // this new state has been applied - forget it until we get a new new state
8100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNewRilRadioTechnology = 0;
8110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        newSS.setStateOutOfService(); // clean slate for next time
8140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasRadioTechnologyChanged) {
8160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
8170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ServiceState.rilRadioTechnologyToString(mRilRadioTechnology));
8180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasRegistered) {
8210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mNetworkAttachedRegistrants.notifyRegistrants();
8220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) {
8240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("pollStateDone: registering current mNitzUpdatedTime=" +
8250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mNitzUpdatedTime + " changing to false");
8260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
8270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mNitzUpdatedTime = false;
8280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
8290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasChanged) {
8310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String operatorNumeric;
8320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            updateSpnDisplay();
8340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
8360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ss.getOperatorAlphaLong());
8370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String prevOperatorNumeric =
8390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, "");
8400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            operatorNumeric = ss.getOperatorNumeric();
8410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
8420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (operatorNumeric == null) {
8440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (DBG) log("operatorNumeric is null");
8450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
8460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mGotCountryCode = false;
8470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNitzUpdatedTime = false;
8480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
8490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                String iso = "";
8507c491bb3d140e2579c2c01edca94305701664db5Rekha Kumar                String mcc = "";
8510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                try{
8527c491bb3d140e2579c2c01edca94305701664db5Rekha Kumar                    mcc = operatorNumeric.substring(0, 3);
8530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    iso = MccTable.countryCodeForMcc(Integer.parseInt(mcc));
8540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } catch ( NumberFormatException ex){
8550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    loge("pollStateDone: countryCodeForMcc error" + ex);
8560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } catch ( StringIndexOutOfBoundsException ex) {
8570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    loge("pollStateDone: countryCodeForMcc error" + ex);
8580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
8590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, iso);
8610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mGotCountryCode = true;
8620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                TimeZone zone = null;
8640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!mNitzUpdatedTime && !mcc.equals("000") && !TextUtils.isEmpty(iso) &&
8660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        getAutoTimeZone()) {
8670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Test both paths if ignore nitz is true
8690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    boolean testOneUniqueOffsetPath = SystemProperties.getBoolean(
8700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                TelephonyProperties.PROPERTY_IGNORE_NITZ, false) &&
8710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                    ((SystemClock.uptimeMillis() & 1) == 0);
8720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ArrayList<TimeZone> uniqueZones = TimeUtils.getTimeZonesWithUniqueOffsets(iso);
8740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if ((uniqueZones.size() == 1) || testOneUniqueOffsetPath) {
8750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = uniqueZones.get(0);
8760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) {
8770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                           log("pollStateDone: no nitz but one TZ for iso-cc=" + iso +
8780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                   " with zone.getID=" + zone.getID() +
8790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                   " testOneUniqueOffsetPath=" + testOneUniqueOffsetPath);
8800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
8810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        setAndBroadcastNetworkSetTimeZone(zone.getID());
8820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
8830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) {
8840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            log("pollStateDone: there are " + uniqueZones.size() +
8850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                " unique offsets for iso-cc='" + iso +
8860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                " testOneUniqueOffsetPath=" + testOneUniqueOffsetPath +
8870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                "', do nothing");
8880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
8890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
8900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
8910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (shouldFixTimeZoneNow(phone, operatorNumeric, prevOperatorNumeric,
8930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mNeedFixZoneAfterNitz)) {
8940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // If the offset is (0, false) and the timezone property
8950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // is set, use the timezone property rather than
8960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // GMT.
8970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    String zoneName = SystemProperties.get(TIMEZONE_PROPERTY);
8980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) {
8990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("pollStateDone: fix time zone zoneName='" + zoneName +
9000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "' mZoneOffset=" + mZoneOffset + " mZoneDst=" + mZoneDst +
9010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            " iso-cc='" + iso +
9020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            "' iso-cc-idx=" + Arrays.binarySearch(GMT_COUNTRY_CODES, iso));
9030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
9040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // "(mZoneOffset == 0) && (mZoneDst == false) &&
9060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    //  (Arrays.binarySearch(GMT_COUNTRY_CODES, iso) < 0)"
9070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // means that we received a NITZ string telling
9080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // it is in GMT+0 w/ DST time zone
9090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // BUT iso tells is NOT, e.g, a wrong NITZ reporting
9100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // local time w/ 0 offset.
9110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if ((mZoneOffset == 0) && (mZoneDst == false) &&
9120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        (zoneName != null) && (zoneName.length() > 0) &&
9130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        (Arrays.binarySearch(GMT_COUNTRY_CODES, iso) < 0)) {
9140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = TimeZone.getDefault();
9150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (mNeedFixZoneAfterNitz) {
9160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            // For wrong NITZ reporting local time w/ 0 offset,
9170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            // need adjust time to reflect default timezone setting
9180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            long ctm = System.currentTimeMillis();
9190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            long tzOffset = zone.getOffset(ctm);
9200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (DBG) {
9210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                log("pollStateDone: tzOffset=" + tzOffset + " ltod=" +
9220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        TimeUtils.logTimeOfDay(ctm));
9230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
9240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            if (getAutoTime()) {
9250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                long adj = ctm - tzOffset;
9260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                if (DBG) log("pollStateDone: adj ltod=" +
9270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        TimeUtils.logTimeOfDay(adj));
9280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                setAndBroadcastNetworkSetTime(adj);
9290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            } else {
9300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                // Adjust the saved NITZ time to account for tzOffset.
9310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                mSavedTime = mSavedTime - tzOffset;
9320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            }
9330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
9340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("pollStateDone: using default TimeZone");
9350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else if (iso.equals("")){
9360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Country code not found.  This is likely a test network.
9370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Get a TimeZone based only on the NITZ parameters (best guess).
9380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = getNitzTimeZone(mZoneOffset, mZoneDst, mZoneTime);
9390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("pollStateDone: using NITZ TimeZone");
9400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
9410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = TimeUtils.getTimeZone(mZoneOffset, mZoneDst, mZoneTime, iso);
9420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) log("pollStateDone: using getTimeZone(off, dst, time, iso)");
9430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
9440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mNeedFixZoneAfterNitz = false;
9460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (zone != null) {
9480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("pollStateDone: zone != null zone.getID=" + zone.getID());
9490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (getAutoTimeZone()) {
9500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            setAndBroadcastNetworkSetTimeZone(zone.getID());
9510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
9520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        saveNitzTimeZone(zone.getID());
9530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
9540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("pollStateDone: zone == null");
9550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
9560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
9570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
9580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
9600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ss.getRoaming() ? "true" : "false");
9610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.notifyServiceStateChanged(ss);
9630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasGprsAttached) {
9660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mAttachedRegistrants.notifyRegistrants();
9670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasGprsDetached) {
9700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mDetachedRegistrants.notifyRegistrants();
9710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasRadioTechnologyChanged) {
9740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.notifyDataConnection(Phone.REASON_NW_TYPE_CHANGED);
9750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasRoamingOn) {
9780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mRoamingOnRegistrants.notifyRegistrants();
9790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasRoamingOff) {
9820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mRoamingOffRegistrants.notifyRegistrants();
9830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasLocationChanged) {
9860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            phone.notifyLocationChanged();
9870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
9880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (! isGprsConsistent(gprsState, ss.getState())) {
9900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!mStartedGprsRegCheck && !mReportedGprsNoReg) {
9910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mStartedGprsRegCheck = true;
9920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                int check_period = Settings.Secure.getInt(
9940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        phone.getContext().getContentResolver(),
9950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        Settings.Secure.GPRS_REGISTER_CHECK_PERIOD_MS,
9960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        DEFAULT_GPRS_CHECK_PERIOD_MILLIS);
9970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                sendMessageDelayed(obtainMessage(EVENT_CHECK_REPORT_GPRS),
9980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        check_period);
9990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
10000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
10010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mReportedGprsNoReg = false;
10020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1003ef1d4bff9bbf7d967dbcace73f08910e14e367d0Wink Saville        // TODO: Add GsmCellIdenity updating, see CdmaLteServiceStateTracker.
10040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
10070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Check if GPRS got registered while voice is registered.
10080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
10090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param gprsState for GPRS registration state, i.e. CGREG in GSM
10100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param serviceState for voice registration state, i.e. CREG in GSM
10110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return false if device only register to voice but not gprs
10120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
10130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean isGprsConsistent(int gprsState, int serviceState) {
10140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return !((serviceState == ServiceState.STATE_IN_SERVICE) &&
10150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                (gprsState != ServiceState.STATE_IN_SERVICE));
10160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
10190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Returns a TimeZone object based only on parameters from the NITZ string.
10200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
10210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private TimeZone getNitzTimeZone(int offset, boolean dst, long when) {
10220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        TimeZone guess = findTimeZone(offset, dst, when);
10230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (guess == null) {
10240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Couldn't find a proper timezone.  Perhaps the DST data is wrong.
10250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            guess = findTimeZone(offset, !dst, when);
10260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("getNitzTimeZone returning " + (guess == null ? guess : guess.getID()));
10280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return guess;
10290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private TimeZone findTimeZone(int offset, boolean dst, long when) {
10320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int rawOffset = offset;
10330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (dst) {
10340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            rawOffset -= 3600000;
10350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String[] zones = TimeZone.getAvailableIDs(rawOffset);
10370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        TimeZone guess = null;
10380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Date d = new Date(when);
10390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (String zone : zones) {
10400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            TimeZone tz = TimeZone.getTimeZone(zone);
10410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (tz.getOffset(when) == offset &&
10420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                tz.inDaylightTime(d) == dst) {
10430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                guess = tz;
10440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
10450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
10460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return guess;
10490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void queueNextSignalStrengthPoll() {
10520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (dontPollSignalStrength) {
10530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // The radio is telling us about signal strength changes
10540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // we don't have to ask it
10550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
10560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
10570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Message msg;
10590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        msg = obtainMessage();
10610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        msg.what = EVENT_POLL_SIGNAL_STRENGTH;
10620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        long nextTime;
10640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // TODO Don't poll signal strength if screen is off
10660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        sendMessageDelayed(msg, POLL_PERIOD_MILLIS);
10670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
10680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
10700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Set restricted state based on the OnRestrictedStateChanged notification
10710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * If any voice or packet restricted state changes, trigger a UI
10720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * notification and notify registrants when sim is ready.
10730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
10740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param ar an int value of RIL_RESTRICTED_STATE_*
10750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
10760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void onRestrictedStateChanged(AsyncResult ar) {
10770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        RestrictedState newRs = new RestrictedState();
10780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("onRestrictedStateChanged: E rs "+ mRestrictedState);
10800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ar.exception == null) {
10820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int[] ints = (int[])ar.result;
10830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int state = ints[0];
10840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            newRs.setCsEmergencyRestricted(
10860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ((state & RILConstants.RIL_RESTRICTED_STATE_CS_EMERGENCY) != 0) ||
10870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
10880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //ignore the normal call and data restricted state before SIM READY
108954007c8258ed3ea20c1a00c9385cf11129218efbAlex Yakavenka            if (mIccCard != null && mIccCard.getState() == IccCardConstants.State.READY) {
10900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                newRs.setCsNormalRestricted(
10910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ((state & RILConstants.RIL_RESTRICTED_STATE_CS_NORMAL) != 0) ||
10920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
10930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                newRs.setPsRestricted(
10940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        (state & RILConstants.RIL_RESTRICTED_STATE_PS_ALL)!= 0);
10950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
10960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (DBG) log("onRestrictedStateChanged: new rs "+ newRs);
10980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!mRestrictedState.isPsRestricted() && newRs.isPsRestricted()) {
11000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPsRestrictEnabledRegistrants.notifyRegistrants();
11010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setNotification(PS_ENABLED);
11020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (mRestrictedState.isPsRestricted() && !newRs.isPsRestricted()) {
11030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mPsRestrictDisabledRegistrants.notifyRegistrants();
11040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setNotification(PS_DISABLED);
11050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            /**
11080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             * There are two kind of cs restriction, normal and emergency. So
11090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             * there are 4 x 4 combinations in current and new restricted states
11100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             * and we only need to notify when state is changed.
11110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             */
11120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mRestrictedState.isCsRestricted()) {
11130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!newRs.isCsRestricted()) {
11140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove all restriction
11150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_DISABLED);
11160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (!newRs.isCsNormalRestricted()) {
11170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove normal restriction
11180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_EMERGENCY_ENABLED);
11190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (!newRs.isCsEmergencyRestricted()) {
11200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove emergency restriction
11210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_NORMAL_ENABLED);
11220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
11230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (mRestrictedState.isCsEmergencyRestricted() &&
11240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    !mRestrictedState.isCsNormalRestricted()) {
11250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!newRs.isCsRestricted()) {
11260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove all restriction
11270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_DISABLED);
11280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsRestricted()) {
11290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // enable all restriction
11300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_ENABLED);
11310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsNormalRestricted()) {
11320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove emergency restriction and enable normal restriction
11330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_NORMAL_ENABLED);
11340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
11350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (!mRestrictedState.isCsEmergencyRestricted() &&
11360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mRestrictedState.isCsNormalRestricted()) {
11370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!newRs.isCsRestricted()) {
11380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove all restriction
11390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_DISABLED);
11400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsRestricted()) {
11410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // enable all restriction
11420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_ENABLED);
11430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsEmergencyRestricted()) {
11440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // remove normal restriction and enable emergency restriction
11450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_EMERGENCY_ENABLED);
11460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
11470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
11480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (newRs.isCsRestricted()) {
11490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // enable all restriction
11500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_ENABLED);
11510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsEmergencyRestricted()) {
11520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // enable emergency restriction
11530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_EMERGENCY_ENABLED);
11540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (newRs.isCsNormalRestricted()) {
11550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // enable normal restriction
11560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setNotification(CS_NORMAL_ENABLED);
11570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
11580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
11590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mRestrictedState = newRs;
11610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        log("onRestrictedStateChanged: X rs "+ mRestrictedState);
11630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** code is registration state 0-5 from TS 27.007 7.2 */
11660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int regCodeToServiceState(int code) {
11670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (code) {
11680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 0:
11690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 2: // 2 is "searching"
11700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 3: // 3 is "registration denied"
11710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 4: // 4 is "unknown" no vaild in current baseband
11720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 10:// same as 0, but indicates that emergency call is possible.
11730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 12:// same as 2, but indicates that emergency call is possible.
11740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 13:// same as 3, but indicates that emergency call is possible.
11750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 14:// same as 4, but indicates that emergency call is possible.
11760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return ServiceState.STATE_OUT_OF_SERVICE;
11770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 1:
11790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return ServiceState.STATE_IN_SERVICE;
11800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case 5:
11820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // in service, roam
11830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return ServiceState.STATE_IN_SERVICE;
11840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
11860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                loge("regCodeToServiceState: unexpected service state " + code);
11870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return ServiceState.STATE_OUT_OF_SERVICE;
11880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
11890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
11900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
11930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * code is registration state 0-5 from TS 27.007 7.2
11940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * returns true if registered roam, false otherwise
11950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
11960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean regCodeIsRoaming (int code) {
11970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // 5 is  "in service -- roam"
11980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return 5 == code;
11990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Set roaming state when gsmRoaming is true and, if operator mcc is the
12030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * same as sim mcc, ons is different from spn
12040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param gsmRoaming TS 27.007 7.2 CREG registered roaming
12050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param s ServiceState hold current ons
12060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true for roaming state set
12070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean isRoamingBetweenOperators(boolean gsmRoaming, ServiceState s) {
12090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String spn = SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, "empty");
12100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String onsl = s.getOperatorAlphaLong();
12120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String onss = s.getOperatorAlphaShort();
12130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean equalsOnsl = onsl != null && spn.equals(onsl);
12150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean equalsOnss = onss != null && spn.equals(onss);
12160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String simNumeric = SystemProperties.get(
12180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "");
12190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String  operatorNumeric = s.getOperatorNumeric();
12200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean equalsMcc = true;
12220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
12230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            equalsMcc = simNumeric.substring(0, 3).
12240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    equals(operatorNumeric.substring(0, 3));
12250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (Exception e){
12260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return gsmRoaming && !(equalsMcc && (equalsOnsl || equalsOnss));
12290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static int twoDigitsAt(String s, int offset) {
12320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int a, b;
12330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        a = Character.digit(s.charAt(offset), 10);
12350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        b = Character.digit(s.charAt(offset+1), 10);
12360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (a < 0 || b < 0) {
12380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new RuntimeException("invalid format");
12400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return a*10 + b;
12430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return The current GPRS state. IN_SERVICE is the same as "attached"
12470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * and OUT_OF_SERVICE is the same as detached.
12480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    int getCurrentGprsState() {
12500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return gprsState;
12510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public int getCurrentDataConnectionState() {
12540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return gprsState;
12550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if phone is camping on a technology (eg UMTS)
12590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * that could support voice and data simultaneously.
12600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean isConcurrentVoiceAndDataAllowed() {
12620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return (mRilRadioTechnology >= ServiceState.RIL_RADIO_TECHNOLOGY_UMTS);
12630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Provides the name of the algorithmic time zone for the specified
12670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * offset.  Taken from TimeZone.java.
12680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
12690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static String displayNameFor(int off) {
12700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        off = off / 1000 / 60;
12710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        char[] buf = new char[9];
12730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf[0] = 'G';
12740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf[1] = 'M';
12750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf[2] = 'T';
12760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (off < 0) {
12780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            buf[3] = '-';
12790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            off = -off;
12800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
12810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            buf[3] = '+';
12820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
12830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int hours = off / 60;
12850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int minutes = off % 60;
12860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf[4] = (char) ('0' + hours / 10);
12880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf[5] = (char) ('0' + hours % 10);
12890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf[6] = ':';
12910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf[7] = (char) ('0' + minutes / 10);
12930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        buf[8] = (char) ('0' + minutes % 10);
12940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return new String(buf);
12960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
12970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
12980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
12990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * nitzReceiveTime is time_t that the NITZ time was posted
13000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
13010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void setTimeFromNITZString (String nitz, long nitzReceiveTime) {
13020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // "yy/mm/dd,hh:mm:ss(+/-)tz"
13030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // tz is in number of quarter-hours
13040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        long start = SystemClock.elapsedRealtime();
13060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {log("NITZ: " + nitz + "," + nitzReceiveTime +
13070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        " start=" + start + " delay=" + (start - nitzReceiveTime));
13080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
13090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
13110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            /* NITZ time (hour:min:sec) will be in UTC but it supplies the timezone
13120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville             * offset as well (which we won't worry about until later) */
13130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
13140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.clear();
13160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.DST_OFFSET, 0);
13170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String[] nitzSubs = nitz.split("[/:,+-]");
13190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int year = 2000 + Integer.parseInt(nitzSubs[0]);
13210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.YEAR, year);
13220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // month is 0 based!
13240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int month = Integer.parseInt(nitzSubs[1]) - 1;
13250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.MONTH, month);
13260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int date = Integer.parseInt(nitzSubs[2]);
13280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.DATE, date);
13290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int hour = Integer.parseInt(nitzSubs[3]);
13310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.HOUR, hour);
13320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int minute = Integer.parseInt(nitzSubs[4]);
13340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.MINUTE, minute);
13350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int second = Integer.parseInt(nitzSubs[5]);
13370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.set(Calendar.SECOND, second);
13380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            boolean sign = (nitz.indexOf('-') == -1);
13400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int tzOffset = Integer.parseInt(nitzSubs[6]);
13420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int dst = (nitzSubs.length >= 8 ) ? Integer.parseInt(nitzSubs[7])
13440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                              : 0;
13450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // The zone offset received from NITZ is for current local time,
13470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // so DST correction is already applied.  Don't add it again.
13480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //
13490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // tzOffset += dst * 4;
13500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //
13510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // We could unapply it if we wanted the raw offset.
13520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            tzOffset = (sign ? 1 : -1) * tzOffset * 15 * 60 * 1000;
13540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            TimeZone    zone = null;
13560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // As a special extension, the Android emulator appends the name of
13580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // the host computer's timezone to the nitz string. this is zoneinfo
13590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // timezone name of the form Area!Location or Area!Location!SubLocation
13600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // so we need to convert the ! into /
13610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (nitzSubs.length >= 9) {
13620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                String  tzname = nitzSubs[8].replace('!','/');
13630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                zone = TimeZone.getTimeZone( tzname );
13640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
13650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String iso = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY);
13670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (zone == null) {
13690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (mGotCountryCode) {
13710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (iso != null && iso.length() > 0) {
13720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = TimeUtils.getTimeZone(tzOffset, dst != 0,
13730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                c.getTimeInMillis(),
13740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                iso);
13750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
13760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // We don't have a valid iso country code.  This is
13770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // most likely because we're on a test network that's
13780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // using a bogus MCC (eg, "001"), so get a TimeZone
13790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // based only on the NITZ parameters.
13800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        zone = getNitzTimeZone(tzOffset, (dst != 0), c.getTimeInMillis());
13810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
13820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
13830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
13840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if ((zone == null) || (mZoneOffset != tzOffset) || (mZoneDst != (dst != 0))){
13860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // We got the time before the country or the zone has changed
13870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // so we don't know how to identify the DST rules yet.  Save
13880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // the information and hope to fix it up later.
13890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNeedFixZoneAfterNitz = true;
13910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mZoneOffset  = tzOffset;
13920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mZoneDst     = dst != 0;
13930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mZoneTime    = c.getTimeInMillis();
13940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
13950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (zone != null) {
13970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (getAutoTimeZone()) {
13980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setAndBroadcastNetworkSetTimeZone(zone.getID());
13990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
14000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                saveNitzTimeZone(zone.getID());
14010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
14020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String ignore = SystemProperties.get("gsm.ignore-nitz");
14040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (ignore != null && ignore.equals("yes")) {
14050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("NITZ: Not setting clock because gsm.ignore-nitz is set");
14060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
14070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
14080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            try {
14100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mWakeLock.acquire();
14110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (getAutoTime()) {
14130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    long millisSinceNitzReceived
14140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            = SystemClock.elapsedRealtime() - nitzReceiveTime;
14150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (millisSinceNitzReceived < 0) {
14170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // Sanity check: something is wrong
14180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) {
14190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            log("NITZ: not setting time, clock has rolled "
14200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                            + "backwards since NITZ time was received, "
14210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                            + nitz);
14220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
14230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        return;
14240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
14250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (millisSinceNitzReceived > Integer.MAX_VALUE) {
14270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // If the time is this far off, something is wrong > 24 days!
14280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (DBG) {
14290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            log("NITZ: not setting time, processing has taken "
14300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        + (millisSinceNitzReceived / (1000 * 60 * 60 * 24))
14310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        + " days");
14320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
14330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        return;
14340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
14350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // Note: with range checks above, cast to int is safe
14370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    c.add(Calendar.MILLISECOND, (int)millisSinceNitzReceived);
14380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (DBG) {
14400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        log("NITZ: Setting time of day to " + c.getTime()
14410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + " NITZ receive delay(ms): " + millisSinceNitzReceived
14420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + " gained(ms): "
14430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + (c.getTimeInMillis() - System.currentTimeMillis())
14440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + " from " + nitz);
14450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
14460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    setAndBroadcastNetworkSetTime(c.getTimeInMillis());
14480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    Log.i(LOG_TAG, "NITZ: after Setting time of day");
14490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
14500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SystemProperties.set("gsm.nitz.time", String.valueOf(c.getTimeInMillis()));
14510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                saveNitzTime(c.getTimeInMillis());
14520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (false) {
14530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    long end = SystemClock.elapsedRealtime();
14540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    log("NITZ: end=" + end + " dur=" + (end - start));
14550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
14560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNitzUpdatedTime = true;
14570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } finally {
14580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mWakeLock.release();
14590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
14600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (RuntimeException ex) {
14610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            loge("NITZ: Parsing NITZ time " + nitz + " ex=" + ex);
14620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
14630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean getAutoTime() {
14660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
14670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return Settings.System.getInt(phone.getContext().getContentResolver(),
14680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    Settings.System.AUTO_TIME) > 0;
14690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (SettingNotFoundException snfe) {
14700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
14710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
14720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean getAutoTimeZone() {
14750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
14760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return Settings.System.getInt(phone.getContext().getContentResolver(),
14770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    Settings.System.AUTO_TIME_ZONE) > 0;
14780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (SettingNotFoundException snfe) {
14790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
14800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
14810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void saveNitzTimeZone(String zoneId) {
14840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mSavedTimeZone = zoneId;
14850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void saveNitzTime(long time) {
14880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mSavedTime = time;
14890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mSavedAtTime = SystemClock.elapsedRealtime();
14900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
14910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
14920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
14930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Set the timezone and send out a sticky broadcast so the system can
14940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * determine if the timezone was set by the carrier.
14950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
14960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param zoneId timezone set by carrier
14970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
14980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void setAndBroadcastNetworkSetTimeZone(String zoneId) {
14990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setAndBroadcastNetworkSetTimeZone: setTimeZone=" + zoneId);
15000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AlarmManager alarm =
15010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE);
15020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        alarm.setTimeZone(zoneId);
15030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE);
15040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
15050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.putExtra("time-zone", zoneId);
15060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.getContext().sendStickyBroadcast(intent);
15070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
15080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("setAndBroadcastNetworkSetTimeZone: call alarm.setTimeZone and broadcast zoneId=" +
15090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                zoneId);
15100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
15140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Set the time and Send out a sticky broadcast so the system can determine
15150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * if the time was set by the carrier.
15160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
15170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param time time set by network
15180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
15190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void setAndBroadcastNetworkSetTime(long time) {
15200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setAndBroadcastNetworkSetTime: time=" + time + "ms");
15210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SystemClock.setCurrentTimeMillis(time);
15220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME);
15230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
15240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        intent.putExtra("time", time);
15250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        phone.getContext().sendStickyBroadcast(intent);
15260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void revertToNitzTime() {
15290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (Settings.System.getInt(phone.getContext().getContentResolver(),
15300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Settings.System.AUTO_TIME, 0) == 0) {
15310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
15320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) {
15340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("Reverting to NITZ Time: mSavedTime=" + mSavedTime
15350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                + " mSavedAtTime=" + mSavedAtTime);
15360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mSavedTime != 0 && mSavedAtTime != 0) {
15380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setAndBroadcastNetworkSetTime(mSavedTime
15390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    + (SystemClock.elapsedRealtime() - mSavedAtTime));
15400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void revertToNitzTimeZone() {
15440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (Settings.System.getInt(phone.getContext().getContentResolver(),
15450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Settings.System.AUTO_TIME_ZONE, 0) == 0) {
15460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
15470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("Reverting to NITZ TimeZone: tz='" + mSavedTimeZone);
15490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (mSavedTimeZone != null) {
15500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            setAndBroadcastNetworkSetTimeZone(mSavedTimeZone);
15510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
15530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
15550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Post a notification to NotificationManager for restricted state
15560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
15570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param notifyType is one state of PS/CS_*_ENABLE/DISABLE
15580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
15590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void setNotification(int notifyType) {
15600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setNotification: create notification " + notifyType);
15620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Context context = phone.getContext();
15630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification = new Notification();
15650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.when = System.currentTimeMillis();
15660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.flags = Notification.FLAG_AUTO_CANCEL;
15670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.icon = com.android.internal.R.drawable.stat_sys_warning;
15680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Intent intent = new Intent();
15690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.contentIntent = PendingIntent
15700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        .getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
15710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CharSequence details = "";
15730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CharSequence title = context.getText(com.android.internal.R.string.RestrictedChangedTitle);
15740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int notificationId = CS_NOTIFICATION;
15750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (notifyType) {
15770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PS_ENABLED:
15780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notificationId = PS_NOTIFICATION;
15790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            details = context.getText(com.android.internal.R.string.RestrictedOnData);;
15800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
15810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case PS_DISABLED:
15820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notificationId = PS_NOTIFICATION;
15830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
15840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CS_ENABLED:
15850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            details = context.getText(com.android.internal.R.string.RestrictedOnAllVoice);;
15860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
15870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CS_NORMAL_ENABLED:
15880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            details = context.getText(com.android.internal.R.string.RestrictedOnNormal);;
15890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
15900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CS_EMERGENCY_ENABLED:
15910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            details = context.getText(com.android.internal.R.string.RestrictedOnEmergency);;
15920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
15930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CS_DISABLED:
15940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // do nothing and cancel the notification later
15950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
15960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
15970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("setNotification: put notification " + title + " / " +details);
15990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.tickerText = title;
16000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mNotification.setLatestEventInfo(context, title, details,
16010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mNotification.contentIntent);
16020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        NotificationManager notificationManager = (NotificationManager)
16040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            context.getSystemService(Context.NOTIFICATION_SERVICE);
16050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (notifyType == PS_DISABLED || notifyType == CS_DISABLED) {
16070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // cancel previous post notification
16080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notificationManager.cancel(notificationId);
16090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
16100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // update restricted state notification
16110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            notificationManager.notify(notificationId, mNotification);
16120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
16130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
1616e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    protected void onUpdateIccAvailability() {
1617e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (mUiccController == null ) {
1618e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            return;
1619e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        }
1620e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
1621e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        IccCard newIccCard = mUiccController.getIccCard();
1622e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka
1623e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        if (mIccCard != newIccCard) {
1624e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            if (mIccCard != null) {
1625e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                log("Removing stale icc objects.");
1626e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                mIccCard.unregisterForReady(this);
1627e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                if (mIccRecords != null) {
1628e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                    mIccRecords.unregisterForRecordsLoaded(this);
1629e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                }
1630e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                mIccRecords = null;
1631e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                mIccCard = null;
1632e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            }
1633e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            if (newIccCard != null) {
1634e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                log("New card found");
1635e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                mIccCard = newIccCard;
1636e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                mIccRecords = mIccCard.getIccRecords();
1637e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                mIccCard.registerForReady(this, EVENT_SIM_READY, null);
1638e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                if (mIccRecords != null) {
1639e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                    mIccRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
1640e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka                }
1641e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka            }
1642e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka        }
1643e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    }
1644e0e2ebb5a50e580cbe6957dcafb3495a2d0a27f2Alex Yakavenka    @Override
16450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void log(String s) {
16460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Log.d(LOG_TAG, "[GsmSST] " + s);
16470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
16500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void loge(String s) {
16510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Log.e(LOG_TAG, "[GsmSST] " + s);
16520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static void sloge(String s) {
16550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Log.e(LOG_TAG, "[GsmSST] " + s);
16560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
16580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
16590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
16600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println("GsmServiceStateTracker extends:");
16610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        super.dump(fd, pw, args);
16620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" phone=" + phone);
16630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" cellLoc=" + cellLoc);
16640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" newCellLoc=" + newCellLoc);
16650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mPreferredNetworkType=" + mPreferredNetworkType);
16660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" gprsState=" + gprsState);
16670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" newGPRSState=" + newGPRSState);
16680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mMaxDataCalls=" + mMaxDataCalls);
16690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNewMaxDataCalls=" + mNewMaxDataCalls);
16700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mReasonDataDenied=" + mReasonDataDenied);
16710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNewReasonDataDenied=" + mNewReasonDataDenied);
16720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mGsmRoaming=" + mGsmRoaming);
16730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mDataRoaming=" + mDataRoaming);
16740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mEmergencyOnly=" + mEmergencyOnly);
16750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNeedFixZoneAfterNitz=" + mNeedFixZoneAfterNitz);
16760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mZoneOffset=" + mZoneOffset);
16770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mZoneDst=" + mZoneDst);
16780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mZoneTime=" + mZoneTime);
16790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mGotCountryCode=" + mGotCountryCode);
16800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNitzUpdatedTime=" + mNitzUpdatedTime);
16810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mSavedTimeZone=" + mSavedTimeZone);
16820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mSavedTime=" + mSavedTime);
16830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mSavedAtTime=" + mSavedAtTime);
16840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mStartedGprsRegCheck=" + mStartedGprsRegCheck);
16850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mReportedGprsNoReg=" + mReportedGprsNoReg);
16860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mNotification=" + mNotification);
16870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" mWakeLock=" + mWakeLock);
16880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" curSpn=" + curSpn);
16890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" curPlmn=" + curPlmn);
16900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        pw.println(" curSpnRule=" + curSpnRule);
16910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
16920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
1693