• 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 import static android.telephony.mockmodem.MockSimService.MOCK_SIM_PROFILE_ID_DEFAULT;
21 import static android.telephony.mockmodem.MockSimService.MOCK_SIM_PROFILE_ID_MAX;
22 import static android.telephony.mockmodem.MockVoiceService.MockCallInfo.CALL_TYPE_EMERGENCY;
23 import static android.telephony.mockmodem.MockVoiceService.MockCallInfo.CALL_TYPE_VOICE;
24 
25 import android.content.Context;
26 import android.hardware.radio.config.PhoneCapability;
27 import android.hardware.radio.config.SimPortInfo;
28 import android.hardware.radio.config.SimSlotStatus;
29 import android.hardware.radio.config.SlotPortMapping;
30 import android.hardware.radio.modem.ImeiInfo;
31 import android.hardware.radio.sim.CardStatus;
32 import android.hardware.radio.voice.CdmaSignalInfoRecord;
33 import android.hardware.radio.voice.LastCallFailCauseInfo;
34 import android.hardware.radio.voice.UusInfo;
35 import android.os.AsyncResult;
36 import android.os.Bundle;
37 import android.os.Handler;
38 import android.os.Message;
39 import android.os.RegistrantList;
40 import android.telephony.Annotation;
41 import android.telephony.mockmodem.MockSimService.SimAppData;
42 import android.util.Log;
43 
44 import java.util.ArrayList;
45 import java.util.Random;
46 
47 public class MockModemConfigBase implements MockModemConfigInterface {
48     // ***** Instance Variables
49     private static final int DEFAULT_SLOT_ID = 0;
50     private static final int ESIM_SLOT_ID = 1;
51     private final String mTAG = "MockModemConfigBase";
52     private final Handler[] mHandler;
53     private Context mContext;
54     private int mSubId;
55     private int mSimPhyicalId;
56     private Object[] mConfigAccess;
57     private final Object mSimMappingAccess = new Object();
58     private int mNumOfSim = MockModemConfigInterface.MAX_NUM_OF_SIM_SLOT;
59     private int mNumOfPhone = MockModemConfigInterface.MAX_NUM_OF_LOGICAL_MODEM;
60 
61     // ***** Events
62     static final int EVENT_SET_RADIO_POWER = 1;
63     static final int EVENT_CHANGE_SIM_PROFILE = 2;
64     static final int EVENT_SERVICE_STATE_CHANGE = 3;
65     static final int EVENT_SET_SIM_INFO = 4;
66     static final int EVENT_CALL_STATE_CHANGE = 5;
67     static final int EVENT_CURRENT_CALLS_RESPONSE = 6;
68     static final int EVENT_CALL_INCOMING = 7;
69     static final int EVENT_RINGBACK_TONE = 8;
70 
71     // ***** Modem config values
72     private String mBasebandVersion = MockModemConfigInterface.DEFAULT_BASEBAND_VERSION;
73     private String[] mImei;
74     private String[] mImeiSv;
75     private String[] mEsn;
76     private String[] mMeid;
77     private int[] mImeiType;
78     private int mRadioState = MockModemConfigInterface.DEFAULT_RADIO_STATE;
79     private byte mNumOfLiveModem = MockModemConfigInterface.DEFAULT_NUM_OF_LIVE_MODEM;
80     private PhoneCapability mPhoneCapability = new PhoneCapability();
81 
82     // ***** Sim config values
83     private SimSlotStatus[] mSimSlotStatus;
84     private CardStatus[] mCardStatus;
85     private int[] mLogicalSimIdMap;
86     private int[] mFdnStatus;
87     private MockSimService[] mSimService;
88     private ArrayList<SimAppData>[] mSimAppList;
89 
90     // **** Voice config values
91     private MockVoiceService[] mVoiceService;
92     private MockCallControlInfo mCallControlInfo;
93 
94     // ***** RegistrantLists
95     // ***** IRadioConfig RegistrantLists
96     private RegistrantList mNumOfLiveModemChangedRegistrants = new RegistrantList();
97     private RegistrantList mPhoneCapabilityChangedRegistrants = new RegistrantList();
98     private RegistrantList mSimSlotStatusChangedRegistrants = new RegistrantList();
99 
100     // ***** IRadioModem RegistrantLists
101     private RegistrantList mBasebandVersionChangedRegistrants = new RegistrantList();
102     private RegistrantList[] mDeviceIdentityChangedRegistrants;
103     private RegistrantList[] mDeviceImeiInfoChangedRegistrants;
104     private RegistrantList mRadioStateChangedRegistrants = new RegistrantList();
105 
106     // ***** IRadioSim RegistrantLists
107     private RegistrantList[] mCardStatusChangedRegistrants;
108     private RegistrantList[] mSimAppDataChangedRegistrants;
109     private RegistrantList[] mSimInfoChangedRegistrants;
110 
111     // ***** IRadioNetwork RegistrantLists
112     private RegistrantList[] mServiceStateChangedRegistrants;
113 
114     // ***** IRadioVoice RegistrantLists
115     private RegistrantList[] mCallStateChangedRegistrants;
116     private RegistrantList[] mCurrentCallsResponseRegistrants;
117     private RegistrantList[] mCallIncomingRegistrants;
118     private RegistrantList[] mRingbackToneRegistrants;
119 
MockModemConfigBase(Context context, int numOfSim, int numOfPhone)120     public MockModemConfigBase(Context context, int numOfSim, int numOfPhone) {
121         mContext = context;
122         mNumOfSim =
123                 (numOfSim > MockModemConfigInterface.MAX_NUM_OF_SIM_SLOT)
124                         ? MockModemConfigInterface.MAX_NUM_OF_SIM_SLOT
125                         : numOfSim;
126         mNumOfPhone =
127                 (numOfPhone > MockModemConfigInterface.MAX_NUM_OF_LOGICAL_MODEM)
128                         ? MockModemConfigInterface.MAX_NUM_OF_LOGICAL_MODEM
129                         : numOfPhone;
130         mConfigAccess = new Object[mNumOfPhone];
131         mHandler = new MockModemConfigHandler[mNumOfPhone];
132 
133         // Registrants initialization
134         // IRadioModem registrants
135         mDeviceIdentityChangedRegistrants = new RegistrantList[mNumOfPhone];
136         mDeviceImeiInfoChangedRegistrants = new RegistrantList[mNumOfPhone];
137         // IRadioSim registrants
138         mCardStatusChangedRegistrants = new RegistrantList[mNumOfPhone];
139         mSimAppDataChangedRegistrants = new RegistrantList[mNumOfPhone];
140         mSimInfoChangedRegistrants = new RegistrantList[mNumOfPhone];
141         // IRadioNetwork registrants
142         mServiceStateChangedRegistrants = new RegistrantList[mNumOfPhone];
143         // IRadioVoice registrants
144         mCallStateChangedRegistrants = new RegistrantList[mNumOfPhone];
145         mCurrentCallsResponseRegistrants = new RegistrantList[mNumOfPhone];
146         mCallIncomingRegistrants = new RegistrantList[mNumOfPhone];
147         mRingbackToneRegistrants = new RegistrantList[mNumOfPhone];
148 
149         // IRadioModem caches
150         mImei = new String[mNumOfPhone];
151         mImeiSv = new String[mNumOfPhone];
152         mEsn = new String[mNumOfPhone];
153         mMeid = new String[mNumOfPhone];
154         mImeiType = new int[mNumOfPhone];
155 
156         // IRadioSim caches
157         mCardStatus = new CardStatus[mNumOfPhone];
158         mSimSlotStatus = new SimSlotStatus[mNumOfSim];
159         mLogicalSimIdMap = new int[mNumOfSim];
160         mFdnStatus = new int[mNumOfSim];
161         mSimService = new MockSimService[mNumOfSim];
162         mSimAppList = (ArrayList<SimAppData>[]) new ArrayList[mNumOfSim];
163 
164         // IRadioVoice caches
165         mVoiceService = new MockVoiceService[mNumOfPhone];
166 
167         // Caches initializtion
168         for (int i = 0; i < mNumOfPhone; i++) {
169             if (mConfigAccess != null && mConfigAccess[i] == null) {
170                 mConfigAccess[i] = new Object();
171             }
172 
173             if (mHandler != null && mHandler[i] == null) {
174                 mHandler[i] = new MockModemConfigHandler(i);
175             }
176 
177             if (mDeviceIdentityChangedRegistrants != null
178                     && mDeviceIdentityChangedRegistrants[i] == null) {
179                 mDeviceIdentityChangedRegistrants[i] = new RegistrantList();
180             }
181 
182             if (mDeviceImeiInfoChangedRegistrants != null
183                     && mDeviceImeiInfoChangedRegistrants[i] == null) {
184                 mDeviceImeiInfoChangedRegistrants[i] = new RegistrantList();
185             }
186 
187             if (mCardStatusChangedRegistrants != null && mCardStatusChangedRegistrants[i] == null) {
188                 mCardStatusChangedRegistrants[i] = new RegistrantList();
189             }
190 
191             if (mSimAppDataChangedRegistrants != null && mSimAppDataChangedRegistrants[i] == null) {
192                 mSimAppDataChangedRegistrants[i] = new RegistrantList();
193             }
194 
195             if (mSimInfoChangedRegistrants != null && mSimInfoChangedRegistrants[i] == null) {
196                 mSimInfoChangedRegistrants[i] = new RegistrantList();
197             }
198 
199             if (mServiceStateChangedRegistrants != null
200                     && mServiceStateChangedRegistrants[i] == null) {
201                 mServiceStateChangedRegistrants[i] = new RegistrantList();
202             }
203 
204             if (mCallStateChangedRegistrants != null && mCallStateChangedRegistrants[i] == null) {
205                 mCallStateChangedRegistrants[i] = new RegistrantList();
206             }
207 
208             if (mCurrentCallsResponseRegistrants != null
209                     && mCurrentCallsResponseRegistrants[i] == null) {
210                 mCurrentCallsResponseRegistrants[i] = new RegistrantList();
211             }
212 
213             if (mCallIncomingRegistrants != null && mCallIncomingRegistrants[i] == null) {
214                 mCallIncomingRegistrants[i] = new RegistrantList();
215             }
216 
217             if (mRingbackToneRegistrants != null && mRingbackToneRegistrants[i] == null) {
218                 mRingbackToneRegistrants[i] = new RegistrantList();
219             }
220 
221             if (mImei != null && mImei[i] == null) {
222                 String imei;
223                 switch (i) {
224                     case 0:
225                         imei = new String(MockModemConfigInterface.DEFAULT_PHONE1_IMEI);
226                         break;
227                     case 1:
228                         imei = new String(MockModemConfigInterface.DEFAULT_PHONE2_IMEI);
229                         break;
230                     default:
231                         imei = new String(MockModemConfigInterface.DEFAULT_PHONE1_IMEI);
232                         break;
233                 }
234                 mImei[i] = imei;
235             }
236 
237             if (mImeiSv != null && mImeiSv[i] == null) {
238                 String imeisv;
239                 switch (i) {
240                     case 0:
241                         imeisv = new String(MockModemConfigInterface.DEFAULT_PHONE1_IMEISV);
242                         break;
243                     case 1:
244                         imeisv = new String(MockModemConfigInterface.DEFAULT_PHONE2_IMEISV);
245                         break;
246                     default:
247                         imeisv = new String(MockModemConfigInterface.DEFAULT_PHONE1_IMEISV);
248                         break;
249                 }
250                 mImeiSv[i] = imeisv;
251             }
252 
253             if (mEsn != null && mEsn[i] == null) {
254                 String esn;
255                 switch (i) {
256                     case 0:
257                         esn = new String(MockModemConfigInterface.DEFAULT_PHONE1_ESN);
258                         break;
259                     case 1:
260                         esn = new String(MockModemConfigInterface.DEFAULT_PHONE2_ESN);
261                         break;
262                     default:
263                         esn = new String(MockModemConfigInterface.DEFAULT_PHONE1_ESN);
264                         break;
265                 }
266                 mEsn[i] = esn;
267             }
268 
269             if (mMeid != null && mMeid[i] == null) {
270                 String meid;
271                 switch (i) {
272                     case 0:
273                         meid = new String(MockModemConfigInterface.DEFAULT_PHONE1_MEID);
274                         break;
275                     case 1:
276                         meid = new String(MockModemConfigInterface.DEFAULT_PHONE2_MEID);
277                         break;
278                     default:
279                         meid = new String(MockModemConfigInterface.DEFAULT_PHONE1_MEID);
280                         break;
281                 }
282                 mMeid[i] = meid;
283             }
284 
285             if (mImeiType != null) {
286                 int imeiType;
287                 if (i == 0) {
288                     imeiType = ImeiInfo.ImeiType.PRIMARY;
289                 } else {
290                     imeiType = ImeiInfo.ImeiType.SECONDARY;
291                 }
292                 mImeiType[i] = imeiType;
293             }
294 
295             if (mCardStatus != null && mCardStatus[i] == null) {
296                 mCardStatus[i] = new CardStatus();
297             }
298 
299             if (mVoiceService != null && mVoiceService[i] == null) {
300                 mVoiceService[i] = new MockVoiceService(mHandler[i]);
301             }
302         }
303 
304         for (int i = 0; i < mNumOfSim; i++) {
305             if (mSimSlotStatus != null && mSimSlotStatus[i] == null) {
306                 mSimSlotStatus[i] = new SimSlotStatus();
307             }
308 
309             if (mLogicalSimIdMap != null) {
310                 mLogicalSimIdMap[i] = i;
311             }
312 
313             if (mFdnStatus != null) {
314                 mFdnStatus[i] = 0;
315             }
316 
317             if (mSimService != null && mSimService[i] == null) {
318                 mSimService[i] = new MockSimService(mContext, i);
319             }
320         }
321 
322         setDefaultConfigValue();
323     }
324 
325     public static class SimInfoChangedResult {
326         public static final int SIM_INFO_TYPE_MCC_MNC = 1;
327         public static final int SIM_INFO_TYPE_IMSI = 2;
328         public static final int SIM_INFO_TYPE_ATR = 3;
329 
330         public int mSimInfoType;
331         public int mEfId;
332         public String mAid;
333 
SimInfoChangedResult(int type, int efid, String aid)334         public SimInfoChangedResult(int type, int efid, String aid) {
335             mSimInfoType = type;
336             mEfId = efid;
337             mAid = aid;
338         }
339 
340         @Override
toString()341         public String toString() {
342             return "SimInfoChangedResult:"
343                     + " simInfoType="
344                     + mSimInfoType
345                     + " efId="
346                     + mEfId
347                     + " aId="
348                     + mAid;
349         }
350     }
351 
352     public class MockModemConfigHandler extends Handler {
353         private int mLogicalSlotId;
354 
MockModemConfigHandler(int slotId)355         MockModemConfigHandler(int slotId) {
356             mLogicalSlotId = slotId;
357         }
358 
359         // ***** Handler implementation
360         @Override
handleMessage(Message msg)361         public void handleMessage(Message msg) {
362             int physicalSimSlot = getSimPhysicalSlotId(mLogicalSlotId);
363 
364             synchronized (mConfigAccess[physicalSimSlot]) {
365                 switch (msg.what) {
366                     case EVENT_SET_RADIO_POWER:
367                         int state = msg.arg1;
368                         if (state >= RADIO_STATE_UNAVAILABLE && state <= RADIO_STATE_ON) {
369                             Log.d(
370                                     mTAG,
371                                     "EVENT_SET_RADIO_POWER: old("
372                                             + mRadioState
373                                             + "), new("
374                                             + state
375                                             + ")");
376                             if (mRadioState != state) {
377                                 mRadioState = state;
378                                 mRadioStateChangedRegistrants.notifyRegistrants(
379                                         new AsyncResult(null, mRadioState, null));
380                             }
381                         } else {
382                             Log.e(mTAG, "EVENT_SET_RADIO_POWER: invalid state(" + state + ")");
383                             mRadioStateChangedRegistrants.notifyRegistrants(null);
384                         }
385                         break;
386                     case EVENT_CHANGE_SIM_PROFILE:
387                         int simprofileid =
388                                 msg.getData()
389                                         .getInt(
390                                                 "changeSimProfile",
391                                                 MockSimService.MOCK_SIM_PROFILE_ID_DEFAULT);
392                         Log.d(mTAG, "EVENT_CHANGE_SIM_PROFILE: sim profile(" + simprofileid + ")");
393                         if (loadSIMCard(physicalSimSlot, simprofileid)) {
394                             if (mLogicalSlotId == DEFAULT_SLOT_ID) {
395                                 mSimSlotStatusChangedRegistrants.notifyRegistrants(
396                                         new AsyncResult(null, mSimSlotStatus, null));
397                             }
398                             mCardStatusChangedRegistrants[mLogicalSlotId].notifyRegistrants(
399                                     new AsyncResult(null, mCardStatus[physicalSimSlot], null));
400                             mSimAppDataChangedRegistrants[mLogicalSlotId].notifyRegistrants(
401                                     new AsyncResult(null, mSimAppList[physicalSimSlot], null));
402                         } else {
403                             Log.e(mTAG, "Load Sim card failed.");
404                         }
405                         break;
406                     case EVENT_SERVICE_STATE_CHANGE:
407                         Log.d(mTAG, "EVENT_SERVICE_STATE_CHANGE");
408                         // Notify object MockNetworkService
409                         mServiceStateChangedRegistrants[mLogicalSlotId].notifyRegistrants(
410                                 new AsyncResult(null, msg.obj, null));
411                         break;
412                     case EVENT_SET_SIM_INFO:
413                         int simInfoType = msg.getData().getInt("setSimInfo:type", -1);
414                         String[] simInfoData = msg.getData().getStringArray("setSimInfo:data");
415                         Log.d(
416                                 mTAG,
417                                 "EVENT_SET_SIM_INFO: type = "
418                                         + simInfoType
419                                         + " data length = "
420                                         + simInfoData.length);
421                         for (int i = 0; i < simInfoData.length; i++) {
422                             Log.d(mTAG, "simInfoData[" + i + "] = " + simInfoData[i]);
423                         }
424                         SimInfoChangedResult simInfoChangeResult =
425                                 setSimInfo(physicalSimSlot, simInfoType, simInfoData);
426                         if (simInfoChangeResult != null) {
427                             switch (simInfoChangeResult.mSimInfoType) {
428                                 case SimInfoChangedResult.SIM_INFO_TYPE_MCC_MNC:
429                                 case SimInfoChangedResult.SIM_INFO_TYPE_IMSI:
430                                     mSimInfoChangedRegistrants[mLogicalSlotId].notifyRegistrants(
431                                             new AsyncResult(null, simInfoChangeResult, null));
432                                     mSimAppDataChangedRegistrants[mLogicalSlotId].notifyRegistrants(
433                                             new AsyncResult(
434                                                     null, mSimAppList[physicalSimSlot], null));
435                                     // Card status changed still needed for updating carrier config
436                                     // in Telephony Framework
437                                     if (mLogicalSlotId == DEFAULT_SLOT_ID) {
438                                         mSimSlotStatusChangedRegistrants.notifyRegistrants(
439                                                 new AsyncResult(null, mSimSlotStatus, null));
440                                     }
441                                     mCardStatusChangedRegistrants[mLogicalSlotId].notifyRegistrants(
442                                             new AsyncResult(
443                                                     null, mCardStatus[physicalSimSlot], null));
444                                     break;
445                                 case SimInfoChangedResult.SIM_INFO_TYPE_ATR:
446                                     if (mLogicalSlotId == DEFAULT_SLOT_ID) {
447                                         mSimSlotStatusChangedRegistrants.notifyRegistrants(
448                                                 new AsyncResult(null, mSimSlotStatus, null));
449                                     }
450                                     mCardStatusChangedRegistrants[mLogicalSlotId].notifyRegistrants(
451                                             new AsyncResult(
452                                                     null, mCardStatus[physicalSimSlot], null));
453                                     break;
454                             }
455                         }
456                         break;
457                     case EVENT_CALL_STATE_CHANGE:
458                         Log.d(mTAG, "EVENT_CALL_STATE_CHANGE");
459                         mCallStateChangedRegistrants[mLogicalSlotId].notifyRegistrants(
460                                 new AsyncResult(null, msg.obj, null));
461                         break;
462 
463                     case EVENT_CURRENT_CALLS_RESPONSE:
464                         Log.d(mTAG, "EVENT_CURRENT_CALLS_RESPONSE");
465                         mCurrentCallsResponseRegistrants[mLogicalSlotId].notifyRegistrants(
466                                 new AsyncResult(null, msg.obj, null));
467                         break;
468 
469                     case EVENT_CALL_INCOMING:
470                         Log.d(mTAG, "EVENT_CALL_INCOMING");
471                         mCallIncomingRegistrants[mLogicalSlotId].notifyRegistrants(
472                                 new AsyncResult(null, msg.obj, null));
473                         break;
474                     case EVENT_RINGBACK_TONE:
475                         Log.d(mTAG, "EVENT_RINGBACK_TONE");
476                         mRingbackToneRegistrants[mLogicalSlotId].notifyRegistrants(
477                                 new AsyncResult(null, msg.obj, null));
478                         break;
479                 }
480             }
481         }
482     }
483 
getSimLogicalSlotId(int physicalSlotId)484     private int getSimLogicalSlotId(int physicalSlotId) {
485         int logicalSimId = DEFAULT_SLOT_ID;
486 
487         synchronized (mSimMappingAccess) {
488             logicalSimId = mLogicalSimIdMap[physicalSlotId];
489         }
490 
491         return logicalSimId;
492     }
493 
getSimPhysicalSlotId(int logicalSlotId)494     private int getSimPhysicalSlotId(int logicalSlotId) {
495         int physicalSlotId = DEFAULT_SLOT_ID;
496 
497         synchronized (mSimMappingAccess) {
498             for (int i = 0; i < mNumOfSim; i++) {
499                 if (mLogicalSimIdMap[i] == logicalSlotId) {
500                     physicalSlotId = i;
501                 }
502             }
503         }
504 
505         return physicalSlotId;
506     }
507 
setDefaultConfigValue()508     private void setDefaultConfigValue() {
509         for (int i = 0; i < mNumOfPhone; i++) {
510             synchronized (mConfigAccess[i]) {
511                 switch (i) {
512                     case 0:
513                         mImei[i] = MockModemConfigInterface.DEFAULT_PHONE1_IMEI;
514                         mImeiSv[i] = MockModemConfigInterface.DEFAULT_PHONE1_IMEISV;
515                         mEsn[i] = MockModemConfigInterface.DEFAULT_PHONE1_ESN;
516                         mMeid[i] = MockModemConfigInterface.DEFAULT_PHONE1_MEID;
517                         mImeiType[i] = MockModemConfigInterface.DEFAULT_PHONE1_IMEITYPE;
518                         break;
519                     case 1:
520                         mImei[i] = MockModemConfigInterface.DEFAULT_PHONE2_IMEI;
521                         mImeiSv[i] = MockModemConfigInterface.DEFAULT_PHONE2_IMEISV;
522                         mEsn[i] = MockModemConfigInterface.DEFAULT_PHONE2_ESN;
523                         mMeid[i] = MockModemConfigInterface.DEFAULT_PHONE2_MEID;
524                         mImeiType[i] = MockModemConfigInterface.DEFAULT_PHONE2_IMEITYPE;
525                         break;
526                     default:
527                         mImei[i] = MockModemConfigInterface.DEFAULT_PHONE1_IMEI;
528                         mImeiSv[i] = MockModemConfigInterface.DEFAULT_PHONE1_IMEISV;
529                         mEsn[i] = MockModemConfigInterface.DEFAULT_PHONE1_ESN;
530                         mMeid[i] = MockModemConfigInterface.DEFAULT_PHONE1_MEID;
531                         mImeiType[i] = MockModemConfigInterface.DEFAULT_PHONE1_IMEITYPE;
532                         break;
533                 }
534 
535                 if (i == DEFAULT_SLOT_ID) {
536                     mBasebandVersion = MockModemConfigInterface.DEFAULT_BASEBAND_VERSION;
537                     mRadioState = MockModemConfigInterface.DEFAULT_RADIO_STATE;
538                     mNumOfLiveModem = MockModemConfigInterface.DEFAULT_NUM_OF_LIVE_MODEM;
539                     setDefaultPhoneCapability(mPhoneCapability);
540                     updateSimSlotStatus();
541                 }
542                 updateCardStatus(i);
543             }
544         }
545     }
546 
setDefaultPhoneCapability(PhoneCapability phoneCapability)547     private void setDefaultPhoneCapability(PhoneCapability phoneCapability) {
548         phoneCapability.logicalModemIds =
549                 new byte[MockModemConfigInterface.MAX_NUM_OF_LOGICAL_MODEM];
550         phoneCapability.maxActiveData = MockModemConfigInterface.DEFAULT_MAX_ACTIVE_DATA;
551         phoneCapability.maxActiveInternetData =
552                 MockModemConfigInterface.DEFAULT_MAX_ACTIVE_INTERNAL_DATA;
553         phoneCapability.isInternetLingeringSupported =
554                 MockModemConfigInterface.DEFAULT_IS_INTERNAL_LINGERING_SUPPORTED;
555         phoneCapability.logicalModemIds[0] = MockModemConfigInterface.DEFAULT_LOGICAL_MODEM1_ID;
556         phoneCapability.logicalModemIds[1] = MockModemConfigInterface.DEFAULT_LOGICAL_MODEM2_ID;
557     }
558 
updateSimSlotStatus()559     private void updateSimSlotStatus() {
560         if (mSimService == null) {
561             Log.e(mTAG, "SIM service didn't be created yet.");
562         }
563 
564         for (int i = 0; i < mNumOfSim; i++) {
565             if (mSimService[i] == null) {
566                 Log.e(mTAG, "SIM service[" + i + "] didn't be created yet.");
567                 continue;
568             }
569             int portInfoListLen = mSimService[i].getNumOfSimPortInfo();
570             mSimSlotStatus[i] = new SimSlotStatus();
571             mSimSlotStatus[i].cardState =
572                     mSimService[i].isCardPresent()
573                             ? CardStatus.STATE_PRESENT
574                             : CardStatus.STATE_ABSENT;
575             mSimSlotStatus[i].atr = mSimService[i].getATR();
576             mSimSlotStatus[i].eid = mSimService[i].getEID();
577             // TODO: support multiple sim port
578             SimPortInfo[] portInfoList0 = new SimPortInfo[portInfoListLen];
579             portInfoList0[0] = new SimPortInfo();
580             portInfoList0[0].portActive = mSimService[i].isSlotPortActive();
581             portInfoList0[0].logicalSlotId = mSimService[i].getLogicalSlotId();
582             portInfoList0[0].iccId = mSimService[i].getICCID();
583             mSimSlotStatus[i].portInfo = portInfoList0;
584         }
585     }
586 
updateCardStatus(int slotId)587     private void updateCardStatus(int slotId) {
588         if (slotId >= 0
589                 && slotId < mSimService.length
590                 && mSimService != null
591                 && mSimService[slotId] != null) {
592             mCardStatus[slotId] = new CardStatus();
593             mCardStatus[slotId].cardState =
594                     mSimService[slotId].isCardPresent()
595                             ? CardStatus.STATE_PRESENT
596                             : CardStatus.STATE_ABSENT;
597             mCardStatus[slotId].universalPinState = mSimService[slotId].getUniversalPinState();
598             mCardStatus[slotId].gsmUmtsSubscriptionAppIndex = mSimService[slotId].getGsmAppIndex();
599             mCardStatus[slotId].cdmaSubscriptionAppIndex = mSimService[slotId].getCdmaAppIndex();
600             mCardStatus[slotId].imsSubscriptionAppIndex = mSimService[slotId].getImsAppIndex();
601             mCardStatus[slotId].applications = mSimService[slotId].getSimApp();
602             mCardStatus[slotId].atr = mSimService[slotId].getATR();
603             mCardStatus[slotId].iccid = mSimService[slotId].getICCID();
604             mCardStatus[slotId].eid = mSimService[slotId].getEID();
605             mCardStatus[slotId].slotMap = new SlotPortMapping();
606             mCardStatus[slotId].slotMap.physicalSlotId = mSimService[slotId].getPhysicalSlotId();
607             mCardStatus[slotId].slotMap.portId = mSimService[slotId].getSlotPortId();
608             mSimAppList[slotId] = mSimService[slotId].getSimAppList();
609         } else {
610             Log.e(mTAG, "Invalid Sim physical id(" + slotId + ") or SIM card didn't be created.");
611         }
612     }
613 
loadSIMCard(int slotId, int simProfileId)614     private boolean loadSIMCard(int slotId, int simProfileId) {
615         boolean result = false;
616         if (slotId >= 0
617                 && slotId < mSimService.length
618                 && mSimService != null
619                 && mSimService[slotId] != null) {
620             result = mSimService[slotId].loadSimCard(simProfileId);
621             if (slotId == DEFAULT_SLOT_ID) {
622                 updateSimSlotStatus();
623             }
624             updateCardStatus(slotId);
625         }
626         return result;
627     }
628 
generateRandomIccid(String baseIccid)629     private String generateRandomIccid(String baseIccid) {
630         String newIccid;
631         Random rnd = new Random();
632         StringBuilder randomNum = new StringBuilder();
633 
634         // Generate random 12-digit account id
635         for (int i = 0; i < 12; i++) {
636             randomNum.append(rnd.nextInt(10));
637         }
638 
639         Log.d(mTAG, "Random Num = " + randomNum.toString());
640 
641         // TODO: regenerate checksum
642         // Simply modify account id from base Iccid
643         newIccid =
644                 baseIccid.substring(0, 7)
645                         + randomNum.toString()
646                         + baseIccid.substring(baseIccid.length() - 1);
647 
648         Log.d(mTAG, "Generate new Iccid = " + newIccid);
649 
650         return newIccid;
651     }
652 
setSimInfo(int slotId, int simInfoType, String[] simInfoData)653     private SimInfoChangedResult setSimInfo(int slotId, int simInfoType, String[] simInfoData) {
654         SimInfoChangedResult result = null;
655 
656         if (simInfoData == null) {
657             Log.e(mTAG, "simInfoData == null");
658             return result;
659         }
660 
661         switch (simInfoType) {
662             case SimInfoChangedResult.SIM_INFO_TYPE_MCC_MNC:
663                 if (simInfoData.length == 2 && simInfoData[0] != null && simInfoData[1] != null) {
664                     String msin = mSimService[slotId].getMsin();
665 
666                     // Adjust msin length to make sure IMSI length is valid.
667                     if (simInfoData[1].length() == 3 && msin.length() == 10) {
668                         msin = msin.substring(0, msin.length() - 1);
669                         Log.d(mTAG, "Modify msin = " + msin);
670                     }
671                     mSimService[slotId].setImsi(simInfoData[0], simInfoData[1], msin);
672 
673                     // Auto-generate a new Iccid to change carrier config id in Android Framework
674                     mSimService[slotId].setICCID(
675                             generateRandomIccid(mSimService[slotId].getICCID()));
676                     updateSimSlotStatus();
677                     updateCardStatus(slotId);
678 
679                     result =
680                             new SimInfoChangedResult(
681                                     simInfoType, EF_ICCID, mSimService[slotId].getActiveSimAppId());
682                 }
683                 break;
684             case SimInfoChangedResult.SIM_INFO_TYPE_IMSI:
685                 if (simInfoData.length == 3
686                         && simInfoData[0] != null
687                         && simInfoData[1] != null
688                         && simInfoData[2] != null) {
689                     mSimService[slotId].setImsi(simInfoData[0], simInfoData[1], simInfoData[2]);
690 
691                     // Auto-generate a new Iccid to change carrier config id in Android Framework
692                     mSimService[slotId].setICCID(
693                             generateRandomIccid(mSimService[slotId].getICCID()));
694                     updateSimSlotStatus();
695                     updateCardStatus(slotId);
696 
697                     result =
698                             new SimInfoChangedResult(
699                                     simInfoType, EF_ICCID, mSimService[slotId].getActiveSimAppId());
700                 }
701                 break;
702             case SimInfoChangedResult.SIM_INFO_TYPE_ATR:
703                 if (simInfoData[0] != null) {
704                     mSimService[slotId].setATR(simInfoData[0]);
705                     updateSimSlotStatus();
706                     updateCardStatus(slotId);
707                     result = new SimInfoChangedResult(simInfoType, 0, "");
708                 }
709                 break;
710             default:
711                 Log.e(mTAG, "Not support Sim info type(" + simInfoType + ") to modify");
712                 break;
713         }
714 
715         return result;
716     }
717 
notifyDeviceIdentityChangedRegistrants(int logicalSlotId)718     private void notifyDeviceIdentityChangedRegistrants(int logicalSlotId) {
719         String[] deviceIdentity = new String[4];
720         int physicalSlotId = getSimLogicalSlotId(logicalSlotId);
721 
722         synchronized (mConfigAccess[physicalSlotId]) {
723             deviceIdentity[0] = mImei[physicalSlotId];
724             deviceIdentity[1] = mImeiSv[physicalSlotId];
725             deviceIdentity[2] = mEsn[physicalSlotId];
726             deviceIdentity[3] = mMeid[physicalSlotId];
727         }
728         AsyncResult ar = new AsyncResult(null, deviceIdentity, null);
729         mDeviceIdentityChangedRegistrants[logicalSlotId].notifyRegistrants(ar);
730     }
731 
notifyDeviceImeiTypeChangedRegistrants(int logicalSlotId)732     private void notifyDeviceImeiTypeChangedRegistrants(int logicalSlotId) {
733         int physicalSlotId = getSimLogicalSlotId(logicalSlotId);
734         android.hardware.radio.modem.ImeiInfo imeiInfo =
735                 new android.hardware.radio.modem.ImeiInfo();
736         synchronized (mConfigAccess[physicalSlotId]) {
737             imeiInfo.type = mImeiType[physicalSlotId];
738             imeiInfo.imei = mImei[physicalSlotId];
739             imeiInfo.svn = mImeiSv[physicalSlotId];
740         }
741         AsyncResult ar = new AsyncResult(null, imeiInfo, null);
742         mDeviceImeiInfoChangedRegistrants[logicalSlotId].notifyRegistrants(ar);
743     }
744 
745     // ***** MockModemConfigInterface implementation
746     @Override
destroy()747     public void destroy() {
748         // Mock Services destroy
749         for (int i = 0; i < mNumOfPhone; i++) {
750             // IRadioVoice
751             if (mVoiceService != null && mVoiceService[i] != null) {
752                 mVoiceService[i].destroy();
753             }
754         }
755     }
756 
757     @Override
getMockModemConfigHandler(int logicalSlotId)758     public Handler getMockModemConfigHandler(int logicalSlotId) {
759         return mHandler[logicalSlotId];
760     }
761 
762     @Override
notifyAllRegistrantNotifications()763     public void notifyAllRegistrantNotifications() {
764         Log.d(mTAG, "notifyAllRegistrantNotifications");
765 
766         // IRadioConfig
767         mNumOfLiveModemChangedRegistrants.notifyRegistrants(
768                 new AsyncResult(null, mNumOfLiveModem, null));
769         mPhoneCapabilityChangedRegistrants.notifyRegistrants(
770                 new AsyncResult(null, mPhoneCapability, null));
771         mSimSlotStatusChangedRegistrants.notifyRegistrants(
772                 new AsyncResult(null, mSimSlotStatus, null));
773 
774         // IRadioModem
775         mBasebandVersionChangedRegistrants.notifyRegistrants(
776                 new AsyncResult(null, mBasebandVersion, null));
777         mRadioStateChangedRegistrants.notifyRegistrants(new AsyncResult(null, mRadioState, null));
778 
779         for (int i = 0; i < mNumOfPhone; i++) {
780             int physicalSlotId = getSimPhysicalSlotId(i);
781 
782             synchronized (mConfigAccess[physicalSlotId]) {
783                 // IRadioModem
784                 notifyDeviceIdentityChangedRegistrants(i);
785                 notifyDeviceImeiTypeChangedRegistrants(i);
786 
787                 // IRadioSim
788                 mCardStatusChangedRegistrants[i].notifyRegistrants(
789                         new AsyncResult(null, mCardStatus[physicalSlotId], null));
790                 mSimAppDataChangedRegistrants[i].notifyRegistrants(
791                         new AsyncResult(null, mSimAppList[physicalSlotId], null));
792             }
793         }
794     }
795 
796     // ***** IRadioConfig notification implementation
797     @Override
registerForNumOfLiveModemChanged( int logicalSlotId, Handler h, int what, Object obj)798     public void registerForNumOfLiveModemChanged(
799             int logicalSlotId, Handler h, int what, Object obj) {
800         mNumOfLiveModemChangedRegistrants.addUnique(h, what, obj);
801     }
802 
803     @Override
unregisterForNumOfLiveModemChanged(int logicalSlotId, Handler h)804     public void unregisterForNumOfLiveModemChanged(int logicalSlotId, Handler h) {
805         mNumOfLiveModemChangedRegistrants.remove(h);
806     }
807 
808     @Override
registerForPhoneCapabilityChanged( int logicalSlotId, Handler h, int what, Object obj)809     public void registerForPhoneCapabilityChanged(
810             int logicalSlotId, Handler h, int what, Object obj) {
811         mPhoneCapabilityChangedRegistrants.addUnique(h, what, obj);
812     }
813 
814     @Override
unregisterForPhoneCapabilityChanged(int logicalSlotId, Handler h)815     public void unregisterForPhoneCapabilityChanged(int logicalSlotId, Handler h) {
816         mPhoneCapabilityChangedRegistrants.remove(h);
817     }
818 
819     @Override
registerForSimSlotStatusChanged( int logicalSlotId, Handler h, int what, Object obj)820     public void registerForSimSlotStatusChanged(
821             int logicalSlotId, Handler h, int what, Object obj) {
822         mSimSlotStatusChangedRegistrants.addUnique(h, what, obj);
823     }
824 
825     @Override
unregisterForSimSlotStatusChanged(int logicalSlotId, Handler h)826     public void unregisterForSimSlotStatusChanged(int logicalSlotId, Handler h) {
827         mSimSlotStatusChangedRegistrants.remove(h);
828     }
829 
830     // ***** IRadioModem notification implementation
831     @Override
registerForBasebandVersionChanged( int logicalSlotId, Handler h, int what, Object obj)832     public void registerForBasebandVersionChanged(
833             int logicalSlotId, Handler h, int what, Object obj) {
834         mBasebandVersionChangedRegistrants.addUnique(h, what, obj);
835     }
836 
837     @Override
unregisterForBasebandVersionChanged(int logicalSlotId, Handler h)838     public void unregisterForBasebandVersionChanged(int logicalSlotId, Handler h) {
839         mBasebandVersionChangedRegistrants.remove(h);
840     }
841 
842     @Override
registerForDeviceIdentityChanged( int logicalSlotId, Handler h, int what, Object obj)843     public void registerForDeviceIdentityChanged(
844             int logicalSlotId, Handler h, int what, Object obj) {
845         mDeviceIdentityChangedRegistrants[logicalSlotId].addUnique(h, what, obj);
846     }
847 
848     @Override
registerForDeviceImeiInfoChanged( int logicalSlotId, Handler h, int what, Object obj)849     public void registerForDeviceImeiInfoChanged(
850             int logicalSlotId, Handler h, int what, Object obj) {
851         mDeviceImeiInfoChangedRegistrants[logicalSlotId].addUnique(h, what, obj);
852     }
853 
854     @Override
unregisterForDeviceIdentityChanged(int logicalSlotId, Handler h)855     public void unregisterForDeviceIdentityChanged(int logicalSlotId, Handler h) {
856         mDeviceIdentityChangedRegistrants[logicalSlotId].remove(h);
857     }
858 
859     @Override
registerForRadioStateChanged(int logicalSlotId, Handler h, int what, Object obj)860     public void registerForRadioStateChanged(int logicalSlotId, Handler h, int what, Object obj) {
861         mRadioStateChangedRegistrants.addUnique(h, what, obj);
862     }
863 
864     @Override
unregisterForRadioStateChanged(int logicalSlotId, Handler h)865     public void unregisterForRadioStateChanged(int logicalSlotId, Handler h) {
866         mRadioStateChangedRegistrants.remove(h);
867     }
868 
869     // ***** IRadioSim notification implementation
870     @Override
registerForCardStatusChanged(int logicalSlotId, Handler h, int what, Object obj)871     public void registerForCardStatusChanged(int logicalSlotId, Handler h, int what, Object obj) {
872         mCardStatusChangedRegistrants[logicalSlotId].addUnique(h, what, obj);
873     }
874 
875     @Override
unregisterForCardStatusChanged(int logicalSlotId, Handler h)876     public void unregisterForCardStatusChanged(int logicalSlotId, Handler h) {
877         mCardStatusChangedRegistrants[logicalSlotId].remove(h);
878     }
879 
880     @Override
registerForSimAppDataChanged(int logicalSlotId, Handler h, int what, Object obj)881     public void registerForSimAppDataChanged(int logicalSlotId, Handler h, int what, Object obj) {
882         mSimAppDataChangedRegistrants[logicalSlotId].addUnique(h, what, obj);
883     }
884 
885     @Override
unregisterForSimAppDataChanged(int logicalSlotId, Handler h)886     public void unregisterForSimAppDataChanged(int logicalSlotId, Handler h) {
887         mSimAppDataChangedRegistrants[logicalSlotId].remove(h);
888     }
889 
890     @Override
registerForSimInfoChanged(int logicalSlotId, Handler h, int what, Object obj)891     public void registerForSimInfoChanged(int logicalSlotId, Handler h, int what, Object obj) {
892         mSimInfoChangedRegistrants[logicalSlotId].addUnique(h, what, obj);
893     }
894 
895     @Override
unregisterForSimInfoChanged(int logicalSlotId, Handler h)896     public void unregisterForSimInfoChanged(int logicalSlotId, Handler h) {
897         mSimInfoChangedRegistrants[logicalSlotId].remove(h);
898     }
899 
900     // ***** IRadioNetwork notification implementation
901     @Override
registerForServiceStateChanged(int logicalSlotId, Handler h, int what, Object obj)902     public void registerForServiceStateChanged(int logicalSlotId, Handler h, int what, Object obj) {
903         mServiceStateChangedRegistrants[logicalSlotId].addUnique(h, what, obj);
904     }
905 
906     @Override
unregisterForServiceStateChanged(int logicalSlotId, Handler h)907     public void unregisterForServiceStateChanged(int logicalSlotId, Handler h) {
908         mServiceStateChangedRegistrants[logicalSlotId].remove(h);
909     }
910 
911     // ***** IRadioVoice notification implementation
912     @Override
registerForCallStateChanged(int logicalSlotId, Handler h, int what, Object obj)913     public void registerForCallStateChanged(int logicalSlotId, Handler h, int what, Object obj) {
914         mCallStateChangedRegistrants[logicalSlotId].addUnique(h, what, obj);
915     }
916 
917     @Override
unregisterForCallStateChanged(int logicalSlotId, Handler h)918     public void unregisterForCallStateChanged(int logicalSlotId, Handler h) {
919         mCallStateChangedRegistrants[logicalSlotId].remove(h);
920     }
921 
922     @Override
registerForCurrentCallsResponse( int logicalSlotId, Handler h, int what, Object obj)923     public void registerForCurrentCallsResponse(
924             int logicalSlotId, Handler h, int what, Object obj) {
925         mCurrentCallsResponseRegistrants[logicalSlotId].addUnique(h, what, obj);
926     }
927 
928     @Override
unregisterForCurrentCallsResponse(int logicalSlotId, Handler h)929     public void unregisterForCurrentCallsResponse(int logicalSlotId, Handler h) {
930         mCurrentCallsResponseRegistrants[logicalSlotId].remove(h);
931     }
932 
933     @Override
registerForCallIncoming(int logicalSlotId, Handler h, int what, Object obj)934     public void registerForCallIncoming(int logicalSlotId, Handler h, int what, Object obj) {
935         mCallIncomingRegistrants[logicalSlotId].addUnique(h, what, obj);
936     }
937 
938     @Override
unregisterForCallIncoming(int logicalSlotId, Handler h)939     public void unregisterForCallIncoming(int logicalSlotId, Handler h) {
940         mCallIncomingRegistrants[logicalSlotId].remove(h);
941     }
942 
943     @Override
registerRingbackTone(int logicalSlotId, Handler h, int what, Object obj)944     public void registerRingbackTone(int logicalSlotId, Handler h, int what, Object obj) {
945         mRingbackToneRegistrants[logicalSlotId].addUnique(h, what, obj);
946     }
947 
948     @Override
unregisterRingbackTone(int logicalSlotId, Handler h)949     public void unregisterRingbackTone(int logicalSlotId, Handler h) {
950         mRingbackToneRegistrants[logicalSlotId].remove(h);
951     }
952 
953     // ***** IRadioConfig set APIs implementation
954 
955     // ***** IRadioModem set APIs implementation
956     @Override
setRadioState(int logicalSlotId, int state, String client)957     public void setRadioState(int logicalSlotId, int state, String client) {
958         Log.d(mTAG, "setRadioState[" + logicalSlotId + "] (" + state + ") from " + client);
959 
960         Message msg = mHandler[logicalSlotId].obtainMessage(EVENT_SET_RADIO_POWER);
961         msg.arg1 = state;
962         mHandler[logicalSlotId].sendMessage(msg);
963     }
964 
965     // ***** IRadioSim set APIs implementation
966 
967     // ***** IRadioNetwork set APIs implementation
968 
969     // ***** IRadioVoice set APIs implementation
970     @Override
getCurrentCalls(int logicalSlotId, String client)971     public boolean getCurrentCalls(int logicalSlotId, String client) {
972         Log.d(mTAG, "getCurrentCalls[" + logicalSlotId + "] from: " + client);
973         return mVoiceService[logicalSlotId].getCurrentCalls();
974     }
975 
976     @Override
dialVoiceCall( int logicalSlotId, String address, int clir, UusInfo[] uusInfo, String client)977     public boolean dialVoiceCall(
978             int logicalSlotId, String address, int clir, UusInfo[] uusInfo, String client) {
979         return dialVoiceCall(logicalSlotId, address, clir, uusInfo, mCallControlInfo, client);
980     }
981 
982     @Override
dialVoiceCall( int logicalSlotId, String address, int clir, UusInfo[] uusInfo, MockCallControlInfo callControlInfo, String client)983     public boolean dialVoiceCall(
984             int logicalSlotId,
985             String address,
986             int clir,
987             UusInfo[] uusInfo,
988             MockCallControlInfo callControlInfo,
989             String client) {
990         Log.d(
991                 mTAG,
992                 "dialVoiceCall["
993                         + logicalSlotId
994                         + "]: address = "
995                         + address
996                         + " clir = "
997                         + clir
998                         + " from: "
999                         + client);
1000         if (uusInfo == null) {
1001             Log.e(mTAG, "ussInfo == null!");
1002             return false;
1003         }
1004 
1005         int callType = CALL_TYPE_VOICE;
1006         return mVoiceService[logicalSlotId].dialVoiceCall(
1007                 address, clir, uusInfo, callType, callControlInfo);
1008     }
1009 
1010     @Override
dialEccVoiceCall( int logicalSlotId, String address, int categories, String[] urns, int routing, String client)1011     public boolean dialEccVoiceCall(
1012             int logicalSlotId,
1013             String address,
1014             int categories,
1015             String[] urns,
1016             int routing,
1017             String client) {
1018         return dialEccVoiceCall(
1019                 logicalSlotId, address, categories, urns, routing, mCallControlInfo, client);
1020     }
1021 
1022     @Override
dialEccVoiceCall( int logicalSlotId, String address, int categories, String[] urns, int routing, MockCallControlInfo callControlInfo, String client)1023     public boolean dialEccVoiceCall(
1024             int logicalSlotId,
1025             String address,
1026             int categories,
1027             String[] urns,
1028             int routing,
1029             MockCallControlInfo callControlInfo,
1030             String client) {
1031         Log.d(
1032                 mTAG,
1033                 "dialEccVoiceCall["
1034                         + logicalSlotId
1035                         + "]: address = "
1036                         + address
1037                         + " categories = "
1038                         + categories
1039                         + " from: "
1040                         + client);
1041 
1042         return mVoiceService[logicalSlotId].dialEccVoiceCall(
1043                 address, categories, urns, routing, CALL_TYPE_EMERGENCY, callControlInfo);
1044     }
1045 
1046     @Override
hangupVoiceCall(int logicalSlotId, int index, String client)1047     public boolean hangupVoiceCall(int logicalSlotId, int index, String client) {
1048         Log.d(
1049                 mTAG,
1050                 "hangupVoiceCall[" + logicalSlotId + "]: index = " + index + " from: " + client);
1051         return mVoiceService[logicalSlotId].hangupVoiceCall(index);
1052     }
1053 
1054     @Override
rejectVoiceCall(int logicalSlotId, String client)1055     public boolean rejectVoiceCall(int logicalSlotId, String client) {
1056         Log.d(mTAG, "rejectVoiceCall[" + logicalSlotId + "] from: " + client);
1057         return mVoiceService[logicalSlotId].rejectVoiceCall();
1058     }
1059 
1060     @Override
acceptVoiceCall(int logicalSlotId, String client)1061     public boolean acceptVoiceCall(int logicalSlotId, String client) {
1062         Log.d(mTAG, "acceptVoiceCall[" + logicalSlotId + "] from: " + client);
1063         return mVoiceService[logicalSlotId].acceptVoiceCall();
1064     }
1065 
1066     @Override
getLastCallFailCause(int logicalSlotId, String client)1067     public LastCallFailCauseInfo getLastCallFailCause(int logicalSlotId, String client) {
1068         Log.d(mTAG, "getLastCallFailCause[" + logicalSlotId + "] from: " + client);
1069         return mVoiceService[logicalSlotId].getLastCallEndInfo();
1070     }
1071 
1072     @Override
setLastCallFailCause( int logicalSlotId, @Annotation.DisconnectCauses int cause, String client)1073     public void setLastCallFailCause(
1074             int logicalSlotId, @Annotation.DisconnectCauses int cause, String client) {
1075         Log.d(
1076                 mTAG,
1077                 "setLastCallFailCause["
1078                         + logicalSlotId
1079                         + "]: cause = "
1080                         + cause
1081                         + "  from: "
1082                         + client);
1083         mVoiceService[logicalSlotId].setLastCallFailCause(cause);
1084     }
1085 
1086     @Override
clearAllCalls( int logicalSlotId, @Annotation.DisconnectCauses int cause, String client)1087     public void clearAllCalls(
1088             int logicalSlotId, @Annotation.DisconnectCauses int cause, String client) {
1089         Log.d(mTAG, "clearAllCalls[" + logicalSlotId + "]: cause = " + cause + "  from: " + client);
1090         mVoiceService[logicalSlotId].clearAllCalls(cause);
1091     }
1092 
1093     @Override
getVoiceMuteMode(int logicalSlotId, String client)1094     public boolean getVoiceMuteMode(int logicalSlotId, String client) {
1095         Log.d(mTAG, "getVoiceMuteMode[" + logicalSlotId + "] from " + client);
1096         return mVoiceService[logicalSlotId].getMuteMode();
1097     }
1098 
1099     @Override
setVoiceMuteMode(int logicalSlotId, boolean muteMode, String client)1100     public boolean setVoiceMuteMode(int logicalSlotId, boolean muteMode, String client) {
1101         Log.d(
1102                 mTAG,
1103                 "setVoiceMuteMode["
1104                         + logicalSlotId
1105                         + "]: muteMode = "
1106                         + muteMode
1107                         + " from: "
1108                         + client);
1109         mVoiceService[logicalSlotId].setMuteMode(muteMode);
1110         return true;
1111     }
1112 
1113     // ***** IRadioData set APIs implementation
1114 
1115     // ***** IRadioMessaging set APIs implementation
1116 
1117     // ***** Utility methods implementation
1118     @Override
isSimCardPresent(int logicalSlotId, String client)1119     public boolean isSimCardPresent(int logicalSlotId, String client) {
1120         Log.d(mTAG, "isSimCardPresent[" + logicalSlotId + "] from: " + client);
1121 
1122         int physicalSlotId = getSimPhysicalSlotId(logicalSlotId);
1123         boolean isPresent = false;
1124         if (physicalSlotId == DEFAULT_SLOT_ID) {
1125             synchronized (mConfigAccess[physicalSlotId]) {
1126                 isPresent =
1127                         (mCardStatus[physicalSlotId].cardState == CardStatus.STATE_PRESENT)
1128                                 ? true
1129                                 : false;
1130             }
1131         } else if (physicalSlotId == ESIM_SLOT_ID) {
1132             synchronized (mConfigAccess[physicalSlotId]) {
1133                 isPresent = (mCardStatus[physicalSlotId].iccid.trim().length() > 0) ? true : false;
1134             }
1135         }
1136         return isPresent;
1137     }
1138 
1139     @Override
changeSimProfile(int logicalSlotId, int simprofileid, String client)1140     public boolean changeSimProfile(int logicalSlotId, int simprofileid, String client) {
1141         boolean result = true;
1142         Log.d(
1143                 mTAG,
1144                 "changeSimProfile["
1145                         + logicalSlotId
1146                         + "]: profile id("
1147                         + simprofileid
1148                         + ") from: "
1149                         + client);
1150 
1151         if (simprofileid >= MOCK_SIM_PROFILE_ID_DEFAULT && simprofileid < MOCK_SIM_PROFILE_ID_MAX) {
1152             Message msg = mHandler[logicalSlotId].obtainMessage(EVENT_CHANGE_SIM_PROFILE);
1153             msg.getData().putInt("changeSimProfile", simprofileid);
1154             mHandler[logicalSlotId].sendMessage(msg);
1155         } else {
1156             result = false;
1157         }
1158 
1159         return result;
1160     }
1161 
1162     @Override
setSimInfo(int logicalSlotId, int type, String[] data, String client)1163     public void setSimInfo(int logicalSlotId, int type, String[] data, String client) {
1164         Log.d(mTAG, "setSimInfo[" + logicalSlotId + "]: type(" + type + ") from: " + client);
1165 
1166         Message msg = mHandler[logicalSlotId].obtainMessage(EVENT_SET_SIM_INFO);
1167         Bundle bundle = msg.getData();
1168         bundle.putInt("setSimInfo:type", type);
1169         bundle.putStringArray("setSimInfo:data", data);
1170         mHandler[logicalSlotId].sendMessage(msg);
1171     }
1172 
1173     @Override
getSimInfo(int logicalSlotId, int type, String client)1174     public String getSimInfo(int logicalSlotId, int type, String client) {
1175         Log.d(mTAG, "getSimInfo[" + logicalSlotId + "]: type(" + type + ") from: " + client);
1176 
1177         String result = "";
1178         int physicalSlotId = getSimPhysicalSlotId(logicalSlotId);
1179 
1180         synchronized (mConfigAccess[physicalSlotId]) {
1181             switch (type) {
1182                 case SimInfoChangedResult.SIM_INFO_TYPE_MCC_MNC:
1183                     result = mSimService[physicalSlotId].getMccMnc();
1184                     break;
1185                 case SimInfoChangedResult.SIM_INFO_TYPE_IMSI:
1186                     result = mSimService[physicalSlotId].getImsi();
1187                     break;
1188                 case SimInfoChangedResult.SIM_INFO_TYPE_ATR:
1189                     result = mCardStatus[physicalSlotId].atr;
1190                     break;
1191                 default:
1192                     Log.e(mTAG, "Not support this type of SIM info.");
1193                     break;
1194             }
1195         }
1196 
1197         return result;
1198     }
1199 
1200     @Override
setCallControlInfo( int logicalSlotId, MockCallControlInfo callControlInfo, String client)1201     public boolean setCallControlInfo(
1202             int logicalSlotId, MockCallControlInfo callControlInfo, String client) {
1203         Log.d(mTAG, "setCallControlInfo[" + logicalSlotId + " from: " + client);
1204         mCallControlInfo = callControlInfo;
1205 
1206         return true;
1207     }
1208 
1209     @Override
getCallControlInfo(int logicalSlotId, String client)1210     public MockCallControlInfo getCallControlInfo(int logicalSlotId, String client) {
1211         Log.d(mTAG, "getCallControlInfo[" + logicalSlotId + " from: " + client);
1212         return mCallControlInfo;
1213     }
1214 
1215     @Override
triggerIncomingVoiceCall( int logicalSlotId, String address, UusInfo[] uusInfo, CdmaSignalInfoRecord cdmaSignalInfoRecord, MockCallControlInfo callControlInfo, String client)1216     public boolean triggerIncomingVoiceCall(
1217             int logicalSlotId,
1218             String address,
1219             UusInfo[] uusInfo,
1220             CdmaSignalInfoRecord cdmaSignalInfoRecord,
1221             MockCallControlInfo callControlInfo,
1222             String client) {
1223         Log.d(
1224                 mTAG,
1225                 "triggerIncomingVoiceCall["
1226                         + logicalSlotId
1227                         + "]: address = "
1228                         + address
1229                         + " from: "
1230                         + client);
1231         if (uusInfo == null) {
1232             Log.e(mTAG, "ussInfo == null!");
1233             return false;
1234         }
1235 
1236         int callType = CALL_TYPE_VOICE;
1237         return mVoiceService[logicalSlotId].triggerIncomingVoiceCall(
1238                 address, uusInfo, callType, cdmaSignalInfoRecord, callControlInfo);
1239     }
1240 
1241     @Override
getNumberOfCalls(int logicalSlotId, String client)1242     public int getNumberOfCalls(int logicalSlotId, String client) {
1243         Log.d(mTAG, "getNumberOfCalls[" + logicalSlotId + "] from: " + client);
1244         return mVoiceService[logicalSlotId].getNumberOfCalls();
1245     }
1246 }
1247