UiccCard.java revision d720945f2be5ea5fe0faf67e67d9ea0e184eba67
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 52e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka/** 53e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * {@hide} 54e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka */ 55e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkapublic class UiccCard { 56e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka protected static final String LOG_TAG = "RIL_UiccCard"; 57e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka protected static final boolean DBG = true; 58e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 59e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private final Object mLock = new Object(); 60e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private CardState mCardState; 61e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private PinState mUniversalPinState; 62e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private int mGsmUmtsSubscriptionAppIndex; 63e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private int mCdmaSubscriptionAppIndex; 64e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private int mImsSubscriptionAppIndex; 65e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private UiccCardApplication[] mUiccApplications = 66e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka new UiccCardApplication[IccCardStatus.CARD_MAX_APPS]; 67e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private Context mContext; 68e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private CommandsInterface mCi; 69e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private CatService mCatService; 70e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private boolean mDestroyed = false; //set to true once this card is commanded to be disposed of. 71e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private RadioState mLastRadioState = RadioState.RADIO_UNAVAILABLE; 72e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 73e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private RegistrantList mAbsentRegistrants = new RegistrantList(); 74e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 75e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private static final int EVENT_CARD_REMOVED = 13; 76e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private static final int EVENT_CARD_ADDED = 14; 77e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 78e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public UiccCard(Context c, CommandsInterface ci, IccCardStatus ics) { 79e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("Creating"); 80e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCardState = ics.mCardState; 81e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka update(c, ci, ics); 82e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 83e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 84e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void dispose() { 85e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 86e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("Disposing card"); 87e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mCatService != null) mCatService.dispose(); 88e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka for (UiccCardApplication app : mUiccApplications) { 89e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (app != null) { 90e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka app.dispose(); 91e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 92e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 93e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCatService = null; 94e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mUiccApplications = null; 95e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 96e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 97e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 98e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void update(Context c, CommandsInterface ci, IccCardStatus ics) { 99e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 100e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mDestroyed) { 101e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka loge("Updated after destroyed! Fix me!"); 102e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return; 103e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 104e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka CardState oldState = mCardState; 105e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCardState = ics.mCardState; 106e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mUniversalPinState = ics.mUniversalPinState; 107e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mGsmUmtsSubscriptionAppIndex = ics.mGsmUmtsSubscriptionAppIndex; 108e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCdmaSubscriptionAppIndex = ics.mCdmaSubscriptionAppIndex; 109e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mImsSubscriptionAppIndex = ics.mImsSubscriptionAppIndex; 110e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mContext = c; 111e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCi = ci; 112e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka //update applications 113e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log(ics.mApplications.length + " applications"); 114e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka for ( int i = 0; i < mUiccApplications.length; i++) { 115e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mUiccApplications[i] == null) { 116e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka //Create newly added Applications 117e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (i < ics.mApplications.length) { 118e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mUiccApplications[i] = new UiccCardApplication(this, 119e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka ics.mApplications[i], mContext, mCi); 120e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 121e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } else if (i >= ics.mApplications.length) { 122e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka //Delete removed applications 123e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mUiccApplications[i].dispose(); 124e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mUiccApplications[i] = null; 125e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } else { 126e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka //Update the rest 127e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mUiccApplications[i].update(ics.mApplications[i], mContext, mCi); 128e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 129e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 130e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 131e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mUiccApplications.length > 0 && mUiccApplications[0] != null) { 132e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Initialize or Reinitialize CatService 133e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCatService = CatService.getInstance(mCi, 134e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mContext, 135e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka this); 136e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } else { 137e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mCatService != null) { 138e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCatService.dispose(); 139e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 140e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCatService = null; 141e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 142e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 143e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka sanitizeApplicationIndexes(); 144e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 145e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka RadioState radioState = mCi.getRadioState(); 146e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("update: radioState=" + radioState + " mLastRadioState=" 147e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka + mLastRadioState); 148e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // No notifications while radio is off or we just powering up 149e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (radioState == RadioState.RADIO_ON && mLastRadioState == RadioState.RADIO_ON) { 150e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (oldState != CardState.CARDSTATE_ABSENT && 151e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCardState == CardState.CARDSTATE_ABSENT) { 152e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("update: notify card removed"); 153e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mAbsentRegistrants.notifyRegistrants(); 154e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_REMOVED, null)); 155e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } else if (oldState == CardState.CARDSTATE_ABSENT && 156e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCardState != CardState.CARDSTATE_ABSENT) { 157e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("update: notify card added"); 158e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_ADDED, null)); 159e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 160e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 161e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mLastRadioState = radioState; 162e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 163e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 164e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 165e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka protected void finalize() { 166e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("UiccCard finalized"); 167e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 168e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 169e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka /** 170e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * This function makes sure that application indexes are valid 171e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * and resets invalid indexes. (This should never happen, but in case 172e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * RIL misbehaves we need to manage situation gracefully) 173e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka */ 174e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private void sanitizeApplicationIndexes() { 175e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mGsmUmtsSubscriptionAppIndex = 176e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka checkIndex(mGsmUmtsSubscriptionAppIndex, AppType.APPTYPE_SIM, AppType.APPTYPE_USIM); 177e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCdmaSubscriptionAppIndex = 178e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka checkIndex(mCdmaSubscriptionAppIndex, AppType.APPTYPE_RUIM, AppType.APPTYPE_CSIM); 179e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mImsSubscriptionAppIndex = 180e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka checkIndex(mImsSubscriptionAppIndex, AppType.APPTYPE_ISIM, null); 181e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 182e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 183e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private int checkIndex(int index, AppType expectedAppType, AppType altExpectedAppType) { 184e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mUiccApplications == null || index >= mUiccApplications.length) { 185e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka loge("App index " + index + " is invalid since there are no applications"); 186e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return -1; 187e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 188e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 189e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (index < 0) { 190e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // This is normal. (i.e. no application of this type) 191e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return -1; 192e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 193e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 194e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mUiccApplications[index].getType() != expectedAppType && 195e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mUiccApplications[index].getType() != altExpectedAppType) { 196e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka loge("App index " + index + " is invalid since it's not " + 197e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka expectedAppType + " and not " + altExpectedAppType); 198e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return -1; 199e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 200e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 201e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Seems to be valid 202e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return index; 203e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 204e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 205e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka /** 206e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * Notifies handler of any transition into State.ABSENT 207e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka */ 208e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void registerForAbsent(Handler h, int what, Object obj) { 209e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 210e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka Registrant r = new Registrant (h, what, obj); 211e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 212e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mAbsentRegistrants.add(r); 213e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 214e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mCardState == CardState.CARDSTATE_ABSENT) { 215e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka r.notifyRegistrant(); 216e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 217e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 218e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 219e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 220e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void unregisterForAbsent(Handler h) { 221e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 222e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mAbsentRegistrants.remove(h); 223e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 224e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 225e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 226e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private void onIccSwap(boolean isAdded) { 227e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 228e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // TODO: Here we assume the device can't handle SIM hot-swap 229e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // and has to reboot. We may want to add a property, 230e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // e.g. REBOOT_ON_SIM_SWAP, to indicate if modem support 231e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // hot-swap. 232e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka DialogInterface.OnClickListener listener = null; 233e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 234e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 235e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // TODO: SimRecords is not reset while SIM ABSENT (only reset while 236e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Radio_off_or_not_available). Have to reset in both both 237e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // added or removed situation. 238e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka listener = new DialogInterface.OnClickListener() { 239e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka @Override 240e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void onClick(DialogInterface dialog, int which) { 241e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 242e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (which == DialogInterface.BUTTON_POSITIVE) { 243e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("Reboot due to SIM swap"); 244e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka PowerManager pm = (PowerManager) mContext 245e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka .getSystemService(Context.POWER_SERVICE); 246e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka pm.reboot("SIM is added."); 247e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 248e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 249e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 250e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 251e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka }; 252e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 253e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka Resources r = Resources.getSystem(); 254e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 255e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka String title = (isAdded) ? r.getString(R.string.sim_added_title) : 256e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka r.getString(R.string.sim_removed_title); 257e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka String message = (isAdded) ? r.getString(R.string.sim_added_message) : 258e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka r.getString(R.string.sim_removed_message); 259e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka String buttonTxt = r.getString(R.string.sim_restart_button); 260e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 261e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka AlertDialog dialog = new AlertDialog.Builder(mContext) 262e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka .setTitle(title) 263e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka .setMessage(message) 264e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka .setPositiveButton(buttonTxt, listener) 265e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka .create(); 266e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); 267e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka dialog.show(); 268e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 269e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 270e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 271e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka protected Handler mHandler = new Handler() { 272e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka @Override 273e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void handleMessage(Message msg){ 274e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mDestroyed) { 275e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka loge("Received message " + msg + "[" + msg.what 276e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka + "] while being destroyed. Ignoring."); 277e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return; 278e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 279e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 280e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka switch (msg.what) { 281e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case EVENT_CARD_REMOVED: 282e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka onIccSwap(false); 283e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 284e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case EVENT_CARD_ADDED: 285e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka onIccSwap(true); 286e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 287e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka default: 288e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka loge("Unknown Event " + msg.what); 289e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 290e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 291e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka }; 292e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 293e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public boolean isApplicationOnIcc(IccCardApplicationStatus.AppType type) { 294e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 295e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka for (int i = 0 ; i < mUiccApplications.length; i++) { 296e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mUiccApplications[i] != null && mUiccApplications[i].getType() == type) { 297e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return true; 298e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 299e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 300e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return false; 301e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 302e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 303e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 304e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public CardState getCardState() { 305e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 306e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mCardState; 307e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 308e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 309e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 310e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public PinState getUniversalPinState() { 311e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 312e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mUniversalPinState; 313e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 314e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 315e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 316e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public UiccCardApplication getApplication(int family) { 317e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 318e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int index = IccCardStatus.CARD_MAX_APPS; 319e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka switch (family) { 320e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case UiccController.APP_FAM_3GPP: 321e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka index = mGsmUmtsSubscriptionAppIndex; 322e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 323e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case UiccController.APP_FAM_3GPP2: 324e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka index = mCdmaSubscriptionAppIndex; 325e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 326e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case UiccController.APP_FAM_IMS: 327e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka index = mImsSubscriptionAppIndex; 328e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 329e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 330e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (index >= 0 && index < mUiccApplications.length) { 331e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mUiccApplications[index]; 332e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 333e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return null; 334e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 335e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 336e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 337e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public UiccCardApplication getApplicationIndex(int index) { 338e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 339e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (index >= 0 && index < mUiccApplications.length) { 340e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mUiccApplications[index]; 341e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 342e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return null; 343e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 344e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 345e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 346e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private void log(String msg) { 347ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, msg); 348e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 349e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 350e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private void loge(String msg) { 351ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, msg); 352e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 353e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka} 354