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