• 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 android.hardware.radio.RadioError;
20 import android.hardware.radio.RadioIndicationType;
21 import android.hardware.radio.RadioResponseInfo;
22 import android.hardware.radio.config.IRadioConfig;
23 import android.hardware.radio.config.IRadioConfigIndication;
24 import android.hardware.radio.config.IRadioConfigResponse;
25 import android.hardware.radio.config.PhoneCapability;
26 import android.hardware.radio.config.SimSlotStatus;
27 import android.hardware.radio.config.SlotPortMapping;
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 IRadioConfigImpl extends IRadioConfig.Stub {
35     private static final String TAG = "MRCFG";
36 
37     private final MockModemService mService;
38     private IRadioConfigResponse mRadioConfigResponse;
39     private IRadioConfigIndication mRadioConfigIndication;
40     private static MockModemConfigInterface[] sMockModemConfigInterfaces;
41     private Object mCacheUpdateMutex;
42     private final Handler mHandler;
43     private int mSubId;
44 
45     // ***** Events
46     static final int EVENT_NUM_OF_LIVE_MODEM_CHANGED = 1;
47     static final int EVENT_PHONE_CAPABILITY_CHANGED = 2;
48     static final int EVENT_SIM_SLOT_STATUS_CHANGED = 3;
49 
50     // ***** Cache of modem attributes/status
51     private int mSlotNum = 1;
52     private byte mNumOfLiveModems = 1;
53     private PhoneCapability mPhoneCapability = new PhoneCapability();
54     private SimSlotStatus[] mSimSlotStatus;
55 
IRadioConfigImpl( MockModemService service, MockModemConfigInterface[] interfaces, int instanceId)56     public IRadioConfigImpl(
57             MockModemService service, MockModemConfigInterface[] interfaces, int instanceId) {
58         Log.d(TAG, "Instantiated");
59 
60         this.mService = service;
61         sMockModemConfigInterfaces = interfaces;
62         mSlotNum = mService.getNumPhysicalSlots();
63         mSimSlotStatus = new SimSlotStatus[mSlotNum];
64         mCacheUpdateMutex = new Object();
65         mHandler = new IRadioConfigHandler();
66         mSubId = instanceId;
67 
68         // Register events
69         sMockModemConfigInterfaces[mSubId].registerForNumOfLiveModemChanged(
70                 mHandler, EVENT_NUM_OF_LIVE_MODEM_CHANGED, null);
71         sMockModemConfigInterfaces[mSubId].registerForPhoneCapabilityChanged(
72                 mHandler, EVENT_PHONE_CAPABILITY_CHANGED, null);
73         sMockModemConfigInterfaces[mSubId].registerForSimSlotStatusChanged(
74                 mHandler, EVENT_SIM_SLOT_STATUS_CHANGED, null);
75     }
76 
77     /** Handler class to handle callbacks */
78     private final class IRadioConfigHandler extends Handler {
79         @Override
handleMessage(Message msg)80         public void handleMessage(Message msg) {
81             AsyncResult ar;
82             synchronized (mCacheUpdateMutex) {
83                 switch (msg.what) {
84                     case EVENT_NUM_OF_LIVE_MODEM_CHANGED:
85                         Log.d(TAG, "Received EVENT_NUM_OF_LIVE_MODEM_CHANGED");
86                         ar = (AsyncResult) msg.obj;
87                         if (ar != null && ar.exception == null) {
88                             mNumOfLiveModems = (byte) ar.result;
89                             Log.i(TAG, "Number of live modem: " + mNumOfLiveModems);
90                         } else {
91                             Log.e(TAG, msg.what + " failure. Exception: " + ar.exception);
92                         }
93                         break;
94                     case EVENT_PHONE_CAPABILITY_CHANGED:
95                         Log.d(TAG, "Received EVENT_PHONE_CAPABILITY_CHANGED");
96                         ar = (AsyncResult) msg.obj;
97                         if (ar != null && ar.exception == null) {
98                             mPhoneCapability = (PhoneCapability) ar.result;
99                             Log.i(TAG, "Phone capability: " + mPhoneCapability);
100                         } else {
101                             Log.e(TAG, msg.what + " failure. Exception: " + ar.exception);
102                         }
103                         break;
104                     case EVENT_SIM_SLOT_STATUS_CHANGED:
105                         Log.d(TAG, "Received EVENT_SIM_SLOT_STATUS_CHANGED");
106                         ar = (AsyncResult) msg.obj;
107                         if (ar != null && ar.exception == null) {
108                             mSimSlotStatus = (SimSlotStatus[]) ar.result;
109                             for (int i = 0; i < mSlotNum; i++) {
110                                 Log.i(TAG, "Sim slot status: " + mSimSlotStatus[i]);
111                             }
112                             unsolSimSlotsStatusChanged();
113                         } else {
114                             Log.e(TAG, msg.what + " failure. Exception: " + ar.exception);
115                         }
116                         break;
117                 }
118             }
119         }
120     }
121 
122     // Implementation of IRadioConfig functions
123     @Override
getHalDeviceCapabilities(int serial)124     public void getHalDeviceCapabilities(int serial) {
125         Log.d(TAG, "getHalDeviceCapabilities");
126 
127         boolean modemReducedFeatureSet1 = false;
128 
129         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
130         try {
131             mRadioConfigResponse.getHalDeviceCapabilitiesResponse(rsp, modemReducedFeatureSet1);
132         } catch (RemoteException ex) {
133             Log.e(
134                     TAG,
135                     "Failed to invoke getHalDeviceCapabilitiesResponse from AIDL. Exception" + ex);
136         }
137     }
138 
139     @Override
getNumOfLiveModems(int serial)140     public void getNumOfLiveModems(int serial) {
141         Log.d(TAG, "getNumOfLiveModems");
142         byte numoflivemodem;
143 
144         synchronized (mCacheUpdateMutex) {
145             numoflivemodem = mNumOfLiveModems;
146         }
147 
148         RadioResponseInfo rsp = mService.makeSolRsp(serial);
149         try {
150             mRadioConfigResponse.getNumOfLiveModemsResponse(rsp, numoflivemodem);
151         } catch (RemoteException ex) {
152             Log.e(TAG, "Failed to invoke getNumOfLiveModemsResponse from AIDL. Exception" + ex);
153         }
154     }
155 
156     @Override
getPhoneCapability(int serial)157     public void getPhoneCapability(int serial) {
158         Log.d(TAG, "getPhoneCapability");
159         PhoneCapability phoneCapability;
160 
161         synchronized (mCacheUpdateMutex) {
162             phoneCapability = mPhoneCapability;
163         }
164 
165         RadioResponseInfo rsp = mService.makeSolRsp(serial);
166         try {
167             mRadioConfigResponse.getPhoneCapabilityResponse(rsp, phoneCapability);
168         } catch (RemoteException ex) {
169             Log.e(TAG, "Failed to invoke getPhoneCapabilityResponse from AIDL. Exception" + ex);
170         }
171     }
172 
173     @Override
getSimSlotsStatus(int serial)174     public void getSimSlotsStatus(int serial) {
175         Log.d(TAG, "getSimSlotsStatus");
176         SimSlotStatus[] slotStatus;
177 
178         synchronized (mCacheUpdateMutex) {
179             if (mSlotNum < 1) {
180                 Log.d(TAG, "No slot information is retured.");
181                 slotStatus = null;
182             } else {
183                 slotStatus = mSimSlotStatus;
184             }
185         }
186 
187         RadioResponseInfo rsp = mService.makeSolRsp(serial);
188         try {
189             mRadioConfigResponse.getSimSlotsStatusResponse(rsp, slotStatus);
190         } catch (RemoteException ex) {
191             Log.e(TAG, "Failed to invoke getSimSlotsStatusResponse from AIDL. Exception" + ex);
192         }
193     }
194 
195     @Override
setNumOfLiveModems(int serial, byte numOfLiveModems)196     public void setNumOfLiveModems(int serial, byte numOfLiveModems) {
197         Log.d(TAG, "setNumOfLiveModems");
198         // TODO: cache value
199 
200         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
201         try {
202             mRadioConfigResponse.setNumOfLiveModemsResponse(rsp);
203         } catch (RemoteException ex) {
204             Log.e(TAG, "Failed to invoke setNumOfLiveModemsResponse from AIDL. Exception" + ex);
205         }
206     }
207 
208     @Override
setPreferredDataModem(int serial, byte modemId)209     public void setPreferredDataModem(int serial, byte modemId) {
210         Log.d(TAG, "setPreferredDataModem");
211         // TODO: cache value
212 
213         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
214         try {
215             mRadioConfigResponse.setPreferredDataModemResponse(rsp);
216         } catch (RemoteException ex) {
217             Log.e(TAG, "Failed to invoke setPreferredDataModemResponse from AIDL. Exception" + ex);
218         }
219     }
220 
221     @Override
setResponseFunctions( IRadioConfigResponse radioConfigResponse, IRadioConfigIndication radioConfigIndication)222     public void setResponseFunctions(
223             IRadioConfigResponse radioConfigResponse,
224             IRadioConfigIndication radioConfigIndication) {
225         Log.d(TAG, "setResponseFunctions");
226         mRadioConfigResponse = radioConfigResponse;
227         mRadioConfigIndication = radioConfigIndication;
228         mService.countDownLatch(MockModemService.LATCH_RADIO_INTERFACES_READY);
229     }
230 
231     @Override
setSimSlotsMapping(int serial, SlotPortMapping[] slotMap)232     public void setSimSlotsMapping(int serial, SlotPortMapping[] slotMap) {
233         Log.d(TAG, "setSimSlotsMapping");
234         // TODO: cache value
235 
236         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
237         try {
238             mRadioConfigResponse.setSimSlotsMappingResponse(rsp);
239         } catch (RemoteException ex) {
240             Log.e(TAG, "Failed to invoke setSimSlotsMappingResponse from AIDL. Exception" + ex);
241         }
242     }
243 
unsolSimSlotsStatusChanged()244     public void unsolSimSlotsStatusChanged() {
245         Log.d(TAG, "unsolSimSlotsStatusChanged");
246         SimSlotStatus[] slotStatus;
247 
248         if (mRadioConfigIndication != null) {
249             synchronized (mCacheUpdateMutex) {
250                 if (mSlotNum < 1) {
251                     Log.d(TAG, "No slot information is retured.");
252                     slotStatus = null;
253                 } else {
254                     slotStatus = mSimSlotStatus;
255                 }
256             }
257 
258             try {
259                 mRadioConfigIndication.simSlotsStatusChanged(
260                         RadioIndicationType.UNSOLICITED, slotStatus);
261             } catch (RemoteException ex) {
262                 Log.e(TAG, "Failed to invoke simSlotsStatusChanged from AIDL. Exception" + ex);
263             }
264         } else {
265             Log.e(TAG, "null mRadioConfigIndication");
266         }
267     }
268 
269     @Override
getInterfaceHash()270     public String getInterfaceHash() {
271         return IRadioConfig.HASH;
272     }
273 
274     @Override
getInterfaceVersion()275     public int getInterfaceVersion() {
276         return IRadioConfig.VERSION;
277     }
278 }
279