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