• 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 com.android.internal.telephony;
18 
19 import android.content.ComponentName;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.ServiceConnection;
23 import android.os.IBinder;
24 
25 import com.android.telephony.Rlog;
26 
27 /** This class provides wrapper APIs for binding interfaces to mock service. */
28 public class MockModem {
29     private static final String TAG = "MockModem";
30     private static final String BIND_IRADIOMODEM = "android.telephony.mockmodem.iradiomodem";
31     private static final String BIND_IRADIOSIM = "android.telephony.mockmodem.iradiosim";
32     private static final String BIND_IRADIOMESSAGING =
33             "android.telephony.mockmodem.iradiomessaging";
34     private static final String BIND_IRADIODATA = "android.telephony.mockmodem.iradiodata";
35     private static final String BIND_IRADIONETWORK = "android.telephony.mockmodem.iradionetwork";
36     private static final String BIND_IRADIOVOICE = "android.telephony.mockmodem.iradiovoice";
37     private static final String BIND_IRADIOCONFIG = "android.telephony.mockmodem.iradioconfig";
38     private static final String PHONE_ID = "phone_id";
39 
40     private static final byte DEFAULT_PHONE_ID = 0x00;
41 
42     static final int RADIOCONFIG_SERVICE = RIL.MAX_SERVICE_IDX + 1;
43 
44     static final int BINDER_RETRY_MILLIS = 3 * 100;
45     static final int BINDER_MAX_RETRY = 3;
46 
47     private Context mContext;
48     private String mServiceName;
49     private String mPackageName;
50 
51     private IBinder mModemBinder;
52     private IBinder mSimBinder;
53     private IBinder mMessagingBinder;
54     private IBinder mDataBinder;
55     private IBinder mNetworkBinder;
56     private IBinder mVoiceBinder;
57     private IBinder mConfigBinder;
58     private ServiceConnection mModemServiceConnection;
59     private ServiceConnection mSimServiceConnection;
60     private ServiceConnection mMessagingServiceConnection;
61     private ServiceConnection mDataServiceConnection;
62     private ServiceConnection mNetworkServiceConnection;
63     private ServiceConnection mVoiceServiceConnection;
64     private ServiceConnection mConfigServiceConnection;
65 
66     private byte mPhoneId;
67 
MockModem(Context context, String serviceName)68     MockModem(Context context, String serviceName) {
69         this(context, serviceName, 0);
70     }
71 
MockModem(Context context, String serviceName, int phoneId)72     MockModem(Context context, String serviceName, int phoneId) {
73         mPhoneId = (byte) phoneId;
74         mContext = context;
75         String[] componentInfo = serviceName.split("/", 2);
76         mPackageName = componentInfo[0];
77         mServiceName = componentInfo[1];
78     }
79 
80     private class MockModemConnection implements ServiceConnection {
81         private int mService;
82 
MockModemConnection(int module)83         MockModemConnection(int module) {
84             mService = module;
85         }
86 
87         @Override
onServiceConnected(ComponentName name, IBinder binder)88         public void onServiceConnected(ComponentName name, IBinder binder) {
89             Rlog.d(TAG, "IRadio " + getModuleName(mService) + "  - onServiceConnected");
90 
91             if (mService == RIL.MODEM_SERVICE) {
92                 mModemBinder = binder;
93             } else if (mService == RIL.SIM_SERVICE) {
94                 mSimBinder = binder;
95             } else if (mService == RIL.MESSAGING_SERVICE) {
96                 mMessagingBinder = binder;
97             } else if (mService == RIL.DATA_SERVICE) {
98                 mDataBinder = binder;
99             } else if (mService == RIL.NETWORK_SERVICE) {
100                 mNetworkBinder = binder;
101             } else if (mService == RIL.VOICE_SERVICE) {
102                 mVoiceBinder = binder;
103             } else if (mService == RADIOCONFIG_SERVICE) {
104                 mConfigBinder = binder;
105             }
106         }
107 
108         @Override
onServiceDisconnected(ComponentName name)109         public void onServiceDisconnected(ComponentName name) {
110             Rlog.d(TAG, "IRadio " + getModuleName(mService) + "  - onServiceDisconnected");
111 
112             if (mService == RIL.MODEM_SERVICE) {
113                 mModemBinder = null;
114             } else if (mService == RIL.SIM_SERVICE) {
115                 mSimBinder = null;
116             } else if (mService == RIL.MESSAGING_SERVICE) {
117                 mMessagingBinder = null;
118             } else if (mService == RIL.DATA_SERVICE) {
119                 mDataBinder = null;
120             } else if (mService == RIL.NETWORK_SERVICE) {
121                 mNetworkBinder = null;
122             } else if (mService == RIL.VOICE_SERVICE) {
123                 mVoiceBinder = null;
124             } else if (mService == RADIOCONFIG_SERVICE) {
125                 mConfigBinder = null;
126             }
127         }
128     }
129 
bindModuleToMockModemService( String actionName, ServiceConnection serviceConnection)130     private boolean bindModuleToMockModemService(
131             String actionName, ServiceConnection serviceConnection) {
132         return bindModuleToMockModemService(DEFAULT_PHONE_ID, actionName, serviceConnection);
133     }
134 
bindModuleToMockModemService( byte phoneId, String actionName, ServiceConnection serviceConnection)135     private boolean bindModuleToMockModemService(
136             byte phoneId, String actionName, ServiceConnection serviceConnection) {
137         boolean status = false;
138 
139         Intent intent = new Intent();
140         intent.setComponent(new ComponentName(mPackageName, mServiceName));
141         intent.setAction(actionName);
142         intent.putExtra(PHONE_ID, phoneId);
143 
144         status = mContext.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
145         return status;
146     }
147 
148     /** waitForBinder */
getServiceBinder(int service)149     public IBinder getServiceBinder(int service) {
150         switch (service) {
151             case RIL.MODEM_SERVICE:
152                 return mModemBinder;
153             case RIL.SIM_SERVICE:
154                 return mSimBinder;
155             case RIL.MESSAGING_SERVICE:
156                 return mMessagingBinder;
157             case RIL.DATA_SERVICE:
158                 return mDataBinder;
159             case RIL.NETWORK_SERVICE:
160                 return mNetworkBinder;
161             case RIL.VOICE_SERVICE:
162                 return mVoiceBinder;
163             case RADIOCONFIG_SERVICE:
164                 return mConfigBinder;
165             default:
166                 return null;
167         }
168     }
169 
170     /** Binding interfaces with mock modem service */
bindAllMockModemService()171     public void bindAllMockModemService() {
172         for (int service = RIL.MIN_SERVICE_IDX; service <= RIL.MAX_SERVICE_IDX; service++) {
173             bindToMockModemService(service);
174         }
175     }
176 
177     /** bindToMockModemService */
bindToMockModemService(int service)178     public void bindToMockModemService(int service) {
179         if (service == RADIOCONFIG_SERVICE) {
180             if (mConfigBinder == null) {
181                 mConfigServiceConnection = new MockModemConnection(RADIOCONFIG_SERVICE);
182 
183                 boolean status =
184                         bindModuleToMockModemService(BIND_IRADIOCONFIG, mConfigServiceConnection);
185                 if (!status) {
186                     Rlog.d(TAG, "IRadio Config bind fail");
187                     mConfigServiceConnection = null;
188                 }
189             } else {
190                 Rlog.d(TAG, "IRadio Config is bound");
191             }
192         } else if (service == RIL.MODEM_SERVICE) {
193             if (mModemBinder == null) {
194                 mModemServiceConnection = new MockModemConnection(RIL.MODEM_SERVICE);
195 
196                 boolean status =
197                         bindModuleToMockModemService(
198                                 mPhoneId, BIND_IRADIOMODEM, mModemServiceConnection);
199                 if (!status) {
200                     Rlog.d(TAG, "IRadio Modem bind fail");
201                     mModemServiceConnection = null;
202                 }
203             } else {
204                 Rlog.d(TAG, "IRadio Modem is bound");
205             }
206         } else if (service == RIL.SIM_SERVICE) {
207             if (mSimBinder == null) {
208                 mSimServiceConnection = new MockModemConnection(RIL.SIM_SERVICE);
209 
210                 boolean status =
211                         bindModuleToMockModemService(
212                                 mPhoneId, BIND_IRADIOSIM, mSimServiceConnection);
213                 if (!status) {
214                     Rlog.d(TAG, "IRadio Sim bind fail");
215                     mSimServiceConnection = null;
216                 }
217             } else {
218                 Rlog.d(TAG, "IRadio Sim is bound");
219             }
220         } else if (service == RIL.MESSAGING_SERVICE) {
221             if (mMessagingBinder == null) {
222                 mMessagingServiceConnection = new MockModemConnection(RIL.MESSAGING_SERVICE);
223 
224                 boolean status =
225                         bindModuleToMockModemService(
226                                 mPhoneId, BIND_IRADIOMESSAGING, mMessagingServiceConnection);
227                 if (!status) {
228                     Rlog.d(TAG, "IRadio Messaging bind fail");
229                     mMessagingServiceConnection = null;
230                 }
231             } else {
232                 Rlog.d(TAG, "IRadio Messaging is bound");
233             }
234         } else if (service == RIL.DATA_SERVICE) {
235             if (mDataBinder == null) {
236                 mDataServiceConnection = new MockModemConnection(RIL.DATA_SERVICE);
237 
238                 boolean status =
239                         bindModuleToMockModemService(
240                                 mPhoneId, BIND_IRADIODATA, mDataServiceConnection);
241                 if (!status) {
242                     Rlog.d(TAG, "IRadio Data bind fail");
243                     mDataServiceConnection = null;
244                 }
245             } else {
246                 Rlog.d(TAG, "IRadio Data is bound");
247             }
248         } else if (service == RIL.NETWORK_SERVICE) {
249             if (mNetworkBinder == null) {
250                 mNetworkServiceConnection = new MockModemConnection(RIL.NETWORK_SERVICE);
251 
252                 boolean status =
253                         bindModuleToMockModemService(
254                                 mPhoneId, BIND_IRADIONETWORK, mNetworkServiceConnection);
255                 if (!status) {
256                     Rlog.d(TAG, "IRadio Network bind fail");
257                     mNetworkServiceConnection = null;
258                 }
259             } else {
260                 Rlog.d(TAG, "IRadio Network is bound");
261             }
262         } else if (service == RIL.VOICE_SERVICE) {
263             if (mVoiceBinder == null) {
264                 mVoiceServiceConnection = new MockModemConnection(RIL.VOICE_SERVICE);
265 
266                 boolean status =
267                         bindModuleToMockModemService(
268                                 mPhoneId, BIND_IRADIOVOICE, mVoiceServiceConnection);
269                 if (!status) {
270                     Rlog.d(TAG, "IRadio Voice bind fail");
271                     mVoiceServiceConnection = null;
272                 }
273             } else {
274                 Rlog.d(TAG, "IRadio Voice is bound");
275             }
276         }
277     }
278 
279     /** unbindMockModemService */
unbindMockModemService(int service)280     public void unbindMockModemService(int service) {
281 
282         if (service == RADIOCONFIG_SERVICE) {
283             if (mConfigServiceConnection != null) {
284                 mContext.unbindService(mConfigServiceConnection);
285                 mConfigServiceConnection = null;
286                 mConfigBinder = null;
287                 Rlog.d(TAG, "unbind IRadio Config");
288             }
289         } else if (service == RIL.MODEM_SERVICE) {
290             if (mModemServiceConnection != null) {
291                 mContext.unbindService(mModemServiceConnection);
292                 mModemServiceConnection = null;
293                 mModemBinder = null;
294                 Rlog.d(TAG, "unbind IRadio Modem");
295             }
296         } else if (service == RIL.SIM_SERVICE) {
297             if (mSimServiceConnection != null) {
298                 mContext.unbindService(mSimServiceConnection);
299                 mSimServiceConnection = null;
300                 mSimBinder = null;
301                 Rlog.d(TAG, "unbind IRadio Sim");
302             }
303         } else if (service == RIL.MESSAGING_SERVICE) {
304             if (mMessagingServiceConnection != null) {
305                 mContext.unbindService(mMessagingServiceConnection);
306                 mMessagingServiceConnection = null;
307                 mMessagingBinder = null;
308                 Rlog.d(TAG, "unbind IRadio Messaging");
309             }
310         } else if (service == RIL.DATA_SERVICE) {
311             if (mDataServiceConnection != null) {
312                 mContext.unbindService(mDataServiceConnection);
313                 mDataServiceConnection = null;
314                 mDataBinder = null;
315                 Rlog.d(TAG, "unbind IRadio Data");
316             }
317         } else if (service == RIL.NETWORK_SERVICE) {
318             if (mNetworkServiceConnection != null) {
319                 mContext.unbindService(mNetworkServiceConnection);
320                 mNetworkServiceConnection = null;
321                 mNetworkBinder = null;
322                 Rlog.d(TAG, "unbind IRadio Network");
323             }
324         } else if (service == RIL.VOICE_SERVICE) {
325             if (mVoiceServiceConnection != null) {
326                 mContext.unbindService(mVoiceServiceConnection);
327                 mVoiceServiceConnection = null;
328                 mVoiceBinder = null;
329                 Rlog.d(TAG, "unbind IRadio Voice");
330             }
331         }
332     }
333 
getServiceName()334     public String getServiceName() {
335         return mServiceName;
336     }
337 
getModuleName(int service)338     private String getModuleName(int service) {
339         switch (service) {
340             case RIL.MODEM_SERVICE:
341                 return "modem";
342             case RIL.SIM_SERVICE:
343                 return "sim";
344             case RIL.MESSAGING_SERVICE:
345                 return "messaging";
346             case RIL.DATA_SERVICE:
347                 return "data";
348             case RIL.NETWORK_SERVICE:
349                 return "network";
350             case RIL.VOICE_SERVICE:
351                 return "voice";
352             case RADIOCONFIG_SERVICE:
353                 return "config";
354             default:
355                 return "none";
356         }
357     }
358 }
359