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; 25390c357ab9e1300f03d7477bf9d86bf67a3c8413Amit Mahajanimport android.os.SystemProperties; 26a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.TelephonyManager; 27ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Savilleimport android.telephony.Rlog; 28c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 29e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.CommandsInterface; 30a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.PhoneConstants; 31a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.SubscriptionController; 32e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 3305ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenkaimport java.io.FileDescriptor; 3405ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenkaimport java.io.PrintWriter; 3505ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka 36e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka/** 37e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * This class is responsible for keeping all knowledge about 38e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * Universal Integrated Circuit Card (UICC), also know as SIM's, 39e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * in the system. It is also used as API to get appropriate 40c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * applications to pass them to phone and service trackers. 41e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * 42e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * UiccController is created with the call to make() function. 43e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * UiccController is a singleton and make() must only be called once 44e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * and throws an exception if called multiple times. 45e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * 46e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * Once created UiccController registers with RIL for "on" and "unsol_sim_status_changed" 47e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * notifications. When such notification arrives UiccController will call 48e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * getIccCardStatus (GET_SIM_STATUS). Based on the response of GET_SIM_STATUS 49e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * request appropriate tree of uicc objects will be created. 50e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * 51e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * Following is class diagram for uicc classes: 52e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * 53e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * UiccController 54e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * # 55e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * | 56e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * UiccCard 57e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * # # 58e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * | ------------------ 59e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * UiccCardApplication CatService 60e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * # # 61e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * | | 62e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * IccRecords IccFileHandler 63e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * ^ ^ ^ ^ ^ ^ ^ ^ 64e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * SIMRecords---- | | | | | | ---SIMFileHandler 65e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * RuimRecords----- | | | | ----RuimFileHandler 66e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * IsimUiccRecords--- | | -----UsimFileHandler 67e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * | ------CsimFileHandler 68e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * ----IsimFileHandler 69e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * 70e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * Legend: # stands for Composition 71e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * ^ stands for Generalization 72e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * 73e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * See also {@link com.android.internal.telephony.IccCard} 74cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville * and {@link com.android.internal.telephony.uicc.IccCardProxy} 75c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 76bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenkapublic class UiccController extends Handler { 77c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final boolean DBG = true; 78cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville private static final String LOG_TAG = "UiccController"; 79c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 80e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public static final int APP_FAM_3GPP = 1; 81e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public static final int APP_FAM_3GPP2 = 2; 82e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public static final int APP_FAM_IMS = 3; 83e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 84bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka private static final int EVENT_ICC_STATUS_CHANGED = 1; 85bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka private static final int EVENT_GET_ICC_STATUS_DONE = 2; 865d8e4457b03d166aa249989916b66a85df898516Steven Liu private static final int EVENT_RADIO_UNAVAILABLE = 3; 8762648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal private static final int EVENT_SIM_REFRESH = 4; 88bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka 89390c357ab9e1300f03d7477bf9d86bf67a3c8413Amit Mahajan private static final String DECRYPT_STATE = "trigger_restart_framework"; 90390c357ab9e1300f03d7477bf9d86bf67a3c8413Amit Mahajan 91a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private CommandsInterface[] mCis; 92a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private UiccCard[] mUiccCards = new UiccCard[TelephonyManager.getDefault().getPhoneCount()]; 93a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 94e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private static final Object mLock = new Object(); 95c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static UiccController mInstance; 96c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 97e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private Context mContext; 98bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka 99a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville protected RegistrantList mIccChangedRegistrants = new RegistrantList(); 100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 101a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public static UiccController make(Context c, CommandsInterface[] ci) { 102a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville synchronized (mLock) { 103a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (mInstance != null) { 104a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville throw new RuntimeException("MSimUiccController.make() should only be called once"); 105a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 106a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mInstance = new UiccController(c, ci); 107a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return (UiccController)mInstance; 108a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 109a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 110a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 111a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private UiccController(Context c, CommandsInterface []ci) { 112a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (DBG) log("Creating UiccController"); 113a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mContext = c; 114a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mCis = ci; 115a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville for (int i = 0; i < mCis.length; i++) { 116a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Integer index = new Integer(i); 117a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mCis[i].registerForIccStatusChanged(this, EVENT_ICC_STATUS_CHANGED, index); 118a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // TODO remove this once modem correctly notifies the unsols 119390c357ab9e1300f03d7477bf9d86bf67a3c8413Amit Mahajan if (DECRYPT_STATE.equals(SystemProperties.get("vold.decrypt"))) { 120390c357ab9e1300f03d7477bf9d86bf67a3c8413Amit Mahajan mCis[i].registerForAvailable(this, EVENT_ICC_STATUS_CHANGED, index); 121390c357ab9e1300f03d7477bf9d86bf67a3c8413Amit Mahajan } else { 122390c357ab9e1300f03d7477bf9d86bf67a3c8413Amit Mahajan mCis[i].registerForOn(this, EVENT_ICC_STATUS_CHANGED, index); 123390c357ab9e1300f03d7477bf9d86bf67a3c8413Amit Mahajan } 1245d8e4457b03d166aa249989916b66a85df898516Steven Liu mCis[i].registerForNotAvailable(this, EVENT_RADIO_UNAVAILABLE, index); 12562648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal mCis[i].registerForIccRefresh(this, EVENT_SIM_REFRESH, index); 126a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 127a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 128c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 129bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka public static UiccController getInstance() { 130e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 131e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mInstance == null) { 132e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka throw new RuntimeException( 133e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka "UiccController.getInstance can't be called before make()"); 134e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 135e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mInstance; 136e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 137e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 138e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 139062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal public UiccCard getUiccCard(int phoneId) { 140e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 141062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal if (isValidCardIndex(phoneId)) { 142062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal return mUiccCards[phoneId]; 143e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 144e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return null; 145e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 146bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka } 147bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka 148a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public UiccCard[] getUiccCards() { 149a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Return cloned array since we don't want to give out reference 150a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // to internal data structure. 151a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville synchronized (mLock) { 152a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return mUiccCards.clone(); 153a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 154a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 155a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 156a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Easy to use API 157062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal public IccRecords getIccRecords(int phoneId, int family) { 158a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville synchronized (mLock) { 159062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal UiccCardApplication app = getUiccCardApplication(phoneId, family); 160a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (app != null) { 161a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return app.getIccRecords(); 162a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 163a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return null; 164a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 165a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 166a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 167a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Easy to use API 168062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal public IccFileHandler getIccFileHandler(int phoneId, int family) { 169a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville synchronized (mLock) { 170062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal UiccCardApplication app = getUiccCardApplication(phoneId, family); 171a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (app != null) { 172a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return app.getIccFileHandler(); 173a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 174a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return null; 175a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 176a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 177a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 178c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 179bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka //Notifies when card status changes 180bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka public void registerForIccChanged(Handler h, int what, Object obj) { 181e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 182e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka Registrant r = new Registrant (h, what, obj); 183e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mIccChangedRegistrants.add(r); 184e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka //Notify registrant right after registering, so that it will get the latest ICC status, 185e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka //otherwise which may not happen until there is an actual change in ICC status. 186e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka r.notifyRegistrant(); 187e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 188bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka } 189e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 190bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka public void unregisterForIccChanged(Handler h) { 191e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 192e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mIccChangedRegistrants.remove(h); 193e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 194bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka } 195bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka 196bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka @Override 197bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka public void handleMessage (Message msg) { 198e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka synchronized (mLock) { 199a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Integer index = getCiIndex(msg); 200a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 201a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (index < 0 || index >= mCis.length) { 202a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Rlog.e(LOG_TAG, "Invalid index : " + index + " received with event " + msg.what); 203a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return; 204a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 205a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 20662648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal AsyncResult ar = (AsyncResult)msg.obj; 207e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka switch (msg.what) { 208e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case EVENT_ICC_STATUS_CHANGED: 209e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("Received EVENT_ICC_STATUS_CHANGED, calling getIccCardStatus"); 210a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mCis[index].getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE, index)); 211e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 212e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case EVENT_GET_ICC_STATUS_DONE: 213e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("Received EVENT_GET_ICC_STATUS_DONE"); 214a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville onGetIccCardStatusDone(ar, index); 215e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 2165d8e4457b03d166aa249989916b66a85df898516Steven Liu case EVENT_RADIO_UNAVAILABLE: 2175d8e4457b03d166aa249989916b66a85df898516Steven Liu if (DBG) log("EVENT_RADIO_UNAVAILABLE, dispose card"); 2185d8e4457b03d166aa249989916b66a85df898516Steven Liu if (mUiccCards[index] != null) { 2195d8e4457b03d166aa249989916b66a85df898516Steven Liu mUiccCards[index].dispose(); 2205d8e4457b03d166aa249989916b66a85df898516Steven Liu } 2215d8e4457b03d166aa249989916b66a85df898516Steven Liu mUiccCards[index] = null; 2225d8e4457b03d166aa249989916b66a85df898516Steven Liu mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null)); 2235d8e4457b03d166aa249989916b66a85df898516Steven Liu break; 22462648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal case EVENT_SIM_REFRESH: 22562648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal if (DBG) log("Received EVENT_SIM_REFRESH"); 22662648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal onSimRefresh(ar, index); 22762648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal break; 228e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka default: 229ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, " Unknown Event " + msg.what); 230e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 231bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka } 232bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka } 233bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka 234a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private Integer getCiIndex(Message msg) { 235a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville AsyncResult ar; 236a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Integer index = new Integer(PhoneConstants.DEFAULT_CARD_INDEX); 237a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 238a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville /* 239a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * The events can be come in two ways. By explicitly sending it using 240a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * sendMessage, in this case the user object passed is msg.obj and from 241a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * the CommandsInterface, in this case the user object is msg.obj.userObj 242a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville */ 243a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (msg != null) { 244a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (msg.obj != null && msg.obj instanceof Integer) { 245a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville index = (Integer)msg.obj; 246a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else if(msg.obj != null && msg.obj instanceof AsyncResult) { 247a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville ar = (AsyncResult)msg.obj; 248a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (ar.userObj != null && ar.userObj instanceof Integer) { 249a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville index = (Integer)ar.userObj; 250a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 251a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 252a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 253a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return index; 254a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 255a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 256a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Easy to use API 257062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal public UiccCardApplication getUiccCardApplication(int phoneId, int family) { 258a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville synchronized (mLock) { 259062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal if (isValidCardIndex(phoneId)) { 260062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal UiccCard c = mUiccCards[phoneId]; 261a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (c != null) { 262062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal return mUiccCards[phoneId].getApplication(family); 263a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 264a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 265a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return null; 266a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 267a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 268a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 269a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private synchronized void onGetIccCardStatusDone(AsyncResult ar, Integer index) { 270bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka if (ar.exception != null) { 271ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG,"Error getting ICC status. " 272bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka + "RIL_REQUEST_GET_ICC_STATUS should " 273bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka + "never return an error", ar.exception); 274bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka return; 275c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 276a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (!isValidCardIndex(index)) { 277a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Rlog.e(LOG_TAG,"onGetIccCardStatusDone: invalid index : " + index); 278a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return; 279a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 280c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 281bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka IccCardStatus status = (IccCardStatus)ar.result; 282bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka 283a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (mUiccCards[index] == null) { 284e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka //Create new card 285a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mUiccCards[index] = new UiccCard(mContext, mCis[index], status, index); 286e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } else { 287e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka //Update already existing card 288a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mUiccCards[index].update(mContext, mCis[index] , status); 289bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka } 290bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka 291bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka if (DBG) log("Notifying IccChangedRegistrants"); 292a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null)); 293a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 294a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 295a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 29662648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal private void onSimRefresh(AsyncResult ar, Integer index) { 29762648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal if (ar.exception != null) { 29862648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal Rlog.e(LOG_TAG, "Sim REFRESH with exception: " + ar.exception); 29962648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal return; 30062648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal } 30162648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal 30262648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal if (!isValidCardIndex(index)) { 30362648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal Rlog.e(LOG_TAG,"onSimRefresh: invalid index : " + index); 30462648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal return; 30562648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal } 30662648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal 30762648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal IccRefreshResponse resp = (IccRefreshResponse) ar.result; 30862648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal Rlog.d(LOG_TAG, "onSimRefresh: " + resp); 30962648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal 31062648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal if (mUiccCards[index] == null) { 31162648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal Rlog.e(LOG_TAG,"onSimRefresh: refresh on null card : " + index); 31262648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal return; 31362648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal } 31462648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal 31562648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal if (resp.refreshResult != IccRefreshResponse.REFRESH_RESULT_RESET || 31662648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal resp.aid == null) { 31762648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal Rlog.d(LOG_TAG, "Ignoring reset: " + resp); 31862648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal return; 31962648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal } 32062648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal 32162648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal boolean changed = mUiccCards[index].resetAppWithAid(resp.aid); 32262648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal if (changed) { 32362648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal boolean requirePowerOffOnSimRefreshReset = mContext.getResources().getBoolean( 32462648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal com.android.internal.R.bool.config_requireRadioPowerOffOnSimRefreshReset); 32562648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal if (requirePowerOffOnSimRefreshReset) { 32662648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal mCis[index].setRadioPower(false, null); 32762648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal } else { 32862648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal mCis[index].getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE)); 32962648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal } 33062648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null)); 33162648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal } 33262648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal // TODO: For a card level notification, we should delete the CarrierPrivilegeRules and the 33362648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal // CAT service. 33462648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal } 33562648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal 336a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private boolean isValidCardIndex(int index) { 337a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return (index >= 0 && index < mUiccCards.length); 338bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka } 339bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka 340c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private void log(String string) { 341ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, string); 342c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 34305ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka 344a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 34505ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 34605ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println("UiccController: " + this); 34705ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mContext=" + mContext); 34805ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mInstance=" + mInstance); 34905ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mIccChangedRegistrants: size=" + mIccChangedRegistrants.size()); 35005ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka for (int i = 0; i < mIccChangedRegistrants.size(); i++) { 35105ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mIccChangedRegistrants[" + i + "]=" 35205ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka + ((Registrant)mIccChangedRegistrants.get(i)).getHandler()); 35305ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka } 35405ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(); 35505ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.flush(); 35638aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal pw.println(" mUiccCards: size=" + mUiccCards.length); 35738aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal for (int i = 0; i < mUiccCards.length; i++) { 35838aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal if (mUiccCards[i] == null) { 35938aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal pw.println(" mUiccCards[" + i + "]=null"); 36038aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal } else { 36138aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal pw.println(" mUiccCards[" + i + "]=" + mUiccCards[i]); 36238aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal mUiccCards[i].dump(fd, pw, args); 36338aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal } 36438aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal } 36505ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka } 366bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka} 367