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