1767a662ecde33c3979bf02b793d392aca0403162Wink Saville/*
2767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Copyright (C) 2008 The Android Open Source Project
3767a662ecde33c3979bf02b793d392aca0403162Wink Saville *
4767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
5767a662ecde33c3979bf02b793d392aca0403162Wink Saville * you may not use this file except in compliance with the License.
6767a662ecde33c3979bf02b793d392aca0403162Wink Saville * You may obtain a copy of the License at
7767a662ecde33c3979bf02b793d392aca0403162Wink Saville *
8767a662ecde33c3979bf02b793d392aca0403162Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
9767a662ecde33c3979bf02b793d392aca0403162Wink Saville *
10767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Unless required by applicable law or agreed to in writing, software
11767a662ecde33c3979bf02b793d392aca0403162Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
12767a662ecde33c3979bf02b793d392aca0403162Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13767a662ecde33c3979bf02b793d392aca0403162Wink Saville * See the License for the specific language governing permissions and
14767a662ecde33c3979bf02b793d392aca0403162Wink Saville * limitations under the License.
15767a662ecde33c3979bf02b793d392aca0403162Wink Saville */
16767a662ecde33c3979bf02b793d392aca0403162Wink Saville
17767a662ecde33c3979bf02b793d392aca0403162Wink Savillepackage com.android.internal.telephony.cdma;
18767a662ecde33c3979bf02b793d392aca0403162Wink Saville
19767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.app.AlarmManager;
20767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.content.ContentResolver;
21767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.content.Context;
22767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.content.Intent;
23767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.database.ContentObserver;
24767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.os.AsyncResult;
25767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.os.Handler;
26767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.os.Message;
27dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Savilleimport android.os.PowerManager;
28767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.os.Registrant;
29767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.os.RegistrantList;
30767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.os.SystemClock;
31767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.os.SystemProperties;
32767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.provider.Settings;
33767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.provider.Settings.SettingNotFoundException;
34767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.provider.Telephony.Intents;
35767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.telephony.ServiceState;
36e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Savilleimport android.telephony.SignalStrength;
37767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.telephony.cdma.CdmaCellLocation;
38767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.text.TextUtils;
39767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.util.EventLog;
40767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.util.Log;
41dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Savilleimport android.util.Config;
42767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.util.TimeUtils;
43767a662ecde33c3979bf02b793d392aca0403162Wink Saville
44767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.CommandException;
45767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.CommandsInterface;
46767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.DataConnectionTracker;
4718e939623556928f73fcc7511c85a537929a4a7eDan Egnorimport com.android.internal.telephony.EventLogTags;
485b462477a90cd08551149fc649ff3035b5331d2djshimport com.android.internal.telephony.IccCard;
491c1ffa0cab8b56274970736d7f3b8c00c01c3d2bRobert Greenwaltimport com.android.internal.telephony.MccTable;
50767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.ServiceStateTracker;
51767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.TelephonyIntents;
5200416365dedc03c9ed74d94728025fd2d68f648dTammo Spalinkimport com.android.internal.telephony.TelephonyProperties;
53767a662ecde33c3979bf02b793d392aca0403162Wink Saville
54767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport java.util.Arrays;
5500416365dedc03c9ed74d94728025fd2d68f648dTammo Spalinkimport java.util.Calendar;
56767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport java.util.Date;
57767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport java.util.TimeZone;
58767a662ecde33c3979bf02b793d392aca0403162Wink Saville
59767a662ecde33c3979bf02b793d392aca0403162Wink Saville/**
60767a662ecde33c3979bf02b793d392aca0403162Wink Saville * {@hide}
61767a662ecde33c3979bf02b793d392aca0403162Wink Saville */
62767a662ecde33c3979bf02b793d392aca0403162Wink Savillefinal class CdmaServiceStateTracker extends ServiceStateTracker {
6300416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    static final String LOG_TAG = "CDMA";
64f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville
65767a662ecde33c3979bf02b793d392aca0403162Wink Saville    CDMAPhone phone;
66767a662ecde33c3979bf02b793d392aca0403162Wink Saville    CdmaCellLocation cellLoc;
67767a662ecde33c3979bf02b793d392aca0403162Wink Saville    CdmaCellLocation newCellLoc;
68767a662ecde33c3979bf02b793d392aca0403162Wink Saville
69aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville     /** if time between NTIZ updates is less than mNitzUpdateSpacing the update may be ignored. */
70aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville    private static final int NITZ_UPDATE_SPACING_DEFAULT = 1000 * 60 * 10;
71aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville    private int mNitzUpdateSpacing = SystemProperties.getInt("ro.nitz_update_spacing",
72aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville            NITZ_UPDATE_SPACING_DEFAULT);
73aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville
74aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville    /** If mNitzUpdateSpacing hasn't been exceeded but update is > mNitzUpdate do the update */
75aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville    private static final int NITZ_UPDATE_DIFF_DEFAULT = 2000;
76aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville    private int mNitzUpdateDiff = SystemProperties.getInt("ro.nitz_update_diff",
77aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville            NITZ_UPDATE_DIFF_DEFAULT);
78ce9b59f0ba00e006d2697480b5e5d1fcbd0d2818Wink Saville
79e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville    /**
8000416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink     *  Values correspond to ServiceStateTracker.DATA_ACCESS_ definitions.
81767a662ecde33c3979bf02b793d392aca0403162Wink Saville     */
82767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private int networkType = 0;
83767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private int newNetworkType = 0;
84767a662ecde33c3979bf02b793d392aca0403162Wink Saville
85767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private boolean mCdmaRoaming = false;
86f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville    private int mRoamingIndicator;
87f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville    private boolean mIsInPrl;
88f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville    private int mDefaultRoamingIndicator;
89767a662ecde33c3979bf02b793d392aca0403162Wink Saville
9000416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    /**
9100416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink     * Initially assume no data connection.
9200416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink     */
93f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville    private int cdmaDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
94f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville    private int newCdmaDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
95767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private int mRegistrationState = -1;
96767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private RegistrantList cdmaDataConnectionAttachedRegistrants = new RegistrantList();
97767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private RegistrantList cdmaDataConnectionDetachedRegistrants = new RegistrantList();
989e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo    private RegistrantList cdmaForSubscriptionInfoReadyRegistrants = new RegistrantList();
99767a662ecde33c3979bf02b793d392aca0403162Wink Saville
10000416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    /**
10100416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink     * Sometimes we get the NITZ time before we know what country we
10200416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink     * are in. Keep the time zone information from the NITZ string so
10300416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink     * we can fix the time zone once know the country.
10400416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink     */
105dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    private boolean mNeedFixZone = false;
106dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    private int mZoneOffset;
107dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    private boolean mZoneDst;
108dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    private long mZoneTime;
109767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private boolean mGotCountryCode = false;
110dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    String mSavedTimeZone;
111dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    long mSavedTime;
112dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    long mSavedAtTime;
113767a662ecde33c3979bf02b793d392aca0403162Wink Saville
11400416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    /**
11500416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink     * We can't register for SIM_RECORDS_LOADED immediately because the
11600416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink     * SIMRecords object may not be instantiated yet.
11700416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink     */
118f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville    private boolean mNeedToRegForRuimLoaded = false;
119767a662ecde33c3979bf02b793d392aca0403162Wink Saville
12000416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    /** Wake lock used while setting time of day. */
121dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    private PowerManager.WakeLock mWakeLock;
122dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    private static final String WAKELOCK_TAG = "ServiceStateTracker";
123dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
12400416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    /** Track of SPN display rules, so we only broadcast intent if something changes. */
125767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private String curSpn = null;
126767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private int curSpnRule = 0;
127767a662ecde33c3979bf02b793d392aca0403162Wink Saville
12800416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    /** Contains the name of the registered network in CDMA (either ONS or ERI text). */
12900416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    private String curPlmn = null;
13000416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink
131f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville    private String mMdn;
132d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang    private int mHomeSystemId[] = null;
133d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang    private int mHomeNetworkId[] = null;
134f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville    private String mMin;
135daccacb865947c00f277f1823333e2fbf91e652aWink Saville    private String mPrlVersion;
1369e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo    private boolean mIsMinInfoReady = false;
137f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville
138e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville    private boolean isEriTextLoaded = false;
139e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville    private boolean isSubscriptionFromRuim = false;
140e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
141fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang    private boolean mPendingRadioPowerOffAfterDataOff = false;
142fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang
14300416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    /* Used only for debugging purposes. */
144f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville    private String mRegistrationDeniedReason;
145e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
146767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private ContentResolver cr;
14722ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    private String currentCarrier = null;
148767a662ecde33c3979bf02b793d392aca0403162Wink Saville
149767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) {
150767a662ecde33c3979bf02b793d392aca0403162Wink Saville        @Override
151767a662ecde33c3979bf02b793d392aca0403162Wink Saville        public void onChange(boolean selfChange) {
152767a662ecde33c3979bf02b793d392aca0403162Wink Saville            Log.i("CdmaServiceStateTracker", "Auto time state called ...");
153dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            revertToNitz();
154dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
155767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
156767a662ecde33c3979bf02b793d392aca0403162Wink Saville    };
157767a662ecde33c3979bf02b793d392aca0403162Wink Saville
158767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public CdmaServiceStateTracker(CDMAPhone phone) {
159767a662ecde33c3979bf02b793d392aca0403162Wink Saville        super();
160767a662ecde33c3979bf02b793d392aca0403162Wink Saville
161767a662ecde33c3979bf02b793d392aca0403162Wink Saville        this.phone = phone;
162ce9b59f0ba00e006d2697480b5e5d1fcbd0d2818Wink Saville        cr = phone.getContext().getContentResolver();
163767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm = phone.mCM;
164767a662ecde33c3979bf02b793d392aca0403162Wink Saville        ss = new ServiceState();
165767a662ecde33c3979bf02b793d392aca0403162Wink Saville        newSS = new ServiceState();
166767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cellLoc = new CdmaCellLocation();
167767a662ecde33c3979bf02b793d392aca0403162Wink Saville        newCellLoc = new CdmaCellLocation();
168e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        mSignalStrength = new SignalStrength();
169767a662ecde33c3979bf02b793d392aca0403162Wink Saville
170dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        PowerManager powerManager =
171dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                (PowerManager)phone.getContext().getSystemService(Context.POWER_SERVICE);
172dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG);
173dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
174767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
175767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
176767a662ecde33c3979bf02b793d392aca0403162Wink Saville
177767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.registerForNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED_CDMA, null);
178dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        cm.setOnNITZTime(this, EVENT_NITZ_TIME, null);
179767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
180767a662ecde33c3979bf02b793d392aca0403162Wink Saville
181767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.registerForRUIMReady(this, EVENT_RUIM_READY, null);
182767a662ecde33c3979bf02b793d392aca0403162Wink Saville
183e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        cm.registerForNVReady(this, EVENT_NV_READY, null);
184e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        phone.registerForEriFileLoaded(this, EVENT_ERI_FILE_LOADED, null);
185daccacb865947c00f277f1823333e2fbf91e652aWink Saville        cm.registerForCdmaOtaProvision(this,EVENT_OTA_PROVISION_STATUS_CHANGE, null);
186767a662ecde33c3979bf02b793d392aca0403162Wink Saville
18700416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink        // System setting property AIRPLANE_MODE_ON is set in Settings.
188ce9b59f0ba00e006d2697480b5e5d1fcbd0d2818Wink Saville        int airplaneMode = Settings.System.getInt(cr, Settings.System.AIRPLANE_MODE_ON, 0);
189767a662ecde33c3979bf02b793d392aca0403162Wink Saville        mDesiredPowerState = ! (airplaneMode > 0);
190767a662ecde33c3979bf02b793d392aca0403162Wink Saville
191767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cr.registerContentObserver(
192767a662ecde33c3979bf02b793d392aca0403162Wink Saville                Settings.System.getUriFor(Settings.System.AUTO_TIME), true,
193767a662ecde33c3979bf02b793d392aca0403162Wink Saville                mAutoTimeObserver);
194e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        setSignalStrengthDefaultValues();
195767a662ecde33c3979bf02b793d392aca0403162Wink Saville
196767a662ecde33c3979bf02b793d392aca0403162Wink Saville        mNeedToRegForRuimLoaded = true;
197767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
198767a662ecde33c3979bf02b793d392aca0403162Wink Saville
199767a662ecde33c3979bf02b793d392aca0403162Wink Saville    public void dispose() {
20000416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink        // Unregister for all events.
201767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.unregisterForAvailable(this);
202767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.unregisterForRadioStateChanged(this);
203767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.unregisterForNetworkStateChanged(this);
204767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.unregisterForRUIMReady(this);
205e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        cm.unregisterForNVReady(this);
206daccacb865947c00f277f1823333e2fbf91e652aWink Saville        cm.unregisterForCdmaOtaProvision(this);
207e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        phone.unregisterForEriFileLoaded(this);
208767a662ecde33c3979bf02b793d392aca0403162Wink Saville        phone.mRuimRecords.unregisterForRecordsLoaded(this);
209767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cm.unSetOnSignalStrengthUpdate(this);
210dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        cm.unSetOnNITZTime(this);
211767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cr.unregisterContentObserver(this.mAutoTimeObserver);
212767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
213767a662ecde33c3979bf02b793d392aca0403162Wink Saville
21422ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    @Override
215767a662ecde33c3979bf02b793d392aca0403162Wink Saville    protected void finalize() {
216e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        if (DBG) log("CdmaServiceStateTracker finalized");
217767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
218767a662ecde33c3979bf02b793d392aca0403162Wink Saville
219767a662ecde33c3979bf02b793d392aca0403162Wink Saville    void registerForNetworkAttach(Handler h, int what, Object obj) {
220767a662ecde33c3979bf02b793d392aca0403162Wink Saville        Registrant r = new Registrant(h, what, obj);
221767a662ecde33c3979bf02b793d392aca0403162Wink Saville        networkAttachedRegistrants.add(r);
222767a662ecde33c3979bf02b793d392aca0403162Wink Saville
223767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (ss.getState() == ServiceState.STATE_IN_SERVICE) {
224767a662ecde33c3979bf02b793d392aca0403162Wink Saville            r.notifyRegistrant();
225767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
226767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
227767a662ecde33c3979bf02b793d392aca0403162Wink Saville
228767a662ecde33c3979bf02b793d392aca0403162Wink Saville    void unregisterForNetworkAttach(Handler h) {
229767a662ecde33c3979bf02b793d392aca0403162Wink Saville        networkAttachedRegistrants.remove(h);
230767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
231767a662ecde33c3979bf02b793d392aca0403162Wink Saville
232767a662ecde33c3979bf02b793d392aca0403162Wink Saville    /**
233767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * Registration point for transition into Data attached.
234767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * @param h handler to notify
235767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * @param what what code of message when delivered
236767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * @param obj placed in Message.obj
237767a662ecde33c3979bf02b793d392aca0403162Wink Saville     */
23800416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    void registerForCdmaDataConnectionAttached(Handler h, int what, Object obj) {
239767a662ecde33c3979bf02b793d392aca0403162Wink Saville        Registrant r = new Registrant(h, what, obj);
240767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cdmaDataConnectionAttachedRegistrants.add(r);
241767a662ecde33c3979bf02b793d392aca0403162Wink Saville
242f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville        if (cdmaDataConnectionState == ServiceState.STATE_IN_SERVICE) {
243767a662ecde33c3979bf02b793d392aca0403162Wink Saville            r.notifyRegistrant();
244767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
245767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
24600416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink
247767a662ecde33c3979bf02b793d392aca0403162Wink Saville    void unregisterForCdmaDataConnectionAttached(Handler h) {
248767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cdmaDataConnectionAttachedRegistrants.remove(h);
249767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
250767a662ecde33c3979bf02b793d392aca0403162Wink Saville
251767a662ecde33c3979bf02b793d392aca0403162Wink Saville    /**
252767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * Registration point for transition into Data detached.
253767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * @param h handler to notify
254767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * @param what what code of message when delivered
255767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * @param obj placed in Message.obj
256767a662ecde33c3979bf02b793d392aca0403162Wink Saville     */
25700416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    void registerForCdmaDataConnectionDetached(Handler h, int what, Object obj) {
258767a662ecde33c3979bf02b793d392aca0403162Wink Saville        Registrant r = new Registrant(h, what, obj);
259767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cdmaDataConnectionDetachedRegistrants.add(r);
260767a662ecde33c3979bf02b793d392aca0403162Wink Saville
261f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville        if (cdmaDataConnectionState != ServiceState.STATE_IN_SERVICE) {
262767a662ecde33c3979bf02b793d392aca0403162Wink Saville            r.notifyRegistrant();
263767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
264767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
26500416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink
266767a662ecde33c3979bf02b793d392aca0403162Wink Saville    void unregisterForCdmaDataConnectionDetached(Handler h) {
267767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cdmaDataConnectionDetachedRegistrants.remove(h);
268767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
269767a662ecde33c3979bf02b793d392aca0403162Wink Saville
2709e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo    /**
2719e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo     * Registration point for subscription info ready
2729e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo     * @param h handler to notify
2739e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo     * @param what what code of message when delivered
2749e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo     * @param obj placed in Message.obj
2759e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo     */
2769e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo    public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
2779e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo        Registrant r = new Registrant(h, what, obj);
2789e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo        cdmaForSubscriptionInfoReadyRegistrants.add(r);
2799e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo
2809e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo        if (isMinInfoReady()) {
2819e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo            r.notifyRegistrant();
2829e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo        }
2839e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo    }
2849e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo
2859e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo    public void unregisterForSubscriptionInfoReady(Handler h) {
2869e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo        cdmaForSubscriptionInfoReadyRegistrants.remove(h);
2879e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo    }
2889e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo
28922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    @Override
29022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    public void handleMessage (Message msg) {
291767a662ecde33c3979bf02b793d392aca0403162Wink Saville        AsyncResult ar;
292767a662ecde33c3979bf02b793d392aca0403162Wink Saville        int[] ints;
293767a662ecde33c3979bf02b793d392aca0403162Wink Saville        String[] strings;
294767a662ecde33c3979bf02b793d392aca0403162Wink Saville
295767a662ecde33c3979bf02b793d392aca0403162Wink Saville        switch (msg.what) {
296767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case EVENT_RADIO_AVAILABLE:
297767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
298767a662ecde33c3979bf02b793d392aca0403162Wink Saville
299767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case EVENT_RUIM_READY:
30000416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            // The RUIM is now ready i.e if it was locked it has been
30100416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            // unlocked. At this stage, the radio is already powered on.
302e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            isSubscriptionFromRuim = true;
303767a662ecde33c3979bf02b793d392aca0403162Wink Saville            if (mNeedToRegForRuimLoaded) {
304767a662ecde33c3979bf02b793d392aca0403162Wink Saville                phone.mRuimRecords.registerForRecordsLoaded(this,
305767a662ecde33c3979bf02b793d392aca0403162Wink Saville                        EVENT_RUIM_RECORDS_LOADED, null);
306767a662ecde33c3979bf02b793d392aca0403162Wink Saville                mNeedToRegForRuimLoaded = false;
307767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
30856d97ebb3ab05407ceea781c5bddc4527f98d828Cheng Yang
30956d97ebb3ab05407ceea781c5bddc4527f98d828Cheng Yang            cm.getCDMASubscription(obtainMessage(EVENT_POLL_STATE_CDMA_SUBSCRIPTION));
31056d97ebb3ab05407ceea781c5bddc4527f98d828Cheng Yang            if (DBG) log("Receive EVENT_RUIM_READY and Send Request getCDMASubscription.");
31156d97ebb3ab05407ceea781c5bddc4527f98d828Cheng Yang
31200416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            // Restore the previous network selection.
313e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            pollState();
314e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
31500416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            // Signal strength polling stops when radio is off.
316e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            queueNextSignalStrengthPoll();
317e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            break;
318e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
319e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        case EVENT_NV_READY:
320e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            isSubscriptionFromRuim = false;
321daccacb865947c00f277f1823333e2fbf91e652aWink Saville            // For Non-RUIM phones, the subscription information is stored in
322daccacb865947c00f277f1823333e2fbf91e652aWink Saville            // Non Volatile. Here when Non-Volatile is ready, we can poll the CDMA
323daccacb865947c00f277f1823333e2fbf91e652aWink Saville            // subscription info.
324daccacb865947c00f277f1823333e2fbf91e652aWink Saville            cm.getCDMASubscription( obtainMessage(EVENT_POLL_STATE_CDMA_SUBSCRIPTION));
325767a662ecde33c3979bf02b793d392aca0403162Wink Saville            pollState();
32600416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            // Signal strength polling stops when radio is off.
327767a662ecde33c3979bf02b793d392aca0403162Wink Saville            queueNextSignalStrengthPoll();
328767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
329767a662ecde33c3979bf02b793d392aca0403162Wink Saville
330767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case EVENT_RADIO_STATE_CHANGED:
33100416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            // This will do nothing in the 'radio not available' case.
332767a662ecde33c3979bf02b793d392aca0403162Wink Saville            setPowerStateToDesired();
333767a662ecde33c3979bf02b793d392aca0403162Wink Saville            pollState();
334767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
335767a662ecde33c3979bf02b793d392aca0403162Wink Saville
336767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case EVENT_NETWORK_STATE_CHANGED_CDMA:
337767a662ecde33c3979bf02b793d392aca0403162Wink Saville            pollState();
338767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
339767a662ecde33c3979bf02b793d392aca0403162Wink Saville
340767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case EVENT_GET_SIGNAL_STRENGTH:
341767a662ecde33c3979bf02b793d392aca0403162Wink Saville            // This callback is called when signal strength is polled
34200416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            // all by itself.
343767a662ecde33c3979bf02b793d392aca0403162Wink Saville
344767a662ecde33c3979bf02b793d392aca0403162Wink Saville            if (!(cm.getRadioState().isOn()) || (cm.getRadioState().isGsm())) {
34500416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink                // Polling will continue when radio turns back on.
346767a662ecde33c3979bf02b793d392aca0403162Wink Saville                return;
347767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
348767a662ecde33c3979bf02b793d392aca0403162Wink Saville            ar = (AsyncResult) msg.obj;
349767a662ecde33c3979bf02b793d392aca0403162Wink Saville            onSignalStrengthResult(ar);
350767a662ecde33c3979bf02b793d392aca0403162Wink Saville            queueNextSignalStrengthPoll();
351767a662ecde33c3979bf02b793d392aca0403162Wink Saville
352767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
353767a662ecde33c3979bf02b793d392aca0403162Wink Saville
354767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case EVENT_GET_LOC_DONE_CDMA:
355767a662ecde33c3979bf02b793d392aca0403162Wink Saville            ar = (AsyncResult) msg.obj;
356767a662ecde33c3979bf02b793d392aca0403162Wink Saville
357767a662ecde33c3979bf02b793d392aca0403162Wink Saville            if (ar.exception == null) {
358767a662ecde33c3979bf02b793d392aca0403162Wink Saville                String states[] = (String[])ar.result;
359767a662ecde33c3979bf02b793d392aca0403162Wink Saville                int baseStationId = -1;
3609384b145e625b3bb6ff8b829ddb1466e16a78f49Mark Vandevoorde                int baseStationLatitude = CdmaCellLocation.INVALID_LAT_LONG;
3619384b145e625b3bb6ff8b829ddb1466e16a78f49Mark Vandevoorde                int baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG;
362d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                int systemId = -1;
363d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                int networkId = -1;
364d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla
365d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                if (states.length > 9) {
366d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                    try {
367d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        if (states[4] != null) {
368d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                            baseStationId = Integer.parseInt(states[4]);
369d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        }
370d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        if (states[5] != null) {
371d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                            baseStationLatitude = Integer.parseInt(states[5]);
372d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        }
373d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        if (states[6] != null) {
374d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                            baseStationLongitude = Integer.parseInt(states[6]);
375767a662ecde33c3979bf02b793d392aca0403162Wink Saville                        }
3769384b145e625b3bb6ff8b829ddb1466e16a78f49Mark Vandevoorde                        // Some carriers only return lat-lngs of 0,0
3779384b145e625b3bb6ff8b829ddb1466e16a78f49Mark Vandevoorde                        if (baseStationLatitude == 0 && baseStationLongitude == 0) {
3789384b145e625b3bb6ff8b829ddb1466e16a78f49Mark Vandevoorde                            baseStationLatitude  = CdmaCellLocation.INVALID_LAT_LONG;
3799384b145e625b3bb6ff8b829ddb1466e16a78f49Mark Vandevoorde                            baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG;
3809384b145e625b3bb6ff8b829ddb1466e16a78f49Mark Vandevoorde                        }
381d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        if (states[8] != null) {
382d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                            systemId = Integer.parseInt(states[8]);
383d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        }
384d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        if (states[9] != null) {
385d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                            networkId = Integer.parseInt(states[9]);
386d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        }
387d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                    } catch (NumberFormatException ex) {
388d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        Log.w(LOG_TAG, "error parsing cell location data: " + ex);
389767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    }
390767a662ecde33c3979bf02b793d392aca0403162Wink Saville                }
391767a662ecde33c3979bf02b793d392aca0403162Wink Saville
392d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                cellLoc.setCellLocationData(baseStationId, baseStationLatitude,
393d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        baseStationLongitude, systemId, networkId);
3947a043b351b43e963605afef6ab76a52ae3a9270eTammo Spalink                phone.notifyLocationChanged();
395767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
396767a662ecde33c3979bf02b793d392aca0403162Wink Saville
3977a043b351b43e963605afef6ab76a52ae3a9270eTammo Spalink            // Release any temporary cell lock, which could have been
3987a043b351b43e963605afef6ab76a52ae3a9270eTammo Spalink            // aquired to allow a single-shot location update.
3997a043b351b43e963605afef6ab76a52ae3a9270eTammo Spalink            disableSingleLocationUpdate();
400767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
401767a662ecde33c3979bf02b793d392aca0403162Wink Saville
402e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        case EVENT_POLL_STATE_REGISTRATION_CDMA:
403767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case EVENT_POLL_STATE_OPERATOR_CDMA:
404767a662ecde33c3979bf02b793d392aca0403162Wink Saville            ar = (AsyncResult) msg.obj;
405767a662ecde33c3979bf02b793d392aca0403162Wink Saville            handlePollStateResult(msg.what, ar);
406767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
407767a662ecde33c3979bf02b793d392aca0403162Wink Saville
408daccacb865947c00f277f1823333e2fbf91e652aWink Saville        case EVENT_POLL_STATE_CDMA_SUBSCRIPTION: // Handle RIL_CDMA_SUBSCRIPTION
409daccacb865947c00f277f1823333e2fbf91e652aWink Saville            ar = (AsyncResult) msg.obj;
410daccacb865947c00f277f1823333e2fbf91e652aWink Saville
411daccacb865947c00f277f1823333e2fbf91e652aWink Saville            if (ar.exception == null) {
412daccacb865947c00f277f1823333e2fbf91e652aWink Saville                String cdmaSubscription[] = (String[])ar.result;
413daccacb865947c00f277f1823333e2fbf91e652aWink Saville                if (cdmaSubscription != null && cdmaSubscription.length >= 5) {
414daccacb865947c00f277f1823333e2fbf91e652aWink Saville                    mMdn = cdmaSubscription[0];
41590b34b37731307cd0ccd5dfa60971364b37515d8jsh                    if (cdmaSubscription[1] != null) {
41690b34b37731307cd0ccd5dfa60971364b37515d8jsh                        String[] sid = cdmaSubscription[1].split(",");
417d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                        mHomeSystemId = new int[sid.length];
418d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                        for (int i = 0; i < sid.length; i++) {
419d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                            try {
420d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                                mHomeSystemId[i] = Integer.parseInt(sid[i]);
421d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                            } catch (NumberFormatException ex) {
422d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                                Log.e(LOG_TAG, "error parsing system id: ", ex);
423d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                            }
424d2fb98006054f94753d8c58cf6a809840964db2ejohnwang                        }
42590b34b37731307cd0ccd5dfa60971364b37515d8jsh                    }
426d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                    Log.d(LOG_TAG,"GET_CDMA_SUBSCRIPTION SID=" + cdmaSubscription[1] );
427d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang
42890b34b37731307cd0ccd5dfa60971364b37515d8jsh                    if (cdmaSubscription[2] != null) {
42990b34b37731307cd0ccd5dfa60971364b37515d8jsh                        String[] nid = cdmaSubscription[2].split(",");
430d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                        mHomeNetworkId = new int[nid.length];
431d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                        for (int i = 0; i < nid.length; i++) {
432d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                            try {
433d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                                mHomeNetworkId[i] = Integer.parseInt(nid[i]);
434d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                            } catch (NumberFormatException ex) {
435d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                                Log.e(LOG_TAG, "error parsing network id: ", ex);
436d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                            }
437d2fb98006054f94753d8c58cf6a809840964db2ejohnwang                        }
43890b34b37731307cd0ccd5dfa60971364b37515d8jsh                    }
439d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                    Log.d(LOG_TAG,"GET_CDMA_SUBSCRIPTION NID=" + cdmaSubscription[2] );
440daccacb865947c00f277f1823333e2fbf91e652aWink Saville                    mMin = cdmaSubscription[3];
441daccacb865947c00f277f1823333e2fbf91e652aWink Saville                    mPrlVersion = cdmaSubscription[4];
442daccacb865947c00f277f1823333e2fbf91e652aWink Saville                    Log.d(LOG_TAG,"GET_CDMA_SUBSCRIPTION MDN=" + mMdn);
4439e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo                    //Notify apps subscription info is ready
4449e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo                    if (cdmaForSubscriptionInfoReadyRegistrants != null) {
4459e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo                        cdmaForSubscriptionInfoReadyRegistrants.notifyRegistrants();
4469e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo                    }
4479e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo                    if (!mIsMinInfoReady) {
4489e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo                        mIsMinInfoReady = true;
4499e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo                    }
4505b462477a90cd08551149fc649ff3035b5331d2djsh                    phone.getIccCard().broadcastIccStateChangedIntent(IccCard.INTENT_VALUE_ICC_IMSI,
4515b462477a90cd08551149fc649ff3035b5331d2djsh                            null);
452daccacb865947c00f277f1823333e2fbf91e652aWink Saville                } else {
453daccacb865947c00f277f1823333e2fbf91e652aWink Saville                    Log.w(LOG_TAG,"error parsing cdmaSubscription params num="
454daccacb865947c00f277f1823333e2fbf91e652aWink Saville                            + cdmaSubscription.length);
455daccacb865947c00f277f1823333e2fbf91e652aWink Saville                }
456daccacb865947c00f277f1823333e2fbf91e652aWink Saville            }
457daccacb865947c00f277f1823333e2fbf91e652aWink Saville            break;
458daccacb865947c00f277f1823333e2fbf91e652aWink Saville
459767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case EVENT_POLL_SIGNAL_STRENGTH:
460767a662ecde33c3979bf02b793d392aca0403162Wink Saville            // Just poll signal strength...not part of pollState()
461767a662ecde33c3979bf02b793d392aca0403162Wink Saville
462767a662ecde33c3979bf02b793d392aca0403162Wink Saville            cm.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
463767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
464767a662ecde33c3979bf02b793d392aca0403162Wink Saville
465dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        case EVENT_NITZ_TIME:
466dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            ar = (AsyncResult) msg.obj;
467dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
468dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            String nitzString = (String)((Object[])ar.result)[0];
469dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            long nitzReceiveTime = ((Long)((Object[])ar.result)[1]).longValue();
470dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
471dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            setTimeFromNITZString(nitzString, nitzReceiveTime);
472dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            break;
473dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
474767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case EVENT_SIGNAL_STRENGTH_UPDATE:
47500416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            // This is a notification from CommandsInterface.setOnSignalStrengthUpdate.
476767a662ecde33c3979bf02b793d392aca0403162Wink Saville
477767a662ecde33c3979bf02b793d392aca0403162Wink Saville            ar = (AsyncResult) msg.obj;
478767a662ecde33c3979bf02b793d392aca0403162Wink Saville
47900416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            // The radio is telling us about signal strength changes,
48000416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            // so we don't have to ask it.
481767a662ecde33c3979bf02b793d392aca0403162Wink Saville            dontPollSignalStrength = true;
482767a662ecde33c3979bf02b793d392aca0403162Wink Saville
483767a662ecde33c3979bf02b793d392aca0403162Wink Saville            onSignalStrengthResult(ar);
484767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
485767a662ecde33c3979bf02b793d392aca0403162Wink Saville
486767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case EVENT_RUIM_RECORDS_LOADED:
487767a662ecde33c3979bf02b793d392aca0403162Wink Saville            updateSpnDisplay();
488767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
489767a662ecde33c3979bf02b793d392aca0403162Wink Saville
490767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case EVENT_LOCATION_UPDATES_ENABLED:
491767a662ecde33c3979bf02b793d392aca0403162Wink Saville            ar = (AsyncResult) msg.obj;
492767a662ecde33c3979bf02b793d392aca0403162Wink Saville
493767a662ecde33c3979bf02b793d392aca0403162Wink Saville            if (ar.exception == null) {
4947a043b351b43e963605afef6ab76a52ae3a9270eTammo Spalink                cm.getRegistrationState(obtainMessage(EVENT_GET_LOC_DONE_CDMA, null));
495767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
496767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
497767a662ecde33c3979bf02b793d392aca0403162Wink Saville
498e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        case EVENT_ERI_FILE_LOADED:
49900416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            // Repoll the state once the ERI file has been loaded.
500e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            if (DBG) log("[CdmaServiceStateTracker] ERI file has been loaded, repolling.");
501e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            pollState();
502e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            break;
503e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
504daccacb865947c00f277f1823333e2fbf91e652aWink Saville        case EVENT_OTA_PROVISION_STATUS_CHANGE:
505daccacb865947c00f277f1823333e2fbf91e652aWink Saville            ar = (AsyncResult)msg.obj;
506daccacb865947c00f277f1823333e2fbf91e652aWink Saville            if (ar.exception == null) {
507daccacb865947c00f277f1823333e2fbf91e652aWink Saville                ints = (int[]) ar.result;
508daccacb865947c00f277f1823333e2fbf91e652aWink Saville                int otaStatus = ints[0];
509daccacb865947c00f277f1823333e2fbf91e652aWink Saville                if (otaStatus == phone.CDMA_OTA_PROVISION_STATUS_COMMITTED
510daccacb865947c00f277f1823333e2fbf91e652aWink Saville                    || otaStatus == phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED) {
511daccacb865947c00f277f1823333e2fbf91e652aWink Saville                    Log.d(LOG_TAG, "Received OTA_PROGRAMMING Complete,Reload MDN ");
512daccacb865947c00f277f1823333e2fbf91e652aWink Saville                    cm.getCDMASubscription( obtainMessage(EVENT_POLL_STATE_CDMA_SUBSCRIPTION));
513daccacb865947c00f277f1823333e2fbf91e652aWink Saville                }
514daccacb865947c00f277f1823333e2fbf91e652aWink Saville            }
515daccacb865947c00f277f1823333e2fbf91e652aWink Saville            break;
516daccacb865947c00f277f1823333e2fbf91e652aWink Saville
517fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang        case EVENT_SET_RADIO_POWER_OFF:
518fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang            synchronized(this) {
519fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang                if (mPendingRadioPowerOffAfterDataOff) {
520fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang                    if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now.");
5213805c7ca324f232972c959e06253de4242f83607John Wang                    hangupAndPowerOff();
522fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang                    mPendingRadioPowerOffAfterDataOff = false;
523fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang                }
524fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang            }
525fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang            break;
526fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang
527767a662ecde33c3979bf02b793d392aca0403162Wink Saville        default:
528767a662ecde33c3979bf02b793d392aca0403162Wink Saville            Log.e(LOG_TAG, "Unhandled message with number: " + msg.what);
529767a662ecde33c3979bf02b793d392aca0403162Wink Saville        break;
530767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
531767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
532767a662ecde33c3979bf02b793d392aca0403162Wink Saville
533767a662ecde33c3979bf02b793d392aca0403162Wink Saville    //***** Private Instance Methods
534767a662ecde33c3979bf02b793d392aca0403162Wink Saville
53522ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    @Override
53622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    protected void setPowerStateToDesired() {
537767a662ecde33c3979bf02b793d392aca0403162Wink Saville        // If we want it on and it's off, turn it on
538767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (mDesiredPowerState
539767a662ecde33c3979bf02b793d392aca0403162Wink Saville            && cm.getRadioState() == CommandsInterface.RadioState.RADIO_OFF) {
540767a662ecde33c3979bf02b793d392aca0403162Wink Saville            cm.setRadioPower(true, null);
541767a662ecde33c3979bf02b793d392aca0403162Wink Saville        } else if (!mDesiredPowerState && cm.getRadioState().isOn()) {
542767a662ecde33c3979bf02b793d392aca0403162Wink Saville            DataConnectionTracker dcTracker = phone.mDataConnection;
543767a662ecde33c3979bf02b793d392aca0403162Wink Saville            if (! dcTracker.isDataConnectionAsDesired()) {
54418e939623556928f73fcc7511c85a537929a4a7eDan Egnor                EventLog.writeEvent(EventLogTags.DATA_NETWORK_STATUS_ON_RADIO_OFF,
545767a662ecde33c3979bf02b793d392aca0403162Wink Saville                        dcTracker.getStateInString(),
54662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor                        dcTracker.getAnyDataEnabled() ? 1 : 0);
547767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
548e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
5493805c7ca324f232972c959e06253de4242f83607John Wang            // If it's on and available and we want it off gracefully
5503805c7ca324f232972c959e06253de4242f83607John Wang            powerOffRadioSafely();
5513805c7ca324f232972c959e06253de4242f83607John Wang        } // Otherwise, we're in the desired state
5523805c7ca324f232972c959e06253de4242f83607John Wang    }
5533805c7ca324f232972c959e06253de4242f83607John Wang
5543805c7ca324f232972c959e06253de4242f83607John Wang    @Override
5553805c7ca324f232972c959e06253de4242f83607John Wang    protected void powerOffRadioSafely(){
5563805c7ca324f232972c959e06253de4242f83607John Wang        // clean data connection
5573805c7ca324f232972c959e06253de4242f83607John Wang        DataConnectionTracker dcTracker = phone.mDataConnection;
5583805c7ca324f232972c959e06253de4242f83607John Wang
5593805c7ca324f232972c959e06253de4242f83607John Wang        Message msg = dcTracker.obtainMessage(DataConnectionTracker.EVENT_CLEAN_UP_CONNECTION);
5603805c7ca324f232972c959e06253de4242f83607John Wang        msg.arg1 = 1; // tearDown is true
5613805c7ca324f232972c959e06253de4242f83607John Wang        msg.obj = CDMAPhone.REASON_RADIO_TURNED_OFF;
5623805c7ca324f232972c959e06253de4242f83607John Wang        dcTracker.sendMessage(msg);
5633805c7ca324f232972c959e06253de4242f83607John Wang
5643805c7ca324f232972c959e06253de4242f83607John Wang        synchronized(this) {
5653805c7ca324f232972c959e06253de4242f83607John Wang            if (!mPendingRadioPowerOffAfterDataOff) {
5663805c7ca324f232972c959e06253de4242f83607John Wang                DataConnectionTracker.State currentState = dcTracker.getState();
5673805c7ca324f232972c959e06253de4242f83607John Wang                if (currentState != DataConnectionTracker.State.CONNECTED
5683805c7ca324f232972c959e06253de4242f83607John Wang                        && currentState != DataConnectionTracker.State.DISCONNECTING
5693805c7ca324f232972c959e06253de4242f83607John Wang                        && currentState != DataConnectionTracker.State.INITING) {
5703805c7ca324f232972c959e06253de4242f83607John Wang                    if (DBG) log("Data disconnected, turn off radio right away.");
5713805c7ca324f232972c959e06253de4242f83607John Wang                    hangupAndPowerOff();
5723805c7ca324f232972c959e06253de4242f83607John Wang                }
5733805c7ca324f232972c959e06253de4242f83607John Wang                else if (sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF, 30000)) {
5743805c7ca324f232972c959e06253de4242f83607John Wang                    if (DBG) {
5753805c7ca324f232972c959e06253de4242f83607John Wang                        log("Wait up to 30 sec for data to disconnect, then turn off radio.");
576fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang                    }
5773805c7ca324f232972c959e06253de4242f83607John Wang                    mPendingRadioPowerOffAfterDataOff = true;
5783805c7ca324f232972c959e06253de4242f83607John Wang                } else {
5793805c7ca324f232972c959e06253de4242f83607John Wang                    Log.w(LOG_TAG, "Cannot send delayed Msg, turn off radio right away.");
5803805c7ca324f232972c959e06253de4242f83607John Wang                    hangupAndPowerOff();
581767a662ecde33c3979bf02b793d392aca0403162Wink Saville                }
582767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
5833805c7ca324f232972c959e06253de4242f83607John Wang        }
584767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
585767a662ecde33c3979bf02b793d392aca0403162Wink Saville
58622ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    @Override
587767a662ecde33c3979bf02b793d392aca0403162Wink Saville    protected void updateSpnDisplay() {
588f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville        String spn = "";
589f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville        boolean showSpn = false;
590f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville        String plmn = "";
591f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville        boolean showPlmn = false;
592f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville        int rule = 0;
593f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville        if (cm.getRadioState().isRUIMReady()) {
594f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville            // TODO RUIM SPN is not implemnted, EF_SPN has to be read and Display Condition
595f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville            //   Character Encoding, Language Indicator and SPN has to be set
596f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville            // rule = phone.mRuimRecords.getDisplayRule(ss.getOperatorNumeric());
597f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville            // spn = phone.mSIMRecords.getServiceProvideName();
598f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville            plmn = ss.getOperatorAlphaLong(); // mOperatorAlphaLong contains the ONS
599f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville            // showSpn = (rule & ...
600f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville            showPlmn = true; // showPlmn = (rule & ...
601767a662ecde33c3979bf02b793d392aca0403162Wink Saville
602f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville        } else {
603f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville            // In this case there is no SPN available from RUIM, we show the ERI text
604f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville            plmn = ss.getOperatorAlphaLong(); // mOperatorAlphaLong contains the ERI text
605f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville            showPlmn = true;
606f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville        }
607767a662ecde33c3979bf02b793d392aca0403162Wink Saville
608f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville        if (rule != curSpnRule
609f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                || !TextUtils.equals(spn, curSpn)
610f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                || !TextUtils.equals(plmn, curPlmn)) {
611767a662ecde33c3979bf02b793d392aca0403162Wink Saville            Intent intent = new Intent(Intents.SPN_STRINGS_UPDATED_ACTION);
6121c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
613767a662ecde33c3979bf02b793d392aca0403162Wink Saville            intent.putExtra(Intents.EXTRA_SHOW_SPN, showSpn);
614767a662ecde33c3979bf02b793d392aca0403162Wink Saville            intent.putExtra(Intents.EXTRA_SPN, spn);
615f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville            intent.putExtra(Intents.EXTRA_SHOW_PLMN, showPlmn);
616f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville            intent.putExtra(Intents.EXTRA_PLMN, plmn);
617767a662ecde33c3979bf02b793d392aca0403162Wink Saville            phone.getContext().sendStickyBroadcast(intent);
618767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
619767a662ecde33c3979bf02b793d392aca0403162Wink Saville
620f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville        curSpnRule = rule;
621f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville        curSpn = spn;
622f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville        curPlmn = plmn;
623767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
624767a662ecde33c3979bf02b793d392aca0403162Wink Saville
625767a662ecde33c3979bf02b793d392aca0403162Wink Saville    /**
626767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * Handle the result of one of the pollState()-related requests
627767a662ecde33c3979bf02b793d392aca0403162Wink Saville     */
628767a662ecde33c3979bf02b793d392aca0403162Wink Saville
62922ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    @Override
63022ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville    protected void handlePollStateResult (int what, AsyncResult ar) {
631767a662ecde33c3979bf02b793d392aca0403162Wink Saville        int ints[];
632767a662ecde33c3979bf02b793d392aca0403162Wink Saville        String states[];
633767a662ecde33c3979bf02b793d392aca0403162Wink Saville
63400416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink        // Ignore stale requests from last poll.
635767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (ar.userObj != pollingContext) return;
636767a662ecde33c3979bf02b793d392aca0403162Wink Saville
637767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (ar.exception != null) {
638767a662ecde33c3979bf02b793d392aca0403162Wink Saville            CommandException.Error err=null;
639767a662ecde33c3979bf02b793d392aca0403162Wink Saville
640767a662ecde33c3979bf02b793d392aca0403162Wink Saville            if (ar.exception instanceof CommandException) {
641767a662ecde33c3979bf02b793d392aca0403162Wink Saville                err = ((CommandException)(ar.exception)).getCommandError();
642767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
643767a662ecde33c3979bf02b793d392aca0403162Wink Saville
644767a662ecde33c3979bf02b793d392aca0403162Wink Saville            if (err == CommandException.Error.RADIO_NOT_AVAILABLE) {
64500416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink                // Radio has crashed or turned off.
646767a662ecde33c3979bf02b793d392aca0403162Wink Saville                cancelPollState();
647767a662ecde33c3979bf02b793d392aca0403162Wink Saville                return;
648767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
649767a662ecde33c3979bf02b793d392aca0403162Wink Saville
650767a662ecde33c3979bf02b793d392aca0403162Wink Saville            if (!cm.getRadioState().isOn()) {
65100416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink                // Radio has crashed or turned off.
652767a662ecde33c3979bf02b793d392aca0403162Wink Saville                cancelPollState();
653767a662ecde33c3979bf02b793d392aca0403162Wink Saville                return;
654767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
655767a662ecde33c3979bf02b793d392aca0403162Wink Saville
656767a662ecde33c3979bf02b793d392aca0403162Wink Saville            if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW &&
657767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) {
658767a662ecde33c3979bf02b793d392aca0403162Wink Saville                Log.e(LOG_TAG,
659767a662ecde33c3979bf02b793d392aca0403162Wink Saville                        "RIL implementation has returned an error where it must succeed",
660767a662ecde33c3979bf02b793d392aca0403162Wink Saville                        ar.exception);
661767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
662767a662ecde33c3979bf02b793d392aca0403162Wink Saville        } else try {
663767a662ecde33c3979bf02b793d392aca0403162Wink Saville            switch (what) {
664f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville            case EVENT_POLL_STATE_REGISTRATION_CDMA: // Handle RIL_REQUEST_REGISTRATION_STATE.
665767a662ecde33c3979bf02b793d392aca0403162Wink Saville                states = (String[])ar.result;
666767a662ecde33c3979bf02b793d392aca0403162Wink Saville
667f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                int registrationState = 4;     //[0] registrationState
668f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                int radioTechnology = -1;      //[3] radioTechnology
669f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                int baseStationId = -1;        //[4] baseStationId
6709384b145e625b3bb6ff8b829ddb1466e16a78f49Mark Vandevoorde                //[5] baseStationLatitude
6719384b145e625b3bb6ff8b829ddb1466e16a78f49Mark Vandevoorde                int baseStationLatitude = CdmaCellLocation.INVALID_LAT_LONG;
6729384b145e625b3bb6ff8b829ddb1466e16a78f49Mark Vandevoorde                //[6] baseStationLongitude
6739384b145e625b3bb6ff8b829ddb1466e16a78f49Mark Vandevoorde                int baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG;
674f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                int cssIndicator = 0;          //[7] init with 0, because it is treated as a boolean
675f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                int systemId = 0;              //[8] systemId
676f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                int networkId = 0;             //[9] networkId
677f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                int roamingIndicator = -1;     //[10] Roaming indicator
678f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                int systemIsInPrl = 0;         //[11] Indicates if current system is in PRL
679f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                int defaultRoamingIndicator = 0;  //[12] Is default roaming indicator from PRL
680f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                int reasonForDenial = 0;       //[13] Denial reason if registrationState = 3
681767a662ecde33c3979bf02b793d392aca0403162Wink Saville
682e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                if (states.length == 14) {
683767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    try {
684d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        if (states[0] != null) {
685d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                            registrationState = Integer.parseInt(states[0]);
686d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        }
687d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        if (states[3] != null) {
688d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                            radioTechnology = Integer.parseInt(states[3]);
689d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        }
690d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        if (states[4] != null) {
691d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                            baseStationId = Integer.parseInt(states[4]);
692d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        }
693d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        if (states[5] != null) {
694d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                            baseStationLatitude = Integer.parseInt(states[5]);
695d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        }
696d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        if (states[6] != null) {
697d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                            baseStationLongitude = Integer.parseInt(states[6]);
698d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        }
6999384b145e625b3bb6ff8b829ddb1466e16a78f49Mark Vandevoorde                        // Some carriers only return lat-lngs of 0,0
7009384b145e625b3bb6ff8b829ddb1466e16a78f49Mark Vandevoorde                        if (baseStationLatitude == 0 && baseStationLongitude == 0) {
7019384b145e625b3bb6ff8b829ddb1466e16a78f49Mark Vandevoorde                            baseStationLatitude  = CdmaCellLocation.INVALID_LAT_LONG;
7029384b145e625b3bb6ff8b829ddb1466e16a78f49Mark Vandevoorde                            baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG;
7039384b145e625b3bb6ff8b829ddb1466e16a78f49Mark Vandevoorde                        }
704d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        if (states[7] != null) {
705d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                            cssIndicator = Integer.parseInt(states[7]);
706d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        }
707d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        if (states[8] != null) {
708d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                            systemId = Integer.parseInt(states[8]);
709d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        }
710d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        if (states[9] != null) {
711d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                            networkId = Integer.parseInt(states[9]);
712d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        }
713d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        if (states[10] != null) {
714d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                            roamingIndicator = Integer.parseInt(states[10]);
715d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        }
716d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        if (states[11] != null) {
717d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                            systemIsInPrl = Integer.parseInt(states[11]);
718d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        }
719d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        if (states[12] != null) {
720d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                            defaultRoamingIndicator = Integer.parseInt(states[12]);
721d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        }
722d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        if (states[13] != null) {
723d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                            reasonForDenial = Integer.parseInt(states[13]);
724d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                        }
725d393184ac595ab5490c77305a27fd049badf9a5dNaveen Kalla                    } catch (NumberFormatException ex) {
726f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                        Log.w(LOG_TAG, "error parsing RegistrationState: " + ex);
727e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    }
728e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                } else {
729e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    throw new RuntimeException("Warning! Wrong number of parameters returned from "
730e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                                         + "RIL_REQUEST_REGISTRATION_STATE: expected 14 got "
731e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                                         + states.length);
732767a662ecde33c3979bf02b793d392aca0403162Wink Saville                }
733767a662ecde33c3979bf02b793d392aca0403162Wink Saville
734f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                mRegistrationState = registrationState;
73500416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink                // When registration state is roaming and TSB58
73600416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink                // roaming indicator is not in the carrier-specified
73700416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink                // list of ERIs for home system, mCdmaRoaming is true.
7388e80fd4478764643ac9543d63a77db62014a843aYong Zhang                mCdmaRoaming =
7398e80fd4478764643ac9543d63a77db62014a843aYong Zhang                        regCodeIsRoaming(registrationState) && !isRoamIndForHomeSystem(states[10]);
740f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                newSS.setState (regCodeToServiceState(registrationState));
741f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville
74200416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink                this.newCdmaDataConnectionState =
74300416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink                        radioTechnologyToDataServiceState(radioTechnology);
744f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                newSS.setRadioTechnology(radioTechnology);
745f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                newNetworkType = radioTechnology;
746767a662ecde33c3979bf02b793d392aca0403162Wink Saville
747f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                newSS.setCssIndicator(cssIndicator);
748f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                newSS.setSystemAndNetworkId(systemId, networkId);
749f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                mRoamingIndicator = roamingIndicator;
750f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                mIsInPrl = (systemIsInPrl == 0) ? false : true;
751f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                mDefaultRoamingIndicator = defaultRoamingIndicator;
752e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
753767a662ecde33c3979bf02b793d392aca0403162Wink Saville
75400416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink                // Values are -1 if not available.
755f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                newCellLoc.setCellLocationData(baseStationId, baseStationLatitude,
756a4d2fb5ef6bb5dfb6e26ac6a139de389984db5d3Mike Lockwood                        baseStationLongitude, systemId, networkId);
757e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
758f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                if (reasonForDenial == 0) {
759e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    mRegistrationDeniedReason = ServiceStateTracker.REGISTRATION_DENIED_GEN;
760f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                } else if (reasonForDenial == 1) {
761e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    mRegistrationDeniedReason = ServiceStateTracker.REGISTRATION_DENIED_AUTH;
762e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                } else {
763e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    mRegistrationDeniedReason = "";
764e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                }
765e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
766e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                if (mRegistrationState == 3) {
767e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    if (DBG) log("Registration denied, " + mRegistrationDeniedReason);
768e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                }
769767a662ecde33c3979bf02b793d392aca0403162Wink Saville                break;
770767a662ecde33c3979bf02b793d392aca0403162Wink Saville
771e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            case EVENT_POLL_STATE_OPERATOR_CDMA: // Handle RIL_REQUEST_OPERATOR
772767a662ecde33c3979bf02b793d392aca0403162Wink Saville                String opNames[] = (String[])ar.result;
773767a662ecde33c3979bf02b793d392aca0403162Wink Saville
774a14f47f975064816df3008e66055d41ddb9d7353Wink Saville                if (opNames != null && opNames.length >= 3) {
775f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                    if (cm.getRadioState().isNVReady()) {
77600416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink                        // In CDMA in case on NV, the ss.mOperatorAlphaLong is set later with the
77700416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink                        // ERI text, so here it is ignored what is coming from the modem.
778e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                        newSS.setOperatorName(null, opNames[1], opNames[2]);
779e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    } else {
780e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                        newSS.setOperatorName(opNames[0], opNames[1], opNames[2]);
78122ccaf5321cf9d2df57cf0d686d1abcd74acb193Wink Saville                    }
782e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                } else {
783e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    Log.w(LOG_TAG, "error parsing opNames");
784767a662ecde33c3979bf02b793d392aca0403162Wink Saville                }
785767a662ecde33c3979bf02b793d392aca0403162Wink Saville                break;
786767a662ecde33c3979bf02b793d392aca0403162Wink Saville
787767a662ecde33c3979bf02b793d392aca0403162Wink Saville            default:
788767a662ecde33c3979bf02b793d392aca0403162Wink Saville                Log.e(LOG_TAG, "RIL response handle in wrong phone!"
789767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    + " Expected CDMA RIL request and get GSM RIL request.");
790767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
791767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
792767a662ecde33c3979bf02b793d392aca0403162Wink Saville
793767a662ecde33c3979bf02b793d392aca0403162Wink Saville        } catch (RuntimeException ex) {
794767a662ecde33c3979bf02b793d392aca0403162Wink Saville            Log.e(LOG_TAG, "Exception while polling service state. "
795767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    + "Probably malformed RIL response.", ex);
796767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
797767a662ecde33c3979bf02b793d392aca0403162Wink Saville
798767a662ecde33c3979bf02b793d392aca0403162Wink Saville        pollingContext[0]--;
799767a662ecde33c3979bf02b793d392aca0403162Wink Saville
800767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (pollingContext[0] == 0) {
801e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            boolean namMatch = false;
802d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang            if (!isSidsAllZeros() && isHomeSid(newSS.getSystemId())) {
803e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                namMatch = true;
804e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            }
805767a662ecde33c3979bf02b793d392aca0403162Wink Saville
806e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            // Setting SS Roaming (general)
807e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            if (isSubscriptionFromRuim) {
808e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                newSS.setRoaming(isRoamingBetweenOperators(mCdmaRoaming, newSS));
809e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            } else {
810e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                newSS.setRoaming(mCdmaRoaming);
811e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            }
812e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
813e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            // Setting SS CdmaRoamingIndicator and CdmaDefaultRoamingIndicator
814d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang            newSS.setCdmaDefaultRoamingIndicator(mDefaultRoamingIndicator);
815d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang            newSS.setCdmaRoamingIndicator(mRoamingIndicator);
816d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang            boolean isPrlLoaded = true;
817d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang            if (TextUtils.isEmpty(mPrlVersion)) {
818d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                isPrlLoaded = false;
819d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang            }
820d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang            if (!isPrlLoaded) {
821d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_FLASH);
822d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang            } else if (!isSidsAllZeros()) {
823d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                if (!namMatch && !mIsInPrl) {
824d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                    // Use default
825d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                    newSS.setCdmaRoamingIndicator(mDefaultRoamingIndicator);
826d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                } else if (namMatch && !mIsInPrl) {
827f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                    newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_FLASH);
828d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                } else if (!namMatch && mIsInPrl) {
829d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                    // Use the one from PRL/ERI
830d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                    newSS.setCdmaRoamingIndicator(mRoamingIndicator);
831f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                } else {
832d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                    // It means namMatch && mIsInPrl
833d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                    if ((mRoamingIndicator <= 2)) {
834d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                        newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_OFF);
835d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                    } else {
836d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                        // Use the one from PRL/ERI
837d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                        newSS.setCdmaRoamingIndicator(mRoamingIndicator);
838d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                    }
839f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                }
8409c2a3be8bad8867cc524d8813dc6468a7ffb3f09Jaikumar Ganesh            }
8419c2a3be8bad8867cc524d8813dc6468a7ffb3f09Jaikumar Ganesh
842cc5c1ad53ce4541f17842daba29e7ccba221c079Robert Greenwalt            int roamingIndicator = newSS.getCdmaRoamingIndicator();
843cc5c1ad53ce4541f17842daba29e7ccba221c079Robert Greenwalt            newSS.setCdmaEriIconIndex(phone.mEriManager.getCdmaEriIconIndex(roamingIndicator,
844cc5c1ad53ce4541f17842daba29e7ccba221c079Robert Greenwalt                    mDefaultRoamingIndicator));
845cc5c1ad53ce4541f17842daba29e7ccba221c079Robert Greenwalt            newSS.setCdmaEriIconMode(phone.mEriManager.getCdmaEriIconMode(roamingIndicator,
846cc5c1ad53ce4541f17842daba29e7ccba221c079Robert Greenwalt                    mDefaultRoamingIndicator));
847cc5c1ad53ce4541f17842daba29e7ccba221c079Robert Greenwalt
84800416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            // NOTE: Some operator may require overriding mCdmaRoaming
84900416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            // (set by the modem), depending on the mRoamingIndicator.
850e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
851e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            if (DBG) {
852e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                log("Set CDMA Roaming Indicator to: " + newSS.getCdmaRoamingIndicator()
853d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                    + ". mCdmaRoaming = " + mCdmaRoaming + ", isPrlLoaded = " + isPrlLoaded
854d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                    + ". namMatch = " + namMatch + " , mIsInPrl = " + mIsInPrl
855d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                    + ", mRoamingIndicator = " + mRoamingIndicator
856e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    + ", mDefaultRoamingIndicator= " + mDefaultRoamingIndicator);
857767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
858767a662ecde33c3979bf02b793d392aca0403162Wink Saville            pollStateDone();
859767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
860767a662ecde33c3979bf02b793d392aca0403162Wink Saville
861767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
862767a662ecde33c3979bf02b793d392aca0403162Wink Saville
863e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville    private void setSignalStrengthDefaultValues() {
864e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, false);
865767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
866767a662ecde33c3979bf02b793d392aca0403162Wink Saville
867767a662ecde33c3979bf02b793d392aca0403162Wink Saville    /**
868767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * A complete "service state" from our perspective is
869767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * composed of a handful of separate requests to the radio.
870767a662ecde33c3979bf02b793d392aca0403162Wink Saville     *
871767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * We make all of these requests at once, but then abandon them
872767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * and start over again if the radio notifies us that some
873767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * event has changed
874767a662ecde33c3979bf02b793d392aca0403162Wink Saville     */
875767a662ecde33c3979bf02b793d392aca0403162Wink Saville
876767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private void
877767a662ecde33c3979bf02b793d392aca0403162Wink Saville    pollState() {
878767a662ecde33c3979bf02b793d392aca0403162Wink Saville        pollingContext = new int[1];
879767a662ecde33c3979bf02b793d392aca0403162Wink Saville        pollingContext[0] = 0;
880767a662ecde33c3979bf02b793d392aca0403162Wink Saville
881767a662ecde33c3979bf02b793d392aca0403162Wink Saville        switch (cm.getRadioState()) {
882767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case RADIO_UNAVAILABLE:
883767a662ecde33c3979bf02b793d392aca0403162Wink Saville            newSS.setStateOutOfService();
884767a662ecde33c3979bf02b793d392aca0403162Wink Saville            newCellLoc.setStateInvalid();
885e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            setSignalStrengthDefaultValues();
886767a662ecde33c3979bf02b793d392aca0403162Wink Saville            mGotCountryCode = false;
887767a662ecde33c3979bf02b793d392aca0403162Wink Saville
888767a662ecde33c3979bf02b793d392aca0403162Wink Saville            pollStateDone();
889767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
890767a662ecde33c3979bf02b793d392aca0403162Wink Saville
891767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case RADIO_OFF:
892767a662ecde33c3979bf02b793d392aca0403162Wink Saville            newSS.setStateOff();
893767a662ecde33c3979bf02b793d392aca0403162Wink Saville            newCellLoc.setStateInvalid();
894e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            setSignalStrengthDefaultValues();
895767a662ecde33c3979bf02b793d392aca0403162Wink Saville            mGotCountryCode = false;
896767a662ecde33c3979bf02b793d392aca0403162Wink Saville
897767a662ecde33c3979bf02b793d392aca0403162Wink Saville            pollStateDone();
898767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
899767a662ecde33c3979bf02b793d392aca0403162Wink Saville
900767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case SIM_NOT_READY:
901767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case SIM_LOCKED_OR_ABSENT:
902767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case SIM_READY:
903767a662ecde33c3979bf02b793d392aca0403162Wink Saville            log("Radio Technology Change ongoing, setting SS to off");
904767a662ecde33c3979bf02b793d392aca0403162Wink Saville            newSS.setStateOff();
905767a662ecde33c3979bf02b793d392aca0403162Wink Saville            newCellLoc.setStateInvalid();
906e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            setSignalStrengthDefaultValues();
907767a662ecde33c3979bf02b793d392aca0403162Wink Saville            mGotCountryCode = false;
908767a662ecde33c3979bf02b793d392aca0403162Wink Saville
90900416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            // NOTE: pollStateDone() is not needed in this case
910767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
911767a662ecde33c3979bf02b793d392aca0403162Wink Saville
912767a662ecde33c3979bf02b793d392aca0403162Wink Saville        default:
91300416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            // Issue all poll-related commands at once, then count
91400416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            // down the responses which are allowed to arrive
91500416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            // out-of-order.
916767a662ecde33c3979bf02b793d392aca0403162Wink Saville
917767a662ecde33c3979bf02b793d392aca0403162Wink Saville            pollingContext[0]++;
918e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            // RIL_REQUEST_OPERATOR is necessary for CDMA
919e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            cm.getOperator(
920e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    obtainMessage(EVENT_POLL_STATE_OPERATOR_CDMA, pollingContext));
921e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
922e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            pollingContext[0]++;
923e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            // RIL_REQUEST_REGISTRATION_STATE is necessary for CDMA
924e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            cm.getRegistrationState(
925e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    obtainMessage(EVENT_POLL_STATE_REGISTRATION_CDMA, pollingContext));
926e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
927e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            break;
928767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
929767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
930767a662ecde33c3979bf02b793d392aca0403162Wink Saville
931767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private static String networkTypeToString(int type) {
932767a662ecde33c3979bf02b793d392aca0403162Wink Saville        String ret = "unknown";
933767a662ecde33c3979bf02b793d392aca0403162Wink Saville
934767a662ecde33c3979bf02b793d392aca0403162Wink Saville        switch (type) {
935767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case DATA_ACCESS_CDMA_IS95A:
936767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case DATA_ACCESS_CDMA_IS95B:
937767a662ecde33c3979bf02b793d392aca0403162Wink Saville            ret = "CDMA";
938767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
939767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case DATA_ACCESS_CDMA_1xRTT:
940767a662ecde33c3979bf02b793d392aca0403162Wink Saville            ret = "CDMA - 1xRTT";
941767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
942767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case DATA_ACCESS_CDMA_EvDo_0:
943767a662ecde33c3979bf02b793d392aca0403162Wink Saville            ret = "CDMA - EvDo rev. 0";
944767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
945767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case DATA_ACCESS_CDMA_EvDo_A:
946767a662ecde33c3979bf02b793d392aca0403162Wink Saville            ret = "CDMA - EvDo rev. A";
947767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
948767a662ecde33c3979bf02b793d392aca0403162Wink Saville        default:
949767a662ecde33c3979bf02b793d392aca0403162Wink Saville            if (DBG) {
950767a662ecde33c3979bf02b793d392aca0403162Wink Saville                Log.e(LOG_TAG, "Wrong network. Can not return a string.");
951767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
952767a662ecde33c3979bf02b793d392aca0403162Wink Saville        break;
953767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
954767a662ecde33c3979bf02b793d392aca0403162Wink Saville
955767a662ecde33c3979bf02b793d392aca0403162Wink Saville        return ret;
956767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
957767a662ecde33c3979bf02b793d392aca0403162Wink Saville
958dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    private void fixTimeZone(String isoCountryCode) {
959dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        TimeZone zone = null;
960dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        // If the offset is (0, false) and the time zone property
961dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        // is set, use the time zone property rather than GMT.
962dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        String zoneName = SystemProperties.get(TIMEZONE_PROPERTY);
963dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        if ((mZoneOffset == 0) && (mZoneDst == false) && (zoneName != null)
964dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                && (zoneName.length() > 0)
965dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                && (Arrays.binarySearch(GMT_COUNTRY_CODES, isoCountryCode) < 0)) {
966dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            // For NITZ string without time zone,
967dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            // need adjust time to reflect default time zone setting
968dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            zone = TimeZone.getDefault();
969dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            long tzOffset;
970dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            tzOffset = zone.getOffset(System.currentTimeMillis());
971dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            if (getAutoTime()) {
972dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                setAndBroadcastNetworkSetTime(System.currentTimeMillis() - tzOffset);
973dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            } else {
974dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                // Adjust the saved NITZ time to account for tzOffset.
975dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                mSavedTime = mSavedTime - tzOffset;
976dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            }
977dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        } else if (isoCountryCode.equals("")) {
978dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            // Country code not found. This is likely a test network.
979dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            // Get a TimeZone based only on the NITZ parameters (best guess).
980dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            zone = getNitzTimeZone(mZoneOffset, mZoneDst, mZoneTime);
981dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        } else {
982dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            zone = TimeUtils.getTimeZone(mZoneOffset, mZoneDst, mZoneTime, isoCountryCode);
983dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        }
984dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
985dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        mNeedFixZone = false;
986dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
987dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        if (zone != null) {
988dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            if (getAutoTime()) {
989dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                setAndBroadcastNetworkSetTimeZone(zone.getID());
990dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            }
991dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            saveNitzTimeZone(zone.getID());
992dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        }
993dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    }
994dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
995dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    private void pollStateDone() {
996e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        if (DBG) log("Poll ServiceState done: oldSS=[" + ss + "] newSS=[" + newSS + "]");
997767a662ecde33c3979bf02b793d392aca0403162Wink Saville
998767a662ecde33c3979bf02b793d392aca0403162Wink Saville        boolean hasRegistered =
999767a662ecde33c3979bf02b793d392aca0403162Wink Saville            ss.getState() != ServiceState.STATE_IN_SERVICE
1000767a662ecde33c3979bf02b793d392aca0403162Wink Saville            && newSS.getState() == ServiceState.STATE_IN_SERVICE;
1001767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1002767a662ecde33c3979bf02b793d392aca0403162Wink Saville        boolean hasDeregistered =
1003767a662ecde33c3979bf02b793d392aca0403162Wink Saville            ss.getState() == ServiceState.STATE_IN_SERVICE
1004767a662ecde33c3979bf02b793d392aca0403162Wink Saville            && newSS.getState() != ServiceState.STATE_IN_SERVICE;
1005767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1006767a662ecde33c3979bf02b793d392aca0403162Wink Saville        boolean hasCdmaDataConnectionAttached =
1007f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville            this.cdmaDataConnectionState != ServiceState.STATE_IN_SERVICE
1008f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville            && this.newCdmaDataConnectionState == ServiceState.STATE_IN_SERVICE;
1009767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1010767a662ecde33c3979bf02b793d392aca0403162Wink Saville        boolean hasCdmaDataConnectionDetached =
1011f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville            this.cdmaDataConnectionState == ServiceState.STATE_IN_SERVICE
1012f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville            && this.newCdmaDataConnectionState != ServiceState.STATE_IN_SERVICE;
1013767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1014767a662ecde33c3979bf02b793d392aca0403162Wink Saville        boolean hasCdmaDataConnectionChanged =
1015767a662ecde33c3979bf02b793d392aca0403162Wink Saville                       cdmaDataConnectionState != newCdmaDataConnectionState;
1016767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1017767a662ecde33c3979bf02b793d392aca0403162Wink Saville        boolean hasNetworkTypeChanged = networkType != newNetworkType;
1018767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1019767a662ecde33c3979bf02b793d392aca0403162Wink Saville        boolean hasChanged = !newSS.equals(ss);
1020767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1021767a662ecde33c3979bf02b793d392aca0403162Wink Saville        boolean hasRoamingOn = !ss.getRoaming() && newSS.getRoaming();
1022767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1023767a662ecde33c3979bf02b793d392aca0403162Wink Saville        boolean hasRoamingOff = ss.getRoaming() && !newSS.getRoaming();
1024767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1025767a662ecde33c3979bf02b793d392aca0403162Wink Saville        boolean hasLocationChanged = !newCellLoc.equals(cellLoc);
1026767a662ecde33c3979bf02b793d392aca0403162Wink Saville
102718e939623556928f73fcc7511c85a537929a4a7eDan Egnor        // Add an event log when connection state changes
102818e939623556928f73fcc7511c85a537929a4a7eDan Egnor        if (ss.getState() != newSS.getState() ||
102918e939623556928f73fcc7511c85a537929a4a7eDan Egnor                cdmaDataConnectionState != newCdmaDataConnectionState) {
103018e939623556928f73fcc7511c85a537929a4a7eDan Egnor            EventLog.writeEvent(EventLogTags.CDMA_SERVICE_STATE_CHANGE,
103118e939623556928f73fcc7511c85a537929a4a7eDan Egnor                    ss.getState(), cdmaDataConnectionState,
103218e939623556928f73fcc7511c85a537929a4a7eDan Egnor                    newSS.getState(), newCdmaDataConnectionState);
103318e939623556928f73fcc7511c85a537929a4a7eDan Egnor        }
103418e939623556928f73fcc7511c85a537929a4a7eDan Egnor
1035767a662ecde33c3979bf02b793d392aca0403162Wink Saville        ServiceState tss;
1036767a662ecde33c3979bf02b793d392aca0403162Wink Saville        tss = ss;
1037767a662ecde33c3979bf02b793d392aca0403162Wink Saville        ss = newSS;
1038767a662ecde33c3979bf02b793d392aca0403162Wink Saville        newSS = tss;
1039767a662ecde33c3979bf02b793d392aca0403162Wink Saville        // clean slate for next time
1040767a662ecde33c3979bf02b793d392aca0403162Wink Saville        newSS.setStateOutOfService();
1041767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1042767a662ecde33c3979bf02b793d392aca0403162Wink Saville        CdmaCellLocation tcl = cellLoc;
1043767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cellLoc = newCellLoc;
1044767a662ecde33c3979bf02b793d392aca0403162Wink Saville        newCellLoc = tcl;
1045767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1046767a662ecde33c3979bf02b793d392aca0403162Wink Saville        cdmaDataConnectionState = newCdmaDataConnectionState;
1047767a662ecde33c3979bf02b793d392aca0403162Wink Saville        networkType = newNetworkType;
1048767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1049767a662ecde33c3979bf02b793d392aca0403162Wink Saville        newSS.setStateOutOfService(); // clean slate for next time
1050767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1051767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (hasNetworkTypeChanged) {
105200416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
1053767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    networkTypeToString(networkType));
1054767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
1055767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1056767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (hasRegistered) {
1057767a662ecde33c3979bf02b793d392aca0403162Wink Saville            networkAttachedRegistrants.notifyRegistrants();
1058767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
1059767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1060767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (hasChanged) {
1061f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville            if (cm.getRadioState().isNVReady()) {
1062e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                String eriText;
1063e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                // Now the CDMAPhone sees the new ServiceState so it can get the new ERI text
1064e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                if (ss.getState() == ServiceState.STATE_IN_SERVICE) {
1065e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    eriText = phone.getCdmaEriText();
1066e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                } else {
1067f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                    // Note that ServiceState.STATE_OUT_OF_SERVICE is valid used for
1068f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                    // mRegistrationState 0,2,3 and 4
1069f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                    eriText = phone.getContext().getText(
1070f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville                            com.android.internal.R.string.roamingTextSearching).toString();
1071e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                }
1072e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                ss.setCdmaEriText(eriText);
1073e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            }
1074e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
1075767a662ecde33c3979bf02b793d392aca0403162Wink Saville            String operatorNumeric;
1076767a662ecde33c3979bf02b793d392aca0403162Wink Saville
107700416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
1078767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    ss.getOperatorAlphaLong());
1079767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1080767a662ecde33c3979bf02b793d392aca0403162Wink Saville            operatorNumeric = ss.getOperatorNumeric();
108100416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
1082767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1083767a662ecde33c3979bf02b793d392aca0403162Wink Saville            if (operatorNumeric == null) {
108400416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink                phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
1085767a662ecde33c3979bf02b793d392aca0403162Wink Saville            } else {
1086dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                String isoCountryCode = "";
1087767a662ecde33c3979bf02b793d392aca0403162Wink Saville                try{
1088dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                    isoCountryCode = MccTable.countryCodeForMcc(Integer.parseInt(
1089767a662ecde33c3979bf02b793d392aca0403162Wink Saville                            operatorNumeric.substring(0,3)));
1090767a662ecde33c3979bf02b793d392aca0403162Wink Saville                } catch ( NumberFormatException ex){
1091767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    Log.w(LOG_TAG, "countryCodeForMcc error" + ex);
1092767a662ecde33c3979bf02b793d392aca0403162Wink Saville                } catch ( StringIndexOutOfBoundsException ex) {
1093767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    Log.w(LOG_TAG, "countryCodeForMcc error" + ex);
1094767a662ecde33c3979bf02b793d392aca0403162Wink Saville                }
1095767a662ecde33c3979bf02b793d392aca0403162Wink Saville
109600416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink                phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY,
109700416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink                        isoCountryCode);
1098767a662ecde33c3979bf02b793d392aca0403162Wink Saville                mGotCountryCode = true;
1099dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                if (mNeedFixZone) {
1100dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                    fixTimeZone(isoCountryCode);
1101dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                }
1102767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
1103767a662ecde33c3979bf02b793d392aca0403162Wink Saville
110400416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
1105767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    ss.getRoaming() ? "true" : "false");
1106767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1107767a662ecde33c3979bf02b793d392aca0403162Wink Saville            updateSpnDisplay();
1108767a662ecde33c3979bf02b793d392aca0403162Wink Saville            phone.notifyServiceStateChanged(ss);
1109767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
1110767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1111767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (hasCdmaDataConnectionAttached) {
1112767a662ecde33c3979bf02b793d392aca0403162Wink Saville            cdmaDataConnectionAttachedRegistrants.notifyRegistrants();
1113767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
1114767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1115767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (hasCdmaDataConnectionDetached) {
1116767a662ecde33c3979bf02b793d392aca0403162Wink Saville            cdmaDataConnectionDetachedRegistrants.notifyRegistrants();
1117767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
1118767a662ecde33c3979bf02b793d392aca0403162Wink Saville
111950e05ead5e4fb2e4899e2e1c92cd48692b254ac8jsh        if (hasCdmaDataConnectionChanged || hasNetworkTypeChanged) {
1120767a662ecde33c3979bf02b793d392aca0403162Wink Saville            phone.notifyDataConnection(null);
1121767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
1122767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1123767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (hasRoamingOn) {
1124767a662ecde33c3979bf02b793d392aca0403162Wink Saville            roamingOnRegistrants.notifyRegistrants();
1125767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
1126767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1127767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (hasRoamingOff) {
1128767a662ecde33c3979bf02b793d392aca0403162Wink Saville            roamingOffRegistrants.notifyRegistrants();
1129767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
1130767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1131767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (hasLocationChanged) {
1132767a662ecde33c3979bf02b793d392aca0403162Wink Saville            phone.notifyLocationChanged();
1133767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
1134767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
1135767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1136767a662ecde33c3979bf02b793d392aca0403162Wink Saville    /**
1137767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * Returns a TimeZone object based only on parameters from the NITZ string.
1138767a662ecde33c3979bf02b793d392aca0403162Wink Saville     */
1139767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private TimeZone getNitzTimeZone(int offset, boolean dst, long when) {
1140767a662ecde33c3979bf02b793d392aca0403162Wink Saville        TimeZone guess = findTimeZone(offset, dst, when);
1141767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (guess == null) {
1142767a662ecde33c3979bf02b793d392aca0403162Wink Saville            // Couldn't find a proper timezone.  Perhaps the DST data is wrong.
1143767a662ecde33c3979bf02b793d392aca0403162Wink Saville            guess = findTimeZone(offset, !dst, when);
1144767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
1145e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        if (DBG) log("getNitzTimeZone returning " + (guess == null ? guess : guess.getID()));
1146767a662ecde33c3979bf02b793d392aca0403162Wink Saville        return guess;
1147767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
1148767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1149767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private TimeZone findTimeZone(int offset, boolean dst, long when) {
1150767a662ecde33c3979bf02b793d392aca0403162Wink Saville        int rawOffset = offset;
1151767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (dst) {
1152767a662ecde33c3979bf02b793d392aca0403162Wink Saville            rawOffset -= 3600000;
1153767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
1154767a662ecde33c3979bf02b793d392aca0403162Wink Saville        String[] zones = TimeZone.getAvailableIDs(rawOffset);
1155767a662ecde33c3979bf02b793d392aca0403162Wink Saville        TimeZone guess = null;
1156767a662ecde33c3979bf02b793d392aca0403162Wink Saville        Date d = new Date(when);
1157767a662ecde33c3979bf02b793d392aca0403162Wink Saville        for (String zone : zones) {
1158767a662ecde33c3979bf02b793d392aca0403162Wink Saville            TimeZone tz = TimeZone.getTimeZone(zone);
1159767a662ecde33c3979bf02b793d392aca0403162Wink Saville            if (tz.getOffset(when) == offset &&
1160767a662ecde33c3979bf02b793d392aca0403162Wink Saville                    tz.inDaylightTime(d) == dst) {
1161767a662ecde33c3979bf02b793d392aca0403162Wink Saville                guess = tz;
1162767a662ecde33c3979bf02b793d392aca0403162Wink Saville                break;
1163767a662ecde33c3979bf02b793d392aca0403162Wink Saville            }
1164767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
1165767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1166767a662ecde33c3979bf02b793d392aca0403162Wink Saville        return guess;
1167767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
1168767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1169f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville    /**
1170f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville     * TODO: This code is exactly the same as in GsmServiceStateTracker
1171f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville     * and has a TODO to not poll signal strength if screen is off.
1172f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville     * This code should probably be hoisted to the base class so
1173f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville     * the fix, when added, works for both.
1174f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville     */
1175767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private void
1176767a662ecde33c3979bf02b793d392aca0403162Wink Saville    queueNextSignalStrengthPoll() {
1177767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (dontPollSignalStrength || (cm.getRadioState().isGsm())) {
1178767a662ecde33c3979bf02b793d392aca0403162Wink Saville            // The radio is telling us about signal strength changes
1179767a662ecde33c3979bf02b793d392aca0403162Wink Saville            // we don't have to ask it
1180767a662ecde33c3979bf02b793d392aca0403162Wink Saville            return;
1181767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
1182767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1183767a662ecde33c3979bf02b793d392aca0403162Wink Saville        Message msg;
1184767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1185767a662ecde33c3979bf02b793d392aca0403162Wink Saville        msg = obtainMessage();
1186767a662ecde33c3979bf02b793d392aca0403162Wink Saville        msg.what = EVENT_POLL_SIGNAL_STRENGTH;
1187767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1188f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville        // TODO Don't poll signal strength if screen is off
1189767a662ecde33c3979bf02b793d392aca0403162Wink Saville        sendMessageDelayed(msg, POLL_PERIOD_MILLIS);
1190767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
1191767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1192767a662ecde33c3979bf02b793d392aca0403162Wink Saville    /**
1193e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville     *  send signal-strength-changed notification if changed
119496f2747dd6fabd998619524bcff4a44502a64bbdYong Zhang     *  Called both for solicited and unsolicited signal strength updates
1195767a662ecde33c3979bf02b793d392aca0403162Wink Saville     */
1196767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private void
1197767a662ecde33c3979bf02b793d392aca0403162Wink Saville    onSignalStrengthResult(AsyncResult ar) {
1198e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        SignalStrength oldSignalStrength = mSignalStrength;
1199767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1200767a662ecde33c3979bf02b793d392aca0403162Wink Saville        if (ar.exception != null) {
1201e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            // Most likely radio is resetting/disconnected change to default values.
1202e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            setSignalStrengthDefaultValues();
1203767a662ecde33c3979bf02b793d392aca0403162Wink Saville        } else {
1204767a662ecde33c3979bf02b793d392aca0403162Wink Saville            int[] ints = (int[])ar.result;
1205e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            int offset = 2;
120696f2747dd6fabd998619524bcff4a44502a64bbdYong Zhang            int cdmaDbm = (ints[offset] > 0) ? -ints[offset] : -120;
120796f2747dd6fabd998619524bcff4a44502a64bbdYong Zhang            int cdmaEcio = (ints[offset+1] > 0) ? -ints[offset+1] : -160;
12087d97ff10c7555d6b80dc5e6925f066fa8df8258cWink Saville            int evdoRssi = (ints[offset+2] > 0) ? -ints[offset+2] : -120;
12097d97ff10c7555d6b80dc5e6925f066fa8df8258cWink Saville            int evdoEcio = (ints[offset+3] > 0) ? -ints[offset+3] : -1;
12107d97ff10c7555d6b80dc5e6925f066fa8df8258cWink Saville            int evdoSnr  = ((ints[offset+4] > 0) && (ints[offset+4] <= 8)) ? ints[offset+4] : -1;
1211e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
12127d97ff10c7555d6b80dc5e6925f066fa8df8258cWink Saville            //log(String.format("onSignalStrengthResult cdmaDbm=%d cdmaEcio=%d evdoRssi=%d evdoEcio=%d evdoSnr=%d",
12137d97ff10c7555d6b80dc5e6925f066fa8df8258cWink Saville            //        cdmaDbm, cdmaEcio, evdoRssi, evdoEcio, evdoSnr));
1214e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio,
1215e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    evdoRssi, evdoEcio, evdoSnr, false);
1216767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
1217767a662ecde33c3979bf02b793d392aca0403162Wink Saville
12187d97ff10c7555d6b80dc5e6925f066fa8df8258cWink Saville        try {
12197d97ff10c7555d6b80dc5e6925f066fa8df8258cWink Saville            phone.notifySignalStrength();
12207d97ff10c7555d6b80dc5e6925f066fa8df8258cWink Saville        } catch (NullPointerException ex) {
12217d97ff10c7555d6b80dc5e6925f066fa8df8258cWink Saville            log("onSignalStrengthResult() Phone already destroyed: " + ex
12227d97ff10c7555d6b80dc5e6925f066fa8df8258cWink Saville                    + "SignalStrength not notified");
1223767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
1224767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
1225767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1226767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1227f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville    private int radioTechnologyToDataServiceState(int code) {
1228f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville        int retVal = ServiceState.STATE_OUT_OF_SERVICE;
1229767a662ecde33c3979bf02b793d392aca0403162Wink Saville        switch(code) {
1230767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case 0:
1231767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case 1:
1232767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case 2:
1233767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case 3:
1234767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case 4:
1235767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case 5:
1236767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
1237f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville        case 6: // RADIO_TECHNOLOGY_1xRTT
1238f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville        case 7: // RADIO_TECHNOLOGY_EVDO_0
1239f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville        case 8: // RADIO_TECHNOLOGY_EVDO_A
1240f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville            retVal = ServiceState.STATE_IN_SERVICE;
1241767a662ecde33c3979bf02b793d392aca0403162Wink Saville            break;
1242767a662ecde33c3979bf02b793d392aca0403162Wink Saville        default:
1243767a662ecde33c3979bf02b793d392aca0403162Wink Saville            Log.e(LOG_TAG, "Wrong radioTechnology code.");
1244767a662ecde33c3979bf02b793d392aca0403162Wink Saville        break;
1245767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
1246767a662ecde33c3979bf02b793d392aca0403162Wink Saville        return(retVal);
1247767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
1248767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1249767a662ecde33c3979bf02b793d392aca0403162Wink Saville    /** code is registration state 0-5 from TS 27.007 7.2 */
1250767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private int
1251767a662ecde33c3979bf02b793d392aca0403162Wink Saville    regCodeToServiceState(int code) {
1252767a662ecde33c3979bf02b793d392aca0403162Wink Saville        switch (code) {
1253767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case 0: // Not searching and not registered
1254767a662ecde33c3979bf02b793d392aca0403162Wink Saville            return ServiceState.STATE_OUT_OF_SERVICE;
1255767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case 1:
1256767a662ecde33c3979bf02b793d392aca0403162Wink Saville            return ServiceState.STATE_IN_SERVICE;
1257767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case 2: // 2 is "searching", fall through
1258767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case 3: // 3 is "registration denied", fall through
1259767a662ecde33c3979bf02b793d392aca0403162Wink Saville        case 4: // 4 is "unknown" no vaild in current baseband
1260767a662ecde33c3979bf02b793d392aca0403162Wink Saville            return ServiceState.STATE_OUT_OF_SERVICE;
1261e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        case 5:// 5 is "Registered, roaming"
1262767a662ecde33c3979bf02b793d392aca0403162Wink Saville            return ServiceState.STATE_IN_SERVICE;
1263767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1264767a662ecde33c3979bf02b793d392aca0403162Wink Saville        default:
1265767a662ecde33c3979bf02b793d392aca0403162Wink Saville            Log.w(LOG_TAG, "unexpected service state " + code);
1266767a662ecde33c3979bf02b793d392aca0403162Wink Saville        return ServiceState.STATE_OUT_OF_SERVICE;
1267767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
1268767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
1269767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1270767a662ecde33c3979bf02b793d392aca0403162Wink Saville    /**
1271767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * @return The current CDMA data connection state. ServiceState.RADIO_TECHNOLOGY_1xRTT or
1272767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * ServiceState.RADIO_TECHNOLOGY_EVDO is the same as "attached" and
1273767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * ServiceState.RADIO_TECHNOLOGY_UNKNOWN is the same as detached.
1274767a662ecde33c3979bf02b793d392aca0403162Wink Saville     */
1275767a662ecde33c3979bf02b793d392aca0403162Wink Saville    /*package*/ int getCurrentCdmaDataConnectionState() {
1276767a662ecde33c3979bf02b793d392aca0403162Wink Saville        return cdmaDataConnectionState;
1277767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
1278767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1279767a662ecde33c3979bf02b793d392aca0403162Wink Saville    /**
1280767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * code is registration state 0-5 from TS 27.007 7.2
1281767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * returns true if registered roam, false otherwise
1282767a662ecde33c3979bf02b793d392aca0403162Wink Saville     */
1283767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private boolean
1284767a662ecde33c3979bf02b793d392aca0403162Wink Saville    regCodeIsRoaming (int code) {
1285767a662ecde33c3979bf02b793d392aca0403162Wink Saville        // 5 is  "in service -- roam"
1286767a662ecde33c3979bf02b793d392aca0403162Wink Saville        return 5 == code;
1287767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
1288767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1289767a662ecde33c3979bf02b793d392aca0403162Wink Saville    /**
12908e80fd4478764643ac9543d63a77db62014a843aYong Zhang     * Determine whether a roaming indicator is in the carrier-specified list of ERIs for
12918e80fd4478764643ac9543d63a77db62014a843aYong Zhang     * home system
12928e80fd4478764643ac9543d63a77db62014a843aYong Zhang     *
12938e80fd4478764643ac9543d63a77db62014a843aYong Zhang     * @param roamInd roaming indicator in String
12948e80fd4478764643ac9543d63a77db62014a843aYong Zhang     * @return true if the roamInd is in the carrier-specified list of ERIs for home network
12958e80fd4478764643ac9543d63a77db62014a843aYong Zhang     */
12968e80fd4478764643ac9543d63a77db62014a843aYong Zhang    private boolean isRoamIndForHomeSystem(String roamInd) {
12978e80fd4478764643ac9543d63a77db62014a843aYong Zhang        // retrieve the carrier-specified list of ERIs for home system
12988e80fd4478764643ac9543d63a77db62014a843aYong Zhang        String homeRoamIndcators = SystemProperties.get("ro.cdma.homesystem");
12998e80fd4478764643ac9543d63a77db62014a843aYong Zhang
13008e80fd4478764643ac9543d63a77db62014a843aYong Zhang        if (!TextUtils.isEmpty(homeRoamIndcators)) {
13018e80fd4478764643ac9543d63a77db62014a843aYong Zhang            // searches through the comma-separated list for a match,
13028e80fd4478764643ac9543d63a77db62014a843aYong Zhang            // return true if one is found.
13038e80fd4478764643ac9543d63a77db62014a843aYong Zhang            for (String homeRoamInd : homeRoamIndcators.split(",")) {
13048e80fd4478764643ac9543d63a77db62014a843aYong Zhang                if (homeRoamInd.equals(roamInd)) {
13058e80fd4478764643ac9543d63a77db62014a843aYong Zhang                    return true;
13068e80fd4478764643ac9543d63a77db62014a843aYong Zhang                }
13078e80fd4478764643ac9543d63a77db62014a843aYong Zhang            }
13088e80fd4478764643ac9543d63a77db62014a843aYong Zhang            // no matches found against the list!
13098e80fd4478764643ac9543d63a77db62014a843aYong Zhang            return false;
13108e80fd4478764643ac9543d63a77db62014a843aYong Zhang        }
13118e80fd4478764643ac9543d63a77db62014a843aYong Zhang
13128e80fd4478764643ac9543d63a77db62014a843aYong Zhang        // no system property found for the roaming indicators for home system
13138e80fd4478764643ac9543d63a77db62014a843aYong Zhang        return false;
13148e80fd4478764643ac9543d63a77db62014a843aYong Zhang    }
13158e80fd4478764643ac9543d63a77db62014a843aYong Zhang
13168e80fd4478764643ac9543d63a77db62014a843aYong Zhang    /**
1317767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * Set roaming state when cdmaRoaming is true and ons is different from spn
1318767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * @param cdmaRoaming TS 27.007 7.2 CREG registered roaming
1319767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * @param s ServiceState hold current ons
1320767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * @return true for roaming state set
1321767a662ecde33c3979bf02b793d392aca0403162Wink Saville     */
1322767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private
1323767a662ecde33c3979bf02b793d392aca0403162Wink Saville    boolean isRoamingBetweenOperators(boolean cdmaRoaming, ServiceState s) {
132400416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink        String spn = SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, "empty");
1325767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1326e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        // NOTE: in case of RUIM we should completely ignore the ERI data file and
1327e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        // mOperatorAlphaLong is set from RIL_REQUEST_OPERATOR response 0 (alpha ONS)
1328767a662ecde33c3979bf02b793d392aca0403162Wink Saville        String onsl = s.getOperatorAlphaLong();
1329767a662ecde33c3979bf02b793d392aca0403162Wink Saville        String onss = s.getOperatorAlphaShort();
1330767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1331767a662ecde33c3979bf02b793d392aca0403162Wink Saville        boolean equalsOnsl = onsl != null && spn.equals(onsl);
1332767a662ecde33c3979bf02b793d392aca0403162Wink Saville        boolean equalsOnss = onss != null && spn.equals(onss);
1333767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1334767a662ecde33c3979bf02b793d392aca0403162Wink Saville        return cdmaRoaming && !(equalsOnsl || equalsOnss);
1335767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
1336767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1337dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1338dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    /**
1339dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville     * nitzReceiveTime is time_t that the NITZ time was posted
1340dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville     */
1341dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1342dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    private
1343dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    void setTimeFromNITZString (String nitz, long nitzReceiveTime)
1344dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    {
1345dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        // "yy/mm/dd,hh:mm:ss(+/-)tz"
1346dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        // tz is in number of quarter-hours
1347dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1348dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        long start = SystemClock.elapsedRealtime();
1349dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        Log.i(LOG_TAG, "NITZ: " + nitz + "," + nitzReceiveTime +
1350dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                        " start=" + start + " delay=" + (start - nitzReceiveTime));
1351dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1352dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        try {
1353dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            /* NITZ time (hour:min:sec) will be in UTC but it supplies the timezone
1354dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville             * offset as well (which we won't worry about until later) */
1355dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
1356dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1357dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            c.clear();
1358dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            c.set(Calendar.DST_OFFSET, 0);
1359dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1360dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            String[] nitzSubs = nitz.split("[/:,+-]");
1361dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1362dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            int year = 2000 + Integer.parseInt(nitzSubs[0]);
1363dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            c.set(Calendar.YEAR, year);
1364dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1365dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            // month is 0 based!
1366dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            int month = Integer.parseInt(nitzSubs[1]) - 1;
1367dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            c.set(Calendar.MONTH, month);
1368dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1369dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            int date = Integer.parseInt(nitzSubs[2]);
1370dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            c.set(Calendar.DATE, date);
1371dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1372dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            int hour = Integer.parseInt(nitzSubs[3]);
1373dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            c.set(Calendar.HOUR, hour);
1374dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1375dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            int minute = Integer.parseInt(nitzSubs[4]);
1376dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            c.set(Calendar.MINUTE, minute);
1377dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1378dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            int second = Integer.parseInt(nitzSubs[5]);
1379dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            c.set(Calendar.SECOND, second);
1380dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1381dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            boolean sign = (nitz.indexOf('-') == -1);
1382dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1383dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            int tzOffset = Integer.parseInt(nitzSubs[6]);
1384dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1385dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            int dst = (nitzSubs.length >= 8 ) ? Integer.parseInt(nitzSubs[7])
1386dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                                              : 0;
1387dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1388dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            // The zone offset received from NITZ is for current local time,
1389dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            // so DST correction is already applied.  Don't add it again.
1390dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            //
1391dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            // tzOffset += dst * 4;
1392dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            //
1393dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            // We could unapply it if we wanted the raw offset.
1394dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1395dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            tzOffset = (sign ? 1 : -1) * tzOffset * 15 * 60 * 1000;
1396dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1397dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            TimeZone    zone = null;
1398dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1399dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            // As a special extension, the Android emulator appends the name of
1400dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            // the host computer's timezone to the nitz string. this is zoneinfo
1401dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            // timezone name of the form Area!Location or Area!Location!SubLocation
1402dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            // so we need to convert the ! into /
1403dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            if (nitzSubs.length >= 9) {
1404dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                String  tzname = nitzSubs[8].replace('!','/');
1405dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                zone = TimeZone.getTimeZone( tzname );
1406dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            }
1407dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
140800416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink            String iso = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY);
1409dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1410dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            if (zone == null) {
1411dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1412dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                if (mGotCountryCode) {
1413dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                    if (iso != null && iso.length() > 0) {
1414dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                        zone = TimeUtils.getTimeZone(tzOffset, dst != 0,
1415dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                                c.getTimeInMillis(),
1416dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                                iso);
1417dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                    } else {
1418dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                        // We don't have a valid iso country code.  This is
1419dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                        // most likely because we're on a test network that's
1420dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                        // using a bogus MCC (eg, "001"), so get a TimeZone
1421dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                        // based only on the NITZ parameters.
1422dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                        zone = getNitzTimeZone(tzOffset, (dst != 0), c.getTimeInMillis());
1423dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                    }
1424dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                }
1425dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            }
1426dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1427dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            if (zone == null) {
1428dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                // We got the time before the country, so we don't know
1429dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                // how to identify the DST rules yet.  Save the information
1430dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                // and hope to fix it up later.
1431dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1432dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                mNeedFixZone = true;
1433dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                mZoneOffset  = tzOffset;
1434dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                mZoneDst     = dst != 0;
1435dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                mZoneTime    = c.getTimeInMillis();
1436dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            }
1437dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1438dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            if (zone != null) {
1439dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                if (getAutoTime()) {
1440dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                    setAndBroadcastNetworkSetTimeZone(zone.getID());
1441dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                }
1442dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                saveNitzTimeZone(zone.getID());
1443dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            }
1444dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1445dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            String ignore = SystemProperties.get("gsm.ignore-nitz");
1446dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            if (ignore != null && ignore.equals("yes")) {
1447dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                Log.i(LOG_TAG, "NITZ: Not setting clock because gsm.ignore-nitz is set");
1448dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                return;
1449dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            }
1450dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1451dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            try {
1452dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                mWakeLock.acquire();
1453dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1454aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                /**
1455aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                 * Correct the NITZ time by how long its taken to get here.
1456aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                 */
1457aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                long millisSinceNitzReceived
1458aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                        = SystemClock.elapsedRealtime() - nitzReceiveTime;
1459aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville
1460aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                if (millisSinceNitzReceived < 0) {
1461aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                    // Sanity check: something is wrong
1462aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                    Log.i(LOG_TAG, "NITZ: not setting time, clock has rolled "
1463aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                                        + "backwards since NITZ time was received, "
1464aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                                        + nitz);
1465aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                    return;
1466aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                }
1467dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1468aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                if (millisSinceNitzReceived > Integer.MAX_VALUE) {
1469aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                    // If the time is this far off, something is wrong > 24 days!
1470aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                    Log.i(LOG_TAG, "NITZ: not setting time, processing has taken "
1471aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                                    + (millisSinceNitzReceived / (1000 * 60 * 60 * 24))
1472aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                                    + " days");
1473aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                    return;
1474aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                }
1475dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1476aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                // Note: with range checks above, cast to int is safe
1477aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                c.add(Calendar.MILLISECOND, (int)millisSinceNitzReceived);
1478dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1479aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                if (getAutoTime()) {
1480aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                    /**
1481aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                     * Update system time automatically
1482aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                     */
1483aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                    long gained = c.getTimeInMillis() - System.currentTimeMillis();
1484aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                    long timeSinceLastUpdate = SystemClock.elapsedRealtime() - mSavedAtTime;
1485edc5189c33de03f3e2f5f73edc0e007992b933c9Doug Zongker                    int nitzUpdateSpacing = Settings.Secure.getInt(cr,
1486edc5189c33de03f3e2f5f73edc0e007992b933c9Doug Zongker                            Settings.Secure.NITZ_UPDATE_SPACING, mNitzUpdateSpacing);
1487edc5189c33de03f3e2f5f73edc0e007992b933c9Doug Zongker                    int nitzUpdateDiff = Settings.Secure.getInt(cr,
1488edc5189c33de03f3e2f5f73edc0e007992b933c9Doug Zongker                            Settings.Secure.NITZ_UPDATE_DIFF, mNitzUpdateDiff);
1489aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville
1490ce9b59f0ba00e006d2697480b5e5d1fcbd0d2818Wink Saville                    if ((mSavedAtTime == 0) || (timeSinceLastUpdate > nitzUpdateSpacing)
1491ce9b59f0ba00e006d2697480b5e5d1fcbd0d2818Wink Saville                            || (Math.abs(gained) > nitzUpdateDiff)) {
1492aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                        Log.i(LOG_TAG, "NITZ: Auto updating time of day to " + c.getTime()
1493aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                                + " NITZ receive delay=" + millisSinceNitzReceived
1494aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                                + "ms gained=" + gained + "ms from " + nitz);
1495aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville
1496aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                        setAndBroadcastNetworkSetTime(c.getTimeInMillis());
1497aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                    } else {
1498aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                        Log.i(LOG_TAG, "NITZ: ignore, a previous update was "
1499aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                                + timeSinceLastUpdate + "ms ago and gained=" + gained + "ms");
1500aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                        return;
1501aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                    }
1502dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                }
1503aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville
1504aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                /**
1505aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                 * Update properties and save the time we did the update
1506aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                 */
1507aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                Log.i(LOG_TAG, "NITZ: update nitz time property");
1508dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                SystemProperties.set("gsm.nitz.time", String.valueOf(c.getTimeInMillis()));
1509aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                mSavedTime = c.getTimeInMillis();
1510aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                mSavedAtTime = SystemClock.elapsedRealtime();
1511dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            } finally {
1512aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                long end = SystemClock.elapsedRealtime();
1513aeff5fd8eb17bc0f611918d6482139c1921e7b60Wink Saville                Log.i(LOG_TAG, "NITZ: end=" + end + " dur=" + (end - start));
1514dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                mWakeLock.release();
1515dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            }
1516dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        } catch (RuntimeException ex) {
1517dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            Log.e(LOG_TAG, "NITZ: Parsing NITZ time " + nitz, ex);
1518dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        }
1519dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    }
1520dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1521767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private boolean getAutoTime() {
1522767a662ecde33c3979bf02b793d392aca0403162Wink Saville        try {
1523ce9b59f0ba00e006d2697480b5e5d1fcbd0d2818Wink Saville            return Settings.System.getInt(cr, Settings.System.AUTO_TIME) > 0;
1524767a662ecde33c3979bf02b793d392aca0403162Wink Saville        } catch (SettingNotFoundException snfe) {
1525767a662ecde33c3979bf02b793d392aca0403162Wink Saville            return true;
1526767a662ecde33c3979bf02b793d392aca0403162Wink Saville        }
1527767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
1528767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1529dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    private void saveNitzTimeZone(String zoneId) {
1530dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        mSavedTimeZone = zoneId;
1531dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    }
1532dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1533dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    /**
1534dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville     * Set the timezone and send out a sticky broadcast so the system can
1535dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville     * determine if the timezone was set by the carrier.
1536dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville     *
1537dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville     * @param zoneId timezone set by carrier
1538dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville     */
1539dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    private void setAndBroadcastNetworkSetTimeZone(String zoneId) {
1540dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        AlarmManager alarm =
1541dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE);
1542dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        alarm.setTimeZone(zoneId);
1543dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE);
15441c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
1545dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        intent.putExtra("time-zone", zoneId);
1546dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        phone.getContext().sendStickyBroadcast(intent);
1547dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    }
1548dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1549dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    /**
1550dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville     * Set the time and Send out a sticky broadcast so the system can determine
1551dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville     * if the time was set by the carrier.
1552dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville     *
1553dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville     * @param time time set by network
1554dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville     */
1555dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    private void setAndBroadcastNetworkSetTime(long time) {
1556dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        SystemClock.setCurrentTimeMillis(time);
1557dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME);
15581c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
1559dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        intent.putExtra("time", time);
1560dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        phone.getContext().sendStickyBroadcast(intent);
1561dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    }
1562dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1563dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville     private void revertToNitz() {
1564ce9b59f0ba00e006d2697480b5e5d1fcbd0d2818Wink Saville        if (Settings.System.getInt(cr, Settings.System.AUTO_TIME, 0) == 0) {
1565dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            return;
1566dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        }
1567dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        Log.d(LOG_TAG, "Reverting to NITZ: tz='" + mSavedTimeZone
1568dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                + "' mSavedTime=" + mSavedTime
1569dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                + " mSavedAtTime=" + mSavedAtTime);
1570dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        if (mSavedTimeZone != null && mSavedTime != 0 && mSavedAtTime != 0) {
1571dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            setAndBroadcastNetworkSetTimeZone(mSavedTimeZone);
1572dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville            setAndBroadcastNetworkSetTime(mSavedTime
1573dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville                    + (SystemClock.elapsedRealtime() - mSavedAtTime));
1574dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville        }
1575dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville    }
1576dda5391d5079537e275c9f4ed2637a1484d0e4e8Wink Saville
1577d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang    private boolean isSidsAllZeros() {
1578d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang        if (mHomeSystemId != null) {
1579d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang            for (int i=0; i < mHomeSystemId.length; i++) {
1580d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                if (mHomeSystemId[i] != 0) {
1581d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                    return false;
1582d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                }
1583d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang            }
1584d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang        }
1585d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang        return true;
1586d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang    }
1587d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang
1588d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang    /**
1589d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang     * Check whether a specified system ID that matches one of the home system IDs.
1590d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang     */
1591d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang    private boolean isHomeSid(int sid) {
1592d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang        if (mHomeSystemId != null) {
1593d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang            for (int i=0; i < mHomeSystemId.length; i++) {
1594d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                if (sid == mHomeSystemId[i]) {
1595d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                    return true;
1596d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang                }
1597d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang            }
1598d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang        }
1599d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang        return false;
1600d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang    }
1601d23b2cd28cae547aaa884964c3fef2a010bcca3aLibin Tang
1602767a662ecde33c3979bf02b793d392aca0403162Wink Saville    /**
1603767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * @return true if phone is camping on a technology
1604767a662ecde33c3979bf02b793d392aca0403162Wink Saville     * that could support voice and data simultaneously.
1605767a662ecde33c3979bf02b793d392aca0403162Wink Saville     */
1606767a662ecde33c3979bf02b793d392aca0403162Wink Saville    boolean isConcurrentVoiceAndData() {
1607767a662ecde33c3979bf02b793d392aca0403162Wink Saville        // Note: it needs to be confirmed which CDMA network types
1608767a662ecde33c3979bf02b793d392aca0403162Wink Saville        // can support voice and data calls concurrently.
1609767a662ecde33c3979bf02b793d392aca0403162Wink Saville        // For the time-being, the return value will be false.
1610767a662ecde33c3979bf02b793d392aca0403162Wink Saville        return false;
1611767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
1612767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1613767a662ecde33c3979bf02b793d392aca0403162Wink Saville    protected void log(String s) {
1614767a662ecde33c3979bf02b793d392aca0403162Wink Saville        Log.d(LOG_TAG, "[CdmaServiceStateTracker] " + s);
1615767a662ecde33c3979bf02b793d392aca0403162Wink Saville    }
1616767a662ecde33c3979bf02b793d392aca0403162Wink Saville
1617f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville    public String getMdnNumber() {
1618f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville        return mMdn;
1619f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville    }
1620f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville
1621f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville    public String getCdmaMin() {
1622f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville         return mMin;
1623f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville    }
1624f315238a2b07c7e84f6ade800e504f520d262e66Wink Saville
1625daccacb865947c00f277f1823333e2fbf91e652aWink Saville    /** Returns null if NV is not yet ready */
1626daccacb865947c00f277f1823333e2fbf91e652aWink Saville    public String getPrlVersion() {
1627daccacb865947c00f277f1823333e2fbf91e652aWink Saville        return mPrlVersion;
1628daccacb865947c00f277f1823333e2fbf91e652aWink Saville    }
1629daccacb865947c00f277f1823333e2fbf91e652aWink Saville
1630142eefc67b661a63f95dd2b92cf622e7b57fcb4bWink Saville    /**
1631142eefc67b661a63f95dd2b92cf622e7b57fcb4bWink Saville     * Returns IMSI as MCC + MNC + MIN
1632142eefc67b661a63f95dd2b92cf622e7b57fcb4bWink Saville     */
163300416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink    String getImsi() {
16347188f946521d64ea21121939d2a4c279f33fe910Wink Saville        // TODO: When RUIM is enabled, IMSI will come from RUIM not build-time props.
163500416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink        String operatorNumeric = SystemProperties.get(
163600416365dedc03c9ed74d94728025fd2d68f648dTammo Spalink                TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "");
1637142eefc67b661a63f95dd2b92cf622e7b57fcb4bWink Saville
1638142eefc67b661a63f95dd2b92cf622e7b57fcb4bWink Saville        if (!TextUtils.isEmpty(operatorNumeric) && getCdmaMin() != null) {
1639142eefc67b661a63f95dd2b92cf622e7b57fcb4bWink Saville            return (operatorNumeric + getCdmaMin());
1640142eefc67b661a63f95dd2b92cf622e7b57fcb4bWink Saville        } else {
1641142eefc67b661a63f95dd2b92cf622e7b57fcb4bWink Saville            return null;
1642142eefc67b661a63f95dd2b92cf622e7b57fcb4bWink Saville        }
1643142eefc67b661a63f95dd2b92cf622e7b57fcb4bWink Saville    }
16449e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo
16459e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo    /**
16469e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo     * Check if subscription data has been assigned to mMin
16479e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo     *
16489e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo     * return true if MIN info is ready; false otherwise.
16499e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo     */
16509e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo    public boolean isMinInfoReady() {
16519e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo        return mIsMinInfoReady;
16529e652dcc213b96087ccadc730b1e6b1891cd02aeJinghui Guo    }
1653fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang
1654fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang    /**
1655fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang     * process the pending request to turn radio off after data is disconnected
1656fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang     *
1657fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang     * return true if there is pending request to process; false otherwise.
1658fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang     */
1659fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang    public boolean processPendingRadioPowerOffAfterDataOff() {
1660fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang        synchronized(this) {
1661fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang            if (mPendingRadioPowerOffAfterDataOff) {
1662fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang                if (DBG) log("Process pending request to turn radio off.");
1663fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang                removeMessages(EVENT_SET_RADIO_POWER_OFF);
16643805c7ca324f232972c959e06253de4242f83607John Wang                hangupAndPowerOff();
1665fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang                mPendingRadioPowerOffAfterDataOff = false;
1666fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang                return true;
1667fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang            }
1668fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang            return false;
1669fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang        }
1670fa2944d93f4c5050fb4a99d90006791c2995b31cYong Zhang    }
16713805c7ca324f232972c959e06253de4242f83607John Wang
16723805c7ca324f232972c959e06253de4242f83607John Wang    private void hangupAndPowerOff() {
16733805c7ca324f232972c959e06253de4242f83607John Wang        // hang up all active voice calls
16743805c7ca324f232972c959e06253de4242f83607John Wang        phone.mCT.ringingCall.hangupIfAlive();
16753805c7ca324f232972c959e06253de4242f83607John Wang        phone.mCT.backgroundCall.hangupIfAlive();
16763805c7ca324f232972c959e06253de4242f83607John Wang        phone.mCT.foregroundCall.hangupIfAlive();
16773805c7ca324f232972c959e06253de4242f83607John Wang        cm.setRadioPower(false, null);
16783805c7ca324f232972c959e06253de4242f83607John Wang    }
1679767a662ecde33c3979bf02b793d392aca0403162Wink Saville}
1680