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