• 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 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         MockModemCell cell = null;
393         if (mCsRegState == RegState.REG_HOME || mPsRegState == RegState.REG_HOME) {
394             cell = getCarrierStatus(mHomeCarrierId);
395         } else if (mCsRegState == RegState.REG_ROAMING || mPsRegState == RegState.REG_ROAMING) {
396             cell = getCarrierStatus(mRoamingCarrierId);
397         }
398         if (cell != null) operatorInfo = cell.getPrimaryCellOperatorInfo();
399 
400         return operatorInfo;
401     }
402 
getPrimaryCellIdentity()403     public android.hardware.radio.network.CellIdentity getPrimaryCellIdentity() {
404         android.hardware.radio.network.CellIdentity cellIdentity =
405                 android.hardware.radio.network.CellIdentity.noinit(true);
406 
407         MockModemCell cell = null;
408         if (mCsRegState == RegState.REG_HOME || mPsRegState == RegState.REG_HOME) {
409             cell = getCarrierStatus(mHomeCarrierId);
410         } else if (mCsRegState == RegState.REG_ROAMING || mPsRegState == RegState.REG_ROAMING) {
411             cell = getCarrierStatus(mRoamingCarrierId);
412         }
413         if (cell != null) cellIdentity = cell.getPrimaryCellIdentity();
414 
415         return cellIdentity;
416     }
417 
getCells()418     public android.hardware.radio.network.CellInfo[] getCells() {
419         ArrayList<android.hardware.radio.network.CellInfo> cellInfos = new ArrayList<>();
420 
421         for (MockModemCell mmc : mCellList) {
422             CellInfo[] cells = mmc.getCells();
423             if (cells != null) {
424                 for (CellInfo cellInfo : cells) {
425                     cellInfos.add(cellInfo);
426                 }
427             }
428         }
429 
430         return cellInfos.stream().toArray(android.hardware.radio.network.CellInfo[]::new);
431     }
432 
updateHighestRegisteredRat(int raf)433     public boolean updateHighestRegisteredRat(int raf) {
434 
435         int rat = mHighRat;
436         mHighRat = getHighestRatFromNetworkType(raf);
437 
438         return (rat == mHighRat);
439     }
440 
updateNetworkStatus(int reason)441     public void updateNetworkStatus(int reason) {
442         if (reason == NETWORK_UPDATE_PREFERRED_MODE_CHANGE) {
443             Log.d(TAG, "updateNetworkStatus: NETWORK_UPDATE_PREFERRED_MODE_CHANGE");
444             // TODO
445         }
446     }
447 
getRegistrationRat()448     public int getRegistrationRat() {
449         int rat = android.hardware.radio.RadioTechnology.UNKNOWN;
450 
451         MockModemCell cell = null;
452         if (mCsRegState == RegState.REG_HOME || mPsRegState == RegState.REG_HOME) {
453             cell = getCarrierStatus(mHomeCarrierId);
454         } else if (mCsRegState == RegState.REG_ROAMING || mPsRegState == RegState.REG_ROAMING) {
455             cell = getCarrierStatus(mRoamingCarrierId);
456         }
457         if (cell != null) rat = cell.getPrimaryCellRat();
458 
459         return rat;
460     }
461 
getSignalStrength()462     public android.hardware.radio.network.SignalStrength getSignalStrength() {
463         android.hardware.radio.network.SignalStrength signalStrength =
464                 new android.hardware.radio.network.SignalStrength();
465 
466         MockModemCell cell = null;
467         if (mCsRegState == RegState.REG_HOME || mPsRegState == RegState.REG_HOME) {
468             cell = getCarrierStatus(mHomeCarrierId);
469         } else if (mCsRegState == RegState.REG_ROAMING || mPsRegState == RegState.REG_ROAMING) {
470             cell = getCarrierStatus(mRoamingCarrierId);
471         } else {
472             // TODO
473         }
474         if (cell != null) signalStrength = cell.getPrimaryCellSignalStrength();
475 
476         return signalStrength;
477     }
478 
getRegistration(int domain)479     public int getRegistration(int domain) {
480         if (domain == android.hardware.radio.network.Domain.CS) {
481             return mCsRegState;
482         } else {
483             return mPsRegState;
484         }
485     }
486 
isInService()487     public boolean isInService() {
488         return ((mCsRegState == RegState.REG_HOME)
489                 || (mPsRegState == RegState.REG_HOME)
490                 || (mCsRegState == RegState.REG_ROAMING)
491                 || (mPsRegState == RegState.REG_ROAMING));
492     }
493 
isPsInService()494     public boolean isPsInService() {
495         return ((mPsRegState == RegState.REG_HOME) || (mPsRegState == RegState.REG_ROAMING));
496     }
497 
updateSimPlmn(String simPlmn)498     public void updateSimPlmn(String simPlmn) {
499         mSimPlmn = simPlmn;
500 
501         // Reset mHomeCarrierId and mRoamingCarrierId
502         mHomeCarrierId = MOCK_CARRIER_NO_SERVICE;
503         mRoamingCarrierId = MOCK_CARRIER_NO_SERVICE;
504 
505         if (mSimPlmn == null || mSimPlmn.isEmpty()) return;
506 
507         if (mCellList.isEmpty()) return;
508 
509         Log.i(TAG, "Update SIM Plmn " + mSimPlmn);
510         for (MockModemCell mmc : mCellList) {
511 
512             if (isHomeCellExisted() && isRoamingCellExisted()) break;
513 
514             // Find out which cell is Home cell
515             for (String plmn : mmc.mEHPlmnList) {
516                 if (!isHomeCellExisted() && mSimPlmn.equals(plmn)) {
517                     mHomeCarrierId = mmc.getCarrierId();
518                     Log.d(TAG, "Cell ID: Home Cell " + mHomeCarrierId);
519                 }
520             }
521 
522             // Find out which cell is Home cell
523             for (String plmn : mmc.mAllowRoamingList) {
524                 if (!isRoamingCellExisted() && mSimPlmn.equals(plmn)) {
525                     mRoamingCarrierId = mmc.getCarrierId();
526                     Log.d(TAG, "Cell ID: Roaming Cell " + mRoamingCarrierId);
527                 }
528             }
529         }
530     }
531 
532     /**
533      * Set the device enters IN SERVICE
534      *
535      * @param isRoaming boolean true if the camping network is Roaming service, otherwise Home
536      *     service
537      * @param inService boolean true if the deviec enters carrier coverge, otherwise the device
538      *     leaves the carrier coverage.
539      */
setServiceStatus(boolean isRoaming, boolean inService)540     public void setServiceStatus(boolean isRoaming, boolean inService) {
541         if (isRoaming) {
542             mIsRoamingCamping = inService;
543         } else {
544             mIsHomeCamping = inService;
545         }
546     }
547 
getIsHomeCamping()548     public boolean getIsHomeCamping() {
549         return mIsHomeCamping;
550     }
551 
getIsRoamingCamping()552     public boolean getIsRoamingCamping() {
553         return mIsRoamingCamping;
554     }
555 
isHomeCellExisted()556     public boolean isHomeCellExisted() {
557         return (mHomeCarrierId != MOCK_CARRIER_NO_SERVICE);
558     }
559 
isRoamingCellExisted()560     public boolean isRoamingCellExisted() {
561         return (mRoamingCarrierId != MOCK_CARRIER_NO_SERVICE);
562     }
563 
setRegFailCause(int regFailCause)564     public void setRegFailCause(int regFailCause) {
565         mRegFailCause = regFailCause;
566     }
567 
getRegFailCause()568     public int getRegFailCause() {
569         return mRegFailCause;
570     }
571 
572     /** updateServiceState */
updateServiceState(int reg)573     public void updateServiceState(int reg) {
574         updateServiceState(reg, Domain.CS | Domain.PS);
575     }
576 
updateServiceState(int reg, int domainBitmask)577     public void updateServiceState(int reg, int domainBitmask) {
578         Log.d(TAG, "Cell ID: updateServiceState " + reg + " with domainBitmask = " + domainBitmask);
579 
580         /* a little range check here */
581         switch (reg) {
582             case RegState.NOT_REG_MT_SEARCHING_OP:
583                 /* fallthrough */
584             case RegState.REG_HOME:
585                 /* fallthrough */
586             case RegState.REG_ROAMING:
587                 /* fallthrough */
588             case RegState.NOT_REG_MT_NOT_SEARCHING_OP:
589                 /* fallthrough */
590             case RegState.REG_DENIED:
591                 break;
592             default:
593                 reg = RegState.NOT_REG_MT_NOT_SEARCHING_OP;
594                 break;
595         }
596 
597         if ((domainBitmask & Domain.CS) != 0) {
598             mCsRegState = reg;
599         }
600         if ((domainBitmask & Domain.PS) != 0) {
601             mPsRegState = reg;
602         }
603 
604         updateCellRegistration();
605     }
606 
updateCellRegistration()607     void updateCellRegistration() {
608         for (MockModemCell mmc : mCellList) {
609             boolean registered;
610             if ((mCsRegState == RegState.REG_HOME || mPsRegState == RegState.REG_HOME)
611                     && mHomeCarrierId == mmc.getCarrierId()) {
612                 registered = true;
613             } else if ((mCsRegState == RegState.REG_ROAMING || mPsRegState == RegState.REG_ROAMING)
614                     && mRoamingCarrierId == mmc.getCarrierId()) {
615                 registered = true;
616             } else {
617                 registered = false;
618             }
619 
620             CellInfo[] cells = mmc.getCells();
621             if (cells != null) {
622                 for (CellInfo cellInfo : cells) {
623                     cellInfo.registered = registered;
624                 }
625             }
626         }
627     }
628 
getCarrierStatus(int carrierId)629     public MockModemCell getCarrierStatus(int carrierId) {
630         for (MockModemCell mmc : mCellList) {
631             if (mmc.getCarrierId() == carrierId) return mmc;
632         }
633 
634         return null;
635     }
636 
637     /**
638      * @return The barring status.
639      */
getBarringInfo()640     public BarringInfo[] getBarringInfo() {
641         return mBarringInfos;
642     }
643 
644     /**
645      * Updates the barring status.
646      * @param barringInfos the barring status.
647      */
updateBarringInfos(BarringInfo[] barringInfos)648     public void updateBarringInfos(BarringInfo[] barringInfos) {
649         mBarringInfos = barringInfos;
650     }
651 
652     /**
653      * Updates the emergency registration state.
654      * @param regResult the emergency registration state.
655      */
setEmergencyRegResult(EmergencyRegResult regResult)656     public void setEmergencyRegResult(EmergencyRegResult regResult) {
657         mEmergencyRegResult = regResult;
658     }
659 
660     /**
661      * @return the emergency registration state.
662      */
getEmergencyRegResult()663     public EmergencyRegResult getEmergencyRegResult() {
664         return mEmergencyRegResult;
665     }
666 
667     /**
668      * Updates the current emergency mode.
669      * @param mode the emergency mode
670      */
setEmergencyMode(int mode)671     public void setEmergencyMode(int mode) {
672         mEmergencyMode = mode;
673     }
674 
675     /**
676      * @return the current emergency mode.
677      */
getEmergencyMode()678     public int getEmergencyMode() {
679         return mEmergencyMode;
680     }
681 
682     /**
683      * Updates whether triggerEmergencyNetworkScan is requested and the attributes.
684      *
685      * @param state {@code true} if the scan is trigerred.
686      * @param accessNetwork the list of preferred network type.
687      * @param scanType indicates the preferred scan type.
688      */
setEmergencyNetworkScanTriggered(boolean state, int[] accessNetwork, int scanType)689     public void setEmergencyNetworkScanTriggered(boolean state,
690             int[] accessNetwork, int scanType) {
691         mEmergencyNetworkScanTriggered = state;
692         if (state) {
693             mEmergencyNetworkScanAccessNetwork = accessNetwork;
694             mEmergencyNetworkScanType = scanType;
695             countDownLatch(LATCH_TRIGGER_EMERGENCY_SCAN);
696         }
697     }
698 
699     /**
700      * Updates whether cancelEmergencyNetworkScan is requested.
701      */
setEmergencyNetworkScanCanceled(boolean state)702     public void setEmergencyNetworkScanCanceled(boolean state) {
703         mEmergencyNetworkScanCanceled = state;
704         if (state) {
705             mEmergencyNetworkScanAccessNetwork = null;
706             mEmergencyNetworkScanType = -1;
707             countDownLatch(LATCH_CANCEL_EMERGENCY_SCAN);
708         }
709     }
710 
711     /**
712      * @return whether emergency network scan is triggered.
713      */
isEmergencyNetworkScanTriggered()714     public boolean isEmergencyNetworkScanTriggered() {
715         return mEmergencyNetworkScanTriggered;
716     }
717 
718     /**
719      * @return whether emergency network scan is canceled.
720      */
isEmergencyNetworkScanCanceled()721     public boolean isEmergencyNetworkScanCanceled() {
722         return mEmergencyNetworkScanCanceled;
723     }
724 
725     /**
726      * @return the list of preferred network type.
727      */
getEmergencyNetworkScanAccessNetwork()728     public int[] getEmergencyNetworkScanAccessNetwork() {
729         return mEmergencyNetworkScanAccessNetwork;
730     }
731 
732     /**
733      * @return the preferred scan type.
734      */
getEmergencyNetworkScanType()735     public int getEmergencyNetworkScanType() {
736         return mEmergencyNetworkScanType;
737     }
738 
739     /**
740      * Resets the emergency network scan attributes.
741      */
resetEmergencyNetworkScan()742     public void resetEmergencyNetworkScan() {
743         mEmergencyRegResult = new EmergencyRegResult();
744         mEmergencyNetworkScanTriggered = false;
745         mEmergencyNetworkScanCanceled = false;
746         mEmergencyNetworkScanAccessNetwork = null;
747         mEmergencyNetworkScanType = -1;
748         mEmergencyMode = 0;
749     }
750 
countDownLatch(int latchIndex)751     private void countDownLatch(int latchIndex) {
752         synchronized (mLatches) {
753             mLatches[latchIndex].countDown();
754         }
755     }
756 
757     /**
758      * Waits for the event of network service.
759      *
760      * @param latchIndex The index of the event.
761      * @param waitMs The timeout in milliseconds.
762      * @return {@code true} if the event happens.
763      */
waitForLatchCountdown(int latchIndex, long waitMs)764     public boolean waitForLatchCountdown(int latchIndex, long waitMs) {
765         boolean complete = false;
766         try {
767             CountDownLatch latch;
768             synchronized (mLatches) {
769                 latch = mLatches[latchIndex];
770             }
771             long startTime = System.currentTimeMillis();
772             complete = latch.await(waitMs, TimeUnit.MILLISECONDS);
773             Log.i(TAG, "Latch " + latchIndex + " took "
774                     + (System.currentTimeMillis() - startTime) + " ms to count down.");
775         } catch (InterruptedException e) {
776             Log.e(TAG, "Waiting latch " + latchIndex + " interrupted, e=" + e);
777         }
778         synchronized (mLatches) {
779             mLatches[latchIndex] = new CountDownLatch(1);
780         }
781         return complete;
782     }
783 
784     /**
785      * Resets the CountDownLatches
786      */
resetAllLatchCountdown()787     public void resetAllLatchCountdown() {
788         synchronized (mLatches) {
789             for (int i = 0; i < LATCH_MAX; i++) {
790                 mLatches[i] = new CountDownLatch(1);
791             }
792         }
793     }
794 
795     @Override
toString()796     public String toString() {
797         return "isInService():" + isInService() + " Rat:" + getRegistrationRat() + "";
798     }
799 }
800