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