• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 com.android.internal.telephony.RILConstants.RIL_REQUEST_RADIO_POWER;
20 
21 import android.hardware.radio.RadioError;
22 import android.hardware.radio.RadioIndicationType;
23 import android.hardware.radio.RadioResponseInfo;
24 import android.hardware.radio.modem.IRadioModem;
25 import android.hardware.radio.modem.IRadioModemIndication;
26 import android.hardware.radio.modem.IRadioModemResponse;
27 import android.hardware.radio.modem.ImeiInfo;
28 import android.hardware.radio.modem.RadioState;
29 import android.os.AsyncResult;
30 import android.os.Handler;
31 import android.os.Message;
32 import android.os.RemoteException;
33 import android.util.Log;
34 
35 public class IRadioModemImpl extends IRadioModem.Stub {
36     private static final String TAG = "MRMDM";
37 
38     private final MockModemService mService;
39     private IRadioModemResponse mRadioModemResponse;
40     private IRadioModemIndication mRadioModemIndication;
41 
42     private int mForceRadioPowerError = -1;
43 
44     private MockModemConfigInterface mMockModemConfigInterface;
45     private Object mCacheUpdateMutex;
46     private final Handler mHandler;
47     private int mSubId;
48     private String mTag;
49 
50     // ***** Events
51     static final int EVENT_BASEBAND_VERSION_CHANGED = 1;
52     static final int EVENT_DEVICE_IDENTITY_CHANGED = 2;
53     static final int EVENT_RADIO_STATE_CHANGED = 3;
54     static final int EVENT_DEVICE_IMEI_INFO_CHANGED = 4;
55 
56     // ***** Cache of modem attributes/status
57     private String mBasebandVer;
58     private String mImei;
59     private String mImeiSv;
60     private String mEsn;
61     private String mMeid;
62     private int mImeiType;
63     private int mRadioState;
64 
IRadioModemImpl( MockModemService service, MockModemConfigInterface configInterface, int instanceId)65     public IRadioModemImpl(
66             MockModemService service, MockModemConfigInterface configInterface, int instanceId) {
67         mTag = TAG + "-" + instanceId;
68         Log.d(mTag, "Instantiated");
69 
70         this.mService = service;
71         mMockModemConfigInterface = configInterface;
72         mCacheUpdateMutex = new Object();
73         mHandler = new IRadioModemHandler();
74         mSubId = instanceId;
75 
76         // Register events
77         mMockModemConfigInterface.registerForBasebandVersionChanged(
78                 mSubId, mHandler, EVENT_BASEBAND_VERSION_CHANGED, null);
79         mMockModemConfigInterface.registerForDeviceIdentityChanged(
80                 mSubId, mHandler, EVENT_DEVICE_IDENTITY_CHANGED, null);
81         mMockModemConfigInterface.registerForRadioStateChanged(
82                 mSubId, mHandler, EVENT_RADIO_STATE_CHANGED, null);
83         mMockModemConfigInterface.registerForDeviceImeiInfoChanged(
84                 mSubId, mHandler, EVENT_DEVICE_IMEI_INFO_CHANGED, null);
85     }
86 
87     /** Handler class to handle callbacks */
88     private final class IRadioModemHandler extends Handler {
89         @Override
handleMessage(Message msg)90         public void handleMessage(Message msg) {
91             AsyncResult ar;
92             synchronized (mCacheUpdateMutex) {
93                 switch (msg.what) {
94                     case EVENT_BASEBAND_VERSION_CHANGED:
95                         Log.d(mTag, "Received EVENT_BASEBAND_VERSION_CHANGED");
96                         ar = (AsyncResult) msg.obj;
97                         if (ar != null && ar.exception == null) {
98                             mBasebandVer = (String) ar.result;
99                             Log.i(mTag, "Basedband version = " + mBasebandVer);
100                         } else {
101                             Log.e(
102                                     mTag,
103                                     msg.what
104                                             + " failure. Not update baseband version."
105                                             + ar.exception);
106                         }
107                         break;
108                     case EVENT_DEVICE_IDENTITY_CHANGED:
109                         Log.d(mTag, "Received EVENT_DEVICE_IDENTITY_CHANGED");
110                         ar = (AsyncResult) msg.obj;
111                         if (ar != null && ar.exception == null) {
112                             String[] deviceIdentity = (String[]) ar.result;
113                             mImei = deviceIdentity[0];
114                             mImeiSv = deviceIdentity[1];
115                             mEsn = deviceIdentity[2];
116                             mMeid = deviceIdentity[3];
117                             Log.i(
118                                     mTag,
119                                     "Device identity: IMEI = "
120                                             + mImei
121                                             + " IMEISV = "
122                                             + mImeiSv
123                                             + " ESN = "
124                                             + mEsn
125                                             + " MEID ="
126                                             + mMeid);
127                         } else {
128                             Log.e(
129                                     mTag,
130                                     msg.what
131                                             + " failure. Not update device identity."
132                                             + ar.exception);
133                         }
134                         break;
135                     case EVENT_RADIO_STATE_CHANGED:
136                         Log.d(mTag, "Received EVENT_RADIO_STATE_CHANGED");
137                         ar = (AsyncResult) msg.obj;
138                         if (ar != null && ar.exception == null) {
139                             mRadioState = (int) ar.result;
140                             Log.i(mTag, "Radio state: " + mRadioState);
141                         } else {
142                             Log.e(mTag, msg.what + " failure. Exception: " + ar.exception);
143                         }
144                         break;
145                     case EVENT_DEVICE_IMEI_INFO_CHANGED:
146                         Log.d(mTag, "Received EVENT_DEVICE_IMEIINFO_CHANGED");
147                         ar = (AsyncResult) msg.obj;
148                         if (ar != null && ar.exception == null) {
149                             ImeiInfo imeiInfo = (ImeiInfo) ar.result;
150                             mImei = imeiInfo.imei;
151                             mImeiSv = imeiInfo.svn;
152                             mImeiType = imeiInfo.type;
153                             Log.i(mTag, "IMEIInfo : ImeiType = " + mImeiType);
154                         } else {
155                             Log.e(mTag, msg.what + " failure. Not update device ImeiInfo."
156                                     + ar.exception);
157                         }
158                         break;
159                 }
160             }
161         }
162     }
163 
164     // Implementation of IRadioModem functions
165     @Override
setResponseFunctions( IRadioModemResponse radioModemResponse, IRadioModemIndication radioModemIndication)166     public void setResponseFunctions(
167             IRadioModemResponse radioModemResponse, IRadioModemIndication radioModemIndication) {
168         Log.d(mTag, "setResponseFunctions");
169         mRadioModemResponse = radioModemResponse;
170         mRadioModemIndication = radioModemIndication;
171         mService.countDownLatch(MockModemService.LATCH_RADIO_INTERFACES_READY);
172     }
173 
174     @Override
enableModem(int serial, boolean on)175     public void enableModem(int serial, boolean on) {
176         Log.d(mTag, "getNumOfLiveModems " + on);
177 
178         // TODO: cache value
179         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
180         try {
181             mRadioModemResponse.enableModemResponse(rsp);
182         } catch (RemoteException ex) {
183             Log.e(mTag, "Failed to enableModem from AIDL. Exception" + ex);
184         }
185     }
186 
187     @Override
getBasebandVersion(int serial)188     public void getBasebandVersion(int serial) {
189         Log.d(mTag, "getBasebandVersion");
190 
191         String baseband;
192 
193         synchronized (mCacheUpdateMutex) {
194             baseband = mBasebandVer;
195         }
196 
197         RadioResponseInfo rsp = mService.makeSolRsp(serial);
198         try {
199             mRadioModemResponse.getBasebandVersionResponse(rsp, baseband);
200         } catch (RemoteException ex) {
201             Log.e(mTag, "Failed to getBasebandVersion from AIDL. Exception" + ex);
202         }
203     }
204 
205     @Override
getDeviceIdentity(int serial)206     public void getDeviceIdentity(int serial) {
207         Log.d(mTag, "getDeviceIdentity");
208 
209         String imei, imeisv, esn, meid;
210 
211         synchronized (mCacheUpdateMutex) {
212             imei = mImei;
213             imeisv = mImeiSv;
214             esn = mEsn;
215             meid = mMeid;
216         }
217 
218         RadioResponseInfo rsp = mService.makeSolRsp(serial);
219         try {
220             mRadioModemResponse.getDeviceIdentityResponse(rsp, imei, imeisv, esn, meid);
221         } catch (RemoteException ex) {
222             Log.e(mTag, "Failed to getDeviceIdentity from AIDL. Exception" + ex);
223         }
224     }
225 
226     @Override
getImei(int serial)227     public void getImei(int serial) {
228         Log.d(mTag, "getImei");
229         android.hardware.radio.modem.ImeiInfo imeiInfo =
230                 new android.hardware.radio.modem.ImeiInfo();
231         synchronized (mCacheUpdateMutex) {
232             imeiInfo.type = mImeiType;
233             imeiInfo.imei = mImei;
234             imeiInfo.svn = mImeiSv;
235         }
236         RadioResponseInfo rsp = mService.makeSolRsp(serial);
237         try {
238             mRadioModemResponse.getImeiResponse(rsp, imeiInfo);
239         } catch (RemoteException ex) {
240             Log.e(mTag, "Failed to getImeiResponse from AIDL. Exception" + ex);
241         }
242     }
243 
244     @Override
getHardwareConfig(int serial)245     public void getHardwareConfig(int serial) {
246         Log.d(mTag, "getHardwareConfig");
247 
248         android.hardware.radio.modem.HardwareConfig[] config =
249                 new android.hardware.radio.modem.HardwareConfig[0];
250         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
251         try {
252             mRadioModemResponse.getHardwareConfigResponse(rsp, config);
253         } catch (RemoteException ex) {
254             Log.e(mTag, "Failed to getHardwareConfig from AIDL. Exception" + ex);
255         }
256     }
257 
258     @Override
getModemActivityInfo(int serial)259     public void getModemActivityInfo(int serial) {
260         Log.d(mTag, "getModemActivityInfo");
261 
262         android.hardware.radio.modem.ActivityStatsInfo activityInfo =
263                 new android.hardware.radio.modem.ActivityStatsInfo();
264 
265         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
266         try {
267             mRadioModemResponse.getModemActivityInfoResponse(rsp, activityInfo);
268         } catch (RemoteException ex) {
269             Log.e(mTag, "Failed to getModemActivityInfo from AIDL. Exception" + ex);
270         }
271     }
272 
273     @Override
getModemStackStatus(int serial)274     public void getModemStackStatus(int serial) {
275         Log.d(mTag, "getModemStackStatus");
276 
277         boolean isEnabled = false;
278 
279         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
280         try {
281             mRadioModemResponse.getModemStackStatusResponse(rsp, isEnabled);
282         } catch (RemoteException ex) {
283             Log.e(mTag, "Failed to getModemStackStatus from AIDL. Exception" + ex);
284         }
285     }
286 
287     @Override
getRadioCapability(int serial)288     public void getRadioCapability(int serial) {
289         Log.d(mTag, "getRadioCapability");
290 
291         android.hardware.radio.modem.RadioCapability rc =
292                 new android.hardware.radio.modem.RadioCapability();
293 
294         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
295         try {
296             mRadioModemResponse.getRadioCapabilityResponse(rsp, rc);
297         } catch (RemoteException ex) {
298             Log.e(mTag, "Failed to getRadioCapability from AIDL. Exception" + ex);
299         }
300     }
301 
302     @Override
nvReadItem(int serial, int itemId)303     public void nvReadItem(int serial, int itemId) {
304         Log.d(mTag, "nvReadItem");
305 
306         // TODO: cache value
307         String result = "";
308 
309         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
310         try {
311             mRadioModemResponse.nvReadItemResponse(rsp, result);
312         } catch (RemoteException ex) {
313             Log.e(mTag, "Failed to nvReadItem from AIDL. Exception" + ex);
314         }
315     }
316 
317     @Override
nvResetConfig(int serial, int resetType)318     public void nvResetConfig(int serial, int resetType) {
319         Log.d(mTag, "nvResetConfig");
320 
321         // TODO: cache value
322 
323         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
324         try {
325             mRadioModemResponse.nvResetConfigResponse(rsp);
326         } catch (RemoteException ex) {
327             Log.e(mTag, "Failed to nvResetConfig from AIDL. Exception" + ex);
328         }
329     }
330 
331     @Override
nvWriteCdmaPrl(int serial, byte[] prl)332     public void nvWriteCdmaPrl(int serial, byte[] prl) {
333         Log.d(mTag, "nvWriteCdmaPrl");
334 
335         // TODO: cache value
336 
337         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
338         try {
339             mRadioModemResponse.nvWriteCdmaPrlResponse(rsp);
340         } catch (RemoteException ex) {
341             Log.e(mTag, "Failed to nvWriteCdmaPrl from AIDL. Exception" + ex);
342         }
343     }
344 
345     @Override
nvWriteItem(int serial, android.hardware.radio.modem.NvWriteItem item)346     public void nvWriteItem(int serial, android.hardware.radio.modem.NvWriteItem item) {
347         Log.d(mTag, "nvWriteItem");
348 
349         // TODO: cache value
350 
351         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
352         try {
353             mRadioModemResponse.nvWriteItemResponse(rsp);
354         } catch (RemoteException ex) {
355             Log.e(mTag, "Failed to nvWriteItem from AIDL. Exception" + ex);
356         }
357     }
358 
359     @Override
requestShutdown(int serial)360     public void requestShutdown(int serial) {
361         Log.d(mTag, "requestShutdown");
362 
363         RadioResponseInfo rsp = mService.makeSolRsp(serial);
364         try {
365             mRadioModemResponse.requestShutdownResponse(rsp);
366         } catch (RemoteException ex) {
367             Log.e(mTag, "Failed to requestShutdown from AIDL. Exception" + ex);
368         }
369     }
370 
371     @Override
sendDeviceState(int serial, int deviceStateType, boolean state)372     public void sendDeviceState(int serial, int deviceStateType, boolean state) {
373         Log.d(mTag, "sendDeviceState");
374 
375         // TODO: cache value
376 
377         RadioResponseInfo rsp = mService.makeSolRsp(serial);
378         try {
379             mRadioModemResponse.sendDeviceStateResponse(rsp);
380         } catch (RemoteException ex) {
381             Log.e(mTag, "Failed to sendDeviceState from AIDL. Exception" + ex);
382         }
383     }
384 
385     @Override
responseAcknowledgement()386     public void responseAcknowledgement() {
387         Log.d(mTag, "responseAcknowledgement");
388     }
389 
390     @Override
setRadioCapability(int serial, android.hardware.radio.modem.RadioCapability rc)391     public void setRadioCapability(int serial, android.hardware.radio.modem.RadioCapability rc) {
392         Log.d(mTag, "setRadioCapability");
393 
394         // TODO: cache value
395         android.hardware.radio.modem.RadioCapability respRc =
396                 new android.hardware.radio.modem.RadioCapability();
397 
398         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
399         try {
400             mRadioModemResponse.setRadioCapabilityResponse(rsp, respRc);
401         } catch (RemoteException ex) {
402             Log.e(mTag, "Failed to setRadioCapability from AIDL. Exception" + ex);
403         }
404     }
405 
406     @Override
setRadioPower( int serial, boolean powerOn, boolean forEmergencyCall, boolean preferredForEmergencyCall)407     public void setRadioPower(
408             int serial,
409             boolean powerOn,
410             boolean forEmergencyCall,
411             boolean preferredForEmergencyCall) {
412         Log.d(mTag, "setRadioPower");
413         RadioResponseInfo rsp = null;
414 
415         // Check if the error response needs to be modified
416         if (mForceRadioPowerError != -1) {
417             rsp = mService.makeSolRsp(serial, mForceRadioPowerError);
418         } else {
419             synchronized (mCacheUpdateMutex) {
420                 if (powerOn) {
421                     mRadioState = MockModemConfigInterface.RADIO_STATE_ON;
422                 } else {
423                     mRadioState = MockModemConfigInterface.RADIO_STATE_OFF;
424                 }
425                 mMockModemConfigInterface.setRadioState(mSubId, mRadioState, mTag);
426             }
427             rsp = mService.makeSolRsp(serial);
428         }
429 
430         try {
431             mRadioModemResponse.setRadioPowerResponse(rsp);
432         } catch (RemoteException ex) {
433             Log.e(mTag, "Failed to setRadioPower from AIDL. Exception" + ex);
434         }
435 
436         if (rsp.error == RadioError.NONE) {
437             if (powerOn) {
438                 radioStateChanged(RadioState.ON);
439             } else {
440                 radioStateChanged(RadioState.OFF);
441             }
442         }
443     }
444 
445     /**
446      * Sent when setRadioCapability() completes. Returns the same RadioCapability as
447      * getRadioCapability() and is the same as the one sent by setRadioCapability().
448      *
449      * @param radioCapability Current radio capability
450      */
radioCapabilityIndication( android.hardware.radio.modem.RadioCapability radioCapability)451     public void radioCapabilityIndication(
452             android.hardware.radio.modem.RadioCapability radioCapability) {
453         Log.d(mTag, "radioCapabilityIndication");
454 
455         if (mRadioModemIndication != null) {
456             try {
457                 mRadioModemIndication.radioCapabilityIndication(
458                         RadioIndicationType.UNSOLICITED, radioCapability);
459             } catch (RemoteException ex) {
460                 Log.e(mTag, "Failed to radioCapabilityIndication from AIDL. Exception" + ex);
461             }
462         } else {
463 
464             Log.e(mTag, "null mRadioModemIndication");
465         }
466     }
467 
468     /**
469      * Indicates when radio state changes.
470      *
471      * @param radioState Current radio state
472      */
radioStateChanged(int radioState)473     public void radioStateChanged(int radioState) {
474         Log.d(mTag, "radioStateChanged");
475 
476         if (mRadioModemIndication != null) {
477             try {
478                 mRadioModemIndication.radioStateChanged(
479                         RadioIndicationType.UNSOLICITED, radioState);
480             } catch (RemoteException ex) {
481                 Log.e(mTag, "Failed to radioStateChanged from AIDL. Exception" + ex);
482             }
483         } else {
484 
485             Log.e(mTag, "null mRadioModemIndication");
486         }
487     }
488 
489     /** Indicates the ril connects and returns the version. */
rilConnected()490     public void rilConnected() {
491         Log.d(mTag, "rilConnected");
492 
493         if (mRadioModemIndication != null) {
494             try {
495                 mRadioModemIndication.rilConnected(RadioIndicationType.UNSOLICITED);
496             } catch (RemoteException ex) {
497                 Log.e(mTag, "Failed to rilConnected from AIDL. Exception" + ex);
498             }
499         } else {
500 
501             Log.e(mTag, "null mRadioModemIndication");
502         }
503     }
504 
forceErrorResponse(int requestId, int error)505     public void forceErrorResponse(int requestId, int error) {
506         switch (requestId) {
507             case RIL_REQUEST_RADIO_POWER:
508                 mForceRadioPowerError = error;
509                 break;
510             default:
511                 break;
512         }
513     }
514 
515     @Override
getInterfaceHash()516     public String getInterfaceHash() {
517         return IRadioModem.HASH;
518     }
519 
520     @Override
getInterfaceVersion()521     public int getInterfaceVersion() {
522         return IRadioModem.VERSION;
523     }
524 }
525