1e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka/* 2e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * Copyright (C) 2006, 2012 The Android Open Source Project 3e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * 4e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * Licensed under the Apache License, Version 2.0 (the "License"); 5e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * you may not use this file except in compliance with the License. 6e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * You may obtain a copy of the License at 7e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * 8e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * http://www.apache.org/licenses/LICENSE-2.0 9e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * 10e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * Unless required by applicable law or agreed to in writing, software 11e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * distributed under the License is distributed on an "AS IS" BASIS, 12e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * See the License for the specific language governing permissions and 14e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * limitations under the License. 15e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka */ 16e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 17d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkapackage com.android.internal.telephony.uicc; 18e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 19e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport static android.Manifest.permission.READ_PHONE_STATE; 20e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.app.ActivityManagerNative; 21e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.app.AlertDialog; 22e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.content.Context; 23e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.content.DialogInterface; 24e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.content.Intent; 25e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.content.res.Resources; 26e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.os.AsyncResult; 27e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.os.Handler; 28e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.os.Message; 29e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.os.PowerManager; 30e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.os.Registrant; 31e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.os.RegistrantList; 32ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Savilleimport android.telephony.Rlog; 33e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.view.WindowManager; 34e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 35d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.CommandsInterface; 36e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.PhoneBase; 37e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.CommandsInterface.RadioState; 38e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.IccCardConstants.State; 39e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.gsm.GSMPhone; 40d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType; 41d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccCardStatus.CardState; 42d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccCardStatus.PinState; 43e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.cat.CatService; 44e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.cdma.CDMALTEPhone; 45e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.cdma.CDMAPhone; 46e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager; 47e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 48e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.os.SystemProperties; 49e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 50e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.R; 51e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 5205ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenkaimport java.io.FileDescriptor; 5305ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenkaimport java.io.PrintWriter; 5405ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka 55e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka/** 56e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * {@hide} 57e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka */ 58e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkapublic class UiccCard { 59cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville protected static final String LOG_TAG = "UiccCard"; 60e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka protected static final boolean DBG = true; 61e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 62e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private final Object mLock = new Object(); 63e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private CardState mCardState; 64e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private PinState mUniversalPinState; 65e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private int mGsmUmtsSubscriptionAppIndex; 66e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private int mCdmaSubscriptionAppIndex; 67e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private int mImsSubscriptionAppIndex; 68e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private UiccCardApplication[] mUiccApplications = 69e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka new UiccCardApplication[IccCardStatus.CARD_MAX_APPS]; 70e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private Context mContext; 71e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private CommandsInterface mCi; 72e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private CatService mCatService; 73e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private boolean mDestroyed = false; //set to true once this card is commanded to be disposed of. 74e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private RadioState mLastRadioState = RadioState.RADIO_UNAVAILABLE; 75e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 76e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private RegistrantList mAbsentRegistrants = new RegistrantList(); 77e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 78e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private static final int EVENT_CARD_REMOVED = 13; 79e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private static final int EVENT_CARD_ADDED = 14; 80e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 81e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public UiccCard(Context c, CommandsInterface ci, IccCardStatus ics) { 82e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("Creating"); 83e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCardState = ics.mCardState; 84e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka update(c, ci, ics); 85e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 86e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 87e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void dispose() { 88e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 89e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("Disposing card"); 90e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mCatService != null) mCatService.dispose(); 91e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka for (UiccCardApplication app : mUiccApplications) { 92e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (app != null) { 93e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka app.dispose(); 94e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 95e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 96e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCatService = null; 97e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mUiccApplications = null; 98e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 99e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 100e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 101e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void update(Context c, CommandsInterface ci, IccCardStatus ics) { 102e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 103e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mDestroyed) { 104e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka loge("Updated after destroyed! Fix me!"); 105e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return; 106e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 107e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka CardState oldState = mCardState; 108e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCardState = ics.mCardState; 109e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mUniversalPinState = ics.mUniversalPinState; 110e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mGsmUmtsSubscriptionAppIndex = ics.mGsmUmtsSubscriptionAppIndex; 111e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCdmaSubscriptionAppIndex = ics.mCdmaSubscriptionAppIndex; 112e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mImsSubscriptionAppIndex = ics.mImsSubscriptionAppIndex; 113e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mContext = c; 114e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCi = ci; 115e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka //update applications 116e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log(ics.mApplications.length + " applications"); 117e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka for ( int i = 0; i < mUiccApplications.length; i++) { 118e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mUiccApplications[i] == null) { 119e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka //Create newly added Applications 120e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (i < ics.mApplications.length) { 121e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mUiccApplications[i] = new UiccCardApplication(this, 122e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka ics.mApplications[i], mContext, mCi); 123e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 124e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } else if (i >= ics.mApplications.length) { 125e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka //Delete removed applications 126e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mUiccApplications[i].dispose(); 127e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mUiccApplications[i] = null; 128e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } else { 129e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka //Update the rest 130e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mUiccApplications[i].update(ics.mApplications[i], mContext, mCi); 131e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 132e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 133e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 134e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mUiccApplications.length > 0 && mUiccApplications[0] != null) { 135e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Initialize or Reinitialize CatService 136e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCatService = CatService.getInstance(mCi, 137e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mContext, 138e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka this); 139e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } else { 140e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mCatService != null) { 141e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCatService.dispose(); 142e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 143e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCatService = null; 144e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 145e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 146e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka sanitizeApplicationIndexes(); 147e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 148e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka RadioState radioState = mCi.getRadioState(); 149e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("update: radioState=" + radioState + " mLastRadioState=" 150e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka + mLastRadioState); 151e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // No notifications while radio is off or we just powering up 152e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (radioState == RadioState.RADIO_ON && mLastRadioState == RadioState.RADIO_ON) { 153e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (oldState != CardState.CARDSTATE_ABSENT && 154e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCardState == CardState.CARDSTATE_ABSENT) { 155e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("update: notify card removed"); 156e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mAbsentRegistrants.notifyRegistrants(); 157e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_REMOVED, null)); 158e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } else if (oldState == CardState.CARDSTATE_ABSENT && 159e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCardState != CardState.CARDSTATE_ABSENT) { 160e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("update: notify card added"); 161e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_ADDED, null)); 162e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 163e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 164e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mLastRadioState = radioState; 165e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 166e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 167e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 168cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 169e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka protected void finalize() { 170e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("UiccCard finalized"); 171e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 172e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 173e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka /** 174e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * This function makes sure that application indexes are valid 175e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * and resets invalid indexes. (This should never happen, but in case 176e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * RIL misbehaves we need to manage situation gracefully) 177e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka */ 178e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private void sanitizeApplicationIndexes() { 179e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mGsmUmtsSubscriptionAppIndex = 180e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka checkIndex(mGsmUmtsSubscriptionAppIndex, AppType.APPTYPE_SIM, AppType.APPTYPE_USIM); 181e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCdmaSubscriptionAppIndex = 182e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka checkIndex(mCdmaSubscriptionAppIndex, AppType.APPTYPE_RUIM, AppType.APPTYPE_CSIM); 183e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mImsSubscriptionAppIndex = 184e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka checkIndex(mImsSubscriptionAppIndex, AppType.APPTYPE_ISIM, null); 185e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 186e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 187e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private int checkIndex(int index, AppType expectedAppType, AppType altExpectedAppType) { 188e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mUiccApplications == null || index >= mUiccApplications.length) { 189e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka loge("App index " + index + " is invalid since there are no applications"); 190e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return -1; 191e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 192e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 193e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (index < 0) { 194e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // This is normal. (i.e. no application of this type) 195e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return -1; 196e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 197e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 198e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mUiccApplications[index].getType() != expectedAppType && 199e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mUiccApplications[index].getType() != altExpectedAppType) { 200e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka loge("App index " + index + " is invalid since it's not " + 201e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka expectedAppType + " and not " + altExpectedAppType); 202e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return -1; 203e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 204e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 205e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Seems to be valid 206e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return index; 207e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 208e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 209e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka /** 210e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * Notifies handler of any transition into State.ABSENT 211e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka */ 212e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void registerForAbsent(Handler h, int what, Object obj) { 213e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 214e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka Registrant r = new Registrant (h, what, obj); 215e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 216e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mAbsentRegistrants.add(r); 217e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 218e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mCardState == CardState.CARDSTATE_ABSENT) { 219e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka r.notifyRegistrant(); 220e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 221e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 222e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 223e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 224e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void unregisterForAbsent(Handler h) { 225e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 226e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mAbsentRegistrants.remove(h); 227e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 228e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 229e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 230e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private void onIccSwap(boolean isAdded) { 231e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 232e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // TODO: Here we assume the device can't handle SIM hot-swap 233e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // and has to reboot. We may want to add a property, 234e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // e.g. REBOOT_ON_SIM_SWAP, to indicate if modem support 235e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // hot-swap. 236e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka DialogInterface.OnClickListener listener = null; 237e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 238e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 239e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // TODO: SimRecords is not reset while SIM ABSENT (only reset while 240e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Radio_off_or_not_available). Have to reset in both both 241e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // added or removed situation. 242e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka listener = new DialogInterface.OnClickListener() { 243e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka @Override 244e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void onClick(DialogInterface dialog, int which) { 245e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 246e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (which == DialogInterface.BUTTON_POSITIVE) { 247e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("Reboot due to SIM swap"); 248e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka PowerManager pm = (PowerManager) mContext 249e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka .getSystemService(Context.POWER_SERVICE); 250e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka pm.reboot("SIM is added."); 251e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 252e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 253e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 254e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 255e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka }; 256e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 257e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka Resources r = Resources.getSystem(); 258e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 259e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka String title = (isAdded) ? r.getString(R.string.sim_added_title) : 260e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka r.getString(R.string.sim_removed_title); 261e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka String message = (isAdded) ? r.getString(R.string.sim_added_message) : 262e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka r.getString(R.string.sim_removed_message); 263e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka String buttonTxt = r.getString(R.string.sim_restart_button); 264e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 265e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka AlertDialog dialog = new AlertDialog.Builder(mContext) 266e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka .setTitle(title) 267e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka .setMessage(message) 268e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka .setPositiveButton(buttonTxt, listener) 269e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka .create(); 270e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); 271e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka dialog.show(); 272e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 273e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 274e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 275e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka protected Handler mHandler = new Handler() { 276e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka @Override 277e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void handleMessage(Message msg){ 278e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mDestroyed) { 279e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka loge("Received message " + msg + "[" + msg.what 280e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka + "] while being destroyed. Ignoring."); 281e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return; 282e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 283e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 284e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka switch (msg.what) { 285e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case EVENT_CARD_REMOVED: 286e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka onIccSwap(false); 287e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 288e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case EVENT_CARD_ADDED: 289e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka onIccSwap(true); 290e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 291e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka default: 292e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka loge("Unknown Event " + msg.what); 293e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 294e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 295e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka }; 296e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 297e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public boolean isApplicationOnIcc(IccCardApplicationStatus.AppType type) { 298e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 299e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka for (int i = 0 ; i < mUiccApplications.length; i++) { 300e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mUiccApplications[i] != null && mUiccApplications[i].getType() == type) { 301e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return true; 302e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 303e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 304e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return false; 305e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 306e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 307e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 308e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public CardState getCardState() { 309e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 310e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mCardState; 311e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 312e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 313e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 314e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public PinState getUniversalPinState() { 315e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 316e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mUniversalPinState; 317e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 318e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 319e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 320e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public UiccCardApplication getApplication(int family) { 321e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 322e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int index = IccCardStatus.CARD_MAX_APPS; 323e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka switch (family) { 324e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case UiccController.APP_FAM_3GPP: 325e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka index = mGsmUmtsSubscriptionAppIndex; 326e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 327e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case UiccController.APP_FAM_3GPP2: 328e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka index = mCdmaSubscriptionAppIndex; 329e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 330e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case UiccController.APP_FAM_IMS: 331e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka index = mImsSubscriptionAppIndex; 332e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 333e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 334e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (index >= 0 && index < mUiccApplications.length) { 335e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mUiccApplications[index]; 336e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 337e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return null; 338e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 339e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 340e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 341e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public UiccCardApplication getApplicationIndex(int index) { 342e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 343e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (index >= 0 && index < mUiccApplications.length) { 344e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mUiccApplications[index]; 345e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 346e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return null; 347e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 348e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 349e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 350e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private void log(String msg) { 351ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, msg); 352e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 353e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 354e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private void loge(String msg) { 355ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, msg); 356e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 35705ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka 35805ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 35905ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println("UiccCard:"); 36005ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mCi=" + mCi); 36105ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mDestroyed=" + mDestroyed); 36205ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mLastRadioState=" + mLastRadioState); 36305ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mCatService=" + mCatService); 36405ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mAbsentRegistrants: size=" + mAbsentRegistrants.size()); 36505ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka for (int i = 0; i < mAbsentRegistrants.size(); i++) { 36605ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mAbsentRegistrants[" + i + "]=" 36705ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka + ((Registrant)mAbsentRegistrants.get(i)).getHandler()); 36805ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka } 36905ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mCardState=" + mCardState); 37005ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mUniversalPinState=" + mUniversalPinState); 37105ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mGsmUmtsSubscriptionAppIndex=" + mGsmUmtsSubscriptionAppIndex); 37205ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mCdmaSubscriptionAppIndex=" + mCdmaSubscriptionAppIndex); 37305ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mImsSubscriptionAppIndex=" + mImsSubscriptionAppIndex); 37405ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mImsSubscriptionAppIndex=" + mImsSubscriptionAppIndex); 37505ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mUiccApplications: length=" + mUiccApplications.length); 37605ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka for (int i = 0; i < mUiccApplications.length; i++) { 37705ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka if (mUiccApplications[i] == null) { 37805ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mUiccApplications[" + i + "]=" + null); 37905ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka } else { 38005ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mUiccApplications[" + i + "]=" 38105ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka + mUiccApplications[i].getType() + " " + mUiccApplications[i]); 38205ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka } 38305ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka } 38405ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(); 38505ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka // Print details of all applications 38605ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka for (UiccCardApplication app : mUiccApplications) { 38705ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka if (app != null) { 38805ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka app.dump(fd, pw, args); 38905ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(); 39005ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka } 39105ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka } 39205ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka // Print details of all IccRecords 39305ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka for (UiccCardApplication app : mUiccApplications) { 39405ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka if (app != null) { 39505ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka IccRecords ir = app.getIccRecords(); 39605ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka if (ir != null) { 39705ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka ir.dump(fd, pw, args); 39805ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(); 39905ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka } 40005ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka } 40105ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka } 40205ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.flush(); 40305ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka } 404e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka} 405