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