• 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.content.Context;
20 import android.hardware.radio.RadioError;
21 import android.hardware.radio.RadioIndicationType;
22 import android.hardware.radio.RadioResponseInfo;
23 import android.hardware.radio.data.DataProfileInfo;
24 import android.hardware.radio.data.IRadioData;
25 import android.hardware.radio.data.IRadioDataIndication;
26 import android.hardware.radio.data.IRadioDataResponse;
27 import android.hardware.radio.data.KeepaliveRequest;
28 import android.hardware.radio.data.LinkAddress;
29 import android.hardware.radio.data.SetupDataCallResult;
30 import android.hardware.radio.data.SliceInfo;
31 import android.os.AsyncResult;
32 import android.os.Handler;
33 import android.os.Message;
34 import android.os.RemoteException;
35 import android.util.Log;
36 
37 import java.util.List;
38 
39 public class IRadioDataImpl extends IRadioData.Stub {
40     private static final String TAG = "MRDATA";
41 
42     private final MockModemService mService;
43     private final MockDataService mMockDataService;
44     private IRadioDataResponse mRadioDataResponse;
45     private IRadioDataIndication mRadioDataIndication;
46     private MockModemConfigInterface mMockModemConfigInterface;
47     private static Object sCacheUpdateMutex = new Object();
48     private final Handler mHandler;
49     private int mSubId;
50     private String mTag;
51 
52     private static MockNetworkService sServiceState;
53 
54     // Event
55     static final int EVENT_NETWORK_STATUS_CHANGED = 1;
56 
IRadioDataImpl( MockModemService service, Context context, MockModemConfigInterface configInterface, int instanceId)57     public IRadioDataImpl(
58             MockModemService service,
59             Context context,
60             MockModemConfigInterface configInterface,
61             int instanceId) {
62         mTag = TAG + "-" + instanceId;
63         Log.d(mTag, "Instantiated");
64 
65         mMockDataService = new MockDataService(context, instanceId);
66         this.mService = service;
67 
68         mMockModemConfigInterface = configInterface;
69         mSubId = instanceId;
70 
71         mHandler = new IRadioDataHandler();
72 
73         // Register event
74         mMockModemConfigInterface.registerForServiceStateChanged(
75                 mSubId, mHandler, EVENT_NETWORK_STATUS_CHANGED, null);
76     }
77 
78     // Implementation of IRadioData functions
79     @Override
setResponseFunctions( IRadioDataResponse radioDataResponse, IRadioDataIndication radioDataIndication)80     public void setResponseFunctions(
81             IRadioDataResponse radioDataResponse, IRadioDataIndication radioDataIndication) {
82         Log.d(mTag, "setResponseFunctions");
83         mRadioDataResponse = radioDataResponse;
84         mRadioDataIndication = radioDataIndication;
85         mService.countDownLatch(MockModemService.LATCH_RADIO_INTERFACES_READY);
86 
87         unsolDataCallListChanged();
88     }
89 
90     @Override
allocatePduSessionId(int serial)91     public void allocatePduSessionId(int serial) {
92         Log.d(mTag, "allocatePduSessionId");
93         int id = 0;
94         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
95         try {
96             mRadioDataResponse.allocatePduSessionIdResponse(rsp, id);
97         } catch (RemoteException ex) {
98             Log.e(mTag, "Failed to allocatePduSessionId from AIDL. Exception" + ex);
99         }
100     }
101 
102     @Override
cancelHandover(int serial, int callId)103     public void cancelHandover(int serial, int callId) {
104         Log.d(mTag, "cancelHandover");
105         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
106         try {
107             mRadioDataResponse.cancelHandoverResponse(rsp);
108         } catch (RemoteException ex) {
109             Log.e(mTag, "Failed to cancelHandover from AIDL. Exception" + ex);
110         }
111     }
112 
113     @Override
deactivateDataCall(int serial, int cid, int reason)114     public void deactivateDataCall(int serial, int cid, int reason) {
115         Log.d(mTag, "deactivateDataCall");
116 
117         mMockDataService.deactivateDataCall(cid, reason);
118         RadioResponseInfo rsp = mService.makeSolRsp(serial);
119         try {
120             mRadioDataResponse.deactivateDataCallResponse(rsp);
121         } catch (RemoteException ex) {
122             Log.e(mTag, "Failed to deactivateDataCall from AIDL. Exception" + ex);
123         }
124         // send the data call list changed
125         unsolDataCallListChanged();
126     }
127 
128     @Override
getDataCallList(int serial)129     public void getDataCallList(int serial) {
130         Log.d(mTag, "getDataCallList");
131 
132         List<SetupDataCallResult> dataCallLists = mMockDataService.getDataCallList();
133         SetupDataCallResult[] dcList = new SetupDataCallResult[dataCallLists.size()];
134         dcList = dataCallLists.toArray(dcList);
135 
136         RadioResponseInfo rsp = mService.makeSolRsp(serial);
137         try {
138             mRadioDataResponse.getDataCallListResponse(rsp, dcList);
139         } catch (RemoteException ex) {
140             Log.e(mTag, "Failed to getDataCallList from AIDL. Exception" + ex);
141         }
142     }
143 
144     @Override
getSlicingConfig(int serial)145     public void getSlicingConfig(int serial) {
146         Log.d(mTag, "getSlicingConfig");
147         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
148         try {
149             mRadioDataResponse.getSlicingConfigResponse(rsp, null);
150         } catch (RemoteException ex) {
151             Log.e(mTag, "Failed to getSlicingConfig from AIDL. Exception" + ex);
152         }
153     }
154 
155     @Override
releasePduSessionId(int serial, int id)156     public void releasePduSessionId(int serial, int id) {
157         Log.d(mTag, "releasePduSessionId");
158         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
159         try {
160             mRadioDataResponse.releasePduSessionIdResponse(rsp);
161         } catch (RemoteException ex) {
162             Log.e(mTag, "Failed to releasePduSessionId from AIDL. Exception" + ex);
163         }
164     }
165 
166     @Override
responseAcknowledgement()167     public void responseAcknowledgement() {
168         Log.d(mTag, "responseAcknowledgement");
169     }
170 
171     @Override
setDataAllowed(int serial, boolean allow)172     public void setDataAllowed(int serial, boolean allow) {
173         Log.d(mTag, "setDataAllowed");
174         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
175         try {
176             mRadioDataResponse.setDataAllowedResponse(rsp);
177         } catch (RemoteException ex) {
178             Log.e(mTag, "Failed to setDataAllowed from AIDL. Exception" + ex);
179         }
180     }
181 
182     @Override
setDataProfile(int serial, DataProfileInfo[] profiles)183     public void setDataProfile(int serial, DataProfileInfo[] profiles) {
184         Log.d(mTag, "setDataProfile");
185 
186         // set data profiles to mockdataservice
187         mMockDataService.setDataProfileInfo(profiles);
188 
189         RadioResponseInfo rsp = mService.makeSolRsp(serial);
190         try {
191             mRadioDataResponse.setDataProfileResponse(rsp);
192         } catch (RemoteException ex) {
193             Log.e(mTag, "Failed to setDataProfile from AIDL. Exception" + ex);
194         }
195     }
196 
197     @Override
setDataThrottling( int serial, byte dataThrottlingAction, long completionDurationMillis)198     public void setDataThrottling(
199             int serial, byte dataThrottlingAction, long completionDurationMillis) {
200         Log.d(mTag, "setDataThrottling");
201         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
202         try {
203             mRadioDataResponse.setDataThrottlingResponse(rsp);
204         } catch (RemoteException ex) {
205             Log.e(mTag, "Failed to setDataThrottling from AIDL. Exception" + ex);
206         }
207     }
208 
209     @Override
setInitialAttachApn(int serial, DataProfileInfo dataProfileInfo)210     public void setInitialAttachApn(int serial, DataProfileInfo dataProfileInfo) {
211         Log.d(mTag, "setInitialAttachApn");
212         // set initial attach apn to mockdataservice
213         mMockDataService.setInitialAttachProfile(dataProfileInfo);
214 
215         RadioResponseInfo rsp = mService.makeSolRsp(serial);
216         try {
217             mRadioDataResponse.setInitialAttachApnResponse(rsp);
218         } catch (RemoteException ex) {
219             Log.e(mTag, "Failed to setInitialAttachApn from AIDL. Exception" + ex);
220         }
221     }
222 
223     @Override
setupDataCall( int serial, int accessNetwork, DataProfileInfo dataProfileInfo, boolean roamingAllowed, int reason, LinkAddress[] addresses, String[] dnses, int pduSessionId, SliceInfo sliceInfo, boolean matchAllRuleAllowed)224     public void setupDataCall(
225             int serial,
226             int accessNetwork,
227             DataProfileInfo dataProfileInfo,
228             boolean roamingAllowed,
229             int reason,
230             LinkAddress[] addresses,
231             String[] dnses,
232             int pduSessionId,
233             SliceInfo sliceInfo,
234             boolean matchAllRuleAllowed) {
235         Log.d(mTag, "setupDataCall");
236 
237         RadioResponseInfo rsp;
238         SetupDataCallResult dc = new SetupDataCallResult();
239         rsp = mService.makeSolRsp(serial);
240         synchronized (sCacheUpdateMutex) {
241             if (sServiceState == null || !sServiceState.isPsInService()) {
242                 rsp = mService.makeSolRsp(serial, RadioError.OP_NOT_ALLOWED_BEFORE_REG_TO_NW);
243             } else {
244                 if (mMockDataService.isSupportedCapability(dataProfileInfo.apn)) {
245                     if (dataProfileInfo.apn.equals("ims")) {
246                         dc = mMockDataService.setupDataCall(mMockDataService.APN_TYPE_IMS);
247                     } else if (dataProfileInfo.apn.equals("internet")) {
248                         dc = mMockDataService.setupDataCall(mMockDataService.APN_TYPE_DEFAULT);
249                     }
250                 } else {
251                     rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
252                 }
253             }
254         }
255 
256         try {
257             mRadioDataResponse.setupDataCallResponse(rsp, dc);
258         } catch (RemoteException ex) {
259             Log.e(mTag, "Failed to setupDataCall from AIDL. Exception" + ex);
260         }
261         // send the data call list changed
262         unsolDataCallListChanged();
263     }
264 
265     @Override
startHandover(int serial, int callId)266     public void startHandover(int serial, int callId) {
267         Log.d(mTag, "startHandover");
268         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
269         try {
270             mRadioDataResponse.startHandoverResponse(rsp);
271         } catch (RemoteException ex) {
272             Log.e(mTag, "Failed to startHandover from AIDL. Exception" + ex);
273         }
274     }
275 
276     @Override
startKeepalive(int serial, KeepaliveRequest keepalive)277     public void startKeepalive(int serial, KeepaliveRequest keepalive) {
278         Log.d(mTag, "startKeepalive");
279         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
280         try {
281             mRadioDataResponse.startKeepaliveResponse(rsp, null);
282         } catch (RemoteException ex) {
283             Log.e(mTag, "Failed to startKeepalive from AIDL. Exception" + ex);
284         }
285     }
286 
287     @Override
stopKeepalive(int serial, int sessionHandle)288     public void stopKeepalive(int serial, int sessionHandle) {
289         Log.d(mTag, "stopKeepalive");
290         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
291         try {
292             mRadioDataResponse.stopKeepaliveResponse(rsp);
293         } catch (RemoteException ex) {
294             Log.e(mTag, "Failed to stopKeepalive from AIDL. Exception" + ex);
295         }
296     }
297 
298     @Override
getInterfaceHash()299     public String getInterfaceHash() {
300         return IRadioData.HASH;
301     }
302 
303     @Override
getInterfaceVersion()304     public int getInterfaceVersion() {
305         return IRadioData.VERSION;
306     }
307 
unsolDataCallListChanged()308     public void unsolDataCallListChanged() {
309         Log.d(mTag, "unsolDataCallListChanged");
310 
311         if (mRadioDataIndication != null) {
312             List<SetupDataCallResult> dataCallLists = mMockDataService.getDataCallList();
313             SetupDataCallResult[] dcList = new SetupDataCallResult[dataCallLists.size()];
314             dcList = dataCallLists.toArray(dcList);
315 
316             try {
317                 mRadioDataIndication.dataCallListChanged(RadioIndicationType.UNSOLICITED, dcList);
318             } catch (RemoteException ex) {
319                 Log.e(
320                         mTag,
321                         "Failed to invoke dataCallListChanged change from AIDL. Exception" + ex);
322             }
323         } else {
324             Log.e(mTag, "null mRadioDataIndication");
325         }
326     }
327 
328     /** Handler class to handle callbacks */
329     private static final class IRadioDataHandler extends Handler {
330         @Override
handleMessage(Message msg)331         public void handleMessage(Message msg) {
332             AsyncResult ar;
333             synchronized (sCacheUpdateMutex) {
334                 switch (msg.what) {
335                     case EVENT_NETWORK_STATUS_CHANGED:
336                         Log.d(TAG, "Received EVENT_NETWORK_STATUS_CHANGED");
337                         ar = (AsyncResult) msg.obj;
338                         if (ar != null && ar.exception == null) {
339                             sServiceState = (MockNetworkService) ar.result;
340                             Log.i(TAG, "Service State: " + sServiceState.toString());
341                         } else {
342                             Log.e(TAG, msg.what + " failure. Exception: " + ar.exception);
343                         }
344                         break;
345                 }
346             }
347         }
348     }
349 }
350