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