• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.EF_ICCID;
20 
21 import android.content.Context;
22 import android.hardware.radio.config.PhoneCapability;
23 import android.hardware.radio.config.SimPortInfo;
24 import android.hardware.radio.config.SimSlotStatus;
25 import android.hardware.radio.config.SlotPortMapping;
26 import android.hardware.radio.sim.CardStatus;
27 import android.os.AsyncResult;
28 import android.os.Bundle;
29 import android.os.Handler;
30 import android.os.Message;
31 import android.os.RegistrantList;
32 import android.telephony.mockmodem.MockSimService.SimAppData;
33 import android.util.Log;
34 
35 import java.util.ArrayList;
36 import java.util.Random;
37 
38 public class MockModemConfigBase implements MockModemConfigInterface {
39     // ***** Instance Variables
40     private static final int DEFAULT_SUB_ID = 0;
41     private String mTAG = "MockModemConfigBase";
42     private final Handler mHandler;
43     private Context mContext;
44     private int mSubId;
45     private int mSimPhyicalId;
46     private final Object mConfigAccess = new Object();
47     private int mNumOfSim = MockModemConfigInterface.MAX_NUM_OF_SIM_SLOT;
48     private int mNumOfPhone = MockModemConfigInterface.MAX_NUM_OF_LOGICAL_MODEM;
49 
50     // ***** Events
51     static final int EVENT_SET_RADIO_POWER = 1;
52     static final int EVENT_CHANGE_SIM_PROFILE = 2;
53     static final int EVENT_SERVICE_STATE_CHANGE = 3;
54     static final int EVENT_SET_SIM_INFO = 4;
55 
56     // ***** Modem config values
57     private String mBasebandVersion = MockModemConfigInterface.DEFAULT_BASEBAND_VERSION;
58     private String mImei = MockModemConfigInterface.DEFAULT_IMEI;
59     private String mImeiSv = MockModemConfigInterface.DEFAULT_IMEISV;
60     private String mEsn = MockModemConfigInterface.DEFAULT_ESN;
61     private String mMeid = MockModemConfigInterface.DEFAULT_MEID;
62     private int mRadioState = MockModemConfigInterface.DEFAULT_RADIO_STATE;
63     private byte mNumOfLiveModem = MockModemConfigInterface.DEFAULT_NUM_OF_LIVE_MODEM;
64     private SimSlotStatus[] mSimSlotStatus;
65     private CardStatus mCardStatus;
66     private int mFdnStatus;
67     private MockSimService[] mSimService;
68     private PhoneCapability mPhoneCapability = new PhoneCapability();
69     private ArrayList<SimAppData> mSimAppList;
70 
71     // ***** RegistrantLists
72     // ***** IRadioConfig RegistrantLists
73     private RegistrantList mNumOfLiveModemChangedRegistrants = new RegistrantList();
74     private RegistrantList mPhoneCapabilityChangedRegistrants = new RegistrantList();
75     private RegistrantList mSimSlotStatusChangedRegistrants = new RegistrantList();
76 
77     // ***** IRadioModem RegistrantLists
78     private RegistrantList mBasebandVersionChangedRegistrants = new RegistrantList();
79     private RegistrantList mDeviceIdentityChangedRegistrants = new RegistrantList();
80     private RegistrantList mRadioStateChangedRegistrants = new RegistrantList();
81 
82     // ***** IRadioSim RegistrantLists
83     private RegistrantList mCardStatusChangedRegistrants = new RegistrantList();
84     private RegistrantList mSimAppDataChangedRegistrants = new RegistrantList();
85     private RegistrantList mSimInfoChangedRegistrants = new RegistrantList();
86 
87     // ***** IRadioNetwork RegistrantLists
88     private RegistrantList mServiceStateChangedRegistrants = new RegistrantList();
89 
MockModemConfigBase(Context context, int instanceId, int numOfSim, int numOfPhone)90     public MockModemConfigBase(Context context, int instanceId, int numOfSim, int numOfPhone) {
91         mContext = context;
92         mSubId = instanceId;
93         mNumOfSim =
94                 (numOfSim > MockModemConfigInterface.MAX_NUM_OF_SIM_SLOT)
95                         ? MockModemConfigInterface.MAX_NUM_OF_SIM_SLOT
96                         : numOfSim;
97         mNumOfPhone =
98                 (numOfPhone > MockModemConfigInterface.MAX_NUM_OF_LOGICAL_MODEM)
99                         ? MockModemConfigInterface.MAX_NUM_OF_LOGICAL_MODEM
100                         : numOfPhone;
101         mTAG = mTAG + "[" + mSubId + "]";
102         mHandler = new MockModemConfigHandler();
103         mSimSlotStatus = new SimSlotStatus[mNumOfSim];
104         mCardStatus = new CardStatus();
105         mSimService = new MockSimService[mNumOfSim];
106         mSimPhyicalId = mSubId; // for default mapping
107         createSIMCards();
108         setDefaultConfigValue();
109     }
110 
111     public static class SimInfoChangedResult {
112         public static final int SIM_INFO_TYPE_MCC_MNC = 1;
113         public static final int SIM_INFO_TYPE_IMSI = 2;
114         public static final int SIM_INFO_TYPE_ATR = 3;
115 
116         public int mSimInfoType;
117         public int mEfId;
118         public String mAid;
119 
SimInfoChangedResult(int type, int efid, String aid)120         public SimInfoChangedResult(int type, int efid, String aid) {
121             mSimInfoType = type;
122             mEfId = efid;
123             mAid = aid;
124         }
125 
126         @Override
toString()127         public String toString() {
128             return "SimInfoChangedResult:"
129                     + " simInfoType="
130                     + mSimInfoType
131                     + " efId="
132                     + mEfId
133                     + " aId="
134                     + mAid;
135         }
136     }
137 
138     public class MockModemConfigHandler extends Handler {
139         // ***** Handler implementation
140         @Override
handleMessage(Message msg)141         public void handleMessage(Message msg) {
142             synchronized (mConfigAccess) {
143                 switch (msg.what) {
144                     case EVENT_SET_RADIO_POWER:
145                         int state = msg.arg1;
146                         if (state >= RADIO_STATE_UNAVAILABLE && state <= RADIO_STATE_ON) {
147                             Log.d(
148                                     mTAG,
149                                     "EVENT_SET_RADIO_POWER: old("
150                                             + mRadioState
151                                             + "), new("
152                                             + state
153                                             + ")");
154                             if (mRadioState != state) {
155                                 mRadioState = state;
156                                 mRadioStateChangedRegistrants.notifyRegistrants(
157                                         new AsyncResult(null, mRadioState, null));
158                             }
159                         } else {
160                             Log.e(mTAG, "EVENT_SET_RADIO_POWER: invalid state(" + state + ")");
161                             mRadioStateChangedRegistrants.notifyRegistrants(null);
162                         }
163                         break;
164                     case EVENT_CHANGE_SIM_PROFILE:
165                         int simprofileid =
166                                 msg.getData()
167                                         .getInt(
168                                                 "changeSimProfile",
169                                                 MockSimService.MOCK_SIM_PROFILE_ID_DEFAULT);
170                         Log.d(mTAG, "EVENT_CHANGE_SIM_PROFILE: sim profile(" + simprofileid + ")");
171                         if (loadSIMCard(simprofileid)) {
172                             if (mSubId == DEFAULT_SUB_ID) {
173                                 mSimSlotStatusChangedRegistrants.notifyRegistrants(
174                                         new AsyncResult(null, mSimSlotStatus, null));
175                             }
176                             mCardStatusChangedRegistrants.notifyRegistrants(
177                                     new AsyncResult(null, mCardStatus, null));
178                             mSimAppDataChangedRegistrants.notifyRegistrants(
179                                     new AsyncResult(null, mSimAppList, null));
180                         } else {
181                             Log.e(mTAG, "Load Sim card failed.");
182                         }
183                         break;
184                     case EVENT_SERVICE_STATE_CHANGE:
185                         Log.d(mTAG, "EVENT_SERVICE_STATE_CHANGE");
186                         // Notify object MockNetworkService
187                         mServiceStateChangedRegistrants.notifyRegistrants(
188                                 new AsyncResult(null, msg.obj, null));
189                         break;
190                     case EVENT_SET_SIM_INFO:
191                         int simInfoType = msg.getData().getInt("setSimInfo:type", -1);
192                         String[] simInfoData = msg.getData().getStringArray("setSimInfo:data");
193                         Log.d(
194                                 mTAG,
195                                 "EVENT_SET_SIM_INFO: type = "
196                                         + simInfoType
197                                         + " data length = "
198                                         + simInfoData.length);
199                         for (int i = 0; i < simInfoData.length; i++) {
200                             Log.d(mTAG, "simInfoData[" + i + "] = " + simInfoData[i]);
201                         }
202                         SimInfoChangedResult simInfoChangeResult =
203                                 setSimInfo(simInfoType, simInfoData);
204                         if (simInfoChangeResult != null) {
205                             switch (simInfoChangeResult.mSimInfoType) {
206                                 case SimInfoChangedResult.SIM_INFO_TYPE_MCC_MNC:
207                                 case SimInfoChangedResult.SIM_INFO_TYPE_IMSI:
208                                     mSimInfoChangedRegistrants.notifyRegistrants(
209                                             new AsyncResult(null, simInfoChangeResult, null));
210                                     mSimAppDataChangedRegistrants.notifyRegistrants(
211                                             new AsyncResult(null, mSimAppList, null));
212                                     // Card status changed still needed for updating carrier config
213                                     // in Telephony Framework
214                                     if (mSubId == DEFAULT_SUB_ID) {
215                                         mSimSlotStatusChangedRegistrants.notifyRegistrants(
216                                                 new AsyncResult(null, mSimSlotStatus, null));
217                                     }
218                                     mCardStatusChangedRegistrants.notifyRegistrants(
219                                             new AsyncResult(null, mCardStatus, null));
220                                     break;
221                                 case SimInfoChangedResult.SIM_INFO_TYPE_ATR:
222                                     if (mSubId == DEFAULT_SUB_ID) {
223                                         mSimSlotStatusChangedRegistrants.notifyRegistrants(
224                                                 new AsyncResult(null, mSimSlotStatus, null));
225                                     }
226                                     mCardStatusChangedRegistrants.notifyRegistrants(
227                                             new AsyncResult(null, mCardStatus, null));
228                                     break;
229                             }
230                         }
231                         break;
232                 }
233             }
234         }
235     }
236 
getMockModemConfigHandler()237     public Handler getMockModemConfigHandler() {
238         return mHandler;
239     }
240 
setDefaultConfigValue()241     private void setDefaultConfigValue() {
242         synchronized (mConfigAccess) {
243             mBasebandVersion = MockModemConfigInterface.DEFAULT_BASEBAND_VERSION;
244             mImei = MockModemConfigInterface.DEFAULT_IMEI;
245             mImeiSv = MockModemConfigInterface.DEFAULT_IMEISV;
246             mEsn = MockModemConfigInterface.DEFAULT_ESN;
247             mMeid = MockModemConfigInterface.DEFAULT_MEID;
248             mRadioState = MockModemConfigInterface.DEFAULT_RADIO_STATE;
249             mNumOfLiveModem = MockModemConfigInterface.DEFAULT_NUM_OF_LIVE_MODEM;
250             setDefaultPhoneCapability(mPhoneCapability);
251             if (mSubId == DEFAULT_SUB_ID) {
252                 updateSimSlotStatus();
253             }
254             updateCardStatus();
255         }
256     }
257 
setDefaultPhoneCapability(PhoneCapability phoneCapability)258     private void setDefaultPhoneCapability(PhoneCapability phoneCapability) {
259         phoneCapability.logicalModemIds =
260                 new byte[MockModemConfigInterface.MAX_NUM_OF_LOGICAL_MODEM];
261         phoneCapability.maxActiveData = MockModemConfigInterface.DEFAULT_MAX_ACTIVE_DATA;
262         phoneCapability.maxActiveInternetData =
263                 MockModemConfigInterface.DEFAULT_MAX_ACTIVE_INTERNAL_DATA;
264         phoneCapability.isInternetLingeringSupported =
265                 MockModemConfigInterface.DEFAULT_IS_INTERNAL_LINGERING_SUPPORTED;
266         phoneCapability.logicalModemIds[0] = MockModemConfigInterface.DEFAULT_LOGICAL_MODEM1_ID;
267         phoneCapability.logicalModemIds[1] = MockModemConfigInterface.DEFAULT_LOGICAL_MODEM2_ID;
268     }
269 
createSIMCards()270     private void createSIMCards() {
271         for (int i = 0; i < mNumOfSim; i++) {
272             if (mSimService[i] == null) {
273                 mSimService[i] = new MockSimService(mContext, i);
274             }
275         }
276     }
277 
updateSimSlotStatus()278     private void updateSimSlotStatus() {
279         if (mSubId != DEFAULT_SUB_ID) {
280             // Only sub 0 needs to response SimSlotStatus
281             return;
282         }
283 
284         if (mSimService == null) {
285             Log.e(mTAG, "SIM service didn't be created yet.");
286         }
287 
288         for (int i = 0; i < mNumOfSim; i++) {
289             if (mSimService[i] == null) {
290                 Log.e(mTAG, "SIM service[" + i + "] didn't be created yet.");
291                 continue;
292             }
293             int portInfoListLen = mSimService[i].getNumOfSimPortInfo();
294             mSimSlotStatus[i] = new SimSlotStatus();
295             mSimSlotStatus[i].cardState =
296                     mSimService[i].isCardPresent()
297                             ? CardStatus.STATE_PRESENT
298                             : CardStatus.STATE_ABSENT;
299             mSimSlotStatus[i].atr = mSimService[i].getATR();
300             mSimSlotStatus[i].eid = mSimService[i].getEID();
301             // Current only support one Sim port in MockSimService
302             SimPortInfo[] portInfoList0 = new SimPortInfo[portInfoListLen];
303             portInfoList0[0] = new SimPortInfo();
304             portInfoList0[0].portActive = mSimService[i].isSlotPortActive();
305             portInfoList0[0].logicalSlotId = mSimService[i].getLogicalSlotId();
306             portInfoList0[0].iccId = mSimService[i].getICCID();
307             mSimSlotStatus[i].portInfo = portInfoList0;
308         }
309     }
310 
updateCardStatus()311     private void updateCardStatus() {
312         if (mSimPhyicalId != -1 && mSimService != null && mSimService[mSimPhyicalId] != null) {
313             int numOfSimApp = mSimService[mSimPhyicalId].getNumOfSimApp();
314             mCardStatus = new CardStatus();
315             mCardStatus.cardState =
316                     mSimService[mSimPhyicalId].isCardPresent()
317                             ? CardStatus.STATE_PRESENT
318                             : CardStatus.STATE_ABSENT;
319             mCardStatus.universalPinState = mSimService[mSimPhyicalId].getUniversalPinState();
320             mCardStatus.gsmUmtsSubscriptionAppIndex = mSimService[mSimPhyicalId].getGsmAppIndex();
321             mCardStatus.cdmaSubscriptionAppIndex = mSimService[mSimPhyicalId].getCdmaAppIndex();
322             mCardStatus.imsSubscriptionAppIndex = mSimService[mSimPhyicalId].getImsAppIndex();
323             mCardStatus.applications = mSimService[mSimPhyicalId].getSimApp();
324             mCardStatus.atr = mSimService[mSimPhyicalId].getATR();
325             mCardStatus.iccid = mSimService[mSimPhyicalId].getICCID();
326             mCardStatus.eid = mSimService[mSimPhyicalId].getEID();
327             mCardStatus.slotMap = new SlotPortMapping();
328             mCardStatus.slotMap.physicalSlotId = mSimService[mSimPhyicalId].getPhysicalSlotId();
329             mCardStatus.slotMap.portId = mSimService[mSimPhyicalId].getSlotPortId();
330             mSimAppList = mSimService[mSimPhyicalId].getSimAppList();
331         } else {
332             Log.e(
333                     mTAG,
334                     "Invalid Sim physical id("
335                             + mSimPhyicalId
336                             + ") or SIM card didn't be created.");
337         }
338     }
339 
loadSIMCard(int simProfileId)340     private boolean loadSIMCard(int simProfileId) {
341         boolean result = false;
342         if (mSimPhyicalId != -1 && mSimService != null && mSimService[mSimPhyicalId] != null) {
343             result = mSimService[mSimPhyicalId].loadSimCard(simProfileId);
344             if (mSubId == DEFAULT_SUB_ID) {
345                 updateSimSlotStatus();
346             }
347             updateCardStatus();
348         }
349         return result;
350     }
351 
generateRandomIccid(String baseIccid)352     private String generateRandomIccid(String baseIccid) {
353         String newIccid;
354         Random rnd = new Random();
355         StringBuilder randomNum = new StringBuilder();
356 
357         // Generate random 12-digit account id
358         for (int i = 0; i < 12; i++) {
359             randomNum.append(rnd.nextInt(10));
360         }
361 
362         Log.d(mTAG, "Random Num = " + randomNum.toString());
363 
364         // TODO: regenerate checksum
365         // Simply modify account id from base Iccid
366         newIccid =
367                 baseIccid.substring(0, 7)
368                         + randomNum.toString()
369                         + baseIccid.substring(baseIccid.length() - 1);
370 
371         Log.d(mTAG, "Generate new Iccid = " + newIccid);
372 
373         return newIccid;
374     }
375 
setSimInfo(int simInfoType, String[] simInfoData)376     private SimInfoChangedResult setSimInfo(int simInfoType, String[] simInfoData) {
377         SimInfoChangedResult result = null;
378 
379         if (simInfoData == null) {
380             Log.e(mTAG, "simInfoData == null");
381             return result;
382         }
383 
384         switch (simInfoType) {
385             case SimInfoChangedResult.SIM_INFO_TYPE_MCC_MNC:
386                 if (simInfoData.length == 2 && simInfoData[0] != null && simInfoData[1] != null) {
387                     String msin = mSimService[mSimPhyicalId].getMsin();
388 
389                     // Adjust msin length to make sure IMSI length is valid.
390                     if (simInfoData[1].length() == 3 && msin.length() == 10) {
391                         msin = msin.substring(0, msin.length() - 1);
392                         Log.d(mTAG, "Modify msin = " + msin);
393                     }
394                     mSimService[mSimPhyicalId].setImsi(simInfoData[0], simInfoData[1], msin);
395 
396                     // Auto-generate a new Iccid to change carrier config id in Android Framework
397                     mSimService[mSimPhyicalId].setICCID(
398                             generateRandomIccid(mSimService[mSimPhyicalId].getICCID()));
399                     updateSimSlotStatus();
400                     updateCardStatus();
401 
402                     result =
403                             new SimInfoChangedResult(
404                                     simInfoType,
405                                     EF_ICCID,
406                                     mSimService[mSimPhyicalId].getActiveSimAppId());
407                 }
408                 break;
409             case SimInfoChangedResult.SIM_INFO_TYPE_IMSI:
410                 if (simInfoData.length == 3
411                         && simInfoData[0] != null
412                         && simInfoData[1] != null
413                         && simInfoData[2] != null) {
414                     mSimService[mSimPhyicalId].setImsi(
415                             simInfoData[0], simInfoData[1], simInfoData[2]);
416 
417                     // Auto-generate a new Iccid to change carrier config id in Android Framework
418                     mSimService[mSimPhyicalId].setICCID(
419                             generateRandomIccid(mSimService[mSimPhyicalId].getICCID()));
420                     updateSimSlotStatus();
421                     updateCardStatus();
422 
423                     result =
424                             new SimInfoChangedResult(
425                                     simInfoType,
426                                     EF_ICCID,
427                                     mSimService[mSimPhyicalId].getActiveSimAppId());
428                 }
429                 break;
430             case SimInfoChangedResult.SIM_INFO_TYPE_ATR:
431                 if (simInfoData[0] != null) {
432                     mSimService[mSimPhyicalId].setATR(simInfoData[0]);
433                     updateSimSlotStatus();
434                     updateCardStatus();
435                     result = new SimInfoChangedResult(simInfoType, 0, "");
436                 }
437                 break;
438             default:
439                 Log.e(mTAG, "Not support Sim info type(" + simInfoType + ") to modify");
440                 break;
441         }
442 
443         return result;
444     }
445 
notifyDeviceIdentityChangedRegistrants()446     private void notifyDeviceIdentityChangedRegistrants() {
447         String[] deviceIdentity = new String[4];
448         synchronized (mConfigAccess) {
449             deviceIdentity[0] = mImei;
450             deviceIdentity[1] = mImeiSv;
451             deviceIdentity[2] = mEsn;
452             deviceIdentity[3] = mMeid;
453         }
454         AsyncResult ar = new AsyncResult(null, deviceIdentity, null);
455         mDeviceIdentityChangedRegistrants.notifyRegistrants(ar);
456     }
457 
458     // ***** MockModemConfigInterface implementation
459     @Override
notifyAllRegistrantNotifications()460     public void notifyAllRegistrantNotifications() {
461         Log.d(mTAG, "notifyAllRegistrantNotifications");
462         synchronized (mConfigAccess) {
463             // IRadioConfig
464             mNumOfLiveModemChangedRegistrants.notifyRegistrants(
465                     new AsyncResult(null, mNumOfLiveModem, null));
466             mPhoneCapabilityChangedRegistrants.notifyRegistrants(
467                     new AsyncResult(null, mPhoneCapability, null));
468             mSimSlotStatusChangedRegistrants.notifyRegistrants(
469                     new AsyncResult(null, mSimSlotStatus, null));
470 
471             // IRadioModem
472             mBasebandVersionChangedRegistrants.notifyRegistrants(
473                     new AsyncResult(null, mBasebandVersion, null));
474             notifyDeviceIdentityChangedRegistrants();
475             mRadioStateChangedRegistrants.notifyRegistrants(
476                     new AsyncResult(null, mRadioState, null));
477 
478             // IRadioSim
479             mCardStatusChangedRegistrants.notifyRegistrants(
480                     new AsyncResult(null, mCardStatus, null));
481             mSimAppDataChangedRegistrants.notifyRegistrants(
482                     new AsyncResult(null, mSimAppList, null));
483         }
484     }
485 
486     // ***** IRadioConfig notification implementation
487     @Override
registerForNumOfLiveModemChanged(Handler h, int what, Object obj)488     public void registerForNumOfLiveModemChanged(Handler h, int what, Object obj) {
489         mNumOfLiveModemChangedRegistrants.addUnique(h, what, obj);
490     }
491 
492     @Override
unregisterForNumOfLiveModemChanged(Handler h)493     public void unregisterForNumOfLiveModemChanged(Handler h) {
494         mNumOfLiveModemChangedRegistrants.remove(h);
495     }
496 
497     @Override
registerForPhoneCapabilityChanged(Handler h, int what, Object obj)498     public void registerForPhoneCapabilityChanged(Handler h, int what, Object obj) {
499         mPhoneCapabilityChangedRegistrants.addUnique(h, what, obj);
500     }
501 
502     @Override
unregisterForPhoneCapabilityChanged(Handler h)503     public void unregisterForPhoneCapabilityChanged(Handler h) {
504         mPhoneCapabilityChangedRegistrants.remove(h);
505     }
506 
507     @Override
registerForSimSlotStatusChanged(Handler h, int what, Object obj)508     public void registerForSimSlotStatusChanged(Handler h, int what, Object obj) {
509         mSimSlotStatusChangedRegistrants.addUnique(h, what, obj);
510     }
511 
512     @Override
unregisterForSimSlotStatusChanged(Handler h)513     public void unregisterForSimSlotStatusChanged(Handler h) {
514         mSimSlotStatusChangedRegistrants.remove(h);
515     }
516 
517     // ***** IRadioModem notification implementation
518     @Override
registerForBasebandVersionChanged(Handler h, int what, Object obj)519     public void registerForBasebandVersionChanged(Handler h, int what, Object obj) {
520         mBasebandVersionChangedRegistrants.addUnique(h, what, obj);
521     }
522 
523     @Override
unregisterForBasebandVersionChanged(Handler h)524     public void unregisterForBasebandVersionChanged(Handler h) {
525         mBasebandVersionChangedRegistrants.remove(h);
526     }
527 
528     @Override
registerForDeviceIdentityChanged(Handler h, int what, Object obj)529     public void registerForDeviceIdentityChanged(Handler h, int what, Object obj) {
530         mDeviceIdentityChangedRegistrants.addUnique(h, what, obj);
531     }
532 
533     @Override
unregisterForDeviceIdentityChanged(Handler h)534     public void unregisterForDeviceIdentityChanged(Handler h) {
535         mDeviceIdentityChangedRegistrants.remove(h);
536     }
537 
538     @Override
registerForRadioStateChanged(Handler h, int what, Object obj)539     public void registerForRadioStateChanged(Handler h, int what, Object obj) {
540         mRadioStateChangedRegistrants.addUnique(h, what, obj);
541     }
542 
543     @Override
unregisterForRadioStateChanged(Handler h)544     public void unregisterForRadioStateChanged(Handler h) {
545         mRadioStateChangedRegistrants.remove(h);
546     }
547 
548     // ***** IRadioSim notification implementation
549     @Override
registerForCardStatusChanged(Handler h, int what, Object obj)550     public void registerForCardStatusChanged(Handler h, int what, Object obj) {
551         mCardStatusChangedRegistrants.addUnique(h, what, obj);
552     }
553 
554     @Override
unregisterForCardStatusChanged(Handler h)555     public void unregisterForCardStatusChanged(Handler h) {
556         mCardStatusChangedRegistrants.remove(h);
557     }
558 
559     @Override
registerForSimAppDataChanged(Handler h, int what, Object obj)560     public void registerForSimAppDataChanged(Handler h, int what, Object obj) {
561         mSimAppDataChangedRegistrants.addUnique(h, what, obj);
562     }
563 
564     @Override
unregisterForSimAppDataChanged(Handler h)565     public void unregisterForSimAppDataChanged(Handler h) {
566         mSimAppDataChangedRegistrants.remove(h);
567     }
568 
569     @Override
registerForSimInfoChanged(Handler h, int what, Object obj)570     public void registerForSimInfoChanged(Handler h, int what, Object obj) {
571         mSimInfoChangedRegistrants.addUnique(h, what, obj);
572     }
573 
574     @Override
unregisterForSimInfoChanged(Handler h)575     public void unregisterForSimInfoChanged(Handler h) {
576         mSimInfoChangedRegistrants.remove(h);
577     }
578 
579     // ***** IRadioNetwork notification implementation
580     @Override
registerForServiceStateChanged(Handler h, int what, Object obj)581     public void registerForServiceStateChanged(Handler h, int what, Object obj) {
582         mServiceStateChangedRegistrants.addUnique(h, what, obj);
583     }
584 
585     @Override
unregisterForServiceStateChanged(Handler h)586     public void unregisterForServiceStateChanged(Handler h) {
587         mServiceStateChangedRegistrants.remove(h);
588     }
589 
590     // ***** IRadioConfig set APIs implementation
591 
592     // ***** IRadioModem set APIs implementation
593     @Override
setRadioState(int state, String client)594     public void setRadioState(int state, String client) {
595         Log.d(mTAG, "setRadioState (" + state + ") from " + client);
596 
597         Message msg = mHandler.obtainMessage(EVENT_SET_RADIO_POWER);
598         msg.arg1 = state;
599         mHandler.sendMessage(msg);
600     }
601 
602     // ***** IRadioSim set APIs implementation
603 
604     // ***** IRadioNetwork set APIs implementation
605 
606     // ***** IRadioVoice set APIs implementation
607 
608     // ***** IRadioData set APIs implementation
609 
610     // ***** IRadioMessaging set APIs implementation
611 
612     // ***** Helper APIs implementation
613     @Override
isSimCardPresent(String client)614     public boolean isSimCardPresent(String client) {
615         Log.d(mTAG, "isSimCardPresent from: " + client);
616         boolean isPresent;
617         synchronized (mConfigAccess) {
618             isPresent = (mCardStatus.cardState == CardStatus.STATE_PRESENT) ? true : false;
619         }
620         return isPresent;
621     }
622 
623     @Override
changeSimProfile(int simprofileid, String client)624     public void changeSimProfile(int simprofileid, String client) {
625         Log.d(mTAG, "changeSimProfile: profile id(" + simprofileid + ") from: " + client);
626 
627         Message msg = mHandler.obtainMessage(EVENT_CHANGE_SIM_PROFILE);
628         msg.getData().putInt("changeSimProfile", simprofileid);
629         mHandler.sendMessage(msg);
630     }
631 
632     @Override
setSimInfo(int type, String[] data, String client)633     public void setSimInfo(int type, String[] data, String client) {
634         Log.d(mTAG, "setSimInfo: type(" + type + ") from: " + client);
635         Message msg = mHandler.obtainMessage(EVENT_SET_SIM_INFO);
636         Bundle bundle = msg.getData();
637         bundle.putInt("setSimInfo:type", type);
638         bundle.putStringArray("setSimInfo:data", data);
639         mHandler.sendMessage(msg);
640     }
641 
642     @Override
getSimInfo(int type, String client)643     public String getSimInfo(int type, String client) {
644         Log.d(mTAG, "getSimInfo: type(" + type + ") from: " + client);
645         String result = "";
646 
647         synchronized (mConfigAccess) {
648             switch (type) {
649                 case SimInfoChangedResult.SIM_INFO_TYPE_MCC_MNC:
650                     result = mSimService[mSimPhyicalId].getMccMnc();
651                     break;
652                 case SimInfoChangedResult.SIM_INFO_TYPE_IMSI:
653                     result = mSimService[mSimPhyicalId].getImsi();
654                     break;
655                 case SimInfoChangedResult.SIM_INFO_TYPE_ATR:
656                     result = mCardStatus.atr;
657                     break;
658                 default:
659                     Log.e(mTAG, "Not support this type of SIM info.");
660                     break;
661             }
662         }
663 
664         return result;
665     }
666 }
667