• 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.os.HwBinder;
20 import android.os.IBinder;
21 import android.os.RemoteException;
22 import android.telephony.UiccSlotMapping;
23 
24 import com.android.telephony.Rlog;
25 
26 import java.util.List;
27 import java.util.Set;
28 
29 /**
30  * RadioConfig proxy class that abstracts the underlying RadioConfig service implementation to
31  * downstream users.
32  */
33 public class RadioConfigProxy {
34     private static final String TAG = "RadioConfigProxy";
35     private HalVersion mRadioHalVersion;
36     private final RadioConfigHidlServiceDeathRecipient mRadioConfigHidlServiceDeathRecipient;
37     private final RadioConfigAidlServiceDeathRecipient mRadioConfigAidlServiceDeathRecipient;
38 
39     private volatile android.hardware.radio.config.V1_1.IRadioConfig mHidlRadioConfigProxy = null;
40     private volatile android.hardware.radio.config.IRadioConfig mAidlRadioConfigProxy = null;
41 
42     private HalVersion mRadioConfigHalVersion = RIL.RADIO_HAL_VERSION_UNKNOWN;
43     private boolean mIsAidl;
44 
RadioConfigProxy(RadioConfig radioConfig, HalVersion radioHalVersion)45     public RadioConfigProxy(RadioConfig radioConfig, HalVersion radioHalVersion) {
46         mRadioHalVersion = radioHalVersion;
47         mRadioConfigAidlServiceDeathRecipient =
48                 new RadioConfigAidlServiceDeathRecipient(radioConfig);
49         mRadioConfigHidlServiceDeathRecipient =
50                 new RadioConfigHidlServiceDeathRecipient(radioConfig);
51     }
52 
53     /**
54      * Set IRadioConfig as the HIDL implementation for RadioConfigProxy
55      *
56      * @param radioConfigHalVersion RadioConfig HAL version
57      * @param radioConfig IRadioConfig implementation
58      */
setHidl( HalVersion radioConfigHalVersion, android.hardware.radio.config.V1_1.IRadioConfig radioConfig)59     public void setHidl(
60             HalVersion radioConfigHalVersion,
61             android.hardware.radio.config.V1_1.IRadioConfig radioConfig) {
62         mRadioConfigHalVersion = radioConfigHalVersion;
63         mHidlRadioConfigProxy = radioConfig;
64         mIsAidl = false;
65         mRadioConfigHidlServiceDeathRecipient.setService(radioConfig);
66     }
67 
68     /**
69      * Get HIDL IRadioConfig V1_1
70      * @return IRadioConfigV1_1
71      */
getHidl11()72     public android.hardware.radio.config.V1_1.IRadioConfig getHidl11() {
73         return mHidlRadioConfigProxy;
74     }
75 
76     /**
77      * Get HIDL IRadioConfig V1_3
78      * @return IRadioConfigV1_3
79      */
getHidl13()80     public android.hardware.radio.config.V1_3.IRadioConfig getHidl13() {
81         return (android.hardware.radio.config.V1_3.IRadioConfig) mHidlRadioConfigProxy;
82     }
83 
84     /**
85      * Set IRadioConfig as the AIDL implementation for RadioConfigProxy
86      *
87      * @param radioConfig IRadioConfig implementation
88      */
setAidl(android.hardware.radio.config.IRadioConfig radioConfig)89     public void setAidl(android.hardware.radio.config.IRadioConfig radioConfig) {
90         try {
91             mRadioConfigHalVersion = RIL.getServiceHalVersion(radioConfig.getInterfaceVersion());
92             Rlog.d(TAG, "setAidl: setting HAL version to version = " + mRadioConfigHalVersion);
93         } catch (RemoteException e) {
94             Rlog.e(TAG, "setAidl: " + e);
95         }
96         mAidlRadioConfigProxy = radioConfig;
97         mIsAidl = true;
98         mRadioConfigAidlServiceDeathRecipient.setService(radioConfig.asBinder());
99     }
100 
101     /**
102      * Get the AIDL implementation of RadioConfigProxy
103      *
104      * @return IRadio implementation
105      */
getAidl()106     public android.hardware.radio.config.IRadioConfig getAidl() {
107         return mAidlRadioConfigProxy;
108     }
109 
110     /** Reset RadioConfigProxy */
clear()111     public void clear() {
112         mRadioConfigHalVersion = RIL.RADIO_HAL_VERSION_UNKNOWN;
113         mHidlRadioConfigProxy = null;
114         mAidlRadioConfigProxy = null;
115         mRadioConfigHidlServiceDeathRecipient.clear();
116         mRadioConfigAidlServiceDeathRecipient.clear();
117     }
118 
119     /**
120      * Wrapper for service's linkToDeath()
121      */
linkToDeath(long cookie)122     public void linkToDeath(long cookie) throws RemoteException {
123         if (isAidl()) {
124             mRadioConfigAidlServiceDeathRecipient.linkToDeath((int) cookie);
125         } else {
126             mRadioConfigHidlServiceDeathRecipient.linkToDeath(cookie);
127         }
128     }
129 
130     /**
131      * Check whether an implementation exists for this service
132      *
133      * @return false if there is neither a HIDL nor AIDL implementation
134      */
isEmpty()135     public boolean isEmpty() {
136         return mAidlRadioConfigProxy == null && mHidlRadioConfigProxy == null;
137     }
138 
139     /**
140      * Whether RadioConfigProxy is an AIDL or HIDL implementation
141      *
142      * @return true if AIDL, false if HIDL
143      */
isAidl()144     public boolean isAidl() {
145         return mIsAidl;
146     }
147 
148     /**
149      * Return RadioConfig HAL version used by this instance
150      * @return RadioConfig HAL Version
151      */
getVersion()152     public HalVersion getVersion() {
153         return mRadioConfigHalVersion;
154     }
155 
156     /**
157      * Set the response functions for RadioConfig instance
158      * @param radioConfig main RadioConfig instance
159      * @throws RemoteException
160      */
setResponseFunctions(RadioConfig radioConfig)161     public void setResponseFunctions(RadioConfig radioConfig) throws RemoteException {
162         if (isEmpty()) return;
163 
164         if (isAidl()) {
165             mAidlRadioConfigProxy.setResponseFunctions(
166                     new RadioConfigResponseAidl(radioConfig, mRadioHalVersion),
167                     new RadioConfigIndicationAidl(radioConfig));
168         } else {
169             mHidlRadioConfigProxy.setResponseFunctions(
170                     new RadioConfigResponseHidl(radioConfig, mRadioHalVersion),
171                     new RadioConfigIndicationHidl(radioConfig));
172         }
173     }
174 
175     /**
176      * Get capabilities based off of the radio hal version and feature set configurations
177      * @return Set string capabilities
178      */
getFullCapabilitySet()179     public Set<String> getFullCapabilitySet() {
180         return RILUtils.getCaps(mRadioHalVersion, false);
181     }
182 
183     /**
184      * Wrapper function for IRadioConfig.getSimSlotsStatus().
185      */
getSimSlotStatus(int serial)186     public void getSimSlotStatus(int serial) throws RemoteException {
187         if (isAidl()) {
188             getAidl().getSimSlotsStatus(serial);
189         } else {
190             getHidl11().getSimSlotsStatus(serial);
191         }
192     }
193 
194     /**
195      * Wrapper function for IRadioConfig.setPreferredDataModem(int modemId).
196      */
setPreferredDataModem(int serial, int modemId)197     public void setPreferredDataModem(int serial, int modemId) throws RemoteException {
198         if (isAidl()) {
199             getAidl().setPreferredDataModem(serial, (byte) modemId);
200         } else {
201             getHidl11().setPreferredDataModem(serial, (byte) modemId);
202         }
203     }
204 
205     /**
206      * Wrapper function for IRadioConfig.getPhoneCapability().
207      */
getPhoneCapability(int serial)208     public void getPhoneCapability(int serial) throws RemoteException {
209         if (isAidl()) {
210             getAidl().getPhoneCapability(serial);
211         } else {
212             getHidl11().getPhoneCapability(serial);
213         }
214     }
215 
216     /**
217      * Wrapper function for IRadioConfig.setSimSlotsMapping(int32_t serial,
218      * vec<SlotPortMapping> portMap).
219      */
setSimSlotsMapping(int serial, List<UiccSlotMapping> slotMapping)220     public void setSimSlotsMapping(int serial, List<UiccSlotMapping> slotMapping)
221             throws RemoteException {
222         if (isAidl()) {
223             getAidl().setSimSlotsMapping(serial, RILUtils.convertSimSlotsMapping(slotMapping));
224         } else {
225             getHidl11().setSimSlotsMapping(serial,
226                     RILUtils.convertSlotMappingToList(slotMapping));
227         }
228     }
229 
230     /**
231      * Wrapper function for IRadioConfig.getSimultaneousCallingSupport()
232      */
updateSimultaneousCallingSupport(int serial)233     public void updateSimultaneousCallingSupport(int serial) throws RemoteException {
234         if (isAidl()) {
235             getAidl().getSimultaneousCallingSupport(serial);
236         }
237         // Only supported on AIDL.
238     }
239 
240     /**
241      * Wrapper function for using IRadioConfig.setNumOfLiveModems(int32_t serial,
242      * byte numOfLiveModems) to switch between single-sim and multi-sim.
243      */
setNumOfLiveModems(int serial, int numOfLiveModems)244     public void setNumOfLiveModems(int serial, int numOfLiveModems) throws RemoteException {
245         if (isAidl()) {
246             getAidl().setNumOfLiveModems(serial, (byte) numOfLiveModems);
247         } else {
248             android.hardware.radio.config.V1_1.ModemsConfig modemsConfig =
249                     new android.hardware.radio.config.V1_1.ModemsConfig();
250             modemsConfig.numOfLiveModems = (byte) numOfLiveModems;
251             getHidl11().setModemsConfig(serial, modemsConfig);
252         }
253     }
254 
255     /**
256      * Gets the hal capabilities from the device.
257      */
getHalDeviceCapabilities(int serial)258     public void getHalDeviceCapabilities(int serial) throws RemoteException {
259         if (isAidl()) {
260             getAidl().getHalDeviceCapabilities(serial);
261         } else {
262             getHidl13().getHalDeviceCapabilities(serial);
263         }
264     }
265 
266     /**
267      * Death Recipient for HIDL binder (if any) of RadioConfig.
268      */
269     private static class RadioConfigHidlServiceDeathRecipient implements HwBinder.DeathRecipient {
270         private static final String TAG = "RadioConfigHidlSDR";
271 
272         private final RadioConfig mRadioConfig;
273         private android.hardware.radio.config.V1_1.IRadioConfig mService;
274 
RadioConfigHidlServiceDeathRecipient(RadioConfig radioConfig)275         RadioConfigHidlServiceDeathRecipient(RadioConfig radioConfig) {
276             mRadioConfig = radioConfig;
277         }
278 
setService(android.hardware.radio.config.V1_1.IRadioConfig service)279         public void setService(android.hardware.radio.config.V1_1.IRadioConfig service) {
280             mService = service;
281         }
282 
linkToDeath(long cookie)283         public void linkToDeath(long cookie) throws RemoteException {
284             if (mService != null) {
285                 mService.linkToDeath(this, cookie);
286             } else {
287                 Rlog.w(TAG, "linkToDeath: skipping since mService is null");
288             }
289         }
290 
clear()291         public void clear() {
292             mService = null;
293         }
294 
295         @Override
serviceDied(long cookie)296         public void serviceDied(long cookie) {
297             // Deal with service going away
298             Rlog.e(TAG, "serviceDied");
299             mRadioConfig.sendMessage(
300                     mRadioConfig.obtainMessage(RadioConfig.EVENT_HIDL_SERVICE_DEAD, cookie));
301         }
302     }
303 
304     /**
305      * DeathRecipient for AIDL binder service (if any) of RadioConfig
306      */
307     private static class RadioConfigAidlServiceDeathRecipient implements IBinder.DeathRecipient {
308         private static final String TAG = "RadioConfigAidlSDR";
309 
310         private final RadioConfig mRadioConfig;
311 
312         private IBinder mService;
313 
RadioConfigAidlServiceDeathRecipient(RadioConfig radioConfig)314         RadioConfigAidlServiceDeathRecipient(RadioConfig radioConfig) {
315             mRadioConfig = radioConfig;
316         }
317 
setService(IBinder service)318         public void setService(IBinder service) {
319             mService = service;
320         }
321 
linkToDeath(int cookie)322         public void linkToDeath(int cookie) throws RemoteException {
323             if (mService != null) {
324                 mService.linkToDeath(this, cookie);
325             } else {
326                 Rlog.w(TAG, "linkToDeath: skipping since mService is null");
327             }
328         }
329 
clear()330         public void clear() {
331             mService = null;
332         }
333 
334         /**
335          * Unlink from RadioConfig if any.
336          */
unlinkToDeath()337         public synchronized void unlinkToDeath() {
338             if (mService != null) {
339                 mService.unlinkToDeath(this, 0);
340                 mService = null;
341             }
342         }
343 
344         @Override
binderDied()345         public void binderDied() {
346             Rlog.e(TAG, "service died.");
347             unlinkToDeath();
348             mRadioConfig.sendMessage(
349                     mRadioConfig.obtainMessage(RadioConfig.EVENT_AIDL_SERVICE_DEAD));
350         }
351     }
352 
353     @Override
toString()354     public String toString() {
355         return "RadioConfigProxy["
356                 + "mRadioHalVersion=" + mRadioHalVersion
357                 + ", mRadioConfigHalVersion=" + mRadioConfigHalVersion + ']';
358     }
359 }
360