GsmServiceStateTracker.java revision e287feac673ff68565b766e0e463d105fa9cef9d
1c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/*
2c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Copyright (C) 2006 The Android Open Source Project
3c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
4c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Licensed under the Apache License, Version 2.0 (the "License");
5c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * you may not use this file except in compliance with the License.
6c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * You may obtain a copy of the License at
7c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
8c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *      http://www.apache.org/licenses/LICENSE-2.0
9c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
10c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Unless required by applicable law or agreed to in writing, software
11c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * distributed under the License is distributed on an "AS IS" BASIS,
12c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * See the License for the specific language governing permissions and
14c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * limitations under the License.
15c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
16c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
17c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepackage com.android.internal.telephony.gsm;
18c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
19c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.CommandException;
20c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.CommandsInterface;
21c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.DataConnectionTracker;
22c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.EventLogTags;
23c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.IccCard;
24c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.IccCardConstants;
25c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.IccCardStatus;
26c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.MccTable;
27c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.Phone;
28c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.RestrictedState;
29c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.RILConstants;
30c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.ServiceStateTracker;
31c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.TelephonyIntents;
32c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.TelephonyProperties;
33e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.UiccCard;
34e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.UiccCardApplication;
35e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.IccCardApplicationStatus.AppState;
36e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.uicc.UiccController;
37c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
38c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.app.AlarmManager;
39c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.app.Notification;
40c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.app.NotificationManager;
41c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.app.PendingIntent;
42c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.BroadcastReceiver;
43c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.ContentResolver;
44c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Context;
45c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Intent;
46c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.IntentFilter;
47c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.res.Resources;
48c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.database.ContentObserver;
49c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.AsyncResult;
50c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Handler;
51c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Message;
52c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.PowerManager;
53c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Registrant;
54c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.RegistrantList;
55c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemClock;
56c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemProperties;
57c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.provider.Settings;
58c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.provider.Settings.SettingNotFoundException;
59c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.telephony.ServiceState;
60c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.telephony.SignalStrength;
61c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.telephony.gsm.GsmCellLocation;
62c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.text.TextUtils;
63c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.util.EventLog;
64c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.util.Log;
65c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.util.TimeUtils;
66c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
67c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.FileDescriptor;
68c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.io.PrintWriter;
69c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.ArrayList;
70c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.Arrays;
71c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.Calendar;
72c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.Collection;
73c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.Date;
74c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.HashSet;
75c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.TimeZone;
76c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
77c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/**
78c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * {@hide}
79c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
80c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillefinal class GsmServiceStateTracker extends ServiceStateTracker {
81c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final String LOG_TAG = "GSM";
82c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final boolean DBG = true;
83c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
84c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    GSMPhone phone;
85c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    GsmCellLocation cellLoc;
86c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    GsmCellLocation newCellLoc;
87c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    int mPreferredNetworkType;
88c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
89c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private int gprsState = ServiceState.STATE_OUT_OF_SERVICE;
90c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private int newGPRSState = ServiceState.STATE_OUT_OF_SERVICE;
91c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private int mMaxDataCalls = 1;
92c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private int mNewMaxDataCalls = 1;
93c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private int mReasonDataDenied = -1;
94c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private int mNewReasonDataDenied = -1;
95c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
96c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
97c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * GSM roaming status solely based on TS 27.007 7.2 CREG. Only used by
98c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * handlePollStateResult to store CREG roaming result.
99c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean mGsmRoaming = false;
101c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
102c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
103c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Data roaming status solely based on TS 27.007 10.1.19 CGREG. Only used by
104c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * handlePollStateResult to store CGREG roaming result.
105c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
106c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean mDataRoaming = false;
107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
108c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Mark when service state is in emergency call only mode
110c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
111c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean mEmergencyOnly = false;
112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
114c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Sometimes we get the NITZ time before we know what country we
115c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * are in. Keep the time zone information from the NITZ string so
116c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * we can fix the time zone once know the country.
117c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
118c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean mNeedFixZoneAfterNitz = false;
119c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private int mZoneOffset;
120c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean mZoneDst;
121c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private long mZoneTime;
122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean mGotCountryCode = false;
123c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private ContentResolver cr;
124c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
125c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Boolean is true is setTimeFromNITZString was called */
126c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean mNitzUpdatedTime = false;
127c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
128c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    String mSavedTimeZone;
129c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    long mSavedTime;
130c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    long mSavedAtTime;
131c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
132c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Started the recheck process after finding gprs should registered but not. */
133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean mStartedGprsRegCheck = false;
134c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
135c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Already sent the event-log for no gprs register. */
136c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean mReportedGprsNoReg = false;
137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
138c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * The Notification object given to the NotificationManager.
140c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private Notification mNotification;
142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
143c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Wake lock used while setting time of day. */
144c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private PowerManager.WakeLock mWakeLock;
145c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final String WAKELOCK_TAG = "ServiceStateTracker";
146c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
147c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Keep track of SPN display rules, so we only broadcast intent if something changes. */
148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private String curSpn = null;
149c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private String curPlmn = null;
150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private int curSpnRule = 0;
151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
152c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** waiting period before recheck gprs and voice registration. */
153c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;
154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
155c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Notification type. */
156c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int PS_ENABLED = 1001;            // Access Control blocks data service
157c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int PS_DISABLED = 1002;           // Access Control enables data service
158c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int CS_ENABLED = 1003;            // Access Control blocks all voice/sms service
159c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int CS_DISABLED = 1004;           // Access Control enables all voice/sms service
160c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int CS_NORMAL_ENABLED = 1005;     // Access Control blocks normal voice/sms service
161c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int CS_EMERGENCY_ENABLED = 1006;  // Access Control blocks emergency call service
162c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
163c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** Notification id. */
164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int PS_NOTIFICATION = 888;  // Id to update and cancel PS restricted
165c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int CS_NOTIFICATION = 999;  // Id to update and cancel CS restricted
166c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
167c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        @Override
169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        public void onReceive(Context context, Intent intent) {
170c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (intent.getAction().equals(Intent.ACTION_LOCALE_CHANGED)) {
171c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // update emergency string whenever locale changed
172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                updateSpnDisplay();
173c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
174c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
175c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    };
176c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
177c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) {
178c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        @Override
179c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        public void onChange(boolean selfChange) {
180c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            Log.i("GsmServiceStateTracker", "Auto time state changed");
181c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            revertToNitzTime();
182c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
183c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    };
184c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
185c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private ContentObserver mAutoTimeZoneObserver = new ContentObserver(new Handler()) {
186c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        @Override
187c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        public void onChange(boolean selfChange) {
188c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            Log.i("GsmServiceStateTracker", "Auto time zone state changed");
189c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            revertToNitzTimeZone();
190c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
191c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    };
192c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
193c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public GsmServiceStateTracker(GSMPhone phone) {
194e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        super(phone.getContext(), phone.mCM);
195c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
196c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        this.phone = phone;
197c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        ss = new ServiceState();
198c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        newSS = new ServiceState();
199c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        cellLoc = new GsmCellLocation();
200c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        newCellLoc = new GsmCellLocation();
201c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mSignalStrength = new SignalStrength();
202c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
203c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        PowerManager powerManager =
204c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                (PowerManager)phone.getContext().getSystemService(Context.POWER_SERVICE);
205c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG);
206c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
207c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
208c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
209c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
210c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        cm.registerForVoiceNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null);
211c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        cm.setOnNITZTime(this, EVENT_NITZ_TIME, null);
212c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
213c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        cm.setOnRestrictedStateChanged(this, EVENT_RESTRICTED_STATE_CHANGED, null);
214c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
215c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // system setting property AIRPLANE_MODE_ON is set in Settings.
216c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int airplaneMode = Settings.System.getInt(
217c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                phone.getContext().getContentResolver(),
218c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                Settings.System.AIRPLANE_MODE_ON, 0);
219c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mDesiredPowerState = ! (airplaneMode > 0);
220c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
221c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        cr = phone.getContext().getContentResolver();
222c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        cr.registerContentObserver(
223c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                Settings.System.getUriFor(Settings.System.AUTO_TIME), true,
224c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mAutoTimeObserver);
225c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        cr.registerContentObserver(
226c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                Settings.System.getUriFor(Settings.System.AUTO_TIME_ZONE), true,
227c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mAutoTimeZoneObserver);
228c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
229c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        setSignalStrengthDefaultValues();
230c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
231c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Monitor locale change
232c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        IntentFilter filter = new IntentFilter();
233c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        filter.addAction(Intent.ACTION_LOCALE_CHANGED);
234c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        phone.getContext().registerReceiver(mIntentReceiver, filter);
235c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
236c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Gsm doesn't support OTASP so its not needed
237c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        phone.notifyOtaspChanged(OTASP_NOT_NEEDED);
238c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
239c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
240c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void dispose() {
241bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        checkCorrectThread();
242c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Unregister for all events.
243c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        cm.unregisterForAvailable(this);
244c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        cm.unregisterForRadioStateChanged(this);
245c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        cm.unregisterForVoiceNetworkStateChanged(this);
246e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mUiccApplcation != null) {mUiccApplcation.unregisterForReady(this);}
247bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        if (mIccRecords != null) {mIccRecords.unregisterForRecordsLoaded(this);}
248c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        cm.unSetOnSignalStrengthUpdate(this);
249c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        cm.unSetOnRestrictedStateChanged(this);
250c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        cm.unSetOnNITZTime(this);
251c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        cr.unregisterContentObserver(this.mAutoTimeObserver);
252c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        cr.unregisterContentObserver(this.mAutoTimeZoneObserver);
253a5fc984c8b0696c187e14bfa75962b6e46c40d02Alex Yakavenka        phone.getContext().unregisterReceiver(mIntentReceiver);
254c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
255c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
256c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void finalize() {
257c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if(DBG) log("finalize");
258c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
259c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
260c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
261c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected Phone getPhone() {
262c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return phone;
263c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
264c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
265c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void handleMessage (Message msg) {
266c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        AsyncResult ar;
267c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int[] ints;
268c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String[] strings;
269c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Message message;
270c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
271c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (!phone.mIsTheCurrentActivePhone) {
272c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            Log.e(LOG_TAG, "Received message " + msg +
273c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    "[" + msg.what + "] while being destroyed. Ignoring.");
274c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
275c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
276c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        switch (msg.what) {
277c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_RADIO_AVAILABLE:
278c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                //this is unnecessary
279c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                //setPowerStateToDesired();
280c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
281c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
282c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_SIM_READY:
283c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // Set the network type, in case the radio does not restore it.
284c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                cm.setCurrentPreferredNetworkType();
285c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
286c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                boolean skipRestoringSelection = phone.getContext().getResources().getBoolean(
287c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        com.android.internal.R.bool.skip_restoring_network_selection);
288c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
289c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (!skipRestoringSelection) {
290c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // restore the previous network selection.
291c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    phone.restoreSavedNetworkSelection(null);
292c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
293c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                pollState();
294c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // Signal strength polling stops when radio is off
295c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                queueNextSignalStrengthPoll();
296c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
297c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
298c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_RADIO_STATE_CHANGED:
299c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // This will do nothing in the radio not
300c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // available case
301c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                setPowerStateToDesired();
302c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                pollState();
303c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
304c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
305c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_NETWORK_STATE_CHANGED:
306c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                pollState();
307c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
308c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
309c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_SIGNAL_STRENGTH:
310c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // This callback is called when signal strength is polled
311c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // all by itself
312c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
313c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (!(cm.getRadioState().isOn())) {
314c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Polling will continue when radio turns back on
315c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    return;
316c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
317c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult) msg.obj;
3185b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam                onSignalStrengthResult(ar, phone, true);
319c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                queueNextSignalStrengthPoll();
320c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
321c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
322c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
323c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_LOC_DONE:
324c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult) msg.obj;
325c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
326c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception == null) {
327c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    String states[] = (String[])ar.result;
328c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    int lac = -1;
329c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    int cid = -1;
330c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (states.length >= 3) {
331c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        try {
332c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            if (states[1] != null && states[1].length() > 0) {
333c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                lac = Integer.parseInt(states[1], 16);
334c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            }
335c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            if (states[2] != null && states[2].length() > 0) {
336c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                cid = Integer.parseInt(states[2], 16);
337c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            }
338c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        } catch (NumberFormatException ex) {
339c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            Log.w(LOG_TAG, "error parsing location: " + ex);
340c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
341c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
342c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    cellLoc.setLacAndCid(lac, cid);
343c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    phone.notifyLocationChanged();
344c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
345c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
346c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // Release any temporary cell lock, which could have been
347c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // acquired to allow a single-shot location update.
348c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                disableSingleLocationUpdate();
349c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
350c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
351c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_POLL_STATE_REGISTRATION:
352c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_POLL_STATE_GPRS:
353c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_POLL_STATE_OPERATOR:
354c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_POLL_STATE_NETWORK_SELECTION_MODE:
355c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult) msg.obj;
356c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
357c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                handlePollStateResult(msg.what, ar);
358c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
359c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
360c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_POLL_SIGNAL_STRENGTH:
361c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // Just poll signal strength...not part of pollState()
362c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
363c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                cm.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
364c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
365c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
366c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_NITZ_TIME:
367c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult) msg.obj;
368c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
369c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                String nitzString = (String)((Object[])ar.result)[0];
370c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                long nitzReceiveTime = ((Long)((Object[])ar.result)[1]).longValue();
371c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
372c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                setTimeFromNITZString(nitzString, nitzReceiveTime);
373c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
374c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
375c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_SIGNAL_STRENGTH_UPDATE:
376c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // This is a notification from
377c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // CommandsInterface.setOnSignalStrengthUpdate
378c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
379c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult) msg.obj;
380c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
381c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // The radio is telling us about signal strength changes
382c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // we don't have to ask it
383c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                dontPollSignalStrength = true;
384c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3855b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam                onSignalStrengthResult(ar, phone, true);
386c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
387c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
388c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_SIM_RECORDS_LOADED:
389c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                updateSpnDisplay();
390c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
391c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
392c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_LOCATION_UPDATES_ENABLED:
393c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult) msg.obj;
394c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
395c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception == null) {
396c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    cm.getVoiceRegistrationState(obtainMessage(EVENT_GET_LOC_DONE, null));
397c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
398c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
399c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
400c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_SET_PREFERRED_NETWORK_TYPE:
401c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult) msg.obj;
402c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // Don't care the result, only use for dereg network (COPS=2)
403c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                message = obtainMessage(EVENT_RESET_PREFERRED_NETWORK_TYPE, ar.userObj);
404c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                cm.setPreferredNetworkType(mPreferredNetworkType, message);
405c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
406c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
407c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_RESET_PREFERRED_NETWORK_TYPE:
408c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult) msg.obj;
409c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.userObj != null) {
410c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    AsyncResult.forMessage(((Message) ar.userObj)).exception
411c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            = ar.exception;
412c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ((Message) ar.userObj).sendToTarget();
413c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
414c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
415c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
416c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_PREFERRED_NETWORK_TYPE:
417c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult) msg.obj;
418c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
419c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception == null) {
420c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mPreferredNetworkType = ((int[])ar.result)[0];
421c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
422c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mPreferredNetworkType = RILConstants.NETWORK_MODE_GLOBAL;
423c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
424c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
425c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                message = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE, ar.userObj);
426c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                int toggledNetworkType = RILConstants.NETWORK_MODE_GLOBAL;
427c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
428c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                cm.setPreferredNetworkType(toggledNetworkType, message);
429c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
430c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
431c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_CHECK_REPORT_GPRS:
432c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ss != null && !isGprsConsistent(gprsState, ss.getState())) {
433c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
434c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Can't register data service while voice service is ok
435c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // i.e. CREG is ok while CGREG is not
436c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // possible a network or baseband side error
437c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
438c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    EventLog.writeEvent(EventLogTags.DATA_NETWORK_REGISTRATION_FAIL,
439c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            ss.getOperatorNumeric(), loc != null ? loc.getCid() : -1);
440c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mReportedGprsNoReg = true;
441c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
442c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mStartedGprsRegCheck = false;
443c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
444c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
445c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_RESTRICTED_STATE_CHANGED:
446c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // This is a notification from
447c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // CommandsInterface.setOnRestrictedStateChanged
448c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
449c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("EVENT_RESTRICTED_STATE_CHANGED");
450c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
451c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult) msg.obj;
452c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
453c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onRestrictedStateChanged(ar);
454c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
455c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
456c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            default:
457c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                super.handleMessage(msg);
458c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
459c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
460c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
461c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
462c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void setPowerStateToDesired() {
463c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // If we want it on and it's off, turn it on
464c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mDesiredPowerState
465c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            && cm.getRadioState() == CommandsInterface.RadioState.RADIO_OFF) {
466c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            cm.setRadioPower(true, null);
467c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else if (!mDesiredPowerState && cm.getRadioState().isOn()) {
468c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // If it's on and available and we want it off gracefully
469c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            DataConnectionTracker dcTracker = phone.mDataConnectionTracker;
470c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            powerOffRadioSafely(dcTracker);
471c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } // Otherwise, we're in the desired state
472c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
473c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
474c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
475c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void hangupAndPowerOff() {
476c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // hang up all active voice calls
477c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (phone.isInCall()) {
478c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            phone.mCT.ringingCall.hangupIfAlive();
479c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            phone.mCT.backgroundCall.hangupIfAlive();
480c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            phone.mCT.foregroundCall.hangupIfAlive();
481c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
482c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
483c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        cm.setRadioPower(false, null);
484c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
485c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
486c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void updateSpnDisplay() {
487bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        if (mIccRecords == null) {
488bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka            return;
489bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        }
490bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        int rule = mIccRecords.getDisplayRule(ss.getOperatorNumeric());
491bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        String spn = mIccRecords.getServiceProviderName();
492c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String plmn = ss.getOperatorAlphaLong();
493c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
494c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // For emergency calls only, pass the EmergencyCallsOnly string via EXTRA_PLMN
495c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mEmergencyOnly && cm.getRadioState().isOn()) {
496c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            plmn = Resources.getSystem().
497c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                getText(com.android.internal.R.string.emergency_calls_only).toString();
498c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (DBG) log("updateSpnDisplay: emergency only and radio is on plmn='" + plmn + "'");
499c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
500c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
501c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (rule != curSpnRule
502c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                || !TextUtils.equals(spn, curSpn)
503c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                || !TextUtils.equals(plmn, curPlmn)) {
504c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            boolean showSpn = !mEmergencyOnly && !TextUtils.isEmpty(spn)
505c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                && (rule & SIMRecords.SPN_RULE_SHOW_SPN) == SIMRecords.SPN_RULE_SHOW_SPN;
506c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            boolean showPlmn = !TextUtils.isEmpty(plmn) &&
507c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                (rule & SIMRecords.SPN_RULE_SHOW_PLMN) == SIMRecords.SPN_RULE_SHOW_PLMN;
508c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
509c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (DBG) {
510c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log(String.format("updateSpnDisplay: changed sending intent" + " rule=" + rule +
511c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            " showPlmn='%b' plmn='%s' showSpn='%b' spn='%s'",
512c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            showPlmn, plmn, showSpn, spn));
513c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
514c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            Intent intent = new Intent(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
515c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
516c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            intent.putExtra(TelephonyIntents.EXTRA_SHOW_SPN, showSpn);
517c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            intent.putExtra(TelephonyIntents.EXTRA_SPN, spn);
518c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            intent.putExtra(TelephonyIntents.EXTRA_SHOW_PLMN, showPlmn);
519c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            intent.putExtra(TelephonyIntents.EXTRA_PLMN, plmn);
520c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            phone.getContext().sendStickyBroadcast(intent);
521c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
522c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
523c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        curSpnRule = rule;
524c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        curSpn = spn;
525c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        curPlmn = plmn;
526c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
527c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
528c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
529c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Handle the result of one of the pollState()-related requests
530c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
531c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void handlePollStateResult (int what, AsyncResult ar) {
532c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int ints[];
533c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String states[];
534c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
535c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Ignore stale requests from last poll
536c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (ar.userObj != pollingContext) return;
537c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
538c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (ar.exception != null) {
539c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            CommandException.Error err=null;
540c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
541c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (ar.exception instanceof CommandException) {
542c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                err = ((CommandException)(ar.exception)).getCommandError();
543c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
544c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
545c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (err == CommandException.Error.RADIO_NOT_AVAILABLE) {
546c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // Radio has crashed or turned off
547c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                cancelPollState();
548c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                return;
549c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
550c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
551c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (!cm.getRadioState().isOn()) {
552c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // Radio has crashed or turned off
553c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                cancelPollState();
554c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                return;
555c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
556c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
557c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) {
558c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                loge("RIL implementation has returned an error where it must succeed" +
559c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        ar.exception);
560c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
561c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else try {
562c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            switch (what) {
563c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                case EVENT_POLL_STATE_REGISTRATION:
564c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    states = (String[])ar.result;
565c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    int lac = -1;
566c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    int cid = -1;
567c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    int regState = -1;
568c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    int reasonRegStateDenied = -1;
569c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    int psc = -1;
570c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (states.length > 0) {
571c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        try {
572c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            regState = Integer.parseInt(states[0]);
573c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            if (states.length >= 3) {
574c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                if (states[1] != null && states[1].length() > 0) {
575c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                    lac = Integer.parseInt(states[1], 16);
576c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                }
577c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                if (states[2] != null && states[2].length() > 0) {
578c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                    cid = Integer.parseInt(states[2], 16);
579c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                }
580c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            }
581c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            if (states.length > 14) {
582c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                if (states[14] != null && states[14].length() > 0) {
583c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                    psc = Integer.parseInt(states[14], 16);
584c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                }
585c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            }
586c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        } catch (NumberFormatException ex) {
587c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            loge("error parsing RegistrationState: " + ex);
588c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
589c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
590c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
591c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mGsmRoaming = regCodeIsRoaming(regState);
592c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    newSS.setState (regCodeToServiceState(regState));
593c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
594c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (regState == 10 || regState == 12 || regState == 13 || regState == 14) {
595c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        mEmergencyOnly = true;
596c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else {
597c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        mEmergencyOnly = false;
598c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
599c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
600c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // LAC and CID are -1 if not avail
601c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    newCellLoc.setLacAndCid(lac, cid);
602c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    newCellLoc.setPsc(psc);
603c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
604c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
605c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                case EVENT_POLL_STATE_GPRS:
606c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    states = (String[])ar.result;
607c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
608c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    int type = 0;
609c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    regState = -1;
610c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mNewReasonDataDenied = -1;
611c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mNewMaxDataCalls = 1;
612c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (states.length > 0) {
613c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        try {
614c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            regState = Integer.parseInt(states[0]);
615c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
616c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            // states[3] (if present) is the current radio technology
617c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            if (states.length >= 4 && states[3] != null) {
618c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                type = Integer.parseInt(states[3]);
619c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            }
620c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            if ((states.length >= 5 ) && (regState == 3)) {
621c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                mNewReasonDataDenied = Integer.parseInt(states[4]);
622c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            }
623c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            if (states.length >= 6) {
624c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                mNewMaxDataCalls = Integer.parseInt(states[5]);
625c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            }
626c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        } catch (NumberFormatException ex) {
627c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            loge("error parsing GprsRegistrationState: " + ex);
628c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
629c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
630c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    newGPRSState = regCodeToServiceState(regState);
631c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mDataRoaming = regCodeIsRoaming(regState);
632c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mNewRilRadioTechnology = type;
633c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    newSS.setRadioTechnology(type);
634c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
635c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
636c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                case EVENT_POLL_STATE_OPERATOR:
637c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    String opNames[] = (String[])ar.result;
638c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
639c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (opNames != null && opNames.length >= 3) {
640c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                         newSS.setOperatorName (opNames[0], opNames[1], opNames[2]);
641c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
642c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
643c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
644c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                case EVENT_POLL_STATE_NETWORK_SELECTION_MODE:
645c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ints = (int[])ar.result;
646c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    newSS.setIsManualSelection(ints[0] == 1);
647c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
648c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
649c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
650c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (RuntimeException ex) {
651c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            loge("Exception while polling service state. Probably malformed RIL response." + ex);
652c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
653c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
654c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pollingContext[0]--;
655c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
656c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (pollingContext[0] == 0) {
657c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            /**
658c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville             *  Since the roaming states of gsm service (from +CREG) and
659c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville             *  data service (from +CGREG) could be different, the new SS
660c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville             *  is set roaming while either one is roaming.
661c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville             *
662c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville             *  There is an exception for the above rule. The new SS is not set
663c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville             *  as roaming while gsm service reports roaming but indeed it is
664c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville             *  not roaming between operators.
665c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville             */
666c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            boolean roaming = (mGsmRoaming || mDataRoaming);
667c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (mGsmRoaming && !isRoamingBetweenOperators(mGsmRoaming, newSS)) {
668c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                roaming = false;
669c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
670c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            newSS.setRoaming(roaming);
671c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            newSS.setEmergencyOnly(mEmergencyOnly);
672c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            pollStateDone();
673c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
674c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
675c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
676c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void setSignalStrengthDefaultValues() {
6775b81adc82a53b3064f4baa3acfeabef31586588aUma Maheswari Ramalingam        mSignalStrength = new SignalStrength(true);
678c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
679c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
680c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
681c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * A complete "service state" from our perspective is
682c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * composed of a handful of separate requests to the radio.
683c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
684c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * We make all of these requests at once, but then abandon them
685c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * and start over again if the radio notifies us that some
686c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * event has changed
687c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
688c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void pollState() {
689c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pollingContext = new int[1];
690c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pollingContext[0] = 0;
691c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
692c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        switch (cm.getRadioState()) {
693c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case RADIO_UNAVAILABLE:
694c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                newSS.setStateOutOfService();
695c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                newCellLoc.setStateInvalid();
696c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                setSignalStrengthDefaultValues();
697c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mGotCountryCode = false;
698c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mNitzUpdatedTime = false;
699c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                pollStateDone();
700c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
701c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
702c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case RADIO_OFF:
703c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                newSS.setStateOff();
704c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                newCellLoc.setStateInvalid();
705c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                setSignalStrengthDefaultValues();
706c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mGotCountryCode = false;
707c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mNitzUpdatedTime = false;
708c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                pollStateDone();
709c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
710c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
711c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            default:
712c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // Issue all poll-related commands at once
713c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // then count down the responses, which
714c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // are allowed to arrive out-of-order
715c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
716c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                pollingContext[0]++;
717c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                cm.getOperator(
718c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    obtainMessage(
719c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        EVENT_POLL_STATE_OPERATOR, pollingContext));
720c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
721c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                pollingContext[0]++;
722c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                cm.getDataRegistrationState(
723c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    obtainMessage(
724c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        EVENT_POLL_STATE_GPRS, pollingContext));
725c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
726c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                pollingContext[0]++;
727c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                cm.getVoiceRegistrationState(
728c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    obtainMessage(
729c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        EVENT_POLL_STATE_REGISTRATION, pollingContext));
730c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
731c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                pollingContext[0]++;
732c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                cm.getNetworkSelectionMode(
733c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    obtainMessage(
734c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        EVENT_POLL_STATE_NETWORK_SELECTION_MODE, pollingContext));
735c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
736c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
737c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
738c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
739c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void pollStateDone() {
740c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) {
741c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            log("Poll ServiceState done: " +
742c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                " oldSS=[" + ss + "] newSS=[" + newSS +
743c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                "] oldGprs=" + gprsState + " newData=" + newGPRSState +
744c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                " oldMaxDataCalls=" + mMaxDataCalls +
745c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                " mNewMaxDataCalls=" + mNewMaxDataCalls +
746c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                " oldReasonDataDenied=" + mReasonDataDenied +
747c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                " mNewReasonDataDenied=" + mNewReasonDataDenied +
748c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                " oldType=" + ServiceState.rilRadioTechnologyToString(mRilRadioTechnology) +
749c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                " newType=" + ServiceState.rilRadioTechnologyToString(mNewRilRadioTechnology));
750c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
751c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
752c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean hasRegistered =
753c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            ss.getState() != ServiceState.STATE_IN_SERVICE
754c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            && newSS.getState() == ServiceState.STATE_IN_SERVICE;
755c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
756c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean hasDeregistered =
757c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            ss.getState() == ServiceState.STATE_IN_SERVICE
758c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            && newSS.getState() != ServiceState.STATE_IN_SERVICE;
759c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
760c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean hasGprsAttached =
761c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                gprsState != ServiceState.STATE_IN_SERVICE
762c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                && newGPRSState == ServiceState.STATE_IN_SERVICE;
763c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
764c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean hasGprsDetached =
765c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                gprsState == ServiceState.STATE_IN_SERVICE
766c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                && newGPRSState != ServiceState.STATE_IN_SERVICE;
767c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
768c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean hasRadioTechnologyChanged = mRilRadioTechnology != mNewRilRadioTechnology;
769c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
770c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean hasChanged = !newSS.equals(ss);
771c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
772c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean hasRoamingOn = !ss.getRoaming() && newSS.getRoaming();
773c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
774c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean hasRoamingOff = ss.getRoaming() && !newSS.getRoaming();
775c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
776c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean hasLocationChanged = !newCellLoc.equals(cellLoc);
777c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
778c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Add an event log when connection state changes
779c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (ss.getState() != newSS.getState() || gprsState != newGPRSState) {
780c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            EventLog.writeEvent(EventLogTags.GSM_SERVICE_STATE_CHANGE,
781c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ss.getState(), gprsState, newSS.getState(), newGPRSState);
782c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
783c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
784c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        ServiceState tss;
785c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        tss = ss;
786c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        ss = newSS;
787c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        newSS = tss;
788c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // clean slate for next time
789c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        newSS.setStateOutOfService();
790c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
791c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        GsmCellLocation tcl = cellLoc;
792c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        cellLoc = newCellLoc;
793c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        newCellLoc = tcl;
794c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
795c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Add an event log when network type switched
796c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // TODO: we may add filtering to reduce the event logged,
797c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // i.e. check preferred network setting, only switch to 2G, etc
798c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (hasRadioTechnologyChanged) {
799c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            int cid = -1;
800c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
801c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (loc != null) cid = loc.getCid();
802c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            EventLog.writeEvent(EventLogTags.GSM_RAT_SWITCHED, cid, mRilRadioTechnology,
803c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mNewRilRadioTechnology);
804c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (DBG) {
805c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("RAT switched " + ServiceState.rilRadioTechnologyToString(mRilRadioTechnology) +
806c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        " -> " + ServiceState.rilRadioTechnologyToString(mNewRilRadioTechnology) +
807c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        " at cell " + cid);
808c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
809c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
810c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
811c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        gprsState = newGPRSState;
812c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mReasonDataDenied = mNewReasonDataDenied;
813c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mMaxDataCalls = mNewMaxDataCalls;
814c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mRilRadioTechnology = mNewRilRadioTechnology;
815c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // this new state has been applied - forget it until we get a new new state
816c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mNewRilRadioTechnology = 0;
817c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
818c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
819c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        newSS.setStateOutOfService(); // clean slate for next time
820c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
821c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (hasRadioTechnologyChanged) {
822c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
823c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ServiceState.rilRadioTechnologyToString(mRilRadioTechnology));
824c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
825c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
826c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (hasRegistered) {
827c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            mNetworkAttachedRegistrants.notifyRegistrants();
828c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
829c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (DBG) {
830c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("pollStateDone: registering current mNitzUpdatedTime=" +
831c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        mNitzUpdatedTime + " changing to false");
832c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
833c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            mNitzUpdatedTime = false;
834c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
835c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
836c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (hasChanged) {
837c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String operatorNumeric;
838c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
839c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            updateSpnDisplay();
840c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
841c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
842c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ss.getOperatorAlphaLong());
843c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
844c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String prevOperatorNumeric =
845c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, "");
846c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            operatorNumeric = ss.getOperatorNumeric();
847c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
848c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
849c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (operatorNumeric == null) {
850c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("operatorNumeric is null");
851c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
852c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mGotCountryCode = false;
853c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mNitzUpdatedTime = false;
854c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } else {
855c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                String iso = "";
8567c491bb3d140e2579c2c01edca94305701664db5Rekha Kumar                String mcc = "";
857c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                try{
8587c491bb3d140e2579c2c01edca94305701664db5Rekha Kumar                    mcc = operatorNumeric.substring(0, 3);
859c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    iso = MccTable.countryCodeForMcc(Integer.parseInt(mcc));
860c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } catch ( NumberFormatException ex){
861c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    loge("pollStateDone: countryCodeForMcc error" + ex);
862c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } catch ( StringIndexOutOfBoundsException ex) {
863c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    loge("pollStateDone: countryCodeForMcc error" + ex);
864c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
865c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
866c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, iso);
867c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mGotCountryCode = true;
868c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
869c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                TimeZone zone = null;
870c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
871c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (!mNitzUpdatedTime && !mcc.equals("000") && !TextUtils.isEmpty(iso) &&
872c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        getAutoTimeZone()) {
873c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
874c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Test both paths if ignore nitz is true
875c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    boolean testOneUniqueOffsetPath = SystemProperties.getBoolean(
876c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                TelephonyProperties.PROPERTY_IGNORE_NITZ, false) &&
877c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                    ((SystemClock.uptimeMillis() & 1) == 0);
878c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
879c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ArrayList<TimeZone> uniqueZones = TimeUtils.getTimeZonesWithUniqueOffsets(iso);
880c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if ((uniqueZones.size() == 1) || testOneUniqueOffsetPath) {
881c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        zone = uniqueZones.get(0);
882c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        if (DBG) {
883c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                           log("pollStateDone: no nitz but one TZ for iso-cc=" + iso +
884c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                   " with zone.getID=" + zone.getID() +
885c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                   " testOneUniqueOffsetPath=" + testOneUniqueOffsetPath);
886c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
887c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        setAndBroadcastNetworkSetTimeZone(zone.getID());
888c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else {
889c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        if (DBG) {
890c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            log("pollStateDone: there are " + uniqueZones.size() +
891c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                " unique offsets for iso-cc='" + iso +
892c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                " testOneUniqueOffsetPath=" + testOneUniqueOffsetPath +
893c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                "', do nothing");
894c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
895c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
896c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
897c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
898c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (shouldFixTimeZoneNow(phone, operatorNumeric, prevOperatorNumeric,
899c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        mNeedFixZoneAfterNitz)) {
900c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // If the offset is (0, false) and the timezone property
901c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // is set, use the timezone property rather than
902c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // GMT.
903c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    String zoneName = SystemProperties.get(TIMEZONE_PROPERTY);
904c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (DBG) {
905c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        log("pollStateDone: fix time zone zoneName='" + zoneName +
906c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            "' mZoneOffset=" + mZoneOffset + " mZoneDst=" + mZoneDst +
907c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            " iso-cc='" + iso +
908c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            "' iso-cc-idx=" + Arrays.binarySearch(GMT_COUNTRY_CODES, iso));
909c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
910c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
911c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // "(mZoneOffset == 0) && (mZoneDst == false) &&
912c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    //  (Arrays.binarySearch(GMT_COUNTRY_CODES, iso) < 0)"
913c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // means that we received a NITZ string telling
914c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // it is in GMT+0 w/ DST time zone
915c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // BUT iso tells is NOT, e.g, a wrong NITZ reporting
916c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // local time w/ 0 offset.
917c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if ((mZoneOffset == 0) && (mZoneDst == false) &&
918c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        (zoneName != null) && (zoneName.length() > 0) &&
919c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        (Arrays.binarySearch(GMT_COUNTRY_CODES, iso) < 0)) {
920c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        zone = TimeZone.getDefault();
921c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        if (mNeedFixZoneAfterNitz) {
922c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            // For wrong NITZ reporting local time w/ 0 offset,
923c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            // need adjust time to reflect default timezone setting
924c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            long ctm = System.currentTimeMillis();
925c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            long tzOffset = zone.getOffset(ctm);
926c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            if (DBG) {
927c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                log("pollStateDone: tzOffset=" + tzOffset + " ltod=" +
928c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                        TimeUtils.logTimeOfDay(ctm));
929c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            }
930c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            if (getAutoTime()) {
931c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                long adj = ctm - tzOffset;
932c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                if (DBG) log("pollStateDone: adj ltod=" +
933c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                        TimeUtils.logTimeOfDay(adj));
934c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                setAndBroadcastNetworkSetTime(adj);
935c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            } else {
936c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                // Adjust the saved NITZ time to account for tzOffset.
937c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                mSavedTime = mSavedTime - tzOffset;
938c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            }
939c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
940c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        if (DBG) log("pollStateDone: using default TimeZone");
941c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else if (iso.equals("")){
942c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // Country code not found.  This is likely a test network.
943c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // Get a TimeZone based only on the NITZ parameters (best guess).
944c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        zone = getNitzTimeZone(mZoneOffset, mZoneDst, mZoneTime);
945c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        if (DBG) log("pollStateDone: using NITZ TimeZone");
946c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else {
947c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        zone = TimeUtils.getTimeZone(mZoneOffset, mZoneDst, mZoneTime, iso);
948c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        if (DBG) log("pollStateDone: using getTimeZone(off, dst, time, iso)");
949c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
950c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
951c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mNeedFixZoneAfterNitz = false;
952c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
953c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (zone != null) {
954c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        log("pollStateDone: zone != null zone.getID=" + zone.getID());
955c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        if (getAutoTimeZone()) {
956c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            setAndBroadcastNetworkSetTimeZone(zone.getID());
957c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
958c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        saveNitzTimeZone(zone.getID());
959c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else {
960c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        log("pollStateDone: zone == null");
961c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
962c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
963c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
964c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
965c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
966c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ss.getRoaming() ? "true" : "false");
967c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
968c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            phone.notifyServiceStateChanged(ss);
969c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
970c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
971c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (hasGprsAttached) {
972c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            mAttachedRegistrants.notifyRegistrants();
973c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
974c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
975c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (hasGprsDetached) {
976c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            mDetachedRegistrants.notifyRegistrants();
977c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
978c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
979c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (hasRadioTechnologyChanged) {
980c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            phone.notifyDataConnection(Phone.REASON_NW_TYPE_CHANGED);
981c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
982c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
983c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (hasRoamingOn) {
984c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            mRoamingOnRegistrants.notifyRegistrants();
985c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
986c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
987c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (hasRoamingOff) {
988c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            mRoamingOffRegistrants.notifyRegistrants();
989c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
990c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
991c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (hasLocationChanged) {
992c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            phone.notifyLocationChanged();
993c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
994c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
995c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (! isGprsConsistent(gprsState, ss.getState())) {
996c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (!mStartedGprsRegCheck && !mReportedGprsNoReg) {
997c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mStartedGprsRegCheck = true;
998c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
999c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                int check_period = Settings.Secure.getInt(
1000c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        phone.getContext().getContentResolver(),
1001c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        Settings.Secure.GPRS_REGISTER_CHECK_PERIOD_MS,
1002c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        DEFAULT_GPRS_CHECK_PERIOD_MILLIS);
1003c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                sendMessageDelayed(obtainMessage(EVENT_CHECK_REPORT_GPRS),
1004c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        check_period);
1005c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1006c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
1007c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            mReportedGprsNoReg = false;
1008c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1009c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1010c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1011c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1012c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Check if GPRS got registered while voice is registered.
1013c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
1014c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param gprsState for GPRS registration state, i.e. CGREG in GSM
1015c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param serviceState for voice registration state, i.e. CREG in GSM
1016c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return false if device only register to voice but not gprs
1017c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1018c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean isGprsConsistent(int gprsState, int serviceState) {
1019c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return !((serviceState == ServiceState.STATE_IN_SERVICE) &&
1020c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                (gprsState != ServiceState.STATE_IN_SERVICE));
1021c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1022c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1023c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1024c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Returns a TimeZone object based only on parameters from the NITZ string.
1025c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1026c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private TimeZone getNitzTimeZone(int offset, boolean dst, long when) {
1027c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        TimeZone guess = findTimeZone(offset, dst, when);
1028c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (guess == null) {
1029c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // Couldn't find a proper timezone.  Perhaps the DST data is wrong.
1030c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            guess = findTimeZone(offset, !dst, when);
1031c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1032c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) log("getNitzTimeZone returning " + (guess == null ? guess : guess.getID()));
1033c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return guess;
1034c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1035c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1036c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private TimeZone findTimeZone(int offset, boolean dst, long when) {
1037c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int rawOffset = offset;
1038c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (dst) {
1039c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            rawOffset -= 3600000;
1040c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1041c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String[] zones = TimeZone.getAvailableIDs(rawOffset);
1042c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        TimeZone guess = null;
1043c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Date d = new Date(when);
1044c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        for (String zone : zones) {
1045c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            TimeZone tz = TimeZone.getTimeZone(zone);
1046c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (tz.getOffset(when) == offset &&
1047c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                tz.inDaylightTime(d) == dst) {
1048c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                guess = tz;
1049c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1050c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1051c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1052c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1053c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return guess;
1054c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1055c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1056c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void queueNextSignalStrengthPoll() {
1057c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (dontPollSignalStrength) {
1058c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // The radio is telling us about signal strength changes
1059c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // we don't have to ask it
1060c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
1061c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1062c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1063c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Message msg;
1064c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1065c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        msg = obtainMessage();
1066c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        msg.what = EVENT_POLL_SIGNAL_STRENGTH;
1067c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1068c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        long nextTime;
1069c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1070c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // TODO Don't poll signal strength if screen is off
1071c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        sendMessageDelayed(msg, POLL_PERIOD_MILLIS);
1072c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1073c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1074c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1075c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Set restricted state based on the OnRestrictedStateChanged notification
1076c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * If any voice or packet restricted state changes, trigger a UI
1077c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * notification and notify registrants when sim is ready.
1078c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
1079c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param ar an int value of RIL_RESTRICTED_STATE_*
1080c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1081c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void onRestrictedStateChanged(AsyncResult ar) {
1082c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        RestrictedState newRs = new RestrictedState();
1083c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1084c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) log("onRestrictedStateChanged: E rs "+ mRestrictedState);
1085c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1086c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (ar.exception == null) {
1087c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            int[] ints = (int[])ar.result;
1088c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            int state = ints[0];
1089c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1090c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            newRs.setCsEmergencyRestricted(
1091c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ((state & RILConstants.RIL_RESTRICTED_STATE_CS_EMERGENCY) != 0) ||
1092c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
1093c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            //ignore the normal call and data restricted state before SIM READY
1094e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mUiccApplcation != null && mUiccApplcation.getState() == AppState.APPSTATE_READY) {
1095c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                newRs.setCsNormalRestricted(
1096c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        ((state & RILConstants.RIL_RESTRICTED_STATE_CS_NORMAL) != 0) ||
1097c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
1098c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                newRs.setPsRestricted(
1099c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        (state & RILConstants.RIL_RESTRICTED_STATE_PS_ALL)!= 0);
1100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1101c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1102c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (DBG) log("onRestrictedStateChanged: new rs "+ newRs);
1103c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1104c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (!mRestrictedState.isPsRestricted() && newRs.isPsRestricted()) {
1105c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mPsRestrictEnabledRegistrants.notifyRegistrants();
1106c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                setNotification(PS_ENABLED);
1107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } else if (mRestrictedState.isPsRestricted() && !newRs.isPsRestricted()) {
1108c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mPsRestrictDisabledRegistrants.notifyRegistrants();
1109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                setNotification(PS_DISABLED);
1110c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1111c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            /**
1113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville             * There are two kind of cs restriction, normal and emergency. So
1114c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville             * there are 4 x 4 combinations in current and new restricted states
1115c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville             * and we only need to notify when state is changed.
1116c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville             */
1117c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (mRestrictedState.isCsRestricted()) {
1118c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (!newRs.isCsRestricted()) {
1119c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // remove all restriction
1120c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    setNotification(CS_DISABLED);
1121c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else if (!newRs.isCsNormalRestricted()) {
1122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // remove normal restriction
1123c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    setNotification(CS_EMERGENCY_ENABLED);
1124c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else if (!newRs.isCsEmergencyRestricted()) {
1125c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // remove emergency restriction
1126c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    setNotification(CS_NORMAL_ENABLED);
1127c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1128c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } else if (mRestrictedState.isCsEmergencyRestricted() &&
1129c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    !mRestrictedState.isCsNormalRestricted()) {
1130c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (!newRs.isCsRestricted()) {
1131c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // remove all restriction
1132c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    setNotification(CS_DISABLED);
1133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else if (newRs.isCsRestricted()) {
1134c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // enable all restriction
1135c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    setNotification(CS_ENABLED);
1136c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else if (newRs.isCsNormalRestricted()) {
1137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // remove emergency restriction and enable normal restriction
1138c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    setNotification(CS_NORMAL_ENABLED);
1139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1140c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } else if (!mRestrictedState.isCsEmergencyRestricted() &&
1141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mRestrictedState.isCsNormalRestricted()) {
1142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (!newRs.isCsRestricted()) {
1143c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // remove all restriction
1144c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    setNotification(CS_DISABLED);
1145c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else if (newRs.isCsRestricted()) {
1146c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // enable all restriction
1147c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    setNotification(CS_ENABLED);
1148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else if (newRs.isCsEmergencyRestricted()) {
1149c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // remove normal restriction and enable emergency restriction
1150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    setNotification(CS_EMERGENCY_ENABLED);
1151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1152c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } else {
1153c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (newRs.isCsRestricted()) {
1154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // enable all restriction
1155c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    setNotification(CS_ENABLED);
1156c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else if (newRs.isCsEmergencyRestricted()) {
1157c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // enable emergency restriction
1158c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    setNotification(CS_EMERGENCY_ENABLED);
1159c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else if (newRs.isCsNormalRestricted()) {
1160c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // enable normal restriction
1161c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    setNotification(CS_NORMAL_ENABLED);
1162c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1163c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1165c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            mRestrictedState = newRs;
1166c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1167c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        log("onRestrictedStateChanged: X rs "+ mRestrictedState);
1168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1170c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** code is registration state 0-5 from TS 27.007 7.2 */
1171c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private int regCodeToServiceState(int code) {
1172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        switch (code) {
1173c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case 0:
1174c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case 2: // 2 is "searching"
1175c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case 3: // 3 is "registration denied"
1176c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case 4: // 4 is "unknown" no vaild in current baseband
1177c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case 10:// same as 0, but indicates that emergency call is possible.
1178c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case 12:// same as 2, but indicates that emergency call is possible.
1179c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case 13:// same as 3, but indicates that emergency call is possible.
1180c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case 14:// same as 4, but indicates that emergency call is possible.
1181c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                return ServiceState.STATE_OUT_OF_SERVICE;
1182c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1183c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case 1:
1184c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                return ServiceState.STATE_IN_SERVICE;
1185c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1186c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case 5:
1187c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // in service, roam
1188c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                return ServiceState.STATE_IN_SERVICE;
1189c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1190c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            default:
1191c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                loge("regCodeToServiceState: unexpected service state " + code);
1192c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                return ServiceState.STATE_OUT_OF_SERVICE;
1193c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1194c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1195c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1196c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1197c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1198c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * code is registration state 0-5 from TS 27.007 7.2
1199c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * returns true if registered roam, false otherwise
1200c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1201c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean regCodeIsRoaming (int code) {
1202c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // 5 is  "in service -- roam"
1203c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return 5 == code;
1204c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1205c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1206c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1207c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Set roaming state when gsmRoaming is true and, if operator mcc is the
1208c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * same as sim mcc, ons is different from spn
1209c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param gsmRoaming TS 27.007 7.2 CREG registered roaming
1210c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param s ServiceState hold current ons
1211c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return true for roaming state set
1212c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1213c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean isRoamingBetweenOperators(boolean gsmRoaming, ServiceState s) {
1214c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String spn = SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, "empty");
1215c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1216c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String onsl = s.getOperatorAlphaLong();
1217c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String onss = s.getOperatorAlphaShort();
1218c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1219c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean equalsOnsl = onsl != null && spn.equals(onsl);
1220c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean equalsOnss = onss != null && spn.equals(onss);
1221c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1222c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String simNumeric = SystemProperties.get(
1223c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "");
1224c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String  operatorNumeric = s.getOperatorNumeric();
1225c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1226c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean equalsMcc = true;
1227c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try {
1228c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            equalsMcc = simNumeric.substring(0, 3).
1229c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    equals(operatorNumeric.substring(0, 3));
1230c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (Exception e){
1231c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1232c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1233c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return gsmRoaming && !(equalsMcc && (equalsOnsl || equalsOnss));
1234c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1235c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1236c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static int twoDigitsAt(String s, int offset) {
1237c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int a, b;
1238c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1239c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        a = Character.digit(s.charAt(offset), 10);
1240c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        b = Character.digit(s.charAt(offset+1), 10);
1241c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1242c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (a < 0 || b < 0) {
1243c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1244c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            throw new RuntimeException("invalid format");
1245c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1246c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1247c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return a*10 + b;
1248c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1249c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1250c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1251c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return The current GPRS state. IN_SERVICE is the same as "attached"
1252c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * and OUT_OF_SERVICE is the same as detached.
1253c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1254c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    int getCurrentGprsState() {
1255c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return gprsState;
1256c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1257c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1258c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public int getCurrentDataConnectionState() {
1259c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return gprsState;
1260c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1261c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1262c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1263c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @return true if phone is camping on a technology (eg UMTS)
1264c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * that could support voice and data simultaneously.
1265c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1266c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean isConcurrentVoiceAndDataAllowed() {
1267c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return (mRilRadioTechnology >= ServiceState.RIL_RADIO_TECHNOLOGY_UMTS);
1268c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1269c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1270c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1271c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Provides the name of the algorithmic time zone for the specified
1272c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * offset.  Taken from TimeZone.java.
1273c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1274c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static String displayNameFor(int off) {
1275c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        off = off / 1000 / 60;
1276c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1277c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        char[] buf = new char[9];
1278c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        buf[0] = 'G';
1279c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        buf[1] = 'M';
1280c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        buf[2] = 'T';
1281c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1282c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (off < 0) {
1283c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            buf[3] = '-';
1284c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            off = -off;
1285c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
1286c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            buf[3] = '+';
1287c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1288c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1289c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int hours = off / 60;
1290c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int minutes = off % 60;
1291c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1292c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        buf[4] = (char) ('0' + hours / 10);
1293c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        buf[5] = (char) ('0' + hours % 10);
1294c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1295c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        buf[6] = ':';
1296c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1297c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        buf[7] = (char) ('0' + minutes / 10);
1298c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        buf[8] = (char) ('0' + minutes % 10);
1299c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1300c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return new String(buf);
1301c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1302c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1303c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1304c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * nitzReceiveTime is time_t that the NITZ time was posted
1305c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1306c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void setTimeFromNITZString (String nitz, long nitzReceiveTime) {
1307c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // "yy/mm/dd,hh:mm:ss(+/-)tz"
1308c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // tz is in number of quarter-hours
1309c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1310c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        long start = SystemClock.elapsedRealtime();
1311c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) {log("NITZ: " + nitz + "," + nitzReceiveTime +
1312c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        " start=" + start + " delay=" + (start - nitzReceiveTime));
1313c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1314c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1315c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try {
1316c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            /* NITZ time (hour:min:sec) will be in UTC but it supplies the timezone
1317c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville             * offset as well (which we won't worry about until later) */
1318c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
1319c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1320c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            c.clear();
1321c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            c.set(Calendar.DST_OFFSET, 0);
1322c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1323c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String[] nitzSubs = nitz.split("[/:,+-]");
1324c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1325c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            int year = 2000 + Integer.parseInt(nitzSubs[0]);
1326c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            c.set(Calendar.YEAR, year);
1327c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1328c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // month is 0 based!
1329c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            int month = Integer.parseInt(nitzSubs[1]) - 1;
1330c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            c.set(Calendar.MONTH, month);
1331c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1332c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            int date = Integer.parseInt(nitzSubs[2]);
1333c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            c.set(Calendar.DATE, date);
1334c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1335c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            int hour = Integer.parseInt(nitzSubs[3]);
1336c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            c.set(Calendar.HOUR, hour);
1337c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1338c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            int minute = Integer.parseInt(nitzSubs[4]);
1339c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            c.set(Calendar.MINUTE, minute);
1340c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1341c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            int second = Integer.parseInt(nitzSubs[5]);
1342c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            c.set(Calendar.SECOND, second);
1343c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1344c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            boolean sign = (nitz.indexOf('-') == -1);
1345c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1346c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            int tzOffset = Integer.parseInt(nitzSubs[6]);
1347c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1348c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            int dst = (nitzSubs.length >= 8 ) ? Integer.parseInt(nitzSubs[7])
1349c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                              : 0;
1350c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1351c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // The zone offset received from NITZ is for current local time,
1352c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // so DST correction is already applied.  Don't add it again.
1353c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            //
1354c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // tzOffset += dst * 4;
1355c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            //
1356c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // We could unapply it if we wanted the raw offset.
1357c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1358c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            tzOffset = (sign ? 1 : -1) * tzOffset * 15 * 60 * 1000;
1359c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1360c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            TimeZone    zone = null;
1361c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1362c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // As a special extension, the Android emulator appends the name of
1363c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // the host computer's timezone to the nitz string. this is zoneinfo
1364c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // timezone name of the form Area!Location or Area!Location!SubLocation
1365c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // so we need to convert the ! into /
1366c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (nitzSubs.length >= 9) {
1367c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                String  tzname = nitzSubs[8].replace('!','/');
1368c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                zone = TimeZone.getTimeZone( tzname );
1369c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1370c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1371c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String iso = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY);
1372c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1373c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (zone == null) {
1374c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1375c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (mGotCountryCode) {
1376c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (iso != null && iso.length() > 0) {
1377c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        zone = TimeUtils.getTimeZone(tzOffset, dst != 0,
1378c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                c.getTimeInMillis(),
1379c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                iso);
1380c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else {
1381c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // We don't have a valid iso country code.  This is
1382c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // most likely because we're on a test network that's
1383c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // using a bogus MCC (eg, "001"), so get a TimeZone
1384c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // based only on the NITZ parameters.
1385c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        zone = getNitzTimeZone(tzOffset, (dst != 0), c.getTimeInMillis());
1386c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
1387c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1388c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1389c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1390c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if ((zone == null) || (mZoneOffset != tzOffset) || (mZoneDst != (dst != 0))){
1391c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // We got the time before the country or the zone has changed
1392c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // so we don't know how to identify the DST rules yet.  Save
1393c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // the information and hope to fix it up later.
1394c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1395c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mNeedFixZoneAfterNitz = true;
1396c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mZoneOffset  = tzOffset;
1397c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mZoneDst     = dst != 0;
1398c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mZoneTime    = c.getTimeInMillis();
1399c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1400c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1401c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (zone != null) {
1402c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (getAutoTimeZone()) {
1403c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    setAndBroadcastNetworkSetTimeZone(zone.getID());
1404c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1405c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                saveNitzTimeZone(zone.getID());
1406c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1407c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1408c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String ignore = SystemProperties.get("gsm.ignore-nitz");
1409c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (ignore != null && ignore.equals("yes")) {
1410c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("NITZ: Not setting clock because gsm.ignore-nitz is set");
1411c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                return;
1412c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1413c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1414c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            try {
1415c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mWakeLock.acquire();
1416c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1417c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (getAutoTime()) {
1418c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    long millisSinceNitzReceived
1419c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            = SystemClock.elapsedRealtime() - nitzReceiveTime;
1420c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1421c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (millisSinceNitzReceived < 0) {
1422c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // Sanity check: something is wrong
1423c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        if (DBG) {
1424c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            log("NITZ: not setting time, clock has rolled "
1425c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                            + "backwards since NITZ time was received, "
1426c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                            + nitz);
1427c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
1428c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        return;
1429c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
1430c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1431c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (millisSinceNitzReceived > Integer.MAX_VALUE) {
1432c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // If the time is this far off, something is wrong > 24 days!
1433c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        if (DBG) {
1434c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            log("NITZ: not setting time, processing has taken "
1435c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                        + (millisSinceNitzReceived / (1000 * 60 * 60 * 24))
1436c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                        + " days");
1437c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
1438c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        return;
1439c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
1440c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1441c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Note: with range checks above, cast to int is safe
1442c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    c.add(Calendar.MILLISECOND, (int)millisSinceNitzReceived);
1443c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1444c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (DBG) {
1445c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        log("NITZ: Setting time of day to " + c.getTime()
1446c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            + " NITZ receive delay(ms): " + millisSinceNitzReceived
1447c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            + " gained(ms): "
1448c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            + (c.getTimeInMillis() - System.currentTimeMillis())
1449c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            + " from " + nitz);
1450c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
1451c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1452c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    setAndBroadcastNetworkSetTime(c.getTimeInMillis());
1453c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    Log.i(LOG_TAG, "NITZ: after Setting time of day");
1454c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1455c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                SystemProperties.set("gsm.nitz.time", String.valueOf(c.getTimeInMillis()));
1456c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                saveNitzTime(c.getTimeInMillis());
1457c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (false) {
1458c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    long end = SystemClock.elapsedRealtime();
1459c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    log("NITZ: end=" + end + " dur=" + (end - start));
1460c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1461c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mNitzUpdatedTime = true;
1462c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } finally {
1463c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mWakeLock.release();
1464c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1465c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (RuntimeException ex) {
1466c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            loge("NITZ: Parsing NITZ time " + nitz + " ex=" + ex);
1467c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1468c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1469c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1470c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean getAutoTime() {
1471c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try {
1472c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return Settings.System.getInt(phone.getContext().getContentResolver(),
1473c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    Settings.System.AUTO_TIME) > 0;
1474c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (SettingNotFoundException snfe) {
1475c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return true;
1476c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1477c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1478c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1479c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean getAutoTimeZone() {
1480c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try {
1481c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return Settings.System.getInt(phone.getContext().getContentResolver(),
1482c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    Settings.System.AUTO_TIME_ZONE) > 0;
1483c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (SettingNotFoundException snfe) {
1484c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return true;
1485c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1486c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1487c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1488c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void saveNitzTimeZone(String zoneId) {
1489c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mSavedTimeZone = zoneId;
1490c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1491c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1492c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void saveNitzTime(long time) {
1493c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mSavedTime = time;
1494c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mSavedAtTime = SystemClock.elapsedRealtime();
1495c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1496c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1497c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1498c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Set the timezone and send out a sticky broadcast so the system can
1499c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * determine if the timezone was set by the carrier.
1500c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
1501c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param zoneId timezone set by carrier
1502c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1503c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void setAndBroadcastNetworkSetTimeZone(String zoneId) {
1504c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) log("setAndBroadcastNetworkSetTimeZone: setTimeZone=" + zoneId);
1505c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        AlarmManager alarm =
1506c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE);
1507c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        alarm.setTimeZone(zoneId);
1508c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE);
1509c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
1510c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        intent.putExtra("time-zone", zoneId);
1511c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        phone.getContext().sendStickyBroadcast(intent);
1512c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) {
1513c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            log("setAndBroadcastNetworkSetTimeZone: call alarm.setTimeZone and broadcast zoneId=" +
1514c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                zoneId);
1515c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1516c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1517c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1518c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1519c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Set the time and Send out a sticky broadcast so the system can determine
1520c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * if the time was set by the carrier.
1521c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
1522c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param time time set by network
1523c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1524c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void setAndBroadcastNetworkSetTime(long time) {
1525c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) log("setAndBroadcastNetworkSetTime: time=" + time + "ms");
1526c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        SystemClock.setCurrentTimeMillis(time);
1527c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME);
1528c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
1529c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        intent.putExtra("time", time);
1530c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        phone.getContext().sendStickyBroadcast(intent);
1531c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1532c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1533c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void revertToNitzTime() {
1534c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (Settings.System.getInt(phone.getContext().getContentResolver(),
1535c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                Settings.System.AUTO_TIME, 0) == 0) {
1536c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
1537c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1538c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) {
1539c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            log("Reverting to NITZ Time: mSavedTime=" + mSavedTime
1540c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                + " mSavedAtTime=" + mSavedAtTime);
1541c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1542c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mSavedTime != 0 && mSavedAtTime != 0) {
1543c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            setAndBroadcastNetworkSetTime(mSavedTime
1544c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    + (SystemClock.elapsedRealtime() - mSavedAtTime));
1545c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1546c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1547c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1548c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void revertToNitzTimeZone() {
1549c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (Settings.System.getInt(phone.getContext().getContentResolver(),
1550c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                Settings.System.AUTO_TIME_ZONE, 0) == 0) {
1551c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
1552c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1553c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) log("Reverting to NITZ TimeZone: tz='" + mSavedTimeZone);
1554c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mSavedTimeZone != null) {
1555c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            setAndBroadcastNetworkSetTimeZone(mSavedTimeZone);
1556c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1557c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1558c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1559c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1560c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Post a notification to NotificationManager for restricted state
1561c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
1562c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param notifyType is one state of PS/CS_*_ENABLE/DISABLE
1563c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1564c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void setNotification(int notifyType) {
1565c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1566c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) log("setNotification: create notification " + notifyType);
1567c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Context context = phone.getContext();
1568c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1569c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mNotification = new Notification();
1570c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mNotification.when = System.currentTimeMillis();
1571c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mNotification.flags = Notification.FLAG_AUTO_CANCEL;
1572c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mNotification.icon = com.android.internal.R.drawable.stat_sys_warning;
1573c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Intent intent = new Intent();
1574c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mNotification.contentIntent = PendingIntent
1575c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        .getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
1576c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1577c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        CharSequence details = "";
1578c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        CharSequence title = context.getText(com.android.internal.R.string.RestrictedChangedTitle);
1579c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int notificationId = CS_NOTIFICATION;
1580c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1581c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        switch (notifyType) {
1582c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        case PS_ENABLED:
1583c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            notificationId = PS_NOTIFICATION;
1584c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            details = context.getText(com.android.internal.R.string.RestrictedOnData);;
1585c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
1586c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        case PS_DISABLED:
1587c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            notificationId = PS_NOTIFICATION;
1588c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
1589c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        case CS_ENABLED:
1590c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            details = context.getText(com.android.internal.R.string.RestrictedOnAllVoice);;
1591c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
1592c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        case CS_NORMAL_ENABLED:
1593c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            details = context.getText(com.android.internal.R.string.RestrictedOnNormal);;
1594c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
1595c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        case CS_EMERGENCY_ENABLED:
1596c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            details = context.getText(com.android.internal.R.string.RestrictedOnEmergency);;
1597c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
1598c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        case CS_DISABLED:
1599c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // do nothing and cancel the notification later
1600c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
1601c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1602c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1603c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) log("setNotification: put notification " + title + " / " +details);
1604c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mNotification.tickerText = title;
1605c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mNotification.setLatestEventInfo(context, title, details,
1606c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mNotification.contentIntent);
1607c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1608c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        NotificationManager notificationManager = (NotificationManager)
1609c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            context.getSystemService(Context.NOTIFICATION_SERVICE);
1610c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1611c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (notifyType == PS_DISABLED || notifyType == CS_DISABLED) {
1612c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // cancel previous post notification
1613c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            notificationManager.cancel(notificationId);
1614c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
1615c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // update restricted state notification
1616c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            notificationManager.notify(notificationId, mNotification);
1617c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1618c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1619c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1620c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
1621bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka    protected void onUpdateIccAvailability() {
1622bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        if (mUiccController == null ) {
1623bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka            return;
1624bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        }
1625bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka
1626e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        UiccCardApplication newUiccApplication =
1627e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccController.getUiccCardApplication(UiccController.APP_FAM_3GPP);
1628bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka
1629e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mUiccApplcation != newUiccApplication) {
1630e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (mUiccApplcation != null) {
1631bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka                log("Removing stale icc objects.");
1632e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplcation.unregisterForReady(this);
1633bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka                if (mIccRecords != null) {
1634bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka                    mIccRecords.unregisterForRecordsLoaded(this);
1635bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka                }
1636bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka                mIccRecords = null;
1637e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplcation = null;
1638bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka            }
1639e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (newUiccApplication != null) {
1640bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka                log("New card found");
1641e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplcation = newUiccApplication;
1642e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mIccRecords = mUiccApplcation.getIccRecords();
1643e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mUiccApplcation.registerForReady(this, EVENT_SIM_READY, null);
1644bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka                if (mIccRecords != null) {
1645bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka                    mIccRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
1646bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka                }
1647bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka            }
1648bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        }
1649bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka    }
1650bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka    @Override
1651c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void log(String s) {
1652c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Log.d(LOG_TAG, "[GsmSST] " + s);
1653c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1654c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1655c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
1656c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void loge(String s) {
1657c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Log.e(LOG_TAG, "[GsmSST] " + s);
1658c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1659c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1660c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static void sloge(String s) {
1661c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Log.e(LOG_TAG, "[GsmSST] " + s);
1662c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1663c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1664c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
1665c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1666c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println("GsmServiceStateTracker extends:");
1667c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        super.dump(fd, pw, args);
1668c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" phone=" + phone);
1669c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" cellLoc=" + cellLoc);
1670c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" newCellLoc=" + newCellLoc);
1671c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mPreferredNetworkType=" + mPreferredNetworkType);
1672c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" gprsState=" + gprsState);
1673c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" newGPRSState=" + newGPRSState);
1674c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mMaxDataCalls=" + mMaxDataCalls);
1675c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mNewMaxDataCalls=" + mNewMaxDataCalls);
1676c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mReasonDataDenied=" + mReasonDataDenied);
1677c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mNewReasonDataDenied=" + mNewReasonDataDenied);
1678c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mGsmRoaming=" + mGsmRoaming);
1679c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mDataRoaming=" + mDataRoaming);
1680c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mEmergencyOnly=" + mEmergencyOnly);
1681c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mNeedFixZoneAfterNitz=" + mNeedFixZoneAfterNitz);
1682c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mZoneOffset=" + mZoneOffset);
1683c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mZoneDst=" + mZoneDst);
1684c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mZoneTime=" + mZoneTime);
1685c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mGotCountryCode=" + mGotCountryCode);
1686c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mNitzUpdatedTime=" + mNitzUpdatedTime);
1687c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mSavedTimeZone=" + mSavedTimeZone);
1688c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mSavedTime=" + mSavedTime);
1689c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mSavedAtTime=" + mSavedAtTime);
1690c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mStartedGprsRegCheck=" + mStartedGprsRegCheck);
1691c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mReportedGprsNoReg=" + mReportedGprsNoReg);
1692c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mNotification=" + mNotification);
1693c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" mWakeLock=" + mWakeLock);
1694c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" curSpn=" + curSpn);
1695c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" curPlmn=" + curPlmn);
1696c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pw.println(" curSpnRule=" + curSpnRule);
1697c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1698c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
1699