UiccController.java revision 5d8e4457b03d166aa249989916b66a85df898516
1c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/* 2e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * Copyright (C) 2011-2012 The Android Open Source Project 3c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 4c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Licensed under the Apache License, Version 2.0 (the "License"); 5c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * you may not use this file except in compliance with the License. 6c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * You may obtain a copy of the License at 7c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 8c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * http://www.apache.org/licenses/LICENSE-2.0 9c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 10c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Unless required by applicable law or agreed to in writing, software 11c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * distributed under the License is distributed on an "AS IS" BASIS, 12c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * See the License for the specific language governing permissions and 14c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * limitations under the License. 15c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 16c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 17c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepackage com.android.internal.telephony.uicc; 18c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 19e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport android.content.Context; 20bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenkaimport android.os.AsyncResult; 21bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenkaimport android.os.Handler; 22bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenkaimport android.os.Message; 23bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenkaimport android.os.Registrant; 24bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenkaimport android.os.RegistrantList; 25a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.TelephonyManager; 26ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Savilleimport android.telephony.Rlog; 27c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 28e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.CommandsInterface; 29a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.PhoneConstants; 30a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.SubscriptionController; 31e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 3205ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenkaimport java.io.FileDescriptor; 3305ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenkaimport java.io.PrintWriter; 3405ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka 35e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka/** 36e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * This class is responsible for keeping all knowledge about 37e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * Universal Integrated Circuit Card (UICC), also know as SIM's, 38e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * in the system. It is also used as API to get appropriate 39c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * applications to pass them to phone and service trackers. 40e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * 41e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * UiccController is created with the call to make() function. 42e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * UiccController is a singleton and make() must only be called once 43e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * and throws an exception if called multiple times. 44e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * 45e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * Once created UiccController registers with RIL for "on" and "unsol_sim_status_changed" 46e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * notifications. When such notification arrives UiccController will call 47e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * getIccCardStatus (GET_SIM_STATUS). Based on the response of GET_SIM_STATUS 48e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * request appropriate tree of uicc objects will be created. 49e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * 50e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * Following is class diagram for uicc classes: 51e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * 52e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * UiccController 53e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * # 54e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * | 55e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * UiccCard 56e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * # # 57e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * | ------------------ 58e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * UiccCardApplication CatService 59e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * # # 60e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * | | 61e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * IccRecords IccFileHandler 62e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * ^ ^ ^ ^ ^ ^ ^ ^ 63e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * SIMRecords---- | | | | | | ---SIMFileHandler 64e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * RuimRecords----- | | | | ----RuimFileHandler 65e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * IsimUiccRecords--- | | -----UsimFileHandler 66e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * | ------CsimFileHandler 67e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * ----IsimFileHandler 68e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * 69e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * Legend: # stands for Composition 70e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * ^ stands for Generalization 71e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * 72e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * See also {@link com.android.internal.telephony.IccCard} 73cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville * and {@link com.android.internal.telephony.uicc.IccCardProxy} 74c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 75bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenkapublic class UiccController extends Handler { 76c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final boolean DBG = true; 77cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville private static final String LOG_TAG = "UiccController"; 78c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 79e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public static final int APP_FAM_3GPP = 1; 80e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public static final int APP_FAM_3GPP2 = 2; 81e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public static final int APP_FAM_IMS = 3; 82e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 83bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka private static final int EVENT_ICC_STATUS_CHANGED = 1; 84bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka private static final int EVENT_GET_ICC_STATUS_DONE = 2; 855d8e4457b03d166aa249989916b66a85df898516Steven Liu private static final int EVENT_RADIO_UNAVAILABLE = 3; 86bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka 87a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private CommandsInterface[] mCis; 88a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private UiccCard[] mUiccCards = new UiccCard[TelephonyManager.getDefault().getPhoneCount()]; 89a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 90e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private static final Object mLock = new Object(); 91c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static UiccController mInstance; 92c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 93e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private Context mContext; 94a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville/* 95bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka private CommandsInterface mCi; 96e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private UiccCard mUiccCard; 97a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville*/ 98bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka 99a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville protected RegistrantList mIccChangedRegistrants = new RegistrantList(); 100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 101a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville/* 102e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public static UiccController make(Context c, CommandsInterface ci) { 103e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 104e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mInstance != null) { 105e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka throw new RuntimeException("UiccController.make() should only be called once"); 106e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 107e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mInstance = new UiccController(c, ci); 108e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mInstance; 109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 110c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 111a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville*/ 112a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 113a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public static UiccController make(Context c, CommandsInterface[] ci) { 114a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville synchronized (mLock) { 115a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (mInstance != null) { 116a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville throw new RuntimeException("MSimUiccController.make() should only be called once"); 117a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 118a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mInstance = new UiccController(c, ci); 119a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return (UiccController)mInstance; 120a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 121a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 122a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 123a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private UiccController(Context c, CommandsInterface []ci) { 124a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (DBG) log("Creating UiccController"); 125a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mContext = c; 126a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mCis = ci; 127a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville for (int i = 0; i < mCis.length; i++) { 128a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Integer index = new Integer(i); 129a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mCis[i].registerForIccStatusChanged(this, EVENT_ICC_STATUS_CHANGED, index); 130a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // TODO remove this once modem correctly notifies the unsols 131a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mCis[i].registerForAvailable(this, EVENT_ICC_STATUS_CHANGED, index); 1325d8e4457b03d166aa249989916b66a85df898516Steven Liu mCis[i].registerForNotAvailable(this, EVENT_RADIO_UNAVAILABLE, index); 133a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 134a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 135c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 136bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka public static UiccController getInstance() { 137e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 138e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mInstance == null) { 139e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka throw new RuntimeException( 140e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka "UiccController.getInstance can't be called before make()"); 141e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 142e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mInstance; 143e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 144e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 145e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 146e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public UiccCard getUiccCard() { 147a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return getUiccCard(SubscriptionController.getInstance().getPhoneId(SubscriptionController.getInstance().getDefaultSubId())); 148e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 149e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 150a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public UiccCard getUiccCard(int slotId) { 151e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 152a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (isValidCardIndex(slotId)) { 153a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return mUiccCards[slotId]; 154e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 155e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return null; 156e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 157bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka } 158bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka 159a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public UiccCard[] getUiccCards() { 160a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Return cloned array since we don't want to give out reference 161a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // to internal data structure. 162a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville synchronized (mLock) { 163a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return mUiccCards.clone(); 164a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 165a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 166a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 167a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Easy to use API 168a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public UiccCardApplication getUiccCardApplication(int family) { 169a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return getUiccCardApplication(SubscriptionController.getInstance().getPhoneId(SubscriptionController.getInstance().getDefaultSubId()), family); 170a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 171a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 172a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville/* 173e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Easy to use API 174e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public IccRecords getIccRecords(int family) { 175e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 176e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mUiccCard != null) { 177e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka UiccCardApplication app = mUiccCard.getApplication(family); 178e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (app != null) { 179e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return app.getIccRecords(); 180e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 181e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 182e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return null; 183e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 184e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 185a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville*/ 186e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 187e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Easy to use API 188a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public IccRecords getIccRecords(int slotId, int family) { 189a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville synchronized (mLock) { 190a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville UiccCardApplication app = getUiccCardApplication(slotId, family); 191a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (app != null) { 192a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return app.getIccRecords(); 193a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 194a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return null; 195a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 196a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 197a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 198a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville/* 199a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Easy to use API 200e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public IccFileHandler getIccFileHandler(int family) { 201e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 202e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mUiccCard != null) { 203e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka UiccCardApplication app = mUiccCard.getApplication(family); 204e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (app != null) { 205e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return app.getIccFileHandler(); 206e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 207e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 208e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return null; 209e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 210c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 211a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville*/ 212a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 213a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Easy to use API 214a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public IccFileHandler getIccFileHandler(int slotId, int family) { 215a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville synchronized (mLock) { 216a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville UiccCardApplication app = getUiccCardApplication(slotId, family); 217a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (app != null) { 218a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return app.getIccFileHandler(); 219a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 220a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return null; 221a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 222a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 223a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 224c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 225bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka //Notifies when card status changes 226bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka public void registerForIccChanged(Handler h, int what, Object obj) { 227e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 228e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka Registrant r = new Registrant (h, what, obj); 229e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mIccChangedRegistrants.add(r); 230e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka //Notify registrant right after registering, so that it will get the latest ICC status, 231e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka //otherwise which may not happen until there is an actual change in ICC status. 232e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka r.notifyRegistrant(); 233e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 234bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka } 235e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 236bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka public void unregisterForIccChanged(Handler h) { 237e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 238e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mIccChangedRegistrants.remove(h); 239e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 240bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka } 241bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka 242bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka @Override 243bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka public void handleMessage (Message msg) { 244e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 245a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Integer index = getCiIndex(msg); 246a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 247a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (index < 0 || index >= mCis.length) { 248a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Rlog.e(LOG_TAG, "Invalid index : " + index + " received with event " + msg.what); 249a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return; 250a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 251a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 252e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka switch (msg.what) { 253e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case EVENT_ICC_STATUS_CHANGED: 254e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("Received EVENT_ICC_STATUS_CHANGED, calling getIccCardStatus"); 255a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mCis[index].getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE, index)); 256e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 257e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case EVENT_GET_ICC_STATUS_DONE: 258e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("Received EVENT_GET_ICC_STATUS_DONE"); 259e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka AsyncResult ar = (AsyncResult)msg.obj; 260a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville onGetIccCardStatusDone(ar, index); 261e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 2625d8e4457b03d166aa249989916b66a85df898516Steven Liu case EVENT_RADIO_UNAVAILABLE: 2635d8e4457b03d166aa249989916b66a85df898516Steven Liu if (DBG) log("EVENT_RADIO_UNAVAILABLE, dispose card"); 2645d8e4457b03d166aa249989916b66a85df898516Steven Liu if (mUiccCards[index] != null) { 2655d8e4457b03d166aa249989916b66a85df898516Steven Liu mUiccCards[index].dispose(); 2665d8e4457b03d166aa249989916b66a85df898516Steven Liu } 2675d8e4457b03d166aa249989916b66a85df898516Steven Liu mUiccCards[index] = null; 2685d8e4457b03d166aa249989916b66a85df898516Steven Liu mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null)); 2695d8e4457b03d166aa249989916b66a85df898516Steven Liu break; 270e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka default: 271ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, " Unknown Event " + msg.what); 272e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 273bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka } 274bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka } 275bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka 276a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private Integer getCiIndex(Message msg) { 277a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville AsyncResult ar; 278a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Integer index = new Integer(PhoneConstants.DEFAULT_CARD_INDEX); 279a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 280a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville /* 281a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * The events can be come in two ways. By explicitly sending it using 282a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * sendMessage, in this case the user object passed is msg.obj and from 283a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * the CommandsInterface, in this case the user object is msg.obj.userObj 284a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville */ 285a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (msg != null) { 286a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (msg.obj != null && msg.obj instanceof Integer) { 287a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville index = (Integer)msg.obj; 288a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else if(msg.obj != null && msg.obj instanceof AsyncResult) { 289a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville ar = (AsyncResult)msg.obj; 290a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (ar.userObj != null && ar.userObj instanceof Integer) { 291a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville index = (Integer)ar.userObj; 292a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 293a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 294a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 295a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return index; 296a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 297a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 298a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville/* 299e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private UiccController(Context c, CommandsInterface ci) { 300c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (DBG) log("Creating UiccController"); 301e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mContext = c; 302e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCi = ci; 303e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCi.registerForIccStatusChanged(this, EVENT_ICC_STATUS_CHANGED, null); 3041a792b265d929c27246c5b173f2f2694f30dc228Suresh Koleti // This is needed so that we query for sim status in the case when we boot in APM 3051a792b265d929c27246c5b173f2f2694f30dc228Suresh Koleti mCi.registerForAvailable(this, EVENT_ICC_STATUS_CHANGED, null); 306c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 307a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville*/ 308c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 309a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Easy to use API 310a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public UiccCardApplication getUiccCardApplication(int slotId, int family) { 311a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville synchronized (mLock) { 312a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (isValidCardIndex(slotId)) { 313a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville UiccCard c = mUiccCards[slotId]; 314a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (c != null) { 315a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return mUiccCards[slotId].getApplication(family); 316a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 317a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 318a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return null; 319a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 320a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 321a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 322a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private synchronized void onGetIccCardStatusDone(AsyncResult ar, Integer index) { 323bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka if (ar.exception != null) { 324ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG,"Error getting ICC status. " 325bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka + "RIL_REQUEST_GET_ICC_STATUS should " 326bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka + "never return an error", ar.exception); 327bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka return; 328c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 329a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (!isValidCardIndex(index)) { 330a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Rlog.e(LOG_TAG,"onGetIccCardStatusDone: invalid index : " + index); 331a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return; 332a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 333c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 334bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka IccCardStatus status = (IccCardStatus)ar.result; 335bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka 336a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (mUiccCards[index] == null) { 337e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka //Create new card 338a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mUiccCards[index] = new UiccCard(mContext, mCis[index], status, index); 339a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 340a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville/* 341a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Update the UiccCard in base class, so that if someone calls 342a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // UiccManager.getUiccCard(), it will return the default card. 343a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (index == PhoneConstants.DEFAULT_CARD_INDEX) { 344a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mUiccCard = mUiccCards[index]; 345a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 346a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville*/ 347e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } else { 348e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka //Update already existing card 349a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mUiccCards[index].update(mContext, mCis[index] , status); 350bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka } 351bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka 352bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka if (DBG) log("Notifying IccChangedRegistrants"); 353a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null)); 354a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 355a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 356a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 357a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private boolean isValidCardIndex(int index) { 358a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return (index >= 0 && index < mUiccCards.length); 359bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka } 360bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka 361c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private void log(String string) { 362ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, string); 363c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 36405ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka 365a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 36605ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 36705ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println("UiccController: " + this); 36805ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mContext=" + mContext); 36905ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mInstance=" + mInstance); 370a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// pw.println(" mCi=" + mCi); 371a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// pw.println(" mUiccCard=" + mUiccCard); 37205ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mIccChangedRegistrants: size=" + mIccChangedRegistrants.size()); 37305ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka for (int i = 0; i < mIccChangedRegistrants.size(); i++) { 37405ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mIccChangedRegistrants[" + i + "]=" 37505ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka + ((Registrant)mIccChangedRegistrants.get(i)).getHandler()); 37605ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka } 37705ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(); 37805ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.flush(); 379a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// for (int i = 0; i < mUiccCards.length; i++) { 380a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// mUiccCards[i].dump(fd, pw, args); 381a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// } 38205ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka } 383bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka} 384