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