• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.telephony.mockmodem;
18 
19 import static android.telephony.mockmodem.MockSimService.COMMAND_GET_RESPONSE;
20 import static android.telephony.mockmodem.MockSimService.COMMAND_READ_BINARY;
21 import static android.telephony.mockmodem.MockSimService.COMMAND_SELECT;
22 import static android.telephony.mockmodem.MockSimService.EF_GID1;
23 import static android.telephony.mockmodem.MockSimService.EF_ICCID;
24 
25 import android.hardware.radio.RadioError;
26 import android.hardware.radio.RadioIndicationType;
27 import android.hardware.radio.RadioResponseInfo;
28 import android.hardware.radio.sim.CardStatus;
29 import android.hardware.radio.sim.Carrier;
30 import android.hardware.radio.sim.CarrierInfo;
31 import android.hardware.radio.sim.CarrierRestrictions;
32 import android.hardware.radio.sim.IRadioSim;
33 import android.hardware.radio.sim.IRadioSimIndication;
34 import android.hardware.radio.sim.IRadioSimResponse;
35 import android.hardware.radio.sim.SimRefreshResult;
36 import android.os.AsyncResult;
37 import android.os.Build;
38 import android.os.Handler;
39 import android.os.Message;
40 import android.os.RemoteException;
41 import android.service.carrier.CarrierIdentifier;
42 import android.telephony.mockmodem.MockModemConfigBase.SimInfoChangedResult;
43 import android.telephony.mockmodem.MockSimService.SimAppData;
44 import android.telephony.mockmodem.MockSimService.SimIoData;
45 import android.text.TextUtils;
46 import android.util.Log;
47 
48 import com.android.internal.annotations.GuardedBy;
49 import com.android.internal.telephony.flags.Flags;
50 
51 import java.util.ArrayList;
52 import java.util.HashMap;
53 import java.util.HashSet;
54 import java.util.List;
55 import java.util.Map;
56 import java.util.Set;
57 
58 public class IRadioSimImpl extends IRadioSim.Stub {
59     private static final String TAG = "MRSIM";
60     private final MockModemService mService;
61     private IRadioSimResponse mRadioSimResponse;
62     private IRadioSimIndication mRadioSimIndication;
63     private MockModemConfigInterface mMockModemConfigInterface;
64     private Object mCacheUpdateMutex;
65     private final Handler mHandler;
66     private int mSubId;
67     private String mTag;
68 
69     // ***** Events
70     static final int EVENT_SIM_CARD_STATUS_CHANGED = 1;
71     static final int EVENT_SIM_APP_DATA_CHANGED = 2;
72     static final int EVENT_SIM_INFO_CHANGED = 3;
73     // Event indicates the pre-configured SIM IO through logical channel has changed
74     static final int EVENT_SIM_IO_DATA_CHANGED = 4;
75 
76     // Fixed logical channel number used for SIM IO to indicate no concurrent support at present
77     private static final int LOGICAL_CHANNEL_ID = 1;
78     // AID for applet that opens THE logical channel. Empty if no applet opened the logical channel
79     @GuardedBy("mCurrentAidLock")
80     private String mCurrentAid = "";
81     // Lock to present the concurrent access for the mCurrentAid
82     private final Object mCurrentAidLock = new Object();
83     // File id for the last successful SELECT(0xA4) instruction
84     private String mLastSelectedFileid = "";
85     // Cache of the AID => SimIoData map from MockSimService
86     private Map<String, List<SimIoData>> mSimIoMap = new HashMap<>();
87 
88     // ***** Cache of modem attributes/status
89     private CardStatus mCardStatus;
90     private ArrayList<SimAppData> mSimAppList;
91 
92     private Carrier[] mCarrierList;
93     private int mCarrierRestrictionStatus = CarrierRestrictions.CarrierRestrictionStatus.UNKNOWN;
94 
95     private int mMultiSimPolicy =
96             android.hardware.radio.sim.SimLockMultiSimPolicy.NO_MULTISIM_POLICY;
97     private CarrierRestrictions mCarrierRestrictionRules;
98 
IRadioSimImpl( MockModemService service, MockModemConfigInterface configInterface, int instanceId)99     public IRadioSimImpl(
100             MockModemService service, MockModemConfigInterface configInterface, int instanceId) {
101         mTag = TAG + "-" + instanceId;
102         Log.d(mTag, "Instantiated");
103 
104         this.mService = service;
105         mMockModemConfigInterface = configInterface;
106         mSubId = instanceId;
107         mCardStatus = new CardStatus();
108         mCacheUpdateMutex = new Object();
109         mHandler = new IRadioSimHandler();
110 
111         // Register events
112         mMockModemConfigInterface.registerForCardStatusChanged(
113                 mSubId, mHandler, EVENT_SIM_CARD_STATUS_CHANGED, null);
114 
115         // Register events
116         mMockModemConfigInterface.registerForSimAppDataChanged(
117                 mSubId, mHandler, EVENT_SIM_APP_DATA_CHANGED, null);
118 
119         // Register events
120         mMockModemConfigInterface.registerForSimInfoChanged(
121                 mSubId, mHandler, EVENT_SIM_INFO_CHANGED, null);
122 
123         // Register SIM IO data change events
124         mMockModemConfigInterface.registerForSimIoDataChanged(mSubId, mHandler,
125                 EVENT_SIM_IO_DATA_CHANGED, null);
126     }
127 
128     /** Handler class to handle callbacks */
129     private final class IRadioSimHandler extends Handler {
130         @Override
handleMessage(Message msg)131         public void handleMessage(Message msg) {
132             AsyncResult ar;
133             synchronized (mCacheUpdateMutex) {
134                 switch (msg.what) {
135                     case EVENT_SIM_CARD_STATUS_CHANGED:
136                         Log.d(mTag, "Received EVENT_SIM_CARD_STATUS_CHANGED");
137                         ar = (AsyncResult) msg.obj;
138                         if (ar != null && ar.exception == null) {
139                             mCardStatus = (CardStatus) ar.result;
140                             Log.i(mTag, "Sim card status: " + mCardStatus);
141                             simStatusChanged();
142                         } else {
143                             Log.e(mTag, msg.what + " failure. Exception: " + ar.exception);
144                         }
145                         break;
146 
147                     case EVENT_SIM_APP_DATA_CHANGED:
148                         Log.d(mTag, "Received EVENT_SIM_APP_DATA_CHANGED");
149                         ar = (AsyncResult) msg.obj;
150                         if (ar != null && ar.exception == null) {
151                             mSimAppList = (ArrayList<SimAppData>) ar.result;
152                             if (mSimAppList != null) {
153                                 Log.i(mTag, "number of SIM app data: " + mSimAppList.size());
154                             } else {
155                                 Log.e(mTag, "mSimAppList = null");
156                             }
157                         } else {
158                             Log.e(mTag, msg.what + " failure. Exception: " + ar.exception);
159                         }
160                         break;
161 
162                     case EVENT_SIM_INFO_CHANGED:
163                         ar = (AsyncResult) msg.obj;
164                         if (ar != null && ar.exception == null) {
165                             SimInfoChangedResult simInfoChangeResult =
166                                     (SimInfoChangedResult) ar.result;
167                             Log.d(mTag, "Received EVENT_SIM_INFO_CHANGED: " + simInfoChangeResult);
168                             SimRefreshResult simRefreshResult = new SimRefreshResult();
169                             switch (simInfoChangeResult.mSimInfoType) {
170                                 case SimInfoChangedResult.SIM_INFO_TYPE_MCC_MNC:
171                                 case SimInfoChangedResult.SIM_INFO_TYPE_IMSI:
172                                     if (simRefreshResult != null) {
173                                         simRefreshResult.type =
174                                                 SimRefreshResult.TYPE_SIM_FILE_UPDATE;
175                                         simRefreshResult.efId = simInfoChangeResult.mEfId;
176                                         simRefreshResult.aid = simInfoChangeResult.mAid;
177                                         simRefresh(simRefreshResult);
178                                     }
179                                     break;
180                             }
181                         } else {
182                             Log.e(mTag, msg.what + " failure. Exception: " + ar.exception);
183                         }
184                         break;
185                     case EVENT_SIM_IO_DATA_CHANGED:
186                         ar = (AsyncResult) msg.obj;
187                         if (ar != null && ar.exception == null) {
188                             mSimIoMap = (Map<String, List<SimIoData>>) ar.result;
189                             Log.d(mTag, "Receive EVENT_SIM_IO_DATA_CHANGED: " + mSimIoMap);
190                         }
191                         break;
192                 }
193             }
194         }
195     }
196 
197     // Implementation of IRadioSim functions
198     @Override
setResponseFunctions( IRadioSimResponse radioSimResponse, IRadioSimIndication radioSimIndication)199     public void setResponseFunctions(
200             IRadioSimResponse radioSimResponse, IRadioSimIndication radioSimIndication) {
201         Log.d(mTag, "setResponseFunctions");
202         mRadioSimResponse = radioSimResponse;
203         mRadioSimIndication = radioSimIndication;
204         mService.countDownLatch(MockModemService.LATCH_RADIO_INTERFACES_READY);
205     }
206 
207     @Override
responseAcknowledgement()208     public void responseAcknowledgement() {
209         Log.d(mTag, "responseAcknowledgement");
210         // TODO
211         // acknowledgeRequest(in int serial);
212     }
213 
214     @Override
areUiccApplicationsEnabled(int serial)215     public void areUiccApplicationsEnabled(int serial) {
216         Log.d(mTag, "areUiccApplicationsEnabled");
217 
218         boolean enabled = true;
219 
220         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
221         try {
222             mRadioSimResponse.areUiccApplicationsEnabledResponse(rsp, enabled);
223         } catch (RemoteException ex) {
224             Log.e(mTag, "Failed to areUiccApplicationsEnabled from AIDL. Exception" + ex);
225         }
226     }
227 
228     @Override
changeIccPin2ForApp(int serial, String oldPin2, String newPin2, String aid)229     public void changeIccPin2ForApp(int serial, String oldPin2, String newPin2, String aid) {
230         Log.d(mTag, "changeIccPin2ForApp");
231         // TODO: cache value
232 
233         int remainingRetries = 3;
234 
235         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
236         try {
237             mRadioSimResponse.changeIccPin2ForAppResponse(rsp, remainingRetries);
238         } catch (RemoteException ex) {
239             Log.e(mTag, "Failed to changeIccPin2ForApp from AIDL. Exception" + ex);
240         }
241     }
242 
243     @Override
changeIccPinForApp(int serial, String oldPin, String newPin, String aid)244     public void changeIccPinForApp(int serial, String oldPin, String newPin, String aid) {
245         Log.d(mTag, "changeIccPinForApp");
246         // TODO: cache value
247 
248         int remainingRetries = 3;
249 
250         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
251         try {
252             mRadioSimResponse.changeIccPinForAppResponse(rsp, remainingRetries);
253         } catch (RemoteException ex) {
254             Log.e(mTag, "Failed to changeIccPinForApp from AIDL. Exception" + ex);
255         }
256     }
257 
258     @Override
enableUiccApplications(int serial, boolean enable)259     public void enableUiccApplications(int serial, boolean enable) {
260         Log.d(mTag, "enableUiccApplications");
261         // TODO: cache value
262 
263         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
264         try {
265             mRadioSimResponse.enableUiccApplicationsResponse(rsp);
266         } catch (RemoteException ex) {
267             Log.e(mTag, "Failed to enableUiccApplications from AIDL. Exception" + ex);
268         }
269     }
270 
271     @Override
getAllowedCarriers(int serial)272     public void getAllowedCarriers(int serial) {
273         Log.d(mTag, "getAllowedCarriers");
274         RadioResponseInfo rsp = mService.makeSolRsp(serial);
275         android.hardware.radio.sim.CarrierRestrictions carriers =
276                 new android.hardware.radio.sim.CarrierRestrictions();
277         if (mCarrierList == null || mCarrierList.length < 1) {
278             carriers.allowedCarriers = new Carrier[0];
279         } else {
280             carriers.allowedCarriers = mCarrierList;
281             Log.d(mTag, "getAllowedCarriers InterfaceVersion = " +getInterfaceVersion());
282             if (getInterfaceVersion() >=3 && mCarrierList.length > 0) {
283                 carriers.allowedCarrierInfoList = new CarrierInfo[mCarrierList.length];
284                 for (int count = 0; count < mCarrierList.length; count++) {
285                     String spn = null;
286                     String imsi = null;
287                     String gid1 = null;
288                     String gid2 = null;
289                     if (mCarrierList[count].matchType == CarrierIdentifier.MatchType.GID1) {
290                         gid1 = mCarrierList[count].matchData;
291                     } else if (mCarrierList[count].matchType == CarrierIdentifier.MatchType.GID2) {
292                         gid2 = mCarrierList[count].matchData;
293                     } else if (mCarrierList[count].matchType
294                             == CarrierIdentifier.MatchType.IMSI_PREFIX) {
295                         imsi = mCarrierList[count].matchData;
296                     } else if (mCarrierList[count].matchType == CarrierIdentifier.MatchType.SPN) {
297                         spn = mCarrierList[count].matchData;
298                     }
299                     android.hardware.radio.sim.CarrierInfo carrierInfo = getCarrierInfo(
300                             mCarrierList[count].mcc, mCarrierList[count].mnc, spn, gid1, gid2, imsi,
301                             null, null, null);
302                     carriers.allowedCarrierInfoList[count] = carrierInfo;
303                 }
304             }
305         }
306         carriers.excludedCarriers = new Carrier[0];
307         if (Build.VERSION.SDK_INT > Build.VERSION_CODES.TIRAMISU) {
308             carriers.status = mCarrierRestrictionStatus;
309         }
310         if (Flags.carrierRestrictionRulesEnhancement() && mCarrierRestrictionRules != null) {
311             Log.e(mTag, "Updating carrierInfo information in CarrierRestrictions");
312             carriers.allowedCarrierInfoList = mCarrierRestrictionRules.allowedCarrierInfoList;
313             carriers.excludedCarrierInfoList = mCarrierRestrictionRules.excludedCarrierInfoList;
314         }
315         try {
316             mRadioSimResponse.getAllowedCarriersResponse(rsp, carriers, mMultiSimPolicy);
317         } catch (RemoteException ex) {
318             Log.e(mTag, "Failed to getAllowedCarriers from AIDL. Exception" + ex);
319         } finally {
320             // resetting the mCarrierRestrictionRules
321             mCarrierRestrictionRules = null;
322             mMultiSimPolicy = android.hardware.radio.sim.SimLockMultiSimPolicy.NO_MULTISIM_POLICY;
323         }
324     }
325 
326     @Override
getCdmaSubscription(int serial)327     public void getCdmaSubscription(int serial) {
328         Log.d(mTag, "getCdmaSubscription");
329 
330         String mdn = "";
331         String hSid = "";
332         String hNid = "";
333         String min = "";
334         String prl = "";
335 
336         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
337         try {
338             mRadioSimResponse.getCdmaSubscriptionResponse(rsp, mdn, hSid, hNid, min, prl);
339         } catch (RemoteException ex) {
340             Log.e(mTag, "Failed to getCdmaSubscription from AIDL. Exception" + ex);
341         }
342     }
343 
344     @Override
getCdmaSubscriptionSource(int serial)345     public void getCdmaSubscriptionSource(int serial) {
346         Log.d(mTag, "getCdmaSubscriptionSource");
347 
348         int source = 0; // CdmaSubscriptionSource.RUIM_SIM
349 
350         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
351         try {
352             mRadioSimResponse.getCdmaSubscriptionSourceResponse(rsp, source);
353         } catch (RemoteException ex) {
354             Log.e(mTag, "Failed to getCdmaSubscriptionSource from AIDL. Exception" + ex);
355         }
356     }
357 
358     @Override
getFacilityLockForApp( int serial, String facility, String password, int serviceClass, String appId)359     public void getFacilityLockForApp(
360             int serial, String facility, String password, int serviceClass, String appId) {
361         Log.d(mTag, "getFacilityLockForApp");
362         int numOfSimApp = mSimAppList.size();
363         int responseError = RadioError.NONE;
364         int simAppIdx;
365         boolean isHandled = false;
366         boolean isFacilitySupport = true;
367         int responseData = -1;
368 
369         synchronized (mCacheUpdateMutex) {
370             // TODO: check service class
371             for (simAppIdx = 0;
372                     simAppIdx < numOfSimApp && isFacilitySupport && !isHandled;
373                     simAppIdx++) {
374                 switch (facility) {
375                     case "FD": // FDN status query
376                         if (appId.equals(mSimAppList.get(simAppIdx).getAid())) {
377                             responseData = mSimAppList.get(simAppIdx).getFdnStatus();
378                             isHandled = true;
379                         }
380                         break;
381                     case "SC": // PIN1 status query
382                         if (appId.equals(mSimAppList.get(simAppIdx).getAid())) {
383                             responseData = mSimAppList.get(simAppIdx).getPin1State();
384                             isHandled = true;
385                         }
386                         break;
387                     default:
388                         isFacilitySupport = false;
389                         break;
390                 }
391             }
392         }
393 
394         if (!isHandled) {
395             Log.e(mTag, "Not support sim application aid = " + appId);
396             responseError = RadioError.NO_SUCH_ELEMENT;
397         } else if (!isFacilitySupport) {
398             Log.e(mTag, "Not support facility = " + facility);
399             responseError = RadioError.REQUEST_NOT_SUPPORTED;
400         } else if (responseData == -1) {
401             responseError = RadioError.INTERNAL_ERR;
402         }
403 
404         RadioResponseInfo rsp = mService.makeSolRsp(serial, responseError);
405         try {
406             mRadioSimResponse.getFacilityLockForAppResponse(rsp, responseData);
407         } catch (RemoteException ex) {
408             Log.e(mTag, "Failed to getFacilityLockForApp from AIDL. Exception" + ex);
409         }
410     }
411 
412     @Override
getIccCardStatus(int serial)413     public void getIccCardStatus(int serial) {
414         Log.d(mTag, "getIccCardStatus");
415         CardStatus cardStatus;
416 
417         synchronized (mCacheUpdateMutex) {
418             cardStatus = mCardStatus;
419         }
420 
421         RadioResponseInfo rsp = mService.makeSolRsp(serial);
422         try {
423             mRadioSimResponse.getIccCardStatusResponse(rsp, cardStatus);
424         } catch (RemoteException ex) {
425             Log.e(mTag, "Failed to getIccCardStatus from AIDL. Exception" + ex);
426         }
427     }
428 
429     @Override
getImsiForApp(int serial, String aid)430     public void getImsiForApp(int serial, String aid) {
431         Log.d(mTag, "getImsiForApp");
432         String imsi = "";
433         int numOfSimApp = mSimAppList.size();
434         int responseError = RadioError.NONE;
435         int simAppIdx;
436         boolean isHandled;
437 
438         synchronized (mCacheUpdateMutex) {
439             for (simAppIdx = 0, isHandled = false;
440                     simAppIdx < numOfSimApp && !isHandled;
441                     simAppIdx++) {
442                 if (aid.equals(mSimAppList.get(simAppIdx).getAid())) {
443                     imsi = mSimAppList.get(simAppIdx).getImsi();
444                     isHandled = true;
445                 }
446             }
447         }
448 
449         if (!isHandled) {
450             Log.e(mTag, "Not support sim application aid = " + aid);
451             responseError = RadioError.NO_SUCH_ELEMENT;
452         }
453 
454         RadioResponseInfo rsp = mService.makeSolRsp(serial, responseError);
455         try {
456             mRadioSimResponse.getImsiForAppResponse(rsp, imsi);
457         } catch (RemoteException ex) {
458             Log.e(mTag, "Failed to getImsiForApp from AIDL. Exception" + ex);
459         }
460     }
461 
462     @Override
getSimPhonebookCapacity(int serial)463     public void getSimPhonebookCapacity(int serial) {
464         Log.d(mTag, "getSimPhonebookCapacity");
465 
466         android.hardware.radio.sim.PhonebookCapacity capacity =
467                 new android.hardware.radio.sim.PhonebookCapacity();
468 
469         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
470         try {
471             mRadioSimResponse.getSimPhonebookCapacityResponse(rsp, capacity);
472         } catch (RemoteException ex) {
473             Log.e(mTag, "Failed to getSimPhonebookCapacity from AIDL. Exception" + ex);
474         }
475     }
476 
477     @Override
getSimPhonebookRecords(int serial)478     public void getSimPhonebookRecords(int serial) {
479         Log.d(mTag, "getSimPhonebookRecords");
480 
481         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
482         try {
483             mRadioSimResponse.getSimPhonebookRecordsResponse(rsp);
484         } catch (RemoteException ex) {
485             Log.e(mTag, "Failed to getSimPhonebookRecords from AIDL. Exception" + ex);
486         }
487     }
488 
489     @Override
iccCloseLogicalChannel(int serial, int channelId)490     public void iccCloseLogicalChannel(int serial, int channelId) {
491         Log.d(mTag, "iccCloseLogicalChannel");
492 
493         int error = RadioError.REQUEST_NOT_SUPPORTED;
494         if (channelId > 0) {
495             error = RadioError.NONE;
496             synchronized (mCurrentAidLock) {
497                 mCurrentAid = "";
498             }
499         }
500         RadioResponseInfo rsp = mService.makeSolRsp(serial, error);
501         try {
502             mRadioSimResponse.iccCloseLogicalChannelResponse(rsp);
503         } catch (RemoteException ex) {
504             Log.e(mTag, "Failed to iccCloseLogicalChannel from AIDL. Exception" + ex);
505         }
506     }
507 
508     @Override
iccCloseLogicalChannelWithSessionInfo(int serial, android.hardware.radio.sim.SessionInfo sessionInfo)509     public void iccCloseLogicalChannelWithSessionInfo(int serial,
510             android.hardware.radio.sim.SessionInfo sessionInfo) {
511         Log.d(mTag, "iccCloseLogicalChannelWithSessionInfo");
512         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
513         try {
514             mRadioSimResponse.iccCloseLogicalChannelWithSessionInfoResponse(rsp);
515         } catch (RemoteException ex) {
516             Log.e(mTag,
517                     "Failed to iccCloseLogicalChannelWithSessionInfo from AIDL. Exception" + ex);
518         }
519     }
520 
encodeBcdString(String str)521     private String encodeBcdString(String str) {
522         StringBuffer bcdString = new StringBuffer();
523 
524         if (str.length() % 2 != 0) {
525             Log.d(mTag, "Invalid string(" + str + ") for Bcd format");
526             return "";
527         }
528 
529         for (int i = 0; i < str.length(); i += 2) {
530             bcdString.append(str.substring(i + 1, i + 2));
531             bcdString.append(str.substring(i, i + 1));
532         }
533 
534         return bcdString.toString();
535     }
536 
getIccIoResult( android.hardware.radio.sim.IccIoResult iccIoResult, int command, int fileId, String path, int p1, int p2, int p3, String aid)537     private int getIccIoResult(
538             android.hardware.radio.sim.IccIoResult iccIoResult,
539             int command,
540             int fileId,
541             String path,
542             int p1,
543             int p2,
544             int p3,
545             String aid) {
546         int numOfSimApp = mSimAppList.size();
547         int simAppIdx;
548         boolean foundAid;
549         int responseError = RadioError.GENERIC_FAILURE;
550 
551         if (iccIoResult == null) {
552             return responseError;
553         }
554 
555         synchronized (mCacheUpdateMutex) {
556             for (simAppIdx = 0, foundAid = false; simAppIdx < numOfSimApp; simAppIdx++) {
557                 if (aid.equals(mSimAppList.get(simAppIdx).getAid())) {
558                     foundAid = true;
559                     break;
560                 }
561             }
562 
563             if (!foundAid) {
564                 Log.e(mTag, "Not support sim application aid = " + aid);
565                 iccIoResult.sw1 = 0x6A;
566                 iccIoResult.sw2 = 0x82;
567             } else {
568                 switch (fileId) {
569                     case EF_ICCID:
570                         if (command == COMMAND_READ_BINARY) {
571                             String bcdIccid =
572                                     encodeBcdString(mSimAppList.get(simAppIdx).getIccid());
573                             iccIoResult.simResponse = bcdIccid;
574                             Log.d(mTag, "Get IccIo result: ICCID = " + iccIoResult.simResponse);
575                             iccIoResult.sw1 = 0x90;
576                             responseError = RadioError.NONE;
577                         } else if (command == COMMAND_GET_RESPONSE) {
578                             iccIoResult.simResponse = mSimAppList.get(simAppIdx).getIccidInfo();
579                             Log.d(mTag, "Get IccIo result: ICCID = " + iccIoResult.simResponse);
580                             iccIoResult.sw1 = 0x90;
581                             responseError = RadioError.NONE;
582                         } else {
583                             Log.d(
584                                     mTag,
585                                     "Command("
586                                             + command
587                                             + ") not support for file id = 0x"
588                                             + Integer.toHexString(fileId));
589                             iccIoResult.sw1 = 0x6A;
590                             iccIoResult.sw2 = 0x82;
591                         }
592                         break;
593                     case EF_GID1:
594                         if (command == COMMAND_READ_BINARY) {
595                             String gid1 = mSimAppList.get(simAppIdx).getGid1();
596                             if (gid1 != null) {
597                                 iccIoResult.simResponse = gid1;
598                                 Log.d(
599                                         mTag,
600                                         "COMMAND_READ_BINARY result: GID1 = "
601                                                 + iccIoResult.simResponse);
602                                 iccIoResult.sw1 = 0x90;
603                                 iccIoResult.sw2 = 0x00;
604                                 responseError = RadioError.NONE;
605                             } else {
606                                 Log.d(mTag, "No COMMAND_READ_BINARY result for GID1");
607                                 iccIoResult.sw1 = 0x6A;
608                                 iccIoResult.sw2 = 0x82;
609                             }
610                         } else if (command == COMMAND_GET_RESPONSE) {
611                             String gid1Info = mSimAppList.get(simAppIdx).getGid1Info();
612                             if (gid1Info != null) {
613                                 iccIoResult.simResponse = gid1Info;
614                                 Log.d(
615                                         mTag,
616                                         "COMMAND_GET_RESPONSE result: GID1 = "
617                                                 + iccIoResult.simResponse);
618                                 iccIoResult.sw1 = 0x90;
619                                 iccIoResult.sw2 = 0x00;
620                                 responseError = RadioError.NONE;
621                             } else {
622                                 Log.d(mTag, "No COMMAND_GET_RESPONSE result for GID1");
623                                 iccIoResult.sw1 = 0x6A;
624                                 iccIoResult.sw2 = 0x82;
625                             }
626                         }
627                         break;
628                     default:
629                         Log.d(mTag, "Not find EF file id = 0x" + Integer.toHexString(fileId));
630                         iccIoResult.sw1 = 0x6A;
631                         iccIoResult.sw2 = 0x82;
632                         break;
633                 }
634             }
635         }
636 
637         return responseError;
638     }
639 
640     @Override
iccIoForApp(int serial, android.hardware.radio.sim.IccIo iccIo)641     public void iccIoForApp(int serial, android.hardware.radio.sim.IccIo iccIo) {
642         Log.d(mTag, "iccIoForApp");
643         int responseError = RadioError.NONE;
644         android.hardware.radio.sim.IccIoResult iccIoResult =
645                 new android.hardware.radio.sim.IccIoResult();
646 
647         switch (iccIo.command) {
648             case COMMAND_READ_BINARY:
649             case COMMAND_GET_RESPONSE:
650                 responseError =
651                         getIccIoResult(
652                                 iccIoResult,
653                                 iccIo.command,
654                                 iccIo.fileId,
655                                 iccIo.path,
656                                 iccIo.p1,
657                                 iccIo.p2,
658                                 iccIo.p3,
659                                 iccIo.aid);
660                 break;
661             default:
662                 responseError = RadioError.REQUEST_NOT_SUPPORTED;
663                 break;
664         }
665 
666         RadioResponseInfo rsp = mService.makeSolRsp(serial, responseError);
667         try {
668             mRadioSimResponse.iccIoForAppResponse(rsp, iccIoResult);
669         } catch (RemoteException ex) {
670             Log.e(mTag, "Failed to iccIoForApp from AIDL. Exception" + ex);
671         }
672     }
673 
674     @Override
iccOpenLogicalChannel(int serial, String aid, int p2)675     public void iccOpenLogicalChannel(int serial, String aid, int p2) {
676         Log.d(mTag, "iccOpenLogicalChannel with aid=" + aid + ", p2=" + p2);
677 
678         byte[] selectResponse = new byte[0];
679         int channelId = 0;
680         int error = RadioError.REQUEST_NOT_SUPPORTED;
681 
682         synchronized (mCurrentAidLock) {
683             if (!TextUtils.isEmpty(mCurrentAid)) {
684                 error = RadioError.NO_SUCH_ELEMENT;
685                 Log.e(mTag, "LOGIC_CHANNEL in use by " + mCurrentAid);
686             } else if (!isAidWithLogicalChannelSupported(aid)) {
687                 Log.e(mTag, "AID is not supported: " + aid);
688             } else {
689                 mCurrentAid = aid;
690                 error = RadioError.NONE;
691                 channelId = LOGICAL_CHANNEL_ID;
692                 Log.d(mTag, "LOGIC_CHANNEL open for " + aid);
693             }
694         }
695 
696         RadioResponseInfo rsp = mService.makeSolRsp(serial, error);
697         try {
698             mRadioSimResponse.iccOpenLogicalChannelResponse(rsp, channelId, selectResponse);
699         } catch (RemoteException ex) {
700             Log.e(mTag, "Failed to iccOpenLogicalChannel from AIDL. Exception" + ex);
701         }
702     }
703 
isAidWithLogicalChannelSupported(String aid)704     private boolean isAidWithLogicalChannelSupported(String aid) {
705         Log.d(mTag, "Supported AIDs: " + mSimIoMap.keySet());
706         return mSimIoMap != null && mSimIoMap.containsKey(aid);
707     }
708 
getSupportedFileIds(String aid)709     private Set<String> getSupportedFileIds(String aid) {
710         Set<String> supportedAids = new HashSet<>();
711         if (mSimIoMap != null) {
712             List<SimIoData> simIoData = mSimIoMap.get(aid);
713             if (simIoData != null) {
714                 for (SimIoData sid : simIoData) {
715                     supportedAids.add(sid.mFileId);
716                 }
717                 // empty fileId is also a valid fileid
718                 supportedAids.add("");
719             }
720         }
721         return supportedAids;
722     }
723 
getSimIoData(String fileid, String command)724     private SimIoData getSimIoData(String fileid, String command) {
725         if (TextUtils.isEmpty(fileid)) {
726             fileid = mLastSelectedFileid;
727         }
728         if (mSimIoMap != null) {
729 
730             List<SimIoData> simIoData;
731             synchronized (mCurrentAidLock) {
732                 simIoData = mSimIoMap.get(mCurrentAid);
733             }
734             if (simIoData != null) {
735                 for (SimIoData sid : simIoData) {
736                     if (fileid.equals(sid.mFileId) && command.equals(sid.mCommand)) {
737                         return sid;
738                     }
739                 }
740             }
741         }
742         return null;
743     }
744 
hexIntegerToString(int hexValue)745     private String hexIntegerToString(int hexValue) {
746         return "0x" + Integer.toHexString(hexValue);
747     }
748 
749     @Override
iccTransmitApduBasicChannel( int serial, android.hardware.radio.sim.SimApdu message)750     public void iccTransmitApduBasicChannel(
751             int serial, android.hardware.radio.sim.SimApdu message) {
752         Log.d(mTag, "iccTransmitApduBasicChannel");
753         // TODO: cache value
754         android.hardware.radio.sim.IccIoResult iccIoResult =
755                 new android.hardware.radio.sim.IccIoResult();
756 
757         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
758         try {
759             mRadioSimResponse.iccTransmitApduBasicChannelResponse(rsp, iccIoResult);
760         } catch (RemoteException ex) {
761             Log.e(mTag, "Failed to iccTransmitApduBasicChannel from AIDL. Exception" + ex);
762         }
763     }
764 
765     @Override
iccTransmitApduLogicalChannel( int serial, android.hardware.radio.sim.SimApdu message)766     public void iccTransmitApduLogicalChannel(
767             int serial, android.hardware.radio.sim.SimApdu message) {
768         int channel = message.sessionId;
769         int cmd = message.instruction;
770         String fileid = message.data;
771         Log.d(mTag, "iccTransmitApduLogicalChannel, channel=" + channel + ", cmd="
772                 + Integer.toHexString(cmd) + ", fileid=" + fileid);
773         int error = RadioError.GENERIC_FAILURE;
774         android.hardware.radio.sim.IccIoResult iccIoResult =
775                 new android.hardware.radio.sim.IccIoResult();
776 
777         final boolean isFileidSupported;
778         synchronized (mCurrentAidLock) {
779             isFileidSupported = getSupportedFileIds(mCurrentAid).contains(fileid);
780         }
781         if (channel > 0 && isFileidSupported) {
782             SimIoData simIoData = getSimIoData(fileid, hexIntegerToString(cmd));
783             if (simIoData != null) {
784                 Log.d(mTag, "Found SimIoData: " + simIoData);
785                 error = RadioError.NONE;
786                 iccIoResult.sw1 = Integer.parseInt(simIoData.mSw1.substring(2), 16);
787                 iccIoResult.sw2 = Integer.parseInt(simIoData.mSw2.substring(2), 16);
788                 iccIoResult.simResponse = simIoData.mResponse;
789 
790                 if (cmd == COMMAND_SELECT) {
791                     mLastSelectedFileid = fileid;
792                     Log.d(mTag, "Fileid SELECTEed: " + fileid);
793                 }
794             }
795         }
796 
797         RadioResponseInfo rsp = mService.makeSolRsp(serial, error);
798         try {
799             mRadioSimResponse.iccTransmitApduLogicalChannelResponse(rsp, iccIoResult);
800         } catch (RemoteException ex) {
801             Log.e(mTag, "Failed to iccTransmitApduLogicalChannel from AIDL. Exception" + ex);
802         }
803     }
804 
805     @Override
reportStkServiceIsRunning(int serial)806     public void reportStkServiceIsRunning(int serial) {
807         Log.d(mTag, "reportStkServiceIsRunning");
808 
809         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
810         try {
811             mRadioSimResponse.reportStkServiceIsRunningResponse(rsp);
812         } catch (RemoteException ex) {
813             Log.e(mTag, "Failed to reportStkServiceIsRunning from AIDL. Exception" + ex);
814         }
815     }
816 
817     @Override
requestIccSimAuthentication( int serial, int authContext, String authData, String aid)818     public void requestIccSimAuthentication(
819             int serial, int authContext, String authData, String aid) {
820         Log.d(mTag, "requestIccSimAuthentication");
821         // TODO: cache value
822         android.hardware.radio.sim.IccIoResult iccIoResult =
823                 new android.hardware.radio.sim.IccIoResult();
824 
825         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
826         try {
827             mRadioSimResponse.requestIccSimAuthenticationResponse(rsp, iccIoResult);
828         } catch (RemoteException ex) {
829             Log.e(mTag, "Failed to requestIccSimAuthentication from AIDL. Exception" + ex);
830         }
831     }
832 
833     @Override
sendEnvelope(int serial, String contents)834     public void sendEnvelope(int serial, String contents) {
835         Log.d(mTag, "sendEnvelope");
836         // TODO: cache value
837         String commandResponse = "";
838 
839         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
840         try {
841             mRadioSimResponse.sendEnvelopeResponse(rsp, commandResponse);
842         } catch (RemoteException ex) {
843             Log.e(mTag, "Failed to sendEnvelope from AIDL. Exception" + ex);
844         }
845     }
846 
847     @Override
sendEnvelopeWithStatus(int serial, String contents)848     public void sendEnvelopeWithStatus(int serial, String contents) {
849         Log.d(mTag, "sendEnvelopeWithStatus");
850         // TODO: cache value
851         android.hardware.radio.sim.IccIoResult iccIoResult =
852                 new android.hardware.radio.sim.IccIoResult();
853 
854         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
855         try {
856             mRadioSimResponse.sendEnvelopeWithStatusResponse(rsp, iccIoResult);
857         } catch (RemoteException ex) {
858             Log.e(mTag, "Failed to sendEnvelopeWithStatus from AIDL. Exception" + ex);
859         }
860     }
861 
862     @Override
sendTerminalResponseToSim(int serial, String contents)863     public void sendTerminalResponseToSim(int serial, String contents) {
864         Log.d(mTag, "sendTerminalResponseToSim");
865         // TODO: cache value
866 
867         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
868         try {
869             mRadioSimResponse.sendTerminalResponseToSimResponse(rsp);
870         } catch (RemoteException ex) {
871             Log.e(mTag, "Failed to sendTerminalResponseToSim from AIDL. Exception" + ex);
872         }
873     }
874 
875     @Override
setAllowedCarriers( int serial, android.hardware.radio.sim.CarrierRestrictions carriers, int multiSimPolicy)876     public void setAllowedCarriers(
877             int serial,
878             android.hardware.radio.sim.CarrierRestrictions carriers,
879             int multiSimPolicy) {
880         Log.d(mTag, "sendTerminalResponseToSim");
881         // TODO: cache value
882 
883         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
884         try {
885             mRadioSimResponse.setAllowedCarriersResponse(rsp);
886         } catch (RemoteException ex) {
887             Log.e(mTag, "Failed to setAllowedCarriers from AIDL. Exception" + ex);
888         }
889     }
890 
891     @Override
setCarrierInfoForImsiEncryption( int serial, android.hardware.radio.sim.ImsiEncryptionInfo imsiEncryptionInfo)892     public void setCarrierInfoForImsiEncryption(
893             int serial, android.hardware.radio.sim.ImsiEncryptionInfo imsiEncryptionInfo) {
894         Log.d(mTag, "setCarrierInfoForImsiEncryption");
895         // TODO: cache value
896 
897         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
898         try {
899             mRadioSimResponse.setCarrierInfoForImsiEncryptionResponse(rsp);
900         } catch (RemoteException ex) {
901             Log.e(mTag, "Failed to setCarrierInfoForImsiEncryption from AIDL. Exception" + ex);
902         }
903     }
904 
905     @Override
setCdmaSubscriptionSource(int serial, int cdmaSub)906     public void setCdmaSubscriptionSource(int serial, int cdmaSub) {
907         Log.d(mTag, "setCdmaSubscriptionSource");
908         // TODO: cache value
909 
910         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
911         try {
912             mRadioSimResponse.setCdmaSubscriptionSourceResponse(rsp);
913         } catch (RemoteException ex) {
914             Log.e(mTag, "Failed to setCdmaSubscriptionSource from AIDL. Exception" + ex);
915         }
916     }
917 
918     @Override
setFacilityLockForApp( int serial, String facility, boolean lockState, String password, int serviceClass, String appId)919     public void setFacilityLockForApp(
920             int serial,
921             String facility,
922             boolean lockState,
923             String password,
924             int serviceClass,
925             String appId) {
926         Log.d(mTag, "setFacilityLockForApp");
927         // TODO: cache value
928         int retry = 10;
929 
930         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
931         try {
932             mRadioSimResponse.setFacilityLockForAppResponse(rsp, retry);
933         } catch (RemoteException ex) {
934             Log.e(mTag, "Failed to setFacilityLockForApp from AIDL. Exception" + ex);
935         }
936     }
937 
938     @Override
setSimCardPower(int serial, int powerUp)939     public void setSimCardPower(int serial, int powerUp) {
940         Log.d(mTag, "setSimCardPower");
941         // TODO: cache value
942 
943         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
944         try {
945             mRadioSimResponse.setSimCardPowerResponse(rsp);
946         } catch (RemoteException ex) {
947             Log.e(mTag, "Failed to setSimCardPower from AIDL. Exception" + ex);
948         }
949     }
950 
951     @Override
setUiccSubscription(int serial, android.hardware.radio.sim.SelectUiccSub uiccSub)952     public void setUiccSubscription(int serial, android.hardware.radio.sim.SelectUiccSub uiccSub) {
953         Log.d(mTag, "setUiccSubscription");
954         // TODO: cache value
955 
956         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
957         try {
958             mRadioSimResponse.setUiccSubscriptionResponse(rsp);
959         } catch (RemoteException ex) {
960             Log.e(mTag, "Failed to setUiccSubscription from AIDL. Exception" + ex);
961         }
962     }
963 
964     @Override
supplyIccPin2ForApp(int serial, String pin2, String aid)965     public void supplyIccPin2ForApp(int serial, String pin2, String aid) {
966         Log.d(mTag, "supplyIccPin2ForApp");
967         // TODO: cache value
968         int setFacilityLockForApp = 10;
969 
970         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
971         try {
972             mRadioSimResponse.supplyIccPin2ForAppResponse(rsp, setFacilityLockForApp);
973         } catch (RemoteException ex) {
974             Log.e(mTag, "Failed to supplyIccPin2ForApp from AIDL. Exception" + ex);
975         }
976     }
977 
978     @Override
supplyIccPinForApp(int serial, String pin, String aid)979     public void supplyIccPinForApp(int serial, String pin, String aid) {
980         Log.d(mTag, "supplyIccPinForApp");
981         // TODO: cache value
982         int setFacilityLockForApp = 10;
983 
984         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
985         try {
986             mRadioSimResponse.supplyIccPinForAppResponse(rsp, setFacilityLockForApp);
987         } catch (RemoteException ex) {
988             Log.e(mTag, "Failed to supplyIccPinForApp from AIDL. Exception" + ex);
989         }
990     }
991 
992     @Override
supplyIccPuk2ForApp(int serial, String puk2, String pin2, String aid)993     public void supplyIccPuk2ForApp(int serial, String puk2, String pin2, String aid) {
994         Log.d(mTag, "supplyIccPuk2ForApp");
995         // TODO: cache value
996         int setFacilityLockForApp = 10;
997 
998         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
999         try {
1000             mRadioSimResponse.supplyIccPuk2ForAppResponse(rsp, setFacilityLockForApp);
1001         } catch (RemoteException ex) {
1002             Log.e(mTag, "Failed to supplyIccPuk2ForApp from AIDL. Exception" + ex);
1003         }
1004     }
1005 
1006     @Override
supplyIccPukForApp(int serial, String puk, String pin, String aid)1007     public void supplyIccPukForApp(int serial, String puk, String pin, String aid) {
1008         Log.d(mTag, "supplyIccPukForApp");
1009         // TODO: cache value
1010         int setFacilityLockForApp = 10;
1011 
1012         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
1013         try {
1014             mRadioSimResponse.supplyIccPukForAppResponse(rsp, setFacilityLockForApp);
1015         } catch (RemoteException ex) {
1016             Log.e(mTag, "Failed to supplyIccPukForApp from AIDL. Exception" + ex);
1017         }
1018     }
1019 
1020     @Override
supplySimDepersonalization(int serial, int persoType, String controlKey)1021     public void supplySimDepersonalization(int serial, int persoType, String controlKey) {
1022         Log.d(mTag, "supplySimDepersonalization");
1023         // TODO: cache value
1024         int retPersoType = persoType;
1025         int setFacilityLockForApp = 10;
1026 
1027         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
1028         try {
1029             mRadioSimResponse.supplySimDepersonalizationResponse(
1030                     rsp, retPersoType, setFacilityLockForApp);
1031         } catch (RemoteException ex) {
1032             Log.e(mTag, "Failed to supplySimDepersonalization from AIDL. Exception" + ex);
1033         }
1034     }
1035 
1036     @Override
updateSimPhonebookRecords( int serial, android.hardware.radio.sim.PhonebookRecordInfo recordInfo)1037     public void updateSimPhonebookRecords(
1038             int serial, android.hardware.radio.sim.PhonebookRecordInfo recordInfo) {
1039         Log.d(mTag, "updateSimPhonebookRecords");
1040         // TODO: cache value
1041         int updatedRecordIndex = 0;
1042 
1043         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
1044         try {
1045             mRadioSimResponse.updateSimPhonebookRecordsResponse(rsp, updatedRecordIndex);
1046         } catch (RemoteException ex) {
1047             Log.e(mTag, "Failed to updateSimPhonebookRecords from AIDL. Exception" + ex);
1048         }
1049     }
1050 
carrierInfoForImsiEncryption()1051     public void carrierInfoForImsiEncryption() {
1052         Log.d(mTag, "carrierInfoForImsiEncryption");
1053 
1054         if (mRadioSimIndication != null) {
1055             try {
1056                 mRadioSimIndication.carrierInfoForImsiEncryption(RadioIndicationType.UNSOLICITED);
1057             } catch (RemoteException ex) {
1058                 Log.e(mTag, "Failed to carrierInfoForImsiEncryption from AIDL. Exception" + ex);
1059             }
1060         } else {
1061             Log.e(mTag, "null mRadioSimIndication");
1062         }
1063     }
1064 
cdmaSubscriptionSourceChanged(int cdmaSource)1065     public void cdmaSubscriptionSourceChanged(int cdmaSource) {
1066         Log.d(mTag, "carrierInfoForImsiEncryption");
1067 
1068         if (mRadioSimIndication != null) {
1069             try {
1070                 mRadioSimIndication.cdmaSubscriptionSourceChanged(
1071                         RadioIndicationType.UNSOLICITED, cdmaSource);
1072             } catch (RemoteException ex) {
1073                 Log.e(mTag, "Failed to cdmaSubscriptionSourceChanged from AIDL. Exception" + ex);
1074             }
1075         } else {
1076             Log.e(mTag, "null mRadioSimIndication");
1077         }
1078     }
1079 
simPhonebookChanged()1080     public void simPhonebookChanged() {
1081         Log.d(mTag, "simPhonebookChanged");
1082 
1083         if (mRadioSimIndication != null) {
1084             try {
1085                 mRadioSimIndication.simPhonebookChanged(RadioIndicationType.UNSOLICITED);
1086             } catch (RemoteException ex) {
1087                 Log.e(mTag, "Failed to simPhonebookChanged from AIDL. Exception" + ex);
1088             }
1089         } else {
1090             Log.e(mTag, "null mRadioSimIndication");
1091         }
1092     }
1093 
simPhonebookRecordsReceived( byte status, android.hardware.radio.sim.PhonebookRecordInfo[] records)1094     public void simPhonebookRecordsReceived(
1095             byte status, android.hardware.radio.sim.PhonebookRecordInfo[] records) {
1096         Log.d(mTag, "simPhonebookRecordsReceived");
1097 
1098         if (mRadioSimIndication != null) {
1099             try {
1100                 mRadioSimIndication.simPhonebookRecordsReceived(
1101                         RadioIndicationType.UNSOLICITED, status, records);
1102             } catch (RemoteException ex) {
1103                 Log.e(mTag, "Failed to simPhonebookRecordsReceived from AIDL. Exception" + ex);
1104             }
1105         } else {
1106             Log.e(mTag, "null mRadioSimIndication");
1107         }
1108     }
1109 
simRefresh(SimRefreshResult refreshResult)1110     public void simRefresh(SimRefreshResult refreshResult) {
1111         Log.d(mTag, "simRefresh");
1112 
1113         if (mRadioSimIndication != null) {
1114             try {
1115                 mRadioSimIndication.simRefresh(RadioIndicationType.UNSOLICITED, refreshResult);
1116             } catch (RemoteException ex) {
1117                 Log.e(mTag, "Failed to simRefresh from AIDL. Exception" + ex);
1118             }
1119         } else {
1120             Log.e(mTag, "null mRadioSimIndication");
1121         }
1122     }
1123 
simStatusChanged()1124     public void simStatusChanged() {
1125         Log.d(mTag, "simStatusChanged");
1126 
1127         if (mRadioSimIndication != null) {
1128             try {
1129                 mRadioSimIndication.simStatusChanged(RadioIndicationType.UNSOLICITED);
1130             } catch (RemoteException ex) {
1131                 Log.e(mTag, "Failed to simStatusChanged from AIDL. Exception" + ex);
1132             }
1133         } else {
1134             Log.e(mTag, "null mRadioSimIndication");
1135         }
1136     }
1137 
stkEventNotify(String cmd)1138     public void stkEventNotify(String cmd) {
1139         Log.d(mTag, "stkEventNotify");
1140 
1141         if (mRadioSimIndication != null) {
1142             try {
1143                 mRadioSimIndication.stkEventNotify(RadioIndicationType.UNSOLICITED, cmd);
1144             } catch (RemoteException ex) {
1145                 Log.e(mTag, "Failed to stkEventNotify from AIDL. Exception" + ex);
1146             }
1147         } else {
1148             Log.e(mTag, "null mRadioSimIndication");
1149         }
1150     }
1151 
stkProactiveCommand(String cmd)1152     public void stkProactiveCommand(String cmd) {
1153         Log.d(mTag, "stkProactiveCommand");
1154 
1155         if (mRadioSimIndication != null) {
1156             try {
1157                 mRadioSimIndication.stkProactiveCommand(RadioIndicationType.UNSOLICITED, cmd);
1158             } catch (RemoteException ex) {
1159                 Log.e(mTag, "Failed to stkProactiveCommand from AIDL. Exception" + ex);
1160             }
1161         } else {
1162             Log.e(mTag, "null mRadioSimIndication");
1163         }
1164     }
1165 
stkSessionEnd()1166     public void stkSessionEnd() {
1167         Log.d(mTag, "stkSessionEnd");
1168 
1169         if (mRadioSimIndication != null) {
1170             try {
1171                 mRadioSimIndication.stkSessionEnd(RadioIndicationType.UNSOLICITED);
1172             } catch (RemoteException ex) {
1173                 Log.e(mTag, "Failed to stkSessionEnd from AIDL. Exception" + ex);
1174             }
1175         } else {
1176             Log.e(mTag, "null mRadioSimIndication");
1177         }
1178     }
1179 
subscriptionStatusChanged(boolean activate)1180     public void subscriptionStatusChanged(boolean activate) {
1181         Log.d(mTag, "subscriptionStatusChanged");
1182 
1183         if (mRadioSimIndication != null) {
1184             try {
1185                 mRadioSimIndication.subscriptionStatusChanged(
1186                         RadioIndicationType.UNSOLICITED, activate);
1187             } catch (RemoteException ex) {
1188                 Log.e(mTag, "Failed to subscriptionStatusChanged from AIDL. Exception" + ex);
1189             }
1190         } else {
1191             Log.e(mTag, "null mRadioSimIndication");
1192         }
1193     }
1194 
uiccApplicationsEnablementChanged(boolean enabled)1195     public void uiccApplicationsEnablementChanged(boolean enabled) {
1196         Log.d(mTag, "uiccApplicationsEnablementChanged");
1197 
1198         if (mRadioSimIndication != null) {
1199             try {
1200                 mRadioSimIndication.uiccApplicationsEnablementChanged(
1201                         RadioIndicationType.UNSOLICITED, enabled);
1202             } catch (RemoteException ex) {
1203                 Log.e(
1204                         mTag,
1205                         "Failed to uiccApplicationsEnablementChanged from AIDL. Exception" + ex);
1206             }
1207         } else {
1208             Log.e(mTag, "null mRadioSimIndication");
1209         }
1210     }
1211 
1212     @Override
getInterfaceHash()1213     public String getInterfaceHash() {
1214         return IRadioSim.HASH;
1215     }
1216 
1217     @Override
getInterfaceVersion()1218     public int getInterfaceVersion() {
1219         return IRadioSim.VERSION;
1220     }
1221 
updateCarrierRestrictionStatusInfo( Carrier[] carrierList, int carrierRestrictionStatus)1222     public void updateCarrierRestrictionStatusInfo(
1223             Carrier[] carrierList, int carrierRestrictionStatus) {
1224         mCarrierList = carrierList;
1225         mCarrierRestrictionStatus = carrierRestrictionStatus;
1226     }
1227 
updateCarrierRestrictionRules(CarrierRestrictions carrierRestrictionRules, int multiSimPolicy)1228     public void updateCarrierRestrictionRules(CarrierRestrictions carrierRestrictionRules,
1229             int multiSimPolicy) {
1230         Log.d(mTag, "updateCarrierRestrictionRules");
1231         mCarrierRestrictionRules = carrierRestrictionRules;
1232         mMultiSimPolicy = multiSimPolicy;
1233     }
1234 
getCarrierInfo(String mcc, String mnc, String spn, String gid1, String gid2, String imsi, List<android.hardware.radio.sim.Plmn> ehplmn, String iccid, String impi)1235     private android.hardware.radio.sim.CarrierInfo getCarrierInfo(String mcc, String mnc,
1236             String spn, String gid1, String gid2, String imsi,
1237             List<android.hardware.radio.sim.Plmn> ehplmn, String iccid, String impi) {
1238         android.hardware.radio.sim.CarrierInfo carrierInfo =
1239                 new android.hardware.radio.sim.CarrierInfo();
1240         carrierInfo.mcc = mcc;
1241         carrierInfo.mnc = mnc;
1242         carrierInfo.spn = spn;
1243         carrierInfo.gid1 = gid1;
1244         carrierInfo.gid2 = gid2;
1245         carrierInfo.imsiPrefix = imsi;
1246         carrierInfo.ehplmn = ehplmn;
1247         carrierInfo.iccid = iccid;
1248         carrierInfo.impi = impi;
1249         return carrierInfo;
1250     }
1251 }
1252