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 android.app.AlertDialog; 20 import android.app.usage.UsageStatsManager; 21 import android.content.ActivityNotFoundException; 22 import android.content.ComponentName; 23 import android.content.Context; 24 import android.content.DialogInterface; 25 import android.content.Intent; 26 import android.content.SharedPreferences; 27 import android.content.pm.PackageInfo; 28 import android.content.pm.PackageManager; 29 import android.content.pm.Signature; 30 import android.content.res.Resources; 31 import android.net.Uri; 32 import android.os.AsyncResult; 33 import android.os.Binder; 34 import android.os.Handler; 35 import android.os.Message; 36 import android.os.PowerManager; 37 import android.os.Registrant; 38 import android.os.RegistrantList; 39 import android.preference.PreferenceManager; 40 import android.provider.Settings; 41 import android.telephony.Rlog; 42 import android.telephony.TelephonyManager; 43 import android.text.TextUtils; 44 import android.util.LocalLog; 45 import android.view.WindowManager; 46 47 import com.android.internal.R; 48 import com.android.internal.telephony.CommandsInterface; 49 import com.android.internal.telephony.CommandsInterface.RadioState; 50 import com.android.internal.telephony.cat.CatService; 51 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType; 52 import com.android.internal.telephony.uicc.IccCardStatus.CardState; 53 import com.android.internal.telephony.uicc.IccCardStatus.PinState; 54 55 import java.io.FileDescriptor; 56 import java.io.PrintWriter; 57 import java.util.Arrays; 58 import java.util.HashSet; 59 import java.util.List; 60 61 /** 62 * {@hide} 63 */ 64 public class UiccCard { 65 protected static final String LOG_TAG = "UiccCard"; 66 protected static final boolean DBG = true; 67 68 public static final String EXTRA_ICC_CARD_ADDED = 69 "com.android.internal.telephony.uicc.ICC_CARD_ADDED"; 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 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 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 115 protected UiccCard() { 116 } 117 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 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 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 212 public CatService getCatService() { 213 return mCatService; 214 } 215 216 @Override 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 */ 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 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 */ 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 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 */ 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 293 public void unregisterForCarrierPrivilegeRulesLoaded(Handler h) { 294 synchronized (mLock) { 295 mCarrierPrivilegeRegistrants.remove(h); 296 } 297 } 298 299 private void onIccSwap(boolean isAdded) { 300 301 boolean isHotSwapSupported = mContext.getResources().getBoolean( 302 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 promptForRestart(isAdded); 311 } 312 313 private void promptForRestart(boolean isAdded) { 314 synchronized (mLock) { 315 final Resources res = mContext.getResources(); 316 final String dialogComponent = res.getString( 317 R.string.config_iccHotswapPromptForRestartDialogComponent); 318 if (dialogComponent != null) { 319 Intent intent = new Intent().setComponent(ComponentName.unflattenFromString( 320 dialogComponent)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 321 .putExtra(EXTRA_ICC_CARD_ADDED, isAdded); 322 try { 323 mContext.startActivity(intent); 324 return; 325 } catch (ActivityNotFoundException e) { 326 loge("Unable to find ICC hotswap prompt for restart activity: " + e); 327 } 328 } 329 330 // TODO: Here we assume the device can't handle SIM hot-swap 331 // and has to reboot. We may want to add a property, 332 // e.g. REBOOT_ON_SIM_SWAP, to indicate if modem support 333 // hot-swap. 334 DialogInterface.OnClickListener listener = null; 335 336 337 // TODO: SimRecords is not reset while SIM ABSENT (only reset while 338 // Radio_off_or_not_available). Have to reset in both both 339 // added or removed situation. 340 listener = new DialogInterface.OnClickListener() { 341 @Override 342 public void onClick(DialogInterface dialog, int which) { 343 synchronized (mLock) { 344 if (which == DialogInterface.BUTTON_POSITIVE) { 345 if (DBG) log("Reboot due to SIM swap"); 346 PowerManager pm = (PowerManager) mContext 347 .getSystemService(Context.POWER_SERVICE); 348 pm.reboot("SIM is added."); 349 } 350 } 351 } 352 353 }; 354 355 Resources r = Resources.getSystem(); 356 357 String title = (isAdded) ? r.getString(R.string.sim_added_title) : 358 r.getString(R.string.sim_removed_title); 359 String message = (isAdded) ? r.getString(R.string.sim_added_message) : 360 r.getString(R.string.sim_removed_message); 361 String buttonTxt = r.getString(R.string.sim_restart_button); 362 363 AlertDialog dialog = new AlertDialog.Builder(mContext) 364 .setTitle(title) 365 .setMessage(message) 366 .setPositiveButton(buttonTxt, listener) 367 .create(); 368 dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); 369 dialog.show(); 370 } 371 } 372 373 protected Handler mHandler = new Handler() { 374 @Override 375 public void handleMessage(Message msg){ 376 switch (msg.what) { 377 case EVENT_CARD_REMOVED: 378 onIccSwap(false); 379 break; 380 case EVENT_CARD_ADDED: 381 onIccSwap(true); 382 break; 383 case EVENT_OPEN_LOGICAL_CHANNEL_DONE: 384 case EVENT_CLOSE_LOGICAL_CHANNEL_DONE: 385 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE: 386 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE: 387 case EVENT_SIM_IO_DONE: 388 AsyncResult ar = (AsyncResult)msg.obj; 389 if (ar.exception != null) { 390 loglocal("Exception: " + ar.exception); 391 log("Error in SIM access with exception" + ar.exception); 392 } 393 AsyncResult.forMessage((Message)ar.userObj, ar.result, ar.exception); 394 ((Message)ar.userObj).sendToTarget(); 395 break; 396 case EVENT_CARRIER_PRIVILIGES_LOADED: 397 onCarrierPriviligesLoadedMessage(); 398 break; 399 default: 400 loge("Unknown Event " + msg.what); 401 } 402 } 403 }; 404 405 private boolean isPackageInstalled(String pkgName) { 406 PackageManager pm = mContext.getPackageManager(); 407 try { 408 pm.getPackageInfo(pkgName, PackageManager.GET_ACTIVITIES); 409 if (DBG) log(pkgName + " is installed."); 410 return true; 411 } catch (PackageManager.NameNotFoundException e) { 412 if (DBG) log(pkgName + " is not installed."); 413 return false; 414 } 415 } 416 417 private class ClickListener implements DialogInterface.OnClickListener { 418 String pkgName; 419 public ClickListener(String pkgName) { 420 this.pkgName = pkgName; 421 } 422 @Override 423 public void onClick(DialogInterface dialog, int which) { 424 synchronized (mLock) { 425 if (which == DialogInterface.BUTTON_POSITIVE) { 426 Intent market = new Intent(Intent.ACTION_VIEW); 427 market.setData(Uri.parse("market://details?id=" + pkgName)); 428 market.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 429 mContext.startActivity(market); 430 } else if (which == DialogInterface.BUTTON_NEGATIVE) { 431 if (DBG) log("Not now clicked for carrier app dialog."); 432 } 433 } 434 } 435 } 436 437 private void promptInstallCarrierApp(String pkgName) { 438 DialogInterface.OnClickListener listener = new ClickListener(pkgName); 439 440 Resources r = Resources.getSystem(); 441 String message = r.getString(R.string.carrier_app_dialog_message); 442 String buttonTxt = r.getString(R.string.carrier_app_dialog_button); 443 String notNowTxt = r.getString(R.string.carrier_app_dialog_not_now); 444 445 AlertDialog dialog = new AlertDialog.Builder(mContext) 446 .setMessage(message) 447 .setNegativeButton(notNowTxt, listener) 448 .setPositiveButton(buttonTxt, listener) 449 .create(); 450 dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); 451 dialog.show(); 452 } 453 454 private void onCarrierPriviligesLoadedMessage() { 455 UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService( 456 Context.USAGE_STATS_SERVICE); 457 if (usm != null) { 458 usm.onCarrierPrivilegedAppsChanged(); 459 } 460 synchronized (mLock) { 461 mCarrierPrivilegeRegistrants.notifyRegistrants(); 462 String whitelistSetting = Settings.Global.getString(mContext.getContentResolver(), 463 Settings.Global.CARRIER_APP_WHITELIST); 464 if (TextUtils.isEmpty(whitelistSetting)) { 465 return; 466 } 467 HashSet<String> carrierAppSet = new HashSet<String>( 468 Arrays.asList(whitelistSetting.split("\\s*;\\s*"))); 469 if (carrierAppSet.isEmpty()) { 470 return; 471 } 472 473 List<String> pkgNames = mCarrierPrivilegeRules.getPackageNames(); 474 for (String pkgName : pkgNames) { 475 if (!TextUtils.isEmpty(pkgName) && carrierAppSet.contains(pkgName) 476 && !isPackageInstalled(pkgName)) { 477 promptInstallCarrierApp(pkgName); 478 } 479 } 480 } 481 } 482 483 public boolean isApplicationOnIcc(IccCardApplicationStatus.AppType type) { 484 synchronized (mLock) { 485 for (int i = 0 ; i < mUiccApplications.length; i++) { 486 if (mUiccApplications[i] != null && mUiccApplications[i].getType() == type) { 487 return true; 488 } 489 } 490 return false; 491 } 492 } 493 494 public CardState getCardState() { 495 synchronized (mLock) { 496 return mCardState; 497 } 498 } 499 500 public PinState getUniversalPinState() { 501 synchronized (mLock) { 502 return mUniversalPinState; 503 } 504 } 505 506 public UiccCardApplication getApplication(int family) { 507 synchronized (mLock) { 508 int index = IccCardStatus.CARD_MAX_APPS; 509 switch (family) { 510 case UiccController.APP_FAM_3GPP: 511 index = mGsmUmtsSubscriptionAppIndex; 512 break; 513 case UiccController.APP_FAM_3GPP2: 514 index = mCdmaSubscriptionAppIndex; 515 break; 516 case UiccController.APP_FAM_IMS: 517 index = mImsSubscriptionAppIndex; 518 break; 519 } 520 if (index >= 0 && index < mUiccApplications.length) { 521 return mUiccApplications[index]; 522 } 523 return null; 524 } 525 } 526 527 public UiccCardApplication getApplicationIndex(int index) { 528 synchronized (mLock) { 529 if (index >= 0 && index < mUiccApplications.length) { 530 return mUiccApplications[index]; 531 } 532 return null; 533 } 534 } 535 536 /** 537 * Returns the SIM application of the specified type. 538 * 539 * @param type ICC application type (@see com.android.internal.telephony.PhoneConstants#APPTYPE_xxx) 540 * @return application corresponding to type or a null if no match found 541 */ 542 public UiccCardApplication getApplicationByType(int type) { 543 synchronized (mLock) { 544 for (int i = 0 ; i < mUiccApplications.length; i++) { 545 if (mUiccApplications[i] != null && 546 mUiccApplications[i].getType().ordinal() == type) { 547 return mUiccApplications[i]; 548 } 549 } 550 return null; 551 } 552 } 553 554 /** 555 * Resets the application with the input AID. Returns true if any changes were made. 556 * 557 * A null aid implies a card level reset - all applications must be reset. 558 */ 559 public boolean resetAppWithAid(String aid) { 560 synchronized (mLock) { 561 boolean changed = false; 562 for (int i = 0; i < mUiccApplications.length; i++) { 563 if (mUiccApplications[i] != null 564 && (TextUtils.isEmpty(aid) || aid.equals(mUiccApplications[i].getAid()))) { 565 // Delete removed applications 566 mUiccApplications[i].dispose(); 567 mUiccApplications[i] = null; 568 changed = true; 569 } 570 } 571 return changed; 572 } 573 // TODO: For a card level notification, we should delete the CarrierPrivilegeRules and the 574 // CAT service. 575 } 576 577 /** 578 * Exposes {@link CommandsInterface.iccOpenLogicalChannel} 579 */ 580 public void iccOpenLogicalChannel(String AID, int p2, Message response) { 581 loglocal("Open Logical Channel: " + AID + " , " + p2 + " by pid:" + Binder.getCallingPid() 582 + " uid:" + Binder.getCallingUid()); 583 mCi.iccOpenLogicalChannel(AID, p2, 584 mHandler.obtainMessage(EVENT_OPEN_LOGICAL_CHANNEL_DONE, response)); 585 } 586 587 /** 588 * Exposes {@link CommandsInterface.iccCloseLogicalChannel} 589 */ 590 public void iccCloseLogicalChannel(int channel, Message response) { 591 loglocal("Close Logical Channel: " + channel); 592 mCi.iccCloseLogicalChannel(channel, 593 mHandler.obtainMessage(EVENT_CLOSE_LOGICAL_CHANNEL_DONE, response)); 594 } 595 596 /** 597 * Exposes {@link CommandsInterface.iccTransmitApduLogicalChannel} 598 */ 599 public void iccTransmitApduLogicalChannel(int channel, int cla, int command, 600 int p1, int p2, int p3, String data, Message response) { 601 mCi.iccTransmitApduLogicalChannel(channel, cla, command, p1, p2, p3, 602 data, mHandler.obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE, response)); 603 } 604 605 /** 606 * Exposes {@link CommandsInterface.iccTransmitApduBasicChannel} 607 */ 608 public void iccTransmitApduBasicChannel(int cla, int command, 609 int p1, int p2, int p3, String data, Message response) { 610 mCi.iccTransmitApduBasicChannel(cla, command, p1, p2, p3, 611 data, mHandler.obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE, response)); 612 } 613 614 /** 615 * Exposes {@link CommandsInterface.iccIO} 616 */ 617 public void iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3, 618 String pathID, Message response) { 619 mCi.iccIO(command, fileID, pathID, p1, p2, p3, null, null, 620 mHandler.obtainMessage(EVENT_SIM_IO_DONE, response)); 621 } 622 623 /** 624 * Exposes {@link CommandsInterface.sendEnvelopeWithStatus} 625 */ 626 public void sendEnvelopeWithStatus(String contents, Message response) { 627 mCi.sendEnvelopeWithStatus(contents, response); 628 } 629 630 /* Returns number of applications on this card */ 631 public int getNumApplications() { 632 int count = 0; 633 for (UiccCardApplication a : mUiccApplications) { 634 if (a != null) { 635 count++; 636 } 637 } 638 return count; 639 } 640 641 public int getPhoneId() { 642 return mPhoneId; 643 } 644 645 /** 646 * Returns true iff carrier privileges rules are null (dont need to be loaded) or loaded. 647 */ 648 public boolean areCarrierPriviligeRulesLoaded() { 649 return mCarrierPrivilegeRules == null 650 || mCarrierPrivilegeRules.areCarrierPriviligeRulesLoaded(); 651 } 652 653 /** 654 * Returns true if there are some carrier privilege rules loaded and specified. 655 */ 656 public boolean hasCarrierPrivilegeRules() { 657 return mCarrierPrivilegeRules != null 658 && mCarrierPrivilegeRules.hasCarrierPrivilegeRules(); 659 } 660 661 /** 662 * Exposes {@link UiccCarrierPrivilegeRules.getCarrierPrivilegeStatus}. 663 */ 664 public int getCarrierPrivilegeStatus(Signature signature, String packageName) { 665 return mCarrierPrivilegeRules == null ? 666 TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED : 667 mCarrierPrivilegeRules.getCarrierPrivilegeStatus(signature, packageName); 668 } 669 670 /** 671 * Exposes {@link UiccCarrierPrivilegeRules.getCarrierPrivilegeStatus}. 672 */ 673 public int getCarrierPrivilegeStatus(PackageManager packageManager, String packageName) { 674 return mCarrierPrivilegeRules == null ? 675 TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED : 676 mCarrierPrivilegeRules.getCarrierPrivilegeStatus(packageManager, packageName); 677 } 678 679 /** 680 * Exposes {@link UiccCarrierPrivilegeRules.getCarrierPrivilegeStatus}. 681 */ 682 public int getCarrierPrivilegeStatus(PackageInfo packageInfo) { 683 return mCarrierPrivilegeRules == null ? 684 TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED : 685 mCarrierPrivilegeRules.getCarrierPrivilegeStatus(packageInfo); 686 } 687 688 /** 689 * Exposes {@link UiccCarrierPrivilegeRules.getCarrierPrivilegeStatusForCurrentTransaction}. 690 */ 691 public int getCarrierPrivilegeStatusForCurrentTransaction(PackageManager packageManager) { 692 return mCarrierPrivilegeRules == null ? 693 TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED : 694 mCarrierPrivilegeRules.getCarrierPrivilegeStatusForCurrentTransaction(packageManager); 695 } 696 697 /** 698 * Exposes {@link UiccCarrierPrivilegeRules.getCarrierPackageNamesForIntent}. 699 */ 700 public List<String> getCarrierPackageNamesForIntent( 701 PackageManager packageManager, Intent intent) { 702 return mCarrierPrivilegeRules == null ? null : 703 mCarrierPrivilegeRules.getCarrierPackageNamesForIntent( 704 packageManager, intent); 705 } 706 707 public boolean setOperatorBrandOverride(String brand) { 708 log("setOperatorBrandOverride: " + brand); 709 log("current iccId: " + getIccId()); 710 711 String iccId = getIccId(); 712 if (TextUtils.isEmpty(iccId)) { 713 return false; 714 } 715 716 SharedPreferences.Editor spEditor = 717 PreferenceManager.getDefaultSharedPreferences(mContext).edit(); 718 String key = OPERATOR_BRAND_OVERRIDE_PREFIX + iccId; 719 if (brand == null) { 720 spEditor.remove(key).commit(); 721 } else { 722 spEditor.putString(key, brand).commit(); 723 } 724 return true; 725 } 726 727 public String getOperatorBrandOverride() { 728 String iccId = getIccId(); 729 if (TextUtils.isEmpty(iccId)) { 730 return null; 731 } 732 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); 733 return sp.getString(OPERATOR_BRAND_OVERRIDE_PREFIX + iccId, null); 734 } 735 736 public String getIccId() { 737 // ICCID should be same across all the apps. 738 for (UiccCardApplication app : mUiccApplications) { 739 if (app != null) { 740 IccRecords ir = app.getIccRecords(); 741 if (ir != null && ir.getIccId() != null) { 742 return ir.getIccId(); 743 } 744 } 745 } 746 return null; 747 } 748 749 private void log(String msg) { 750 Rlog.d(LOG_TAG, msg); 751 } 752 753 private void loge(String msg) { 754 Rlog.e(LOG_TAG, msg); 755 } 756 757 private void loglocal(String msg) { 758 if (DBG) mLocalLog.log(msg); 759 } 760 761 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 762 pw.println("UiccCard:"); 763 pw.println(" mCi=" + mCi); 764 pw.println(" mLastRadioState=" + mLastRadioState); 765 pw.println(" mCatService=" + mCatService); 766 pw.println(" mAbsentRegistrants: size=" + mAbsentRegistrants.size()); 767 for (int i = 0; i < mAbsentRegistrants.size(); i++) { 768 pw.println(" mAbsentRegistrants[" + i + "]=" 769 + ((Registrant)mAbsentRegistrants.get(i)).getHandler()); 770 } 771 for (int i = 0; i < mCarrierPrivilegeRegistrants.size(); i++) { 772 pw.println(" mCarrierPrivilegeRegistrants[" + i + "]=" 773 + ((Registrant)mCarrierPrivilegeRegistrants.get(i)).getHandler()); 774 } 775 pw.println(" mCardState=" + mCardState); 776 pw.println(" mUniversalPinState=" + mUniversalPinState); 777 pw.println(" mGsmUmtsSubscriptionAppIndex=" + mGsmUmtsSubscriptionAppIndex); 778 pw.println(" mCdmaSubscriptionAppIndex=" + mCdmaSubscriptionAppIndex); 779 pw.println(" mImsSubscriptionAppIndex=" + mImsSubscriptionAppIndex); 780 pw.println(" mImsSubscriptionAppIndex=" + mImsSubscriptionAppIndex); 781 pw.println(" mUiccApplications: length=" + mUiccApplications.length); 782 for (int i = 0; i < mUiccApplications.length; i++) { 783 if (mUiccApplications[i] == null) { 784 pw.println(" mUiccApplications[" + i + "]=" + null); 785 } else { 786 pw.println(" mUiccApplications[" + i + "]=" 787 + mUiccApplications[i].getType() + " " + mUiccApplications[i]); 788 } 789 } 790 pw.println(); 791 // Print details of all applications 792 for (UiccCardApplication app : mUiccApplications) { 793 if (app != null) { 794 app.dump(fd, pw, args); 795 pw.println(); 796 } 797 } 798 // Print details of all IccRecords 799 for (UiccCardApplication app : mUiccApplications) { 800 if (app != null) { 801 IccRecords ir = app.getIccRecords(); 802 if (ir != null) { 803 ir.dump(fd, pw, args); 804 pw.println(); 805 } 806 } 807 } 808 // Print UiccCarrierPrivilegeRules and registrants. 809 if (mCarrierPrivilegeRules == null) { 810 pw.println(" mCarrierPrivilegeRules: null"); 811 } else { 812 pw.println(" mCarrierPrivilegeRules: " + mCarrierPrivilegeRules); 813 mCarrierPrivilegeRules.dump(fd, pw, args); 814 } 815 pw.println(" mCarrierPrivilegeRegistrants: size=" + mCarrierPrivilegeRegistrants.size()); 816 for (int i = 0; i < mCarrierPrivilegeRegistrants.size(); i++) { 817 pw.println(" mCarrierPrivilegeRegistrants[" + i + "]=" 818 + ((Registrant)mCarrierPrivilegeRegistrants.get(i)).getHandler()); 819 } 820 pw.flush(); 821 pw.println("mLocalLog:"); 822 mLocalLog.dump(fd, pw, args); 823 pw.flush(); 824 } 825 } 826