19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.internal.telephony.gsm;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.AlarmManager;
204df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Projectimport android.app.Notification;
214df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Projectimport android.app.NotificationManager;
224df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Projectimport android.app.PendingIntent;
23670db2c696251370c4806ee3ecc3c7d6370b38e8John Wangimport android.content.BroadcastReceiver;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentResolver;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent;
27670db2c696251370c4806ee3ecc3c7d6370b38e8John Wangimport android.content.IntentFilter;
28670db2c696251370c4806ee3ecc3c7d6370b38e8John Wangimport android.content.res.Resources;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.ContentObserver;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.AsyncResult;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.PowerManager;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Registrant;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RegistrantList;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemProperties;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Checkin;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings.SettingNotFoundException;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Telephony.Intents;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.telephony.ServiceState;
43e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Savilleimport android.telephony.SignalStrength;
44b61c1a0f8b813347f376e7eea6d388342d8adfe3John Wangimport android.telephony.TelephonyManager;
45767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.telephony.gsm.GsmCellLocation;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Config;
48767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.util.EventLog;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.TimeUtils;
51767a662ecde33c3979bf02b793d392aca0403162Wink Saville
52767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.CommandException;
53767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.CommandsInterface;
54767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.DataConnectionTracker;
55767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.IccCard;
561c1ffa0cab8b56274970736d7f3b8c00c01c3d2bRobert Greenwaltimport com.android.internal.telephony.MccTable;
57767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.RILConstants;
58767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.ServiceStateTracker;
59767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.TelephonyEventLog;
60767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.TelephonyIntents;
6100416365dedc03c9ed74d94728025fd2d68f648dTammo Spalinkimport com.android.internal.telephony.TelephonyProperties;
62767a662ecde33c3979bf02b793d392aca0403162Wink Saville
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Arrays;
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Calendar;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Date;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.TimeZone;
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide}
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
71767a662ecde33c3979bf02b793d392aca0403162Wink Savillefinal class GsmServiceStateTracker extends ServiceStateTracker {
7200416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    static final String LOG_TAG = "GSM";
7300416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    static final boolean DBG = true;
74e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    GSMPhone phone;
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    GsmCellLocation cellLoc;
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    GsmCellLocation newCellLoc;
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mPreferredNetworkType;
794df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    RestrictedState rs;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int gprsState = ServiceState.STATE_OUT_OF_SERVICE;
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int newGPRSState = ServiceState.STATE_OUT_OF_SERVICE;
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8500416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink     *  Values correspond to ServiceStateTracker.DATA_ACCESS_ definitions.
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int networkType = 0;
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int newNetworkType = 0;
8900416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink
9037b80ee451a7404c288738255725f78a5af02130John Wang    /**
9137b80ee451a7404c288738255725f78a5af02130John Wang     * GSM roaming status solely based on TS 27.007 7.2 CREG. Only used by
9237b80ee451a7404c288738255725f78a5af02130John Wang     * handlePollStateResult to store CREG roaming result.
9337b80ee451a7404c288738255725f78a5af02130John Wang     */
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mGsmRoaming = false;
9500416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink
9637b80ee451a7404c288738255725f78a5af02130John Wang    /**
9737b80ee451a7404c288738255725f78a5af02130John Wang     * Data roaming status solely based on TS 27.007 10.1.19 CGREG. Only used by
9837b80ee451a7404c288738255725f78a5af02130John Wang     * handlePollStateResult to store CGREG roaming result.
9937b80ee451a7404c288738255725f78a5af02130John Wang     */
1008c6b883cd3c835df32cab4cbf395ebf648bb7d7eJohn Wang    private boolean mDataRoaming = false;
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10208cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang    /**
10308cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang     * Mark when service state is in emergency call only mode
10408cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang     */
10508cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang    private boolean mEmergencyOnly = false;
10608cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang    private boolean mNewEmergencyOnly = false;
10708cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private RegistrantList gprsAttachedRegistrants = new RegistrantList();
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private RegistrantList gprsDetachedRegistrants = new RegistrantList();
1104df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    private RegistrantList psRestrictEnabledRegistrants = new RegistrantList();
1114df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    private RegistrantList psRestrictDisabledRegistrants = new RegistrantList();
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11300416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    /**
11400416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink     * Sometimes we get the NITZ time before we know what country we
11500416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink     * are in. Keep the time zone information from the NITZ string so
11600416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink     * we can fix the time zone once know the country.
11700416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink     */
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mNeedFixZone = false;
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mZoneOffset;
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mZoneDst;
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private long mZoneTime;
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mGotCountryCode = false;
123767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private ContentResolver cr;
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String mSavedTimeZone;
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long mSavedTime;
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long mSavedAtTime;
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12900416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    /**
13000416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink     * We can't register for SIM_RECORDS_LOADED immediately because the
13100416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink     * SIMRecords object may not be instantiated yet.
13200416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink     */
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mNeedToRegForSimLoaded;
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13500416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    /** Started the recheck process after finding gprs should registerd but not. */
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mStartedGprsRegCheck = false;
13700416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink
13800416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    /** Already sent the event-log for no gprs register. */
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mReportedGprsNoReg = false;
140e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
1414df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    /**
1424df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * The Notification object given to the NotificationManager.
1434df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     */
1444df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    private Notification mNotification;
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14600416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    /** Wake lock used while setting time of day. */
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private PowerManager.WakeLock mWakeLock;
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String WAKELOCK_TAG = "ServiceStateTracker";
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15000416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    /** Keep track of SPN display rules, so we only broadcast intent if something changes. */
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String curSpn = null;
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String curPlmn = null;
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int curSpnRule = 0;
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15500416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    /** waiting period before recheck gprs and voice registration. */
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15800416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    /** Notification type. */
15900416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    static final int PS_ENABLED = 1001;            // Access Control blocks data service
16000416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    static final int PS_DISABLED = 1002;           // Access Control enables data service
16100416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    static final int CS_ENABLED = 1003;            // Access Control blocks all voice/sms service
16200416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    static final int CS_DISABLED = 1004;           // Access Control enables all voice/sms service
16300416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    static final int CS_NORMAL_ENABLED = 1005;     // Access Control blocks normal voice/sms service
16400416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    static final int CS_EMERGENCY_ENABLED = 1006;  // Access Control blocks emergency call service
165e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
16600416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    /** Notification id. */
16700416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    static final int PS_NOTIFICATION = 888;  // Id to update and cancel PS restricted
16800416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    static final int CS_NOTIFICATION = 999;  // Id to update and cancel CS restricted
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1706afac8b2926c166458fde085e6068473a95688feYong Zhang    static final int MAX_NUM_DATA_STATE_READS = 15;
1716afac8b2926c166458fde085e6068473a95688feYong Zhang
172670db2c696251370c4806ee3ecc3c7d6370b38e8John Wang    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
173670db2c696251370c4806ee3ecc3c7d6370b38e8John Wang        @Override
174670db2c696251370c4806ee3ecc3c7d6370b38e8John Wang        public void onReceive(Context context, Intent intent) {
175670db2c696251370c4806ee3ecc3c7d6370b38e8John Wang            if (intent.getAction().equals(Intent.ACTION_LOCALE_CHANGED)) {
176670db2c696251370c4806ee3ecc3c7d6370b38e8John Wang                // update emergency string whenever locale changed
177670db2c696251370c4806ee3ecc3c7d6370b38e8John Wang                updateSpnDisplay();
178670db2c696251370c4806ee3ecc3c7d6370b38e8John Wang            }
179670db2c696251370c4806ee3ecc3c7d6370b38e8John Wang        }
180670db2c696251370c4806ee3ecc3c7d6370b38e8John Wang    };
181670db2c696251370c4806ee3ecc3c7d6370b38e8John Wang
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) {
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onChange(boolean selfChange) {
185767a662ecde33c3979bf02b793d392aca0403162Wink Saville            Log.i("GsmServiceStateTracker", "Auto time state changed");
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            revertToNitz();
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
189767a662ecde33c3979bf02b793d392aca0403162Wink Saville
190767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public GsmServiceStateTracker(GSMPhone phone) {
191767a662ecde33c3979bf02b793d392aca0403162Wink Saville        super();
192767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this.phone = phone;
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm = phone.mCM;
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ss = new ServiceState();
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        newSS = new ServiceState();
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cellLoc = new GsmCellLocation();
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        newCellLoc = new GsmCellLocation();
1994df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        rs = new RestrictedState();
200e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        mSignalStrength = new SignalStrength();
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PowerManager powerManager =
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (PowerManager)phone.getContext().getSystemService(Context.POWER_SERVICE);
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG);
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
206767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm.registerForNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null);
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm.setOnNITZTime(this, EVENT_NITZ_TIME, null);
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
212767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.setOnRestrictedStateChanged(this, EVENT_RESTRICTED_STATE_CHANGED, null);
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cm.registerForSIMReady(this, EVENT_SIM_READY, null);
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // system setting property AIRPLANE_MODE_ON is set in Settings.
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int airplaneMode = Settings.System.getInt(
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                phone.getContext().getContentResolver(),
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Settings.System.AIRPLANE_MODE_ON, 0);
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDesiredPowerState = ! (airplaneMode > 0);
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
221767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cr = phone.getContext().getContentResolver();
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cr.registerContentObserver(
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Settings.System.getUriFor(Settings.System.AUTO_TIME), true,
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mAutoTimeObserver);
225e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        setSignalStrengthDefaultValues();
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNeedToRegForSimLoaded = true;
227670db2c696251370c4806ee3ecc3c7d6370b38e8John Wang
228670db2c696251370c4806ee3ecc3c7d6370b38e8John Wang        // Monitor locale change
229670db2c696251370c4806ee3ecc3c7d6370b38e8John Wang        IntentFilter filter = new IntentFilter();
230670db2c696251370c4806ee3ecc3c7d6370b38e8John Wang        filter.addAction(Intent.ACTION_LOCALE_CHANGED);
231670db2c696251370c4806ee3ecc3c7d6370b38e8John Wang        phone.getContext().registerReceiver(mIntentReceiver, filter);
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
234767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public void dispose() {
23500416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink        // Unregister for all events.
236767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.unregisterForAvailable(this);
237767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.unregisterForRadioStateChanged(this);
238767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.unregisterForNetworkStateChanged(this);
239767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.unregisterForSIMReady(this);
240767a662ecde33c3979bf02b793d392aca0403162Wink Saville
241767a662ecde33c3979bf02b793d392aca0403162Wink Saville        phone.mSIMRecords.unregisterForRecordsLoaded(this);
242767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.unSetOnSignalStrengthUpdate(this);
243767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.unSetOnRestrictedStateChanged(this);
244767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.unSetOnNITZTime(this);
245767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cr.unregisterContentObserver(this.mAutoTimeObserver);
246767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
247767a662ecde33c3979bf02b793d392aca0403162Wink Saville
248767a662ecde33c3979bf02b793d392aca0403162Wink Saville    protected void finalize() {
249767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if(DBG) Log.d(LOG_TAG, "GsmServiceStateTracker finalized");
250767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
251767a662ecde33c3979bf02b793d392aca0403162Wink Saville
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Registration point for transition into GPRS attached.
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param h handler to notify
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param what what code of message when delivered
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param obj placed in Message.obj
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
25800416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    void registerForGprsAttached(Handler h, int what, Object obj) {
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Registrant r = new Registrant(h, what, obj);
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        gprsAttachedRegistrants.add(r);
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (gprsState == ServiceState.STATE_IN_SERVICE) {
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            r.notifyRegistrant();
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26700416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    void unregisterForGprsAttached(Handler h) {
268767a662ecde33c3979bf02b793d392aca0403162Wink Saville        gprsAttachedRegistrants.remove(h);
269767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
270767a662ecde33c3979bf02b793d392aca0403162Wink Saville
27100416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    void registerForNetworkAttach(Handler h, int what, Object obj) {
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Registrant r = new Registrant(h, what, obj);
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        networkAttachedRegistrants.add(r);
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ss.getState() == ServiceState.STATE_IN_SERVICE) {
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            r.notifyRegistrant();
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
279767a662ecde33c3979bf02b793d392aca0403162Wink Saville
28000416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    void unregisterForNetworkAttach(Handler h) {
281767a662ecde33c3979bf02b793d392aca0403162Wink Saville        networkAttachedRegistrants.remove(h);
282767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
28300416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Registration point for transition into GPRS detached.
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param h handler to notify
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param what what code of message when delivered
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param obj placed in Message.obj
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
29000416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    void registerForGprsDetached(Handler h, int what, Object obj) {
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Registrant r = new Registrant(h, what, obj);
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        gprsDetachedRegistrants.add(r);
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (gprsState == ServiceState.STATE_OUT_OF_SERVICE) {
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            r.notifyRegistrant();
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29900416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    void unregisterForGprsDetached(Handler h) {
300767a662ecde33c3979bf02b793d392aca0403162Wink Saville        gprsDetachedRegistrants.remove(h);
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3034df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    /**
3044df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * Registration point for transition into packet service restricted zone.
3054df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * @param h handler to notify
3064df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * @param what what code of message when delivered
3074df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * @param obj placed in Message.obj
3084df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     */
30900416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    void registerForPsRestrictedEnabled(Handler h, int what, Object obj) {
310e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        Log.d(LOG_TAG, "[DSAC DEB] " + "registerForPsRestrictedEnabled ");
3114df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        Registrant r = new Registrant(h, what, obj);
3124df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        psRestrictEnabledRegistrants.add(r);
3134df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project
3144df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        if (rs.isPsRestricted()) {
3154df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            r.notifyRegistrant();
3164df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        }
3174df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    }
318767a662ecde33c3979bf02b793d392aca0403162Wink Saville
31900416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    void unregisterForPsRestrictedEnabled(Handler h) {
320767a662ecde33c3979bf02b793d392aca0403162Wink Saville        psRestrictEnabledRegistrants.remove(h);
321767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
322767a662ecde33c3979bf02b793d392aca0403162Wink Saville
3234df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    /**
3244df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * Registration point for transition out of packet service restricted zone.
3254df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * @param h handler to notify
3264df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * @param what what code of message when delivered
3274df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * @param obj placed in Message.obj
3284df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     */
32900416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    void registerForPsRestrictedDisabled(Handler h, int what, Object obj) {
330e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        Log.d(LOG_TAG, "[DSAC DEB] " + "registerForPsRestrictedDisabled ");
3314df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        Registrant r = new Registrant(h, what, obj);
3324df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        psRestrictDisabledRegistrants.add(r);
3334df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project
3344df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        if (rs.isPsRestricted()) {
3354df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            r.notifyRegistrant();
3364df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        }
3374df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    }
338e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
33900416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    void unregisterForPsRestrictedDisabled(Handler h) {
340767a662ecde33c3979bf02b793d392aca0403162Wink Saville        psRestrictDisabledRegistrants.remove(h);
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34300416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    public void handleMessage (Message msg) {
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AsyncResult ar;
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int[] ints;
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String[] strings;
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Message message;
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (msg.what) {
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_RADIO_AVAILABLE:
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                //this is unnecessary
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                //setPowerStateToDesired();
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_SIM_READY:
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // The SIM is now ready i.e if it was locked
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // it has been unlocked. At this stage, the radio is already
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // powered on.
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mNeedToRegForSimLoaded) {
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    phone.mSIMRecords.registerForRecordsLoaded(this,
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            EVENT_SIM_RECORDS_LOADED, null);
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mNeedToRegForSimLoaded = false;
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // restore the previous network selection.
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                phone.restoreSavedNetworkSelection(null);
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pollState();
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Signal strength polling stops when radio is off
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                queueNextSignalStrengthPoll();
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_RADIO_STATE_CHANGED:
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // This will do nothing in the radio not
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // available case
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                setPowerStateToDesired();
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pollState();
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_NETWORK_STATE_CHANGED:
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pollState();
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_GET_SIGNAL_STRENGTH:
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // This callback is called when signal strength is polled
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // all by itself
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
386767a662ecde33c3979bf02b793d392aca0403162Wink Saville                if (!(cm.getRadioState().isOn()) || (cm.getRadioState().isCdma())) {
387767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    // Polling will continue when radio turns back on and not CDMA
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ar = (AsyncResult) msg.obj;
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                onSignalStrengthResult(ar);
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                queueNextSignalStrengthPoll();
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_GET_LOC_DONE:
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ar = (AsyncResult) msg.obj;
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (ar.exception == null) {
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String states[] = (String[])ar.result;
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int lac = -1;
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int cid = -1;
403b9db7c9f5a8924361ae2f439509e19993d82b884Mike Lockwood                    if (states.length >= 3) {
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        try {
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (states[1] != null && states[1].length() > 0) {
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                lac = Integer.parseInt(states[1], 16);
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (states[2] != null && states[2].length() > 0) {
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                cid = Integer.parseInt(states[2], 16);
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } catch (NumberFormatException ex) {
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            Log.w(LOG_TAG, "error parsing location: " + ex);
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
4157a043b351b43e963605afef6ab76a52ae3a9270eTammo Spalink                    cellLoc.setLacAndCid(lac, cid);
4167a043b351b43e963605afef6ab76a52ae3a9270eTammo Spalink                    phone.notifyLocationChanged();
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4197a043b351b43e963605afef6ab76a52ae3a9270eTammo Spalink                // Release any temporary cell lock, which could have been
4207a043b351b43e963605afef6ab76a52ae3a9270eTammo Spalink                // aquired to allow a single-shot location update.
4217a043b351b43e963605afef6ab76a52ae3a9270eTammo Spalink                disableSingleLocationUpdate();
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_POLL_STATE_REGISTRATION:
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_POLL_STATE_GPRS:
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_POLL_STATE_OPERATOR:
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_POLL_STATE_NETWORK_SELECTION_MODE:
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ar = (AsyncResult) msg.obj;
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                handlePollStateResult(msg.what, ar);
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_POLL_SIGNAL_STRENGTH:
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Just poll signal strength...not part of pollState()
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cm.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_NITZ_TIME:
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ar = (AsyncResult) msg.obj;
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String nitzString = (String)((Object[])ar.result)[0];
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                long nitzReceiveTime = ((Long)((Object[])ar.result)[1]).longValue();
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                setTimeFromNITZString(nitzString, nitzReceiveTime);
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_SIGNAL_STRENGTH_UPDATE:
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // This is a notification from
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // CommandsInterface.setOnSignalStrengthUpdate
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ar = (AsyncResult) msg.obj;
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // The radio is telling us about signal strength changes
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // we don't have to ask it
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dontPollSignalStrength = true;
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                onSignalStrengthResult(ar);
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_SIM_RECORDS_LOADED:
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                updateSpnDisplay();
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_LOCATION_UPDATES_ENABLED:
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ar = (AsyncResult) msg.obj;
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (ar.exception == null) {
4697a043b351b43e963605afef6ab76a52ae3a9270eTammo Spalink                    cm.getRegistrationState(obtainMessage(EVENT_GET_LOC_DONE, null));
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_SET_PREFERRED_NETWORK_TYPE:
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ar = (AsyncResult) msg.obj;
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Don't care the result, only use for dereg network (COPS=2)
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                message = obtainMessage(EVENT_RESET_PREFERRED_NETWORK_TYPE, ar.userObj);
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cm.setPreferredNetworkType(mPreferredNetworkType, message);
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_RESET_PREFERRED_NETWORK_TYPE:
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ar = (AsyncResult) msg.obj;
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (ar.userObj != null) {
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    AsyncResult.forMessage(((Message) ar.userObj)).exception
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            = ar.exception;
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ((Message) ar.userObj).sendToTarget();
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_GET_PREFERRED_NETWORK_TYPE:
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ar = (AsyncResult) msg.obj;
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (ar.exception == null) {
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mPreferredNetworkType = ((int[])ar.result)[0];
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
495767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    mPreferredNetworkType = RILConstants.NETWORK_MODE_GLOBAL;
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                message = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE, ar.userObj);
499767a662ecde33c3979bf02b793d392aca0403162Wink Saville                int toggledNetworkType = RILConstants.NETWORK_MODE_GLOBAL;
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cm.setPreferredNetworkType(toggledNetworkType, message);
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EVENT_CHECK_REPORT_GPRS:
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (ss != null && !isGprsConsistant(gprsState, ss.getState())) {
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Can't register data sevice while voice service is ok
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // i.e. CREG is ok while CGREG is not
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // possible a network or baseband side error
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int cid = -1;
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (loc != null) cid = loc.getCid();
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    EventLog.List val = new EventLog.List(ss.getOperatorNumeric(), cid);
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_CGREG_FAIL, val);
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mReportedGprsNoReg = true;
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mStartedGprsRegCheck = false;
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
520e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
5214df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            case EVENT_RESTRICTED_STATE_CHANGED:
5224df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                // This is a notification from
5234df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                // CommandsInterface.setOnRestrictedStateChanged
5244df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project
5254df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                Log.d(LOG_TAG, "[DSAC DEB] " + "EVENT_RESTRICTED_STATE_CHANGED");
526e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
5274df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                ar = (AsyncResult) msg.obj;
5284df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project
5294df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                onRestrictedStateChanged(ar);
5304df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                break;
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
532767a662ecde33c3979bf02b793d392aca0403162Wink Saville            default:
533767a662ecde33c3979bf02b793d392aca0403162Wink Saville                Log.e(LOG_TAG, "Unhandled message with number: " + msg.what);
534767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
53800416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    protected void setPowerStateToDesired() {
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If we want it on and it's off, turn it on
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDesiredPowerState
541767a662ecde33c3979bf02b793d392aca0403162Wink Saville            && cm.getRadioState() == CommandsInterface.RadioState.RADIO_OFF) {
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cm.setRadioPower(true, null);
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (!mDesiredPowerState && cm.getRadioState().isOn()) {
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            DataConnectionTracker dcTracker = phone.mDataConnection;
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (! dcTracker.isDataConnectionAsDesired()) {
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                EventLog.List val = new EventLog.List(
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        dcTracker.getStateInString(),
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        (dcTracker.getAnyDataEnabled() ? 1 : 0) );
550e290ed0f610422fa0420b1fbbf37bb1afd04ab82Tammo Spalink                EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_DATA_STATE_RADIO_OFF, val);
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5529c2a3be8bad8867cc524d8813dc6468a7ffb3f09Jaikumar Ganesh            Message msg = dcTracker.obtainMessage(DataConnectionTracker.EVENT_CLEAN_UP_CONNECTION);
5539c2a3be8bad8867cc524d8813dc6468a7ffb3f09Jaikumar Ganesh            msg.arg1 = 1; // tearDown is true
5549c2a3be8bad8867cc524d8813dc6468a7ffb3f09Jaikumar Ganesh            msg.obj = GSMPhone.REASON_RADIO_TURNED_OFF;
555024af038a7ad04bb551c305c235d25e51cbeda13Jaikumar Ganesh            dcTracker.sendMessage(msg);
556e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // poll data state up to 15 times, with a 100ms delay
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // totaling 1.5 sec. Normal data disable action will finish in 100ms.
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < MAX_NUM_DATA_STATE_READS; i++) {
560e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                if (dcTracker.getState() != DataConnectionTracker.State.CONNECTED
561767a662ecde33c3979bf02b793d392aca0403162Wink Saville                        && dcTracker.getState() != DataConnectionTracker.State.DISCONNECTING) {
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Log.d(LOG_TAG, "Data shutdown complete.");
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SystemClock.sleep(DATA_STATE_POLL_SLEEP_MS);
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If it's on and available and we want it off..
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cm.setRadioPower(false, null);
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } // Otherwise, we're in the desired state
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
571e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
572767a662ecde33c3979bf02b793d392aca0403162Wink Saville    protected void updateSpnDisplay() {
573767a662ecde33c3979bf02b793d392aca0403162Wink Saville        int rule = phone.mSIMRecords.getDisplayRule(ss.getOperatorNumeric());
574767a662ecde33c3979bf02b793d392aca0403162Wink Saville        String spn = phone.mSIMRecords.getServiceProviderName();
575767a662ecde33c3979bf02b793d392aca0403162Wink Saville        String plmn = ss.getOperatorAlphaLong();
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
57708cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang        // For emergency calls only, pass the EmergencyCallsOnly string via EXTRA_PLMN
57808cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang        if (mEmergencyOnly && cm.getRadioState().isOn()) {
579670db2c696251370c4806ee3ecc3c7d6370b38e8John Wang            plmn = Resources.getSystem().
580670db2c696251370c4806ee3ecc3c7d6370b38e8John Wang                getText(com.android.internal.R.string.emergency_calls_only).toString();
58108cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang        }
58208cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang
583767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (rule != curSpnRule
584767a662ecde33c3979bf02b793d392aca0403162Wink Saville                || !TextUtils.equals(spn, curSpn)
585767a662ecde33c3979bf02b793d392aca0403162Wink Saville                || !TextUtils.equals(plmn, curPlmn)) {
586670db2c696251370c4806ee3ecc3c7d6370b38e8John Wang            boolean showSpn = mEmergencyOnly
587670db2c696251370c4806ee3ecc3c7d6370b38e8John Wang                || (rule & SIMRecords.SPN_RULE_SHOW_SPN) == SIMRecords.SPN_RULE_SHOW_SPN;
588767a662ecde33c3979bf02b793d392aca0403162Wink Saville            boolean showPlmn =
589767a662ecde33c3979bf02b793d392aca0403162Wink Saville                (rule & SIMRecords.SPN_RULE_SHOW_PLMN) == SIMRecords.SPN_RULE_SHOW_PLMN;
59008cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang
591767a662ecde33c3979bf02b793d392aca0403162Wink Saville            Intent intent = new Intent(Intents.SPN_STRINGS_UPDATED_ACTION);
592767a662ecde33c3979bf02b793d392aca0403162Wink Saville            intent.putExtra(Intents.EXTRA_SHOW_SPN, showSpn);
593767a662ecde33c3979bf02b793d392aca0403162Wink Saville            intent.putExtra(Intents.EXTRA_SPN, spn);
594767a662ecde33c3979bf02b793d392aca0403162Wink Saville            intent.putExtra(Intents.EXTRA_SHOW_PLMN, showPlmn);
595767a662ecde33c3979bf02b793d392aca0403162Wink Saville            intent.putExtra(Intents.EXTRA_PLMN, plmn);
596767a662ecde33c3979bf02b793d392aca0403162Wink Saville            phone.getContext().sendStickyBroadcast(intent);
597767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
59808cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang
599767a662ecde33c3979bf02b793d392aca0403162Wink Saville        curSpnRule = rule;
600767a662ecde33c3979bf02b793d392aca0403162Wink Saville        curSpn = spn;
601767a662ecde33c3979bf02b793d392aca0403162Wink Saville        curPlmn = plmn;
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Handle the result of one of the pollState()-related requests
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
60700416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    protected void handlePollStateResult (int what, AsyncResult ar) {
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int ints[];
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String states[];
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Ignore stale requests from last poll
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ar.userObj != pollingContext) return;
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ar.exception != null) {
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            CommandException.Error err=null;
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ar.exception instanceof CommandException) {
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                err = ((CommandException)(ar.exception)).getCommandError();
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (err == CommandException.Error.RADIO_NOT_AVAILABLE) {
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Radio has crashed or turned off
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cancelPollState();
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!cm.getRadioState().isOn()) {
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Radio has crashed or turned off
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cancelPollState();
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW &&
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) {
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.e(LOG_TAG,
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "RIL implementation has returned an error where it must succeed" +
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ar.exception);
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else try {
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (what) {
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case EVENT_POLL_STATE_REGISTRATION:
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    states = (String[])ar.result;
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int lac = -1;
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int cid = -1;
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int regState = -1;
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (states.length > 0) {
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        try {
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            regState = Integer.parseInt(states[0]);
649b9db7c9f5a8924361ae2f439509e19993d82b884Mike Lockwood                            if (states.length >= 3) {
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                if (states[1] != null && states[1].length() > 0) {
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    lac = Integer.parseInt(states[1], 16);
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                if (states[2] != null && states[2].length() > 0) {
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    cid = Integer.parseInt(states[2], 16);
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } catch (NumberFormatException ex) {
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            Log.w(LOG_TAG, "error parsing RegistrationState: " + ex);
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mGsmRoaming = regCodeIsRoaming(regState);
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    newSS.setState (regCodeToServiceState(regState));
66408cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang
66508cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang                    if (regState == 10 || regState == 12 || regState == 13 || regState == 14) {
66608cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang                        mNewEmergencyOnly = true;
66708cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang                    } else {
66808cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang                        mNewEmergencyOnly = false;
66908cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang                    }
67008cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // LAC and CID are -1 if not avail
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    newCellLoc.setLacAndCid(lac, cid);
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case EVENT_POLL_STATE_GPRS:
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    states = (String[])ar.result;
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int type = 0;
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    regState = -1;
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (states.length > 0) {
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        try {
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            regState = Integer.parseInt(states[0]);
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // states[3] (if present) is the current radio technology
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (states.length >= 4 && states[3] != null) {
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                type = Integer.parseInt(states[3]);
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } catch (NumberFormatException ex) {
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            Log.w(LOG_TAG, "error parsing GprsRegistrationState: " + ex);
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    newGPRSState = regCodeToServiceState(regState);
69337b80ee451a7404c288738255725f78a5af02130John Wang                    mDataRoaming = regCodeIsRoaming(regState);
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    newNetworkType = type;
695ebe66345e7099ca6fc95e8aa4d31a5b5cbbd6224Li Zhe                    newSS.setRadioTechnology(type);
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case EVENT_POLL_STATE_OPERATOR:
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String opNames[] = (String[])ar.result;
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (opNames != null && opNames.length >= 3) {
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        newSS.setOperatorName (
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                opNames[0], opNames[1], opNames[2]);
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case EVENT_POLL_STATE_NETWORK_SELECTION_MODE:
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ints = (int[])ar.result;
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    newSS.setIsManualSelection(ints[0] == 1);
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RuntimeException ex) {
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(LOG_TAG, "Exception while polling service state. "
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + "Probably malformed RIL response.", ex);
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pollingContext[0]--;
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (pollingContext[0] == 0) {
72137b80ee451a7404c288738255725f78a5af02130John Wang            /**
72237b80ee451a7404c288738255725f78a5af02130John Wang             *  Since the roaming states of gsm service (from +CREG) and
72337b80ee451a7404c288738255725f78a5af02130John Wang             *  data service (from +CGREG) could be different, the new SS
72437b80ee451a7404c288738255725f78a5af02130John Wang             *  is set roaming while either one is roaming.
72537b80ee451a7404c288738255725f78a5af02130John Wang             *
72637b80ee451a7404c288738255725f78a5af02130John Wang             *  There is an exception for the above rule. The new SS is not set
72737b80ee451a7404c288738255725f78a5af02130John Wang             *  as roaming while gsm service reports roaming but indeed it is
72837b80ee451a7404c288738255725f78a5af02130John Wang             *  not roaming between operators.
72937b80ee451a7404c288738255725f78a5af02130John Wang             */
73037b80ee451a7404c288738255725f78a5af02130John Wang            boolean roaming = (mGsmRoaming || mDataRoaming);
73137b80ee451a7404c288738255725f78a5af02130John Wang            if (mGsmRoaming && !isRoamingBetweenOperators(mGsmRoaming, newSS)) {
73237b80ee451a7404c288738255725f78a5af02130John Wang                roaming = false;
7338c6b883cd3c835df32cab4cbf395ebf648bb7d7eJohn Wang            }
73437b80ee451a7404c288738255725f78a5af02130John Wang            newSS.setRoaming(roaming);
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pollStateDone();
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
739e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville    private void setSignalStrengthDefaultValues() {
740e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, true);
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * A complete "service state" from our perspective is
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * composed of a handful of separate requests to the radio.
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * We make all of these requests at once, but then abandon them
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and start over again if the radio notifies us that some
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * event has changed
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
75100416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    private void pollState() {
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pollingContext = new int[1];
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pollingContext[0] = 0;
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (cm.getRadioState()) {
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case RADIO_UNAVAILABLE:
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                newSS.setStateOutOfService();
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                newCellLoc.setStateInvalid();
759e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                setSignalStrengthDefaultValues();
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mGotCountryCode = false;
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pollStateDone();
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case RADIO_OFF:
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                newSS.setStateOff();
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                newCellLoc.setStateInvalid();
767e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                setSignalStrengthDefaultValues();
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mGotCountryCode = false;
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pollStateDone();
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
772767a662ecde33c3979bf02b793d392aca0403162Wink Saville            case RUIM_NOT_READY:
773767a662ecde33c3979bf02b793d392aca0403162Wink Saville            case RUIM_READY:
774767a662ecde33c3979bf02b793d392aca0403162Wink Saville            case RUIM_LOCKED_OR_ABSENT:
775767a662ecde33c3979bf02b793d392aca0403162Wink Saville            case NV_NOT_READY:
776767a662ecde33c3979bf02b793d392aca0403162Wink Saville            case NV_READY:
777767a662ecde33c3979bf02b793d392aca0403162Wink Saville                Log.d(LOG_TAG, "Radio Technology Change ongoing, setting SS to off");
778767a662ecde33c3979bf02b793d392aca0403162Wink Saville                newSS.setStateOff();
779767a662ecde33c3979bf02b793d392aca0403162Wink Saville                newCellLoc.setStateInvalid();
780e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                setSignalStrengthDefaultValues();
781767a662ecde33c3979bf02b793d392aca0403162Wink Saville                mGotCountryCode = false;
782767a662ecde33c3979bf02b793d392aca0403162Wink Saville
783e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                //NOTE: pollStateDone() is not needed in this case
784767a662ecde33c3979bf02b793d392aca0403162Wink Saville                break;
785767a662ecde33c3979bf02b793d392aca0403162Wink Saville
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            default:
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Issue all poll-related commands at once
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // then count down the responses, which
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // are allowed to arrive out-of-order
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pollingContext[0]++;
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cm.getOperator(
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    obtainMessage(
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        EVENT_POLL_STATE_OPERATOR, pollingContext));
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pollingContext[0]++;
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cm.getGPRSRegistrationState(
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    obtainMessage(
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        EVENT_POLL_STATE_GPRS, pollingContext));
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pollingContext[0]++;
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cm.getRegistrationState(
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    obtainMessage(
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        EVENT_POLL_STATE_REGISTRATION, pollingContext));
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pollingContext[0]++;
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cm.getNetworkSelectionMode(
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    obtainMessage(
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        EVENT_POLL_STATE_NETWORK_SELECTION_MODE, pollingContext));
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static String networkTypeToString(int type) {
815767a662ecde33c3979bf02b793d392aca0403162Wink Saville        //Network Type from GPRS_REGISTRATION_STATE
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String ret = "unknown";
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (type) {
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DATA_ACCESS_GPRS:
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ret = "GPRS";
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DATA_ACCESS_EDGE:
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ret = "EDGE";
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DATA_ACCESS_UMTS:
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ret = "UMTS";
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
828ebe66345e7099ca6fc95e8aa4d31a5b5cbbd6224Li Zhe            case DATA_ACCESS_HSDPA:
829ebe66345e7099ca6fc95e8aa4d31a5b5cbbd6224Li Zhe                ret = "HSDPA";
830ebe66345e7099ca6fc95e8aa4d31a5b5cbbd6224Li Zhe                break;
831ebe66345e7099ca6fc95e8aa4d31a5b5cbbd6224Li Zhe            case DATA_ACCESS_HSUPA:
832ebe66345e7099ca6fc95e8aa4d31a5b5cbbd6224Li Zhe                ret = "HSUPA";
833ebe66345e7099ca6fc95e8aa4d31a5b5cbbd6224Li Zhe                break;
834ebe66345e7099ca6fc95e8aa4d31a5b5cbbd6224Li Zhe            case DATA_ACCESS_HSPA:
835ebe66345e7099ca6fc95e8aa4d31a5b5cbbd6224Li Zhe                ret = "HSPA";
836ebe66345e7099ca6fc95e8aa4d31a5b5cbbd6224Li Zhe                break;
837767a662ecde33c3979bf02b793d392aca0403162Wink Saville            default:
838767a662ecde33c3979bf02b793d392aca0403162Wink Saville                Log.e(LOG_TAG, "Wrong network type: " + Integer.toString(type));
839767a662ecde33c3979bf02b793d392aca0403162Wink Saville                break;
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return ret;
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
84500416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    private void pollStateDone() {
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DBG) {
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.d(LOG_TAG, "Poll ServiceState done: " +
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                " oldSS=[" + ss + "] newSS=[" + newSS +
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "] oldGprs=" + gprsState + " newGprs=" + newGPRSState +
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                " oldType=" + networkTypeToString(networkType) +
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                " newType=" + networkTypeToString(newNetworkType));
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean hasRegistered =
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ss.getState() != ServiceState.STATE_IN_SERVICE
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            && newSS.getState() == ServiceState.STATE_IN_SERVICE;
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean hasDeregistered =
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ss.getState() == ServiceState.STATE_IN_SERVICE
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            && newSS.getState() != ServiceState.STATE_IN_SERVICE;
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean hasGprsAttached =
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                gprsState != ServiceState.STATE_IN_SERVICE
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && newGPRSState == ServiceState.STATE_IN_SERVICE;
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean hasGprsDetached =
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                gprsState == ServiceState.STATE_IN_SERVICE
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && newGPRSState != ServiceState.STATE_IN_SERVICE;
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean hasNetworkTypeChanged = networkType != newNetworkType;
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean hasChanged = !newSS.equals(ss);
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
87437b80ee451a7404c288738255725f78a5af02130John Wang        boolean hasRoamingOn = !ss.getRoaming() && newSS.getRoaming();
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
87637b80ee451a7404c288738255725f78a5af02130John Wang        boolean hasRoamingOff = ss.getRoaming() && !newSS.getRoaming();
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean hasLocationChanged = !newCellLoc.equals(cellLoc);
8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
88008cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang        boolean hasEmergencyOnlyChanged = mNewEmergencyOnly != mEmergencyOnly;
88108cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ServiceState tss;
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        tss = ss;
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ss = newSS;
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        newSS = tss;
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // clean slate for next time
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        newSS.setStateOutOfService();
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GsmCellLocation tcl = cellLoc;
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cellLoc = newCellLoc;
8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        newCellLoc = tcl;
8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
89308cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang        mEmergencyOnly = mNewEmergencyOnly;
89408cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang
895b61c1a0f8b813347f376e7eea6d388342d8adfe3John Wang
896b61c1a0f8b813347f376e7eea6d388342d8adfe3John Wang        // Add an event log when network type switched
897b61c1a0f8b813347f376e7eea6d388342d8adfe3John Wang        // TODO: we may add filtering to reduce the event logged,
898b61c1a0f8b813347f376e7eea6d388342d8adfe3John Wang        // i.e. check preferred network setting, only switch to 2G, etc
899b61c1a0f8b813347f376e7eea6d388342d8adfe3John Wang        if (hasNetworkTypeChanged) {
900b61c1a0f8b813347f376e7eea6d388342d8adfe3John Wang            int cid = -1;
901b61c1a0f8b813347f376e7eea6d388342d8adfe3John Wang            GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
902b61c1a0f8b813347f376e7eea6d388342d8adfe3John Wang            if (loc != null) cid = loc.getCid();
903b61c1a0f8b813347f376e7eea6d388342d8adfe3John Wang            EventLog.List val = new EventLog.List(cid, networkType, newNetworkType);
904b61c1a0f8b813347f376e7eea6d388342d8adfe3John Wang            EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_GSM_RAT_SWITCHED, val);
905b61c1a0f8b813347f376e7eea6d388342d8adfe3John Wang            Log.d(LOG_TAG,
906b61c1a0f8b813347f376e7eea6d388342d8adfe3John Wang                    "RAT switched " + networkTypeToString(networkType) + " -> "
907b61c1a0f8b813347f376e7eea6d388342d8adfe3John Wang                    + networkTypeToString(newNetworkType) + " at cell " + cid);
908b61c1a0f8b813347f376e7eea6d388342d8adfe3John Wang        }
909b61c1a0f8b813347f376e7eea6d388342d8adfe3John Wang
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        gprsState = newGPRSState;
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        networkType = newNetworkType;
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        newSS.setStateOutOfService(); // clean slate for next time
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (hasNetworkTypeChanged) {
91600416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    networkTypeToString(networkType));
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (hasRegistered) {
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Checkin.updateStats(phone.getContext().getContentResolver(),
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Checkin.Stats.Tag.PHONE_GSM_REGISTERED, 1, 0.0);
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            networkAttachedRegistrants.notifyRegistrants();
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (hasChanged) {
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String operatorNumeric;
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
92900416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ss.getOperatorAlphaLong());
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            operatorNumeric = ss.getOperatorNumeric();
93300416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (operatorNumeric == null) {
93600416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink                phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String iso = "";
9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try{
9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    iso = MccTable.countryCodeForMcc(Integer.parseInt(
9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            operatorNumeric.substring(0,3)));
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch ( NumberFormatException ex){
9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Log.w(LOG_TAG, "countryCodeForMcc error" + ex);
9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch ( StringIndexOutOfBoundsException ex) {
9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Log.w(LOG_TAG, "countryCodeForMcc error" + ex);
9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
94800416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink                phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, iso);
9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mGotCountryCode = true;
9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mNeedFixZone) {
9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    TimeZone zone = null;
9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // If the offset is (0, false) and the timezone property
9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // is set, use the timezone property rather than
9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // GMT.
9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String zoneName = SystemProperties.get(TIMEZONE_PROPERTY);
9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if ((mZoneOffset == 0) && (mZoneDst == false) &&
9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        (zoneName != null) && (zoneName.length() > 0) &&
9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        (Arrays.binarySearch(GMT_COUNTRY_CODES, iso) < 0)) {
9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        zone = TimeZone.getDefault();
9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // For NITZ string without timezone,
9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // need adjust time to reflect default timezone setting
9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        long tzOffset;
9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        tzOffset = zone.getOffset(System.currentTimeMillis());
9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (getAutoTime()) {
9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            setAndBroadcastNetworkSetTime(System.currentTimeMillis() - tzOffset);
9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else {
9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // Adjust the saved NITZ time to account for tzOffset.
9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            mSavedTime = mSavedTime - tzOffset;
9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else if (iso.equals("")){
9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Country code not found.  This is likely a test network.
9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Get a TimeZone based only on the NITZ parameters (best guess).
9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        zone = getNitzTimeZone(mZoneOffset, mZoneDst, mZoneTime);
9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        zone = TimeUtils.getTimeZone(mZoneOffset,
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            mZoneDst, mZoneTime, iso);
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mNeedFixZone = false;
9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (zone != null) {
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (getAutoTime()) {
9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            setAndBroadcastNetworkSetTimeZone(zone.getID());
9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        saveNitzTimeZone(zone.getID());
9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
99100416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ss.getRoaming() ? "true" : "false");
9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            phone.notifyServiceStateChanged(ss);
9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
99708cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang        if (hasChanged || hasEmergencyOnlyChanged) {
99808cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang            updateSpnDisplay();
99908cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang        }
100008cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang
10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (hasGprsAttached) {
10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            gprsAttachedRegistrants.notifyRegistrants();
10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (hasGprsDetached) {
10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            gprsDetachedRegistrants.notifyRegistrants();
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (hasNetworkTypeChanged) {
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            phone.notifyDataConnection(null);
10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (hasRoamingOn) {
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            roamingOnRegistrants.notifyRegistrants();
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (hasRoamingOff) {
10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            roamingOffRegistrants.notifyRegistrants();
10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (hasLocationChanged) {
10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            phone.notifyLocationChanged();
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (! isGprsConsistant(gprsState, ss.getState())) {
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mStartedGprsRegCheck && !mReportedGprsNoReg) {
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mStartedGprsRegCheck = true;
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int check_period = Settings.Gservices.getInt(
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        phone.getContext().getContentResolver(),
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        Settings.Gservices.GPRS_REGISTER_CHECK_PERIOD_MS,
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        DEFAULT_GPRS_CHECK_PERIOD_MILLIS);
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sendMessageDelayed(obtainMessage(EVENT_CHECK_REPORT_GPRS),
10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        check_period);
10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mReportedGprsNoReg = false;
10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Check if GPRS got registred while voice is registered
10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param gprsState for GPRS registration state, i.e. CGREG in GSM
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param serviceState for voice registration state, i.e. CREG in GSM
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return false if device only register to voice but not gprs
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean isGprsConsistant (int gprsState, int serviceState) {
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return !((serviceState == ServiceState.STATE_IN_SERVICE) &&
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (gprsState != ServiceState.STATE_IN_SERVICE));
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a TimeZone object based only on parameters from the NITZ string.
10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private TimeZone getNitzTimeZone(int offset, boolean dst, long when) {
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TimeZone guess = findTimeZone(offset, dst, when);
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (guess == null) {
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Couldn't find a proper timezone.  Perhaps the DST data is wrong.
10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            guess = findTimeZone(offset, !dst, when);
10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DBG) {
10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.d(LOG_TAG, "getNitzTimeZone returning "
10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + (guess == null ? guess : guess.getID()));
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return guess;
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private TimeZone findTimeZone(int offset, boolean dst, long when) {
10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int rawOffset = offset;
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dst) {
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            rawOffset -= 3600000;
10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String[] zones = TimeZone.getAvailableIDs(rawOffset);
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TimeZone guess = null;
10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Date d = new Date(when);
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (String zone : zones) {
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            TimeZone tz = TimeZone.getTimeZone(zone);
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (tz.getOffset(when) == offset &&
10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tz.inDaylightTime(d) == dst) {
10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                guess = tz;
10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return guess;
10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
108900416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    private void queueNextSignalStrengthPoll() {
1090767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (dontPollSignalStrength || (cm.getRadioState().isCdma())) {
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // The radio is telling us about signal strength changes
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // we don't have to ask it
10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Message msg;
10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        msg = obtainMessage();
10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        msg.what = EVENT_POLL_SIGNAL_STRENGTH;
11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long nextTime;
11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // TODO Done't poll signal strength if screen is off
11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sendMessageDelayed(msg, POLL_PERIOD_MILLIS);
11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1108e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville     *  send signal-strength-changed notification if changed
11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  Called both for solicited and unsolicited signal stength updates
11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
111100416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    private void onSignalStrengthResult(AsyncResult ar) {
1112e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        SignalStrength oldSignalStrength = mSignalStrength;
1113e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        int rssi = 99;
11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ar.exception != null) {
1116e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            // -1 = unknown
11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // most likely radio is resetting/disconnected
1118e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            setSignalStrengthDefaultValues();
11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int[] ints = (int[])ar.result;
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // bug 658816 seems to be a case where the result is 0-length
11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ints.length != 0) {
11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                rssi = ints[0];
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.e(LOG_TAG, "Bogus signal strength response");
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                rssi = 99;
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1131e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        mSignalStrength = new SignalStrength(rssi, -1, -1, -1,
1132e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                -1, -1, -1, true);
1133e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
1134e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        if (!mSignalStrength.equals(oldSignalStrength)) {
1135767a662ecde33c3979bf02b793d392aca0403162Wink Saville            try { // This takes care of delayed EVENT_POLL_SIGNAL_STRENGTH (scheduled after
1136767a662ecde33c3979bf02b793d392aca0403162Wink Saville                  // POLL_PERIOD_MILLIS) during Radio Technology Change)
1137767a662ecde33c3979bf02b793d392aca0403162Wink Saville                phone.notifySignalStrength();
1138767a662ecde33c3979bf02b793d392aca0403162Wink Saville           } catch (NullPointerException ex) {
1139e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                log("onSignalStrengthResult() Phone already destroyed: " + ex
1140e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                        + "SignalStrength not notified");
1141767a662ecde33c3979bf02b793d392aca0403162Wink Saville           }
11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1144767a662ecde33c3979bf02b793d392aca0403162Wink Saville
11454df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    /**
11464df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * Set restricted state based on the OnRestrictedStateChanged notification
11474df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * If any voice or packet restricted state changes, trigger a UI
1148105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * notification and notify registrants when sim is ready.
1149767a662ecde33c3979bf02b793d392aca0403162Wink Saville     *
11504df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * @param ar an int value of RIL_RESTRICTED_STATE_*
11514df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     */
115200416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    private void onRestrictedStateChanged(AsyncResult ar) {
11534df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        Log.d(LOG_TAG, "[DSAC DEB] " + "onRestrictedStateChanged");
11544df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        RestrictedState newRs = new RestrictedState();
1155e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
11564df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        Log.d(LOG_TAG, "[DSAC DEB] " + "current rs at enter "+ rs);
1157e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
11584df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        if (ar.exception == null) {
11594df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            int[] ints = (int[])ar.result;
11604df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            int state = ints[0];
1161e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
11624df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            newRs.setCsEmergencyRestricted(
11634df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                    ((state & RILConstants.RIL_RESTRICTED_STATE_CS_EMERGENCY) != 0) ||
11644df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                    ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
1165105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            //ignore the normal call and data restricted state before SIM READY
1166e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            if (phone.getIccCard().getState() == IccCard.State.READY) {
1167105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                newRs.setCsNormalRestricted(
1168105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                        ((state & RILConstants.RIL_RESTRICTED_STATE_CS_NORMAL) != 0) ||
1169105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                        ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
1170105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                newRs.setPsRestricted(
1171105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                        (state & RILConstants.RIL_RESTRICTED_STATE_PS_ALL)!= 0);
1172105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            }
1173e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
1174e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            Log.d(LOG_TAG, "[DSAC DEB] " + "new rs "+ newRs);
1175e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
11764df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            if (!rs.isPsRestricted() && newRs.isPsRestricted()) {
11774df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                psRestrictEnabledRegistrants.notifyRegistrants();
1178105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                setNotification(PS_ENABLED);
11794df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            } else if (rs.isPsRestricted() && !newRs.isPsRestricted()) {
11804df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                psRestrictDisabledRegistrants.notifyRegistrants();
1181105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                setNotification(PS_DISABLED);
11824df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            }
1183e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
1184105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            /**
1185e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville             * There are two kind of cs restriction, normal and emergency. So
1186105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project             * there are 4 x 4 combinations in current and new restricted states
1187105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project             * and we only need to notify when state is changed.
1188105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project             */
1189105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            if (rs.isCsRestricted()) {
1190105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                if (!newRs.isCsRestricted()) {
1191105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    // remove all restriction
1192105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    setNotification(CS_DISABLED);
1193105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                } else if (!newRs.isCsNormalRestricted()) {
1194105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    // remove normal restriction
1195e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    setNotification(CS_EMERGENCY_ENABLED);
1196105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                } else if (!newRs.isCsEmergencyRestricted()) {
1197105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    // remove emergency restriction
1198e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    setNotification(CS_NORMAL_ENABLED);
1199105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                }
1200105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            } else if (rs.isCsEmergencyRestricted() && !rs.isCsNormalRestricted()) {
1201105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                if (!newRs.isCsRestricted()) {
1202105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    // remove all restriction
1203e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    setNotification(CS_DISABLED);
1204105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                } else if (newRs.isCsRestricted()) {
1205105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    // enable all restriction
1206105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    setNotification(CS_ENABLED);
1207105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                } else if (newRs.isCsNormalRestricted()) {
1208105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    // remove emergency restriction and enable normal restriction
1209e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    setNotification(CS_NORMAL_ENABLED);
12104df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                }
1211105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            } else if (!rs.isCsEmergencyRestricted() && rs.isCsNormalRestricted()) {
1212105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                if (!newRs.isCsRestricted()) {
1213105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    // remove all restriction
1214e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    setNotification(CS_DISABLED);
1215105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                } else if (newRs.isCsRestricted()) {
1216105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    // enable all restriction
1217105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    setNotification(CS_ENABLED);
1218105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                } else if (newRs.isCsEmergencyRestricted()) {
1219105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    // remove normal restriction and enable emergency restriction
1220e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    setNotification(CS_EMERGENCY_ENABLED);
1221105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                }
1222105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            } else {
1223105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                if (newRs.isCsRestricted()) {
1224105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    // enable all restriction
1225105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    setNotification(CS_ENABLED);
1226105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                } else if (newRs.isCsEmergencyRestricted()) {
1227105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    // enable emergency restriction
1228e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    setNotification(CS_EMERGENCY_ENABLED);
1229105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                } else if (newRs.isCsNormalRestricted()) {
1230105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    // enable normal restriction
1231e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    setNotification(CS_NORMAL_ENABLED);
12324df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                }
12334df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            }
1234767a662ecde33c3979bf02b793d392aca0403162Wink Saville
12354df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            rs = newRs;
12364df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        }
12374df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        Log.d(LOG_TAG, "[DSAC DEB] " + "current rs at return "+ rs);
12384df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    }
12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** code is registration state 0-5 from TS 27.007 7.2 */
124100416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    private int regCodeToServiceState(int code) {
12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (code) {
12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case 0:
12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case 2: // 2 is "searching"
12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case 3: // 3 is "registration denied"
12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case 4: // 4 is "unknown" no vaild in current baseband
124708cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang            case 10:// same as 0, but indicates that emergency call is possible.
124808cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang            case 12:// same as 2, but indicates that emergency call is possible.
124908cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang            case 13:// same as 3, but indicates that emergency call is possible.
125008cb0024026e0f42612ab569e1e4067d5ede3bf8John Wang            case 14:// same as 4, but indicates that emergency call is possible.
12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return ServiceState.STATE_OUT_OF_SERVICE;
12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case 1:
12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return ServiceState.STATE_IN_SERVICE;
12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case 5:
12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // in service, roam
12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return ServiceState.STATE_IN_SERVICE;
12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            default:
12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.w(LOG_TAG, "unexpected service state " + code);
12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return ServiceState.STATE_OUT_OF_SERVICE;
12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * code is registration state 0-5 from TS 27.007 7.2
12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * returns true if registered roam, false otherwise
12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
127100416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    private boolean regCodeIsRoaming (int code) {
12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // 5 is  "in service -- roam"
12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 5 == code;
12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set roaming state when gsmRoaming is true and, if operator mcc is the
12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * same as sim mcc, ons is different from spn
12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param gsmRoaming TS 27.007 7.2 CREG registered roaming
12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param s ServiceState hold current ons
12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true for roaming state set
12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
128300416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    private boolean isRoamingBetweenOperators(boolean gsmRoaming, ServiceState s) {
128400416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink        String spn = SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, "empty");
12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String onsl = s.getOperatorAlphaLong();
12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String onss = s.getOperatorAlphaShort();
12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean equalsOnsl = onsl != null && spn.equals(onsl);
12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean equalsOnss = onss != null && spn.equals(onss);
12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
129200416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink        String simNumeric = SystemProperties.get(
129300416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink                TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "");
12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String  operatorNumeric = s.getOperatorNumeric();
12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean equalsMcc = true;
12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            equalsMcc = simNumeric.substring(0, 3).
12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    equals(operatorNumeric.substring(0, 3));
13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (Exception e){
13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return gsmRoaming && !(equalsMcc && (equalsOnsl || equalsOnss));
13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
130600416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    private static int twoDigitsAt(String s, int offset) {
13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int a, b;
13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        a = Character.digit(s.charAt(offset), 10);
13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        b = Character.digit(s.charAt(offset+1), 10);
13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (a < 0 || b < 0) {
13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("invalid format");
13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return a*10 + b;
13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The current GPRS state. IN_SERVICE is the same as "attached"
13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and OUT_OF_SERVICE is the same as detached.
13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
132400416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    int getCurrentGprsState() {
13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return gprsState;
13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if phone is camping on a technology (eg UMTS)
13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that could support voice and data simultaniously.
13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean isConcurrentVoiceAndData() {
1333ebe66345e7099ca6fc95e8aa4d31a5b5cbbd6224Li Zhe        return (networkType >= DATA_ACCESS_UMTS);
13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Provides the name of the algorithmic time zone for the specified
13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * offset.  Taken from TimeZone.java.
13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static String displayNameFor(int off) {
13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        off = off / 1000 / 60;
13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char[] buf = new char[9];
13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        buf[0] = 'G';
13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        buf[1] = 'M';
13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        buf[2] = 'T';
13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (off < 0) {
13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            buf[3] = '-';
13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            off = -off;
13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            buf[3] = '+';
13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int hours = off / 60;
13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int minutes = off % 60;
13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        buf[4] = (char) ('0' + hours / 10);
13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        buf[5] = (char) ('0' + hours % 10);
13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        buf[6] = ':';
13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        buf[7] = (char) ('0' + minutes / 10);
13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        buf[8] = (char) ('0' + minutes % 10);
13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return new String(buf);
13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * nitzReceiveTime is time_t that the NITZ time was posted
13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
137200416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    private void setTimeFromNITZString (String nitz, long nitzReceiveTime) {
13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // "yy/mm/dd,hh:mm:ss(+/-)tz"
13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // tz is in number of quarter-hours
13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long start = SystemClock.elapsedRealtime();
13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Log.i(LOG_TAG, "NITZ: " + nitz + "," + nitzReceiveTime +
13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        " start=" + start + " delay=" + (start - nitzReceiveTime));
13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            /* NITZ time (hour:min:sec) will be in UTC but it supplies the timezone
13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             * offset as well (which we won't worry about until later) */
13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c.clear();
13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c.set(Calendar.DST_OFFSET, 0);
13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String[] nitzSubs = nitz.split("[/:,+-]");
13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int year = 2000 + Integer.parseInt(nitzSubs[0]);
13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c.set(Calendar.YEAR, year);
13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // month is 0 based!
13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int month = Integer.parseInt(nitzSubs[1]) - 1;
13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c.set(Calendar.MONTH, month);
13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int date = Integer.parseInt(nitzSubs[2]);
13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c.set(Calendar.DATE, date);
13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int hour = Integer.parseInt(nitzSubs[3]);
14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c.set(Calendar.HOUR, hour);
14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int minute = Integer.parseInt(nitzSubs[4]);
14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c.set(Calendar.MINUTE, minute);
14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int second = Integer.parseInt(nitzSubs[5]);
14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c.set(Calendar.SECOND, second);
14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean sign = (nitz.indexOf('-') == -1);
14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int tzOffset = Integer.parseInt(nitzSubs[6]);
14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int dst = (nitzSubs.length >= 8 ) ? Integer.parseInt(nitzSubs[7])
14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                              : 0;
14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // The zone offset received from NITZ is for current local time,
14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // so DST correction is already applied.  Don't add it again.
14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //
14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // tzOffset += dst * 4;
14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //
14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // We could unapply it if we wanted the raw offset.
14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            tzOffset = (sign ? 1 : -1) * tzOffset * 15 * 60 * 1000;
14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            TimeZone    zone = null;
14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // As a special extension, the Android emulator appends the name of
14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // the host computer's timezone to the nitz string. this is zoneinfo
14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // timezone name of the form Area!Location or Area!Location!SubLocation
14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // so we need to convert the ! into /
14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (nitzSubs.length >= 9) {
14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String  tzname = nitzSubs[8].replace('!','/');
14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                zone = TimeZone.getTimeZone( tzname );
14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
143600416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            String iso = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY);
14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (zone == null) {
14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mGotCountryCode) {
14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (iso != null && iso.length() > 0) {
14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        zone = TimeUtils.getTimeZone(tzOffset, dst != 0,
14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                c.getTimeInMillis(),
14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                iso);
14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // We don't have a valid iso country code.  This is
14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // most likely because we're on a test network that's
14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // using a bogus MCC (eg, "001"), so get a TimeZone
14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // based only on the NITZ parameters.
14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        zone = getNitzTimeZone(tzOffset, (dst != 0), c.getTimeInMillis());
14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (zone == null) {
14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // We got the time before the country, so we don't know
14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // how to identify the DST rules yet.  Save the information
14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // and hope to fix it up later.
14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mNeedFixZone = true;
14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mZoneOffset  = tzOffset;
14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mZoneDst     = dst != 0;
14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mZoneTime    = c.getTimeInMillis();
14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (zone != null) {
14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (getAutoTime()) {
14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    setAndBroadcastNetworkSetTimeZone(zone.getID());
14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                saveNitzTimeZone(zone.getID());
14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String ignore = SystemProperties.get("gsm.ignore-nitz");
14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ignore != null && ignore.equals("yes")) {
14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.i(LOG_TAG, "NITZ: Not setting clock because gsm.ignore-nitz is set");
14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mWakeLock.acquire();
14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (getAutoTime()) {
14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    long millisSinceNitzReceived
14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            = SystemClock.elapsedRealtime() - nitzReceiveTime;
14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (millisSinceNitzReceived < 0) {
14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Sanity check: something is wrong
14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        Log.i(LOG_TAG, "NITZ: not setting time, clock has rolled "
14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            + "backwards since NITZ time was received, "
14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            + nitz);
14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return;
14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (millisSinceNitzReceived > Integer.MAX_VALUE) {
14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // If the time is this far off, something is wrong > 24 days!
14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        Log.i(LOG_TAG, "NITZ: not setting time, processing has taken "
14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        + (millisSinceNitzReceived / (1000 * 60 * 60 * 24))
14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        + " days");
14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return;
15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Note: with range checks above, cast to int is safe
15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    c.add(Calendar.MILLISECOND, (int)millisSinceNitzReceived);
15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Log.i(LOG_TAG, "NITZ: Setting time of day to " + c.getTime()
15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + " NITZ receive delay(ms): " + millisSinceNitzReceived
15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + " gained(ms): "
15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + (c.getTimeInMillis() - System.currentTimeMillis())
15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + " from " + nitz);
15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1511ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project                    setAndBroadcastNetworkSetTime(c.getTimeInMillis());
15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Log.i(LOG_TAG, "NITZ: after Setting time of day");
15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                SystemProperties.set("gsm.nitz.time", String.valueOf(c.getTimeInMillis()));
15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                saveNitzTime(c.getTimeInMillis());
15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (Config.LOGV) {
15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    long end = SystemClock.elapsedRealtime();
15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Log.v(LOG_TAG, "NITZ: end=" + end + " dur=" + (end - start));
15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } finally {
15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mWakeLock.release();
15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RuntimeException ex) {
15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(LOG_TAG, "NITZ: Parsing NITZ time " + nitz, ex);
15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean getAutoTime() {
15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return Settings.System.getInt(phone.getContext().getContentResolver(),
15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Settings.System.AUTO_TIME) > 0;
15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (SettingNotFoundException snfe) {
15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void saveNitzTimeZone(String zoneId) {
15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mSavedTimeZone = zoneId;
15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void saveNitzTime(long time) {
15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mSavedTime = time;
15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mSavedAtTime = SystemClock.elapsedRealtime();
15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set the timezone and send out a sticky broadcast so the system can
15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * determine if the timezone was set by the carrier.
15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param zoneId timezone set by carrier
15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void setAndBroadcastNetworkSetTimeZone(String zoneId) {
15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AlarmManager alarm =
15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE);
15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        alarm.setTimeZone(zoneId);
15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE);
15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        intent.putExtra("time-zone", zoneId);
15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        phone.getContext().sendStickyBroadcast(intent);
15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set the time and Send out a sticky broadcast so the system can determine
15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if the time was set by the carrier.
15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param time time set by network
15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void setAndBroadcastNetworkSetTime(long time) {
15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SystemClock.setCurrentTimeMillis(time);
15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME);
15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        intent.putExtra("time", time);
15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        phone.getContext().sendStickyBroadcast(intent);
15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void revertToNitz() {
15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (Settings.System.getInt(phone.getContext().getContentResolver(),
15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Settings.System.AUTO_TIME, 0) == 0) {
15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Log.d(LOG_TAG, "Reverting to NITZ: tz='" + mSavedTimeZone
15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + "' mSavedTime=" + mSavedTime
15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mSavedAtTime=" + mSavedAtTime);
15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mSavedTimeZone != null && mSavedTime != 0 && mSavedAtTime != 0) {
15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setAndBroadcastNetworkSetTimeZone(mSavedTimeZone);
15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setAndBroadcastNetworkSetTime(mSavedTime
15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + (SystemClock.elapsedRealtime() - mSavedAtTime));
15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1588767a662ecde33c3979bf02b793d392aca0403162Wink Saville
15894df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    /**
15904df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * Post a notification to NotificationManager for restricted state
1591e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville     *
15924df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * @param notifyType is one state of PS/CS_*_ENABLE/DISABLE
15934df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     */
1594105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    private void setNotification(int notifyType) {
15954df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project
15964df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        Log.d(LOG_TAG, "[DSAC DEB] " + "create notification " + notifyType);
1597105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        Context context = phone.getContext();
1598105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
15994df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        mNotification = new Notification();
16004df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        mNotification.when = System.currentTimeMillis();
16014df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        mNotification.flags = Notification.FLAG_AUTO_CANCEL;
1602105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        mNotification.icon = com.android.internal.R.drawable.stat_sys_warning;
16034df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        Intent intent = new Intent();
16044df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        mNotification.contentIntent = PendingIntent
1605105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        .getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
16064df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project
16074df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        CharSequence details = "";
1608105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        CharSequence title = context.getText(com.android.internal.R.string.RestrictedChangedTitle);
1609105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        int notificationId = CS_NOTIFICATION;
1610e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
16114df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        switch (notifyType) {
16124df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        case PS_ENABLED:
1613105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            notificationId = PS_NOTIFICATION;
1614105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            details = context.getText(com.android.internal.R.string.RestrictedOnData);;
16154df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            break;
16164df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        case PS_DISABLED:
1617105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            notificationId = PS_NOTIFICATION;
16184df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            break;
16194df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        case CS_ENABLED:
1620105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            details = context.getText(com.android.internal.R.string.RestrictedOnAll);;
1621e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            break;
16224df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        case CS_NORMAL_ENABLED:
1623105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            details = context.getText(com.android.internal.R.string.RestrictedOnNormal);;
1624e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            break;
16254df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        case CS_EMERGENCY_ENABLED:
1626105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            details = context.getText(com.android.internal.R.string.RestrictedOnEmergency);;
1627e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            break;
1628105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        case CS_DISABLED:
1629105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            // do nothing and cancel the notification later
1630e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            break;
16314df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        }
1632e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
16334df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        Log.d(LOG_TAG, "[DSAC DEB] " + "put notification " + title + " / " +details);
16344df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        mNotification.tickerText = title;
1635e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        mNotification.setLatestEventInfo(context, title, details,
16364df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                mNotification.contentIntent);
1637e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
1638e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        NotificationManager notificationManager = (NotificationManager)
1639105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            context.getSystemService(Context.NOTIFICATION_SERVICE);
1640105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
1641105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (notifyType == PS_DISABLED || notifyType == CS_DISABLED) {
1642105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            // cancel previous post notification
1643105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            notificationManager.cancel(notificationId);
1644105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        } else {
1645105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            // update restricted state notification
1646105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            notificationManager.notify(notificationId, mNotification);
16474df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        }
16484df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    }
1649e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
1650e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville    private void log(String s) {
1651e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        Log.d(LOG_TAG, "[GsmServiceStateTracker] " + s);
1652e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville    }
16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1654