UiccCard.java revision 062a2a3838c8d8adf16f4d9fbde8d52450da0336
1/* 2 * Copyright (C) 2006, 2012 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.uicc; 18 19import static android.Manifest.permission.READ_PHONE_STATE; 20import android.app.ActivityManagerNative; 21import android.app.AlertDialog; 22import android.content.Context; 23import android.content.DialogInterface; 24import android.content.Intent; 25import android.content.SharedPreferences; 26import android.content.pm.PackageManager; 27import android.content.pm.Signature; 28import android.content.res.Resources; 29import android.os.AsyncResult; 30import android.os.Handler; 31import android.os.Message; 32import android.os.PowerManager; 33import android.os.Registrant; 34import android.os.RegistrantList; 35import android.preference.PreferenceManager; 36import android.telephony.Rlog; 37import android.telephony.TelephonyManager; 38import android.text.TextUtils; 39import android.view.WindowManager; 40 41import com.android.internal.telephony.CommandsInterface; 42import com.android.internal.telephony.PhoneBase; 43import com.android.internal.telephony.CommandsInterface.RadioState; 44import com.android.internal.telephony.IccCardConstants.State; 45import com.android.internal.telephony.gsm.GSMPhone; 46import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType; 47import com.android.internal.telephony.uicc.IccCardStatus.CardState; 48import com.android.internal.telephony.uicc.IccCardStatus.PinState; 49import com.android.internal.telephony.cat.CatService; 50import com.android.internal.telephony.cdma.CDMALTEPhone; 51import com.android.internal.telephony.cdma.CDMAPhone; 52import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager; 53 54import android.os.SystemProperties; 55 56import com.android.internal.R; 57 58import java.io.FileDescriptor; 59import java.io.PrintWriter; 60import java.util.List; 61 62/** 63 * {@hide} 64 */ 65public class UiccCard { 66 protected static final String LOG_TAG = "UiccCard"; 67 protected static final boolean DBG = true; 68 69 private static final String OPERATOR_BRAND_OVERRIDE_PREFIX = "operator_branding_"; 70 71 private final Object mLock = new Object(); 72 private CardState mCardState; 73 private PinState mUniversalPinState; 74 private int mGsmUmtsSubscriptionAppIndex; 75 private int mCdmaSubscriptionAppIndex; 76 private int mImsSubscriptionAppIndex; 77 private UiccCardApplication[] mUiccApplications = 78 new UiccCardApplication[IccCardStatus.CARD_MAX_APPS]; 79 private Context mContext; 80 private CommandsInterface mCi; 81 private CatService mCatService; 82 private RadioState mLastRadioState = RadioState.RADIO_UNAVAILABLE; 83 private UiccCarrierPrivilegeRules mCarrierPrivilegeRules; 84 85 private RegistrantList mAbsentRegistrants = new RegistrantList(); 86 private RegistrantList mCarrierPrivilegeRegistrants = new RegistrantList(); 87 88 private static final int EVENT_CARD_REMOVED = 13; 89 private static final int EVENT_CARD_ADDED = 14; 90 private static final int EVENT_OPEN_LOGICAL_CHANNEL_DONE = 15; 91 private static final int EVENT_CLOSE_LOGICAL_CHANNEL_DONE = 16; 92 private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 17; 93 private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 18; 94 private static final int EVENT_SIM_IO_DONE = 19; 95 private static final int EVENT_CARRIER_PRIVILIGES_LOADED = 20; 96 97 private int mPhoneId; 98 99 public UiccCard(Context c, CommandsInterface ci, IccCardStatus ics) { 100 if (DBG) log("Creating"); 101 mCardState = ics.mCardState; 102 update(c, ci, ics); 103 } 104 105 public UiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId) { 106 mCardState = ics.mCardState; 107 mPhoneId = phoneId; 108 update(c, ci, ics); 109 } 110 111 protected UiccCard() { 112 } 113 114 public void dispose() { 115 synchronized (mLock) { 116 if (DBG) log("Disposing card"); 117 if (mCatService != null) mCatService.dispose(); 118 for (UiccCardApplication app : mUiccApplications) { 119 if (app != null) { 120 app.dispose(); 121 } 122 } 123 mCatService = null; 124 mUiccApplications = null; 125 mCarrierPrivilegeRules = null; 126 } 127 } 128 129 public void update(Context c, CommandsInterface ci, IccCardStatus ics) { 130 synchronized (mLock) { 131 CardState oldState = mCardState; 132 mCardState = ics.mCardState; 133 mUniversalPinState = ics.mUniversalPinState; 134 mGsmUmtsSubscriptionAppIndex = ics.mGsmUmtsSubscriptionAppIndex; 135 mCdmaSubscriptionAppIndex = ics.mCdmaSubscriptionAppIndex; 136 mImsSubscriptionAppIndex = ics.mImsSubscriptionAppIndex; 137 mContext = c; 138 mCi = ci; 139 140 //update applications 141 if (DBG) log(ics.mApplications.length + " applications"); 142 for ( int i = 0; i < mUiccApplications.length; i++) { 143 if (mUiccApplications[i] == null) { 144 //Create newly added Applications 145 if (i < ics.mApplications.length) { 146 mUiccApplications[i] = new UiccCardApplication(this, 147 ics.mApplications[i], mContext, mCi); 148 } 149 } else if (i >= ics.mApplications.length) { 150 //Delete removed applications 151 mUiccApplications[i].dispose(); 152 mUiccApplications[i] = null; 153 } else { 154 //Update the rest 155 mUiccApplications[i].update(ics.mApplications[i], mContext, mCi); 156 } 157 } 158 159 createAndUpdateCatService(); 160 161 // Reload the carrier privilege rules if necessary. 162 log("Before privilege rules: " + mCarrierPrivilegeRules + " : " + mCardState); 163 if (mCarrierPrivilegeRules == null && mCardState == CardState.CARDSTATE_PRESENT) { 164 mCarrierPrivilegeRules = new UiccCarrierPrivilegeRules(this, 165 mHandler.obtainMessage(EVENT_CARRIER_PRIVILIGES_LOADED)); 166 } else if (mCarrierPrivilegeRules != null && mCardState != CardState.CARDSTATE_PRESENT) { 167 mCarrierPrivilegeRules = null; 168 } 169 170 sanitizeApplicationIndexes(); 171 172 RadioState radioState = mCi.getRadioState(); 173 if (DBG) log("update: radioState=" + radioState + " mLastRadioState=" 174 + mLastRadioState); 175 // No notifications while radio is off or we just powering up 176 if (radioState == RadioState.RADIO_ON && mLastRadioState == RadioState.RADIO_ON) { 177 if (oldState != CardState.CARDSTATE_ABSENT && 178 mCardState == CardState.CARDSTATE_ABSENT) { 179 if (DBG) log("update: notify card removed"); 180 mAbsentRegistrants.notifyRegistrants(); 181 mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_REMOVED, null)); 182 } else if (oldState == CardState.CARDSTATE_ABSENT && 183 mCardState != CardState.CARDSTATE_ABSENT) { 184 if (DBG) log("update: notify card added"); 185 mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_ADDED, null)); 186 } 187 } 188 mLastRadioState = radioState; 189 } 190 } 191 192 protected void createAndUpdateCatService() { 193 if (mUiccApplications.length > 0 && mUiccApplications[0] != null) { 194 // Initialize or Reinitialize CatService 195 if (mCatService == null) { 196 mCatService = CatService.getInstance(mCi, mContext, this, mPhoneId); 197 } else { 198 ((CatService)mCatService).update(mCi, mContext, this); 199 } 200 } else { 201 if (mCatService != null) { 202 mCatService.dispose(); 203 } 204 mCatService = null; 205 } 206 } 207 208 public CatService getCatService() { 209 return mCatService; 210 } 211 212 @Override 213 protected void finalize() { 214 if (DBG) log("UiccCard finalized"); 215 } 216 217 /** 218 * This function makes sure that application indexes are valid 219 * and resets invalid indexes. (This should never happen, but in case 220 * RIL misbehaves we need to manage situation gracefully) 221 */ 222 private void sanitizeApplicationIndexes() { 223 mGsmUmtsSubscriptionAppIndex = 224 checkIndex(mGsmUmtsSubscriptionAppIndex, AppType.APPTYPE_SIM, AppType.APPTYPE_USIM); 225 mCdmaSubscriptionAppIndex = 226 checkIndex(mCdmaSubscriptionAppIndex, AppType.APPTYPE_RUIM, AppType.APPTYPE_CSIM); 227 mImsSubscriptionAppIndex = 228 checkIndex(mImsSubscriptionAppIndex, AppType.APPTYPE_ISIM, null); 229 } 230 231 private int checkIndex(int index, AppType expectedAppType, AppType altExpectedAppType) { 232 if (mUiccApplications == null || index >= mUiccApplications.length) { 233 loge("App index " + index + " is invalid since there are no applications"); 234 return -1; 235 } 236 237 if (index < 0) { 238 // This is normal. (i.e. no application of this type) 239 return -1; 240 } 241 242 if (mUiccApplications[index].getType() != expectedAppType && 243 mUiccApplications[index].getType() != altExpectedAppType) { 244 loge("App index " + index + " is invalid since it's not " + 245 expectedAppType + " and not " + altExpectedAppType); 246 return -1; 247 } 248 249 // Seems to be valid 250 return index; 251 } 252 253 /** 254 * Notifies handler of any transition into State.ABSENT 255 */ 256 public void registerForAbsent(Handler h, int what, Object obj) { 257 synchronized (mLock) { 258 Registrant r = new Registrant (h, what, obj); 259 260 mAbsentRegistrants.add(r); 261 262 if (mCardState == CardState.CARDSTATE_ABSENT) { 263 r.notifyRegistrant(); 264 } 265 } 266 } 267 268 public void unregisterForAbsent(Handler h) { 269 synchronized (mLock) { 270 mAbsentRegistrants.remove(h); 271 } 272 } 273 274 /** 275 * Notifies handler when carrier privilege rules are loaded. 276 */ 277 public void registerForCarrierPrivilegeRulesLoaded(Handler h, int what, Object obj) { 278 synchronized (mLock) { 279 Registrant r = new Registrant (h, what, obj); 280 281 mCarrierPrivilegeRegistrants.add(r); 282 283 if (areCarrierPriviligeRulesLoaded()) { 284 r.notifyRegistrant(); 285 } 286 } 287 } 288 289 public void unregisterForCarrierPrivilegeRulesLoaded(Handler h) { 290 synchronized (mLock) { 291 mCarrierPrivilegeRegistrants.remove(h); 292 } 293 } 294 295 private void onIccSwap(boolean isAdded) { 296 297 boolean isHotSwapSupported = mContext.getResources().getBoolean( 298 com.android.internal.R.bool.config_hotswapCapable); 299 300 if (isHotSwapSupported) { 301 log("onIccSwap: isHotSwapSupported is true, don't prompt for rebooting"); 302 return; 303 } 304 log("onIccSwap: isHotSwapSupported is false, prompt for rebooting"); 305 306 synchronized (mLock) { 307 // TODO: Here we assume the device can't handle SIM hot-swap 308 // and has to reboot. We may want to add a property, 309 // e.g. REBOOT_ON_SIM_SWAP, to indicate if modem support 310 // hot-swap. 311 DialogInterface.OnClickListener listener = null; 312 313 314 // TODO: SimRecords is not reset while SIM ABSENT (only reset while 315 // Radio_off_or_not_available). Have to reset in both both 316 // added or removed situation. 317 listener = new DialogInterface.OnClickListener() { 318 @Override 319 public void onClick(DialogInterface dialog, int which) { 320 synchronized (mLock) { 321 if (which == DialogInterface.BUTTON_POSITIVE) { 322 if (DBG) log("Reboot due to SIM swap"); 323 PowerManager pm = (PowerManager) mContext 324 .getSystemService(Context.POWER_SERVICE); 325 pm.reboot("SIM is added."); 326 } 327 } 328 } 329 330 }; 331 332 Resources r = Resources.getSystem(); 333 334 String title = (isAdded) ? r.getString(R.string.sim_added_title) : 335 r.getString(R.string.sim_removed_title); 336 String message = (isAdded) ? r.getString(R.string.sim_added_message) : 337 r.getString(R.string.sim_removed_message); 338 String buttonTxt = r.getString(R.string.sim_restart_button); 339 340 AlertDialog dialog = new AlertDialog.Builder(mContext) 341 .setTitle(title) 342 .setMessage(message) 343 .setPositiveButton(buttonTxt, listener) 344 .create(); 345 dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); 346 dialog.show(); 347 } 348 } 349 350 protected Handler mHandler = new Handler() { 351 @Override 352 public void handleMessage(Message msg){ 353 switch (msg.what) { 354 case EVENT_CARD_REMOVED: 355 onIccSwap(false); 356 break; 357 case EVENT_CARD_ADDED: 358 onIccSwap(true); 359 break; 360 case EVENT_OPEN_LOGICAL_CHANNEL_DONE: 361 case EVENT_CLOSE_LOGICAL_CHANNEL_DONE: 362 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE: 363 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE: 364 case EVENT_SIM_IO_DONE: 365 AsyncResult ar = (AsyncResult)msg.obj; 366 if (ar.exception != null) { 367 if (DBG) 368 log("Error in SIM access with exception" + ar.exception); 369 } 370 AsyncResult.forMessage((Message)ar.userObj, ar.result, ar.exception); 371 ((Message)ar.userObj).sendToTarget(); 372 break; 373 case EVENT_CARRIER_PRIVILIGES_LOADED: 374 onCarrierPriviligesLoadedMessage(); 375 break; 376 default: 377 loge("Unknown Event " + msg.what); 378 } 379 } 380 }; 381 382 private void onCarrierPriviligesLoadedMessage() { 383 synchronized (mLock) { 384 mCarrierPrivilegeRegistrants.notifyRegistrants(); 385 } 386 } 387 388 public boolean isApplicationOnIcc(IccCardApplicationStatus.AppType type) { 389 synchronized (mLock) { 390 for (int i = 0 ; i < mUiccApplications.length; i++) { 391 if (mUiccApplications[i] != null && mUiccApplications[i].getType() == type) { 392 return true; 393 } 394 } 395 return false; 396 } 397 } 398 399 public CardState getCardState() { 400 synchronized (mLock) { 401 return mCardState; 402 } 403 } 404 405 public PinState getUniversalPinState() { 406 synchronized (mLock) { 407 return mUniversalPinState; 408 } 409 } 410 411 public UiccCardApplication getApplication(int family) { 412 synchronized (mLock) { 413 int index = IccCardStatus.CARD_MAX_APPS; 414 switch (family) { 415 case UiccController.APP_FAM_3GPP: 416 index = mGsmUmtsSubscriptionAppIndex; 417 break; 418 case UiccController.APP_FAM_3GPP2: 419 index = mCdmaSubscriptionAppIndex; 420 break; 421 case UiccController.APP_FAM_IMS: 422 index = mImsSubscriptionAppIndex; 423 break; 424 } 425 if (index >= 0 && index < mUiccApplications.length) { 426 return mUiccApplications[index]; 427 } 428 return null; 429 } 430 } 431 432 public UiccCardApplication getApplicationIndex(int index) { 433 synchronized (mLock) { 434 if (index >= 0 && index < mUiccApplications.length) { 435 return mUiccApplications[index]; 436 } 437 return null; 438 } 439 } 440 441 /** 442 * Returns the SIM application of the specified type. 443 * 444 * @param type ICC application type (@see com.android.internal.telephony.PhoneConstants#APPTYPE_xxx) 445 * @return application corresponding to type or a null if no match found 446 */ 447 public UiccCardApplication getApplicationByType(int type) { 448 synchronized (mLock) { 449 for (int i = 0 ; i < mUiccApplications.length; i++) { 450 if (mUiccApplications[i] != null && 451 mUiccApplications[i].getType().ordinal() == type) { 452 return mUiccApplications[i]; 453 } 454 } 455 return null; 456 } 457 } 458 459 /** 460 * Resets the application with the input AID. Returns true if any changes were made. 461 */ 462 public boolean resetAppWithAid(String aid) { 463 synchronized (mLock) { 464 for (int i = 0; i < mUiccApplications.length; i++) { 465 if (mUiccApplications[i] != null && aid.equals(mUiccApplications[i].getAid())) { 466 // Delete removed applications 467 mUiccApplications[i].dispose(); 468 mUiccApplications[i] = null; 469 return true; 470 } 471 } 472 return false; 473 } 474 } 475 476 /** 477 * Exposes {@link CommandsInterface.iccOpenLogicalChannel} 478 */ 479 public void iccOpenLogicalChannel(String AID, Message response) { 480 mCi.iccOpenLogicalChannel(AID, 481 mHandler.obtainMessage(EVENT_OPEN_LOGICAL_CHANNEL_DONE, response)); 482 } 483 484 /** 485 * Exposes {@link CommandsInterface.iccCloseLogicalChannel} 486 */ 487 public void iccCloseLogicalChannel(int channel, Message response) { 488 mCi.iccCloseLogicalChannel(channel, 489 mHandler.obtainMessage(EVENT_CLOSE_LOGICAL_CHANNEL_DONE, response)); 490 } 491 492 /** 493 * Exposes {@link CommandsInterface.iccTransmitApduLogicalChannel} 494 */ 495 public void iccTransmitApduLogicalChannel(int channel, int cla, int command, 496 int p1, int p2, int p3, String data, Message response) { 497 mCi.iccTransmitApduLogicalChannel(channel, cla, command, p1, p2, p3, 498 data, mHandler.obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE, response)); 499 } 500 501 /** 502 * Exposes {@link CommandsInterface.iccTransmitApduBasicChannel} 503 */ 504 public void iccTransmitApduBasicChannel(int cla, int command, 505 int p1, int p2, int p3, String data, Message response) { 506 mCi.iccTransmitApduBasicChannel(cla, command, p1, p2, p3, 507 data, mHandler.obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE, response)); 508 } 509 510 /** 511 * Exposes {@link CommandsInterface.iccIO} 512 */ 513 public void iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3, 514 String pathID, Message response) { 515 mCi.iccIO(command, fileID, pathID, p1, p2, p3, null, null, 516 mHandler.obtainMessage(EVENT_SIM_IO_DONE, response)); 517 } 518 519 /** 520 * Exposes {@link CommandsInterface.sendEnvelopeWithStatus} 521 */ 522 public void sendEnvelopeWithStatus(String contents, Message response) { 523 mCi.sendEnvelopeWithStatus(contents, response); 524 } 525 526 /* Returns number of applications on this card */ 527 public int getNumApplications() { 528 int count = 0; 529 for (UiccCardApplication a : mUiccApplications) { 530 if (a != null) { 531 count++; 532 } 533 } 534 return count; 535 } 536 537 public int getPhoneId() { 538 return mPhoneId; 539 } 540 541 /** 542 * Returns true iff carrier priveleges rules are null (dont need to be loaded) or loaded. 543 */ 544 public boolean areCarrierPriviligeRulesLoaded() { 545 return mCarrierPrivilegeRules == null 546 || mCarrierPrivilegeRules.areCarrierPriviligeRulesLoaded(); 547 } 548 549 /** 550 * Exposes {@link UiccCarrierPrivilegeRules.getCarrierPrivilegeStatus}. 551 */ 552 public int getCarrierPrivilegeStatus(Signature signature, String packageName) { 553 return mCarrierPrivilegeRules == null ? 554 TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED : 555 mCarrierPrivilegeRules.getCarrierPrivilegeStatus(signature, packageName); 556 } 557 558 /** 559 * Exposes {@link UiccCarrierPrivilegeRules.getCarrierPrivilegeStatus}. 560 */ 561 public int getCarrierPrivilegeStatus(PackageManager packageManager, String packageName) { 562 return mCarrierPrivilegeRules == null ? 563 TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED : 564 mCarrierPrivilegeRules.getCarrierPrivilegeStatus(packageManager, packageName); 565 } 566 567 /** 568 * Exposes {@link UiccCarrierPrivilegeRules.getCarrierPrivilegeStatusForCurrentTransaction}. 569 */ 570 public int getCarrierPrivilegeStatusForCurrentTransaction(PackageManager packageManager) { 571 return mCarrierPrivilegeRules == null ? 572 TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED : 573 mCarrierPrivilegeRules.getCarrierPrivilegeStatusForCurrentTransaction(packageManager); 574 } 575 576 /** 577 * Exposes {@link UiccCarrierPrivilegeRules.getCarrierPackageNamesForIntent}. 578 */ 579 public List<String> getCarrierPackageNamesForIntent( 580 PackageManager packageManager, Intent intent) { 581 return mCarrierPrivilegeRules == null ? null : 582 mCarrierPrivilegeRules.getCarrierPackageNamesForIntent( 583 packageManager, intent); 584 } 585 586 public boolean setOperatorBrandOverride(String brand) { 587 log("setOperatorBrandOverride: " + brand); 588 log("current iccId: " + getIccId()); 589 590 String iccId = getIccId(); 591 if (TextUtils.isEmpty(iccId)) { 592 return false; 593 } 594 595 SharedPreferences.Editor spEditor = 596 PreferenceManager.getDefaultSharedPreferences(mContext).edit(); 597 String key = OPERATOR_BRAND_OVERRIDE_PREFIX + iccId; 598 if (brand == null) { 599 spEditor.remove(key).commit(); 600 } else { 601 spEditor.putString(key, brand).commit(); 602 } 603 return true; 604 } 605 606 public String getOperatorBrandOverride() { 607 String iccId = getIccId(); 608 if (TextUtils.isEmpty(iccId)) { 609 return null; 610 } 611 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); 612 return sp.getString(OPERATOR_BRAND_OVERRIDE_PREFIX + iccId, null); 613 } 614 615 public String getIccId() { 616 // ICCID should be same across all the apps. 617 for (UiccCardApplication app : mUiccApplications) { 618 if (app != null) { 619 IccRecords ir = app.getIccRecords(); 620 if (ir != null && ir.getIccId() != null) { 621 return ir.getIccId(); 622 } 623 } 624 } 625 return null; 626 } 627 628 private void log(String msg) { 629 Rlog.d(LOG_TAG, msg); 630 } 631 632 private void loge(String msg) { 633 Rlog.e(LOG_TAG, msg); 634 } 635 636 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 637 pw.println("UiccCard:"); 638 pw.println(" mCi=" + mCi); 639 pw.println(" mLastRadioState=" + mLastRadioState); 640 pw.println(" mCatService=" + mCatService); 641 pw.println(" mAbsentRegistrants: size=" + mAbsentRegistrants.size()); 642 for (int i = 0; i < mAbsentRegistrants.size(); i++) { 643 pw.println(" mAbsentRegistrants[" + i + "]=" 644 + ((Registrant)mAbsentRegistrants.get(i)).getHandler()); 645 } 646 for (int i = 0; i < mCarrierPrivilegeRegistrants.size(); i++) { 647 pw.println(" mCarrierPrivilegeRegistrants[" + i + "]=" 648 + ((Registrant)mCarrierPrivilegeRegistrants.get(i)).getHandler()); 649 } 650 pw.println(" mCardState=" + mCardState); 651 pw.println(" mUniversalPinState=" + mUniversalPinState); 652 pw.println(" mGsmUmtsSubscriptionAppIndex=" + mGsmUmtsSubscriptionAppIndex); 653 pw.println(" mCdmaSubscriptionAppIndex=" + mCdmaSubscriptionAppIndex); 654 pw.println(" mImsSubscriptionAppIndex=" + mImsSubscriptionAppIndex); 655 pw.println(" mImsSubscriptionAppIndex=" + mImsSubscriptionAppIndex); 656 pw.println(" mUiccApplications: length=" + mUiccApplications.length); 657 for (int i = 0; i < mUiccApplications.length; i++) { 658 if (mUiccApplications[i] == null) { 659 pw.println(" mUiccApplications[" + i + "]=" + null); 660 } else { 661 pw.println(" mUiccApplications[" + i + "]=" 662 + mUiccApplications[i].getType() + " " + mUiccApplications[i]); 663 } 664 } 665 pw.println(); 666 // Print details of all applications 667 for (UiccCardApplication app : mUiccApplications) { 668 if (app != null) { 669 app.dump(fd, pw, args); 670 pw.println(); 671 } 672 } 673 // Print details of all IccRecords 674 for (UiccCardApplication app : mUiccApplications) { 675 if (app != null) { 676 IccRecords ir = app.getIccRecords(); 677 if (ir != null) { 678 ir.dump(fd, pw, args); 679 pw.println(); 680 } 681 } 682 } 683 // Print UiccCarrierPrivilegeRules and registrants. 684 if (mCarrierPrivilegeRules == null) { 685 pw.println(" mCarrierPrivilegeRules: null"); 686 } else { 687 pw.println(" mCarrierPrivilegeRules: " + mCarrierPrivilegeRules); 688 mCarrierPrivilegeRules.dump(fd, pw, args); 689 } 690 pw.println(" mCarrierPrivilegeRegistrants: size=" + mCarrierPrivilegeRegistrants.size()); 691 for (int i = 0; i < mCarrierPrivilegeRegistrants.size(); i++) { 692 pw.println(" mCarrierPrivilegeRegistrants[" + i + "]=" 693 + ((Registrant)mCarrierPrivilegeRegistrants.get(i)).getHandler()); 694 } 695 pw.flush(); 696 } 697} 698