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 android.content.Context;
20 import android.hardware.radio.network.BarringInfo;
21 import android.hardware.radio.network.CellConnectionStatus;
22 import android.hardware.radio.network.CellInfo;
23 import android.hardware.radio.network.CellInfoRatSpecificInfo;
24 import android.hardware.radio.network.Domain;
25 import android.hardware.radio.network.EmergencyRegResult;
26 import android.hardware.radio.network.RegState;
27 import android.telephony.RadioAccessFamily;
28 import android.telephony.ServiceState;
29 import android.util.Log;
30 
31 import com.android.internal.telephony.RILConstants;
32 
33 import java.util.ArrayList;
34 import java.util.concurrent.CountDownLatch;
35 import java.util.concurrent.TimeUnit;
36 
37 public class MockNetworkService {
38     private static final String TAG = "MockNetworkService";
39 
40     // Grouping of RAFs
41     // 2G
42     public static final int GSM =
43             RadioAccessFamily.RAF_GSM | RadioAccessFamily.RAF_GPRS | RadioAccessFamily.RAF_EDGE;
44     public static final int CDMA =
45             RadioAccessFamily.RAF_IS95A | RadioAccessFamily.RAF_IS95B | RadioAccessFamily.RAF_1xRTT;
46     // 3G
47     public static final int EVDO =
48             RadioAccessFamily.RAF_EVDO_0
49                     | RadioAccessFamily.RAF_EVDO_A
50                     | RadioAccessFamily.RAF_EVDO_B
51                     | RadioAccessFamily.RAF_EHRPD;
52     public static final int HS =
53             RadioAccessFamily.RAF_HSUPA
54                     | RadioAccessFamily.RAF_HSDPA
55                     | RadioAccessFamily.RAF_HSPA
56                     | RadioAccessFamily.RAF_HSPAP;
57     public static final int WCDMA = HS | RadioAccessFamily.RAF_UMTS;
58     // 4G
59     public static final int LTE = RadioAccessFamily.RAF_LTE | RadioAccessFamily.RAF_LTE_CA;
60     // 5G
61     public static final int NR = RadioAccessFamily.RAF_NR;
62 
63     static final int MOCK_CARRIER_NO_SERVICE = 0;
64 
65     // Network status update reason
66     static final int NETWORK_UPDATE_PREFERRED_MODE_CHANGE = 1;
67 
68     public static final int LATCH_TRIGGER_EMERGENCY_SCAN = 0;
69     public static final int LATCH_CANCEL_EMERGENCY_SCAN = 1;
70     private static final int LATCH_MAX = 2;
71 
72     private int mCsRegState = RegState.NOT_REG_MT_NOT_SEARCHING_OP;
73     private int mPsRegState = RegState.NOT_REG_MT_NOT_SEARCHING_OP;
74 
75     private int mRegFailCause = 0;
76 
77     private Context mContext;
78 
79     private String mSimPlmn;
80     private boolean mIsHomeCamping;
81     private boolean mIsRoamingCamping;
82     private int mHomeCarrierId;
83     private int mRoamingCarrierId;
84     private int mInServiceCarrierId;
85     private int mHighRat;
86 
87     private ArrayList<MockModemCell> mCellList = new ArrayList<MockModemCell>();
88 
89     private BarringInfo[] mBarringInfos = new BarringInfo[0];
90     private EmergencyRegResult mEmergencyRegResult = new EmergencyRegResult();
91     private boolean mEmergencyNetworkScanTriggered = false;
92     private boolean mEmergencyNetworkScanCanceled = false;
93     private int[] mEmergencyNetworkScanAccessNetwork = null;
94     private int mEmergencyNetworkScanType = -1;
95     private int mEmergencyMode = 0;
96 
97     private final CountDownLatch[] mLatches = new CountDownLatch[LATCH_MAX];
98 
99     private class MockModemCell {
100         private int mCarrierId;
101 
102         // Non-AOSP
103         public String[] mEHPlmnList;
104         public String[] mAllowRoamingList;
105 
106         // AOSP
107         private CellInfo[] mCells;
108 
MockModemCell(Context context, String file)109         MockModemCell(Context context, String file) {
110             MockNetworkConfig config;
111 
112             config = new MockNetworkConfig(context);
113             config.getConfigFromAssets(file);
114             mCarrierId = config.getCarrierId();
115             updateHomeRoamingList(config);
116             updateCellList(config);
117         }
118 
getCarrierId()119         public int getCarrierId() {
120             return mCarrierId;
121         }
122 
getCells()123         public CellInfo[] getCells() {
124             return mCells;
125         }
126 
updateHomeRoamingList(MockNetworkConfig config)127         private void updateHomeRoamingList(MockNetworkConfig config) {
128             mEHPlmnList = config.getEHPlmnList();
129             mAllowRoamingList = config.getAllowRoamingList();
130         }
131 
updateCellList(MockNetworkConfig config)132         private void updateCellList(MockNetworkConfig config) {
133             int cellNum;
134 
135             cellNum = config.getCellNum();
136             mCells = new CellInfo[cellNum];
137             for (int i = 0; i < cellNum; i++) {
138                 mCells[i] = config.getCellInfo(i);
139             }
140         }
141 
getPrimaryCellOperatorInfo()142         public android.hardware.radio.network.OperatorInfo getPrimaryCellOperatorInfo() {
143             android.hardware.radio.network.OperatorInfo operatorInfo =
144                     new android.hardware.radio.network.OperatorInfo();
145             for (CellInfo cellInfo : getCells()) {
146                 if (cellInfo.connectionStatus == CellConnectionStatus.PRIMARY_SERVING) {
147                     switch (cellInfo.ratSpecificInfo.getTag()) {
148                         case CellInfoRatSpecificInfo.wcdma:
149                             operatorInfo =
150                                     cellInfo.ratSpecificInfo.getWcdma()
151                                             .cellIdentityWcdma
152                                             .operatorNames;
153                             break;
154                         case CellInfoRatSpecificInfo.lte:
155                             operatorInfo =
156                                     cellInfo.ratSpecificInfo.getLte().cellIdentityLte.operatorNames;
157                             break;
158                         default:
159                             break;
160                     }
161                 }
162             }
163 
164             return operatorInfo;
165         }
166 
getPrimaryCellSignalStrength()167         public android.hardware.radio.network.SignalStrength getPrimaryCellSignalStrength() {
168             android.hardware.radio.network.SignalStrength signalStrength =
169                     new android.hardware.radio.network.SignalStrength();
170 
171             signalStrength.gsm = new android.hardware.radio.network.GsmSignalStrength();
172             signalStrength.cdma = new android.hardware.radio.network.CdmaSignalStrength();
173             signalStrength.evdo = new android.hardware.radio.network.EvdoSignalStrength();
174             signalStrength.lte = new android.hardware.radio.network.LteSignalStrength();
175             signalStrength.tdscdma = new android.hardware.radio.network.TdscdmaSignalStrength();
176             signalStrength.wcdma = new android.hardware.radio.network.WcdmaSignalStrength();
177             signalStrength.nr = new android.hardware.radio.network.NrSignalStrength();
178             signalStrength.nr.csiCqiReport = new byte[0];
179 
180             for (CellInfo cellInfo : getCells()) {
181                 if (cellInfo.connectionStatus == CellConnectionStatus.PRIMARY_SERVING) {
182                     switch (cellInfo.ratSpecificInfo.getTag()) {
183                         case CellInfoRatSpecificInfo.wcdma:
184                             signalStrength.wcdma =
185                                     cellInfo.ratSpecificInfo.getWcdma().signalStrengthWcdma;
186                             break;
187                         case CellInfoRatSpecificInfo.lte:
188                             signalStrength.lte =
189                                     cellInfo.ratSpecificInfo.getLte().signalStrengthLte;
190                             break;
191                         default:
192                             break;
193                     }
194                 }
195             }
196 
197             return signalStrength;
198         }
199 
getPrimaryCellRat()200         public int getPrimaryCellRat() {
201             int rat = android.hardware.radio.RadioTechnology.UNKNOWN;
202 
203             for (CellInfo cellInfo : getCells()) {
204                 if (cellInfo.connectionStatus == CellConnectionStatus.PRIMARY_SERVING) {
205                     switch (cellInfo.ratSpecificInfo.getTag()) {
206                         case CellInfoRatSpecificInfo.wcdma:
207                             // TODO: Need find an element to assign the rat WCDMA, HSUPA, HSDPA, or
208                             // HSPA
209                             rat = android.hardware.radio.RadioTechnology.HSPA;
210                             break;
211                         case CellInfoRatSpecificInfo.lte:
212                             rat = android.hardware.radio.RadioTechnology.LTE;
213                             break;
214                         default:
215                             break;
216                     }
217                 }
218             }
219 
220             return rat;
221         }
222 
getPrimaryCellIdentity()223         public android.hardware.radio.network.CellIdentity getPrimaryCellIdentity() {
224             android.hardware.radio.network.CellIdentity cellIdentity =
225                     android.hardware.radio.network.CellIdentity.noinit(true);
226 
227             for (CellInfo cellInfo : getCells()) {
228                 if (cellInfo.connectionStatus == CellConnectionStatus.PRIMARY_SERVING) {
229                     switch (cellInfo.ratSpecificInfo.getTag()) {
230                         case CellInfoRatSpecificInfo.wcdma:
231                             cellIdentity.setWcdma(
232                                     cellInfo.ratSpecificInfo.getWcdma().cellIdentityWcdma);
233                             break;
234                         case CellInfoRatSpecificInfo.lte:
235                             cellIdentity.setLte(cellInfo.ratSpecificInfo.getLte().cellIdentityLte);
236                             break;
237                         default:
238                             break;
239                     }
240                 }
241             }
242 
243             return cellIdentity;
244         }
245     }
246 
MockNetworkService(Context context)247     public MockNetworkService(Context context) {
248         mContext = context;
249         loadMockModemCell("mock_network_tw_cht.xml");
250         loadMockModemCell("mock_network_tw_fet.xml");
251         loadMockModemCell("mock_network_us_fi.xml");
252         for (int i = 0; i < LATCH_MAX; i++) {
253             mLatches[i] = new CountDownLatch(1);
254         }
255     }
256 
loadMockModemCell(String config)257     public void loadMockModemCell(String config) {
258         MockModemCell tmp = new MockModemCell(mContext, config);
259         int cid = tmp.getCarrierId();
260         if (!mCellList.isEmpty()) {
261             for (MockModemCell mmc : mCellList) {
262                 if (mmc.getCarrierId() == cid) {
263                     Log.d(TAG, "Carrier ID " + cid + " had been loaded.");
264                     return;
265                 }
266             }
267         }
268 
269         Log.d(TAG, "Load carrier(" + cid + ") " + config);
270         mCellList.add(tmp);
271     }
272 
getHighestRatFromNetworkType(int raf)273     private int getHighestRatFromNetworkType(int raf) {
274         int rat;
275         int networkMode = RadioAccessFamily.getNetworkTypeFromRaf(raf);
276 
277         switch (networkMode) {
278             case RILConstants.NETWORK_MODE_WCDMA_PREF:
279                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_HSPA;
280                 break;
281             case RILConstants.NETWORK_MODE_GSM_ONLY:
282                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_GSM;
283                 break;
284             case RILConstants.NETWORK_MODE_WCDMA_ONLY:
285                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_HSPA;
286                 break;
287             case RILConstants.NETWORK_MODE_GSM_UMTS:
288                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_HSPA;
289                 break;
290             case RILConstants.NETWORK_MODE_CDMA:
291                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_IS95A;
292                 break;
293             case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO:
294                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE;
295                 break;
296             case RILConstants.NETWORK_MODE_LTE_GSM_WCDMA:
297                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE;
298                 break;
299             case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
300                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE;
301                 break;
302             case RILConstants.NETWORK_MODE_LTE_ONLY:
303                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE;
304                 break;
305             case RILConstants.NETWORK_MODE_LTE_WCDMA:
306                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE;
307                 break;
308             case RILConstants.NETWORK_MODE_CDMA_NO_EVDO:
309                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_IS95A;
310                 break;
311             case RILConstants.NETWORK_MODE_EVDO_NO_CDMA:
312                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0;
313                 break;
314             case RILConstants.NETWORK_MODE_GLOBAL:
315                 // GSM | WCDMA | CDMA | EVDO;
316                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_HSPA;
317                 break;
318             case RILConstants.NETWORK_MODE_TDSCDMA_ONLY:
319                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA;
320                 break;
321             case RILConstants.NETWORK_MODE_TDSCDMA_WCDMA:
322                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_HSPA;
323                 break;
324             case RILConstants.NETWORK_MODE_LTE_TDSCDMA:
325                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE;
326                 break;
327             case RILConstants.NETWORK_MODE_TDSCDMA_GSM:
328                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA;
329                 break;
330             case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM:
331                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE;
332                 break;
333             case RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
334                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_HSPA;
335                 break;
336             case RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
337                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE;
338                 break;
339             case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
340                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE;
341                 break;
342             case RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
343                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_HSPA;
344                 break;
345             case RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
346                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE;
347                 break;
348             case RILConstants.NETWORK_MODE_NR_ONLY:
349                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR;
350                 break;
351             case RILConstants.NETWORK_MODE_NR_LTE:
352                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR;
353                 break;
354             case RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO:
355                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR;
356                 break;
357             case RILConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA:
358                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR;
359                 break;
360             case RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA:
361                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR;
362                 break;
363             case RILConstants.NETWORK_MODE_NR_LTE_WCDMA:
364                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR;
365                 break;
366             case RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA:
367                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR;
368                 break;
369             case RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM:
370                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR;
371                 break;
372             case RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA:
373                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR;
374                 break;
375             case RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA:
376                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR;
377                 break;
378             case RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
379                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR;
380                 break;
381             default:
382                 rat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
383                 break;
384         }
385         return rat;
386     }
387 
getPrimaryCellOperatorInfo()388     public android.hardware.radio.network.OperatorInfo getPrimaryCellOperatorInfo() {
389         android.hardware.radio.network.OperatorInfo operatorInfo =
390                 new android.hardware.radio.network.OperatorInfo();
391 
392         if (mCsRegState == RegState.REG_HOME || mPsRegState == RegState.REG_HOME) {
393             operatorInfo = getCarrierStatus(mHomeCarrierId).getPrimaryCellOperatorInfo();
394         } else if (mCsRegState == RegState.REG_ROAMING || mPsRegState == RegState.REG_ROAMING) {
395             operatorInfo = getCarrierStatus(mRoamingCarrierId).getPrimaryCellOperatorInfo();
396         }
397 
398         return operatorInfo;
399     }
400 
getPrimaryCellIdentity()401     public android.hardware.radio.network.CellIdentity getPrimaryCellIdentity() {
402         android.hardware.radio.network.CellIdentity cellIdentity =
403                 android.hardware.radio.network.CellIdentity.noinit(true);
404 
405         if (mCsRegState == RegState.REG_HOME || mPsRegState == RegState.REG_HOME) {
406             cellIdentity = getCarrierStatus(mHomeCarrierId).getPrimaryCellIdentity();
407         } else if (mCsRegState == RegState.REG_ROAMING || mPsRegState == RegState.REG_ROAMING) {
408             cellIdentity = getCarrierStatus(mRoamingCarrierId).getPrimaryCellIdentity();
409         }
410 
411         return cellIdentity;
412     }
413 
getCells()414     public android.hardware.radio.network.CellInfo[] getCells() {
415         ArrayList<android.hardware.radio.network.CellInfo> cellInfos = new ArrayList<>();
416 
417         for (MockModemCell mmc : mCellList) {
418             CellInfo[] cells = mmc.getCells();
419             if (cells != null) {
420                 for (CellInfo cellInfo : cells) {
421                     cellInfos.add(cellInfo);
422                 }
423             }
424         }
425 
426         return cellInfos.stream().toArray(android.hardware.radio.network.CellInfo[]::new);
427     }
428 
updateHighestRegisteredRat(int raf)429     public boolean updateHighestRegisteredRat(int raf) {
430 
431         int rat = mHighRat;
432         mHighRat = getHighestRatFromNetworkType(raf);
433 
434         return (rat == mHighRat);
435     }
436 
updateNetworkStatus(int reason)437     public void updateNetworkStatus(int reason) {
438         if (reason == NETWORK_UPDATE_PREFERRED_MODE_CHANGE) {
439             Log.d(TAG, "updateNetworkStatus: NETWORK_UPDATE_PREFERRED_MODE_CHANGE");
440             // TODO
441         }
442     }
443 
getRegistrationRat()444     public int getRegistrationRat() {
445         int rat = android.hardware.radio.RadioTechnology.UNKNOWN;
446 
447         if (mCsRegState == RegState.REG_HOME || mPsRegState == RegState.REG_HOME) {
448             rat = getCarrierStatus(mHomeCarrierId).getPrimaryCellRat();
449         } else if (mCsRegState == RegState.REG_ROAMING || mPsRegState == RegState.REG_ROAMING) {
450             rat = getCarrierStatus(mRoamingCarrierId).getPrimaryCellRat();
451         }
452 
453         return rat;
454     }
455 
getSignalStrength()456     public android.hardware.radio.network.SignalStrength getSignalStrength() {
457         android.hardware.radio.network.SignalStrength signalStrength =
458                 new android.hardware.radio.network.SignalStrength();
459 
460         if (mCsRegState == RegState.REG_HOME || mPsRegState == RegState.REG_HOME) {
461             signalStrength = getCarrierStatus(mHomeCarrierId).getPrimaryCellSignalStrength();
462         } else if (mCsRegState == RegState.REG_ROAMING || mPsRegState == RegState.REG_ROAMING) {
463             signalStrength = getCarrierStatus(mRoamingCarrierId).getPrimaryCellSignalStrength();
464         } else {
465             // TODO
466         }
467 
468         return signalStrength;
469     }
470 
getRegistration(int domain)471     public int getRegistration(int domain) {
472         if (domain == android.hardware.radio.network.Domain.CS) {
473             return mCsRegState;
474         } else {
475             return mPsRegState;
476         }
477     }
478 
isInService()479     public boolean isInService() {
480         return ((mCsRegState == RegState.REG_HOME)
481                 || (mPsRegState == RegState.REG_HOME)
482                 || (mCsRegState == RegState.REG_ROAMING)
483                 || (mPsRegState == RegState.REG_ROAMING));
484     }
485 
isPsInService()486     public boolean isPsInService() {
487         return ((mPsRegState == RegState.REG_HOME) || (mPsRegState == RegState.REG_ROAMING));
488     }
489 
updateSimPlmn(String simPlmn)490     public void updateSimPlmn(String simPlmn) {
491         mSimPlmn = simPlmn;
492 
493         // Reset mHomeCarrierId and mRoamingCarrierId
494         mHomeCarrierId = MOCK_CARRIER_NO_SERVICE;
495         mRoamingCarrierId = MOCK_CARRIER_NO_SERVICE;
496 
497         if (mSimPlmn == null || mSimPlmn.isEmpty()) return;
498 
499         if (mCellList.isEmpty()) return;
500 
501         for (MockModemCell mmc : mCellList) {
502 
503             if (isHomeCellExisted() && isRoamingCellExisted()) break;
504 
505             // Find out which cell is Home cell
506             for (String plmn : mmc.mEHPlmnList) {
507                 if (!isHomeCellExisted() && mSimPlmn.equals(plmn)) {
508                     mHomeCarrierId = mmc.getCarrierId();
509                     Log.d(TAG, "Cell ID: Home Cell " + mHomeCarrierId);
510                 }
511             }
512 
513             // Find out which cell is Home cell
514             for (String plmn : mmc.mAllowRoamingList) {
515                 if (!isRoamingCellExisted() && mSimPlmn.equals(plmn)) {
516                     mRoamingCarrierId = mmc.getCarrierId();
517                     Log.d(TAG, "Cell ID: Roaming Cell " + mRoamingCarrierId);
518                 }
519             }
520         }
521     }
522 
523     /**
524      * Set the device enters IN SERVICE
525      *
526      * @param isRoaming boolean true if the camping network is Roaming service, otherwise Home
527      *     service
528      * @param inService boolean true if the deviec enters carrier coverge, otherwise the device
529      *     leaves the carrier coverage.
530      */
setServiceStatus(boolean isRoaming, boolean inService)531     public void setServiceStatus(boolean isRoaming, boolean inService) {
532         if (isRoaming) {
533             mIsRoamingCamping = inService;
534         } else {
535             mIsHomeCamping = inService;
536         }
537     }
538 
getIsHomeCamping()539     public boolean getIsHomeCamping() {
540         return mIsHomeCamping;
541     }
542 
getIsRoamingCamping()543     public boolean getIsRoamingCamping() {
544         return mIsRoamingCamping;
545     }
546 
isHomeCellExisted()547     public boolean isHomeCellExisted() {
548         return (mHomeCarrierId != MOCK_CARRIER_NO_SERVICE);
549     }
550 
isRoamingCellExisted()551     public boolean isRoamingCellExisted() {
552         return (mRoamingCarrierId != MOCK_CARRIER_NO_SERVICE);
553     }
554 
setRegFailCause(int regFailCause)555     public void setRegFailCause(int regFailCause) {
556         mRegFailCause = regFailCause;
557     }
558 
getRegFailCause()559     public int getRegFailCause() {
560         return mRegFailCause;
561     }
562 
563     /** updateServiceState */
updateServiceState(int reg)564     public void updateServiceState(int reg) {
565         updateServiceState(reg, Domain.CS | Domain.PS);
566     }
567 
updateServiceState(int reg, int domainBitmask)568     public void updateServiceState(int reg, int domainBitmask) {
569         Log.d(TAG, "Cell ID: updateServiceState " + reg + " with domainBitmask = " + domainBitmask);
570 
571         /* a little range check here */
572         switch (reg) {
573             case RegState.NOT_REG_MT_SEARCHING_OP:
574                 /* fallthrough */
575             case RegState.REG_HOME:
576                 /* fallthrough */
577             case RegState.REG_ROAMING:
578                 /* fallthrough */
579             case RegState.NOT_REG_MT_NOT_SEARCHING_OP:
580                 /* fallthrough */
581             case RegState.REG_DENIED:
582                 break;
583             default:
584                 reg = RegState.NOT_REG_MT_NOT_SEARCHING_OP;
585                 break;
586         }
587 
588         if ((domainBitmask & Domain.CS) != 0) {
589             mCsRegState = reg;
590         }
591         if ((domainBitmask & Domain.PS) != 0) {
592             mPsRegState = reg;
593         }
594 
595         updateCellRegistration();
596     }
597 
updateCellRegistration()598     void updateCellRegistration() {
599         for (MockModemCell mmc : mCellList) {
600             boolean registered;
601             if ((mCsRegState == RegState.REG_HOME || mPsRegState == RegState.REG_HOME)
602                     && mHomeCarrierId == mmc.getCarrierId()) {
603                 registered = true;
604             } else if ((mCsRegState == RegState.REG_ROAMING || mPsRegState == RegState.REG_ROAMING)
605                     && mRoamingCarrierId == mmc.getCarrierId()) {
606                 registered = true;
607             } else {
608                 registered = false;
609             }
610 
611             CellInfo[] cells = mmc.getCells();
612             if (cells != null) {
613                 for (CellInfo cellInfo : cells) {
614                     cellInfo.registered = registered;
615                 }
616             }
617         }
618     }
619 
getCarrierStatus(int carrierId)620     public MockModemCell getCarrierStatus(int carrierId) {
621         for (MockModemCell mmc : mCellList) {
622             if (mmc.getCarrierId() == carrierId) return mmc;
623         }
624 
625         return null;
626     }
627 
628     /**
629      * @return The barring status.
630      */
getBarringInfo()631     public BarringInfo[] getBarringInfo() {
632         return mBarringInfos;
633     }
634 
635     /**
636      * Updates the barring status.
637      * @param barringInfos the barring status.
638      */
updateBarringInfos(BarringInfo[] barringInfos)639     public void updateBarringInfos(BarringInfo[] barringInfos) {
640         mBarringInfos = barringInfos;
641     }
642 
643     /**
644      * Updates the emergency registration state.
645      * @param regResult the emergency registration state.
646      */
setEmergencyRegResult(EmergencyRegResult regResult)647     public void setEmergencyRegResult(EmergencyRegResult regResult) {
648         mEmergencyRegResult = regResult;
649     }
650 
651     /**
652      * @return the emergency registration state.
653      */
getEmergencyRegResult()654     public EmergencyRegResult getEmergencyRegResult() {
655         return mEmergencyRegResult;
656     }
657 
658     /**
659      * Updates the current emergency mode.
660      * @param mode the emergency mode
661      */
setEmergencyMode(int mode)662     public void setEmergencyMode(int mode) {
663         mEmergencyMode = mode;
664     }
665 
666     /**
667      * @return the current emergency mode.
668      */
getEmergencyMode()669     public int getEmergencyMode() {
670         return mEmergencyMode;
671     }
672 
673     /**
674      * Updates whether triggerEmergencyNetworkScan is requested and the attributes.
675      *
676      * @param state {@code true} if the scan is trigerred.
677      * @param accessNetwork the list of preferred network type.
678      * @param scanType indicates the preferred scan type.
679      */
setEmergencyNetworkScanTriggered(boolean state, int[] accessNetwork, int scanType)680     public void setEmergencyNetworkScanTriggered(boolean state,
681             int[] accessNetwork, int scanType) {
682         mEmergencyNetworkScanTriggered = state;
683         if (state) {
684             mEmergencyNetworkScanAccessNetwork = accessNetwork;
685             mEmergencyNetworkScanType = scanType;
686             countDownLatch(LATCH_TRIGGER_EMERGENCY_SCAN);
687         }
688     }
689 
690     /**
691      * Updates whether cancelEmergencyNetworkScan is requested.
692      */
setEmergencyNetworkScanCanceled(boolean state)693     public void setEmergencyNetworkScanCanceled(boolean state) {
694         mEmergencyNetworkScanCanceled = state;
695         if (state) {
696             mEmergencyNetworkScanAccessNetwork = null;
697             mEmergencyNetworkScanType = -1;
698             countDownLatch(LATCH_CANCEL_EMERGENCY_SCAN);
699         }
700     }
701 
702     /**
703      * @return whether emergency network scan is triggered.
704      */
isEmergencyNetworkScanTriggered()705     public boolean isEmergencyNetworkScanTriggered() {
706         return mEmergencyNetworkScanTriggered;
707     }
708 
709     /**
710      * @return whether emergency network scan is canceled.
711      */
isEmergencyNetworkScanCanceled()712     public boolean isEmergencyNetworkScanCanceled() {
713         return mEmergencyNetworkScanCanceled;
714     }
715 
716     /**
717      * @return the list of preferred network type.
718      */
getEmergencyNetworkScanAccessNetwork()719     public int[] getEmergencyNetworkScanAccessNetwork() {
720         return mEmergencyNetworkScanAccessNetwork;
721     }
722 
723     /**
724      * @return the preferred scan type.
725      */
getEmergencyNetworkScanType()726     public int getEmergencyNetworkScanType() {
727         return mEmergencyNetworkScanType;
728     }
729 
730     /**
731      * Resets the emergency network scan attributes.
732      */
resetEmergencyNetworkScan()733     public void resetEmergencyNetworkScan() {
734         mEmergencyRegResult = new EmergencyRegResult();
735         mEmergencyNetworkScanTriggered = false;
736         mEmergencyNetworkScanCanceled = false;
737         mEmergencyNetworkScanAccessNetwork = null;
738         mEmergencyNetworkScanType = -1;
739         mEmergencyMode = 0;
740     }
741 
countDownLatch(int latchIndex)742     private void countDownLatch(int latchIndex) {
743         synchronized (mLatches) {
744             mLatches[latchIndex].countDown();
745         }
746     }
747 
748     /**
749      * Waits for the event of network service.
750      *
751      * @param latchIndex The index of the event.
752      * @param waitMs The timeout in milliseconds.
753      * @return {@code true} if the event happens.
754      */
waitForLatchCountdown(int latchIndex, long waitMs)755     public boolean waitForLatchCountdown(int latchIndex, long waitMs) {
756         boolean complete = false;
757         try {
758             CountDownLatch latch;
759             synchronized (mLatches) {
760                 latch = mLatches[latchIndex];
761             }
762             long startTime = System.currentTimeMillis();
763             complete = latch.await(waitMs, TimeUnit.MILLISECONDS);
764             Log.i(TAG, "Latch " + latchIndex + " took "
765                     + (System.currentTimeMillis() - startTime) + " ms to count down.");
766         } catch (InterruptedException e) {
767             Log.e(TAG, "Waiting latch " + latchIndex + " interrupted, e=" + e);
768         }
769         synchronized (mLatches) {
770             mLatches[latchIndex] = new CountDownLatch(1);
771         }
772         return complete;
773     }
774 
775     /**
776      * Resets the CountDownLatches
777      */
resetAllLatchCountdown()778     public void resetAllLatchCountdown() {
779         synchronized (mLatches) {
780             for (int i = 0; i < LATCH_MAX; i++) {
781                 mLatches[i] = new CountDownLatch(1);
782             }
783         }
784     }
785 
786     @Override
toString()787     public String toString() {
788         return "isInService():" + isInService() + " Rat:" + getRegistrationRat() + "";
789     }
790 }
791