• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.ims.compat.stub;
18 
19 import android.compat.annotation.UnsupportedAppUsage;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.os.Build;
23 import android.os.RemoteException;
24 import android.util.Log;
25 
26 import com.android.ims.ImsConfig;
27 import com.android.ims.ImsConfigListener;
28 import com.android.ims.internal.IImsConfig;
29 import com.android.internal.annotations.VisibleForTesting;
30 
31 import java.lang.ref.WeakReference;
32 import java.util.HashMap;
33 
34 
35 /**
36  * Base implementation of ImsConfig.
37  * Override the methods that your implementation of ImsConfig supports.
38  *
39  * DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you
40  * will break other implementations of ImsConfig maintained by other ImsServices.
41  *
42  * Provides APIs to get/set the IMS service feature/capability/parameters.
43  * The config items include:
44  * 1) Items provisioned by the operator.
45  * 2) Items configured by user. Mainly service feature class.
46  *
47  * The inner class {@link ImsConfigStub} implements methods of IImsConfig AIDL interface.
48  * The IImsConfig AIDL interface is called by ImsConfig, which may exist in many other processes.
49  * ImsConfigImpl access to the configuration parameters may be arbitrarily slow, especially in
50  * during initialization, or times when a lot of configuration parameters are being set/get
51  * (such as during boot up or SIM card change). By providing a cache in ImsConfigStub, we can speed
52  * up access to these configuration parameters, so a query to the ImsConfigImpl does not have to be
53  * performed every time.
54  * @hide
55  */
56 
57 public class ImsConfigImplBase {
58 
59     static final private String TAG = "ImsConfigImplBase";
60 
61     ImsConfigStub mImsConfigStub;
62 
63     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
ImsConfigImplBase(Context context)64     public ImsConfigImplBase(Context context) {
65         mImsConfigStub = new ImsConfigStub(this, context);
66     }
67 
68     /**
69      * Gets the value for ims service/capabilities parameters from the provisioned
70      * value storage. Synchronous blocking call.
71      *
72      * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
73      * @return value in Integer format.
74      */
getProvisionedValue(int item)75     public int getProvisionedValue(int item) throws RemoteException {
76         return -1;
77     }
78 
79     /**
80      * Gets the value for ims service/capabilities parameters from the provisioned
81      * value storage. Synchronous blocking call.
82      *
83      * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
84      * @return value in String format.
85      */
getProvisionedStringValue(int item)86     public String getProvisionedStringValue(int item) throws RemoteException {
87         return null;
88     }
89 
90     /**
91      * Sets the value for IMS service/capabilities parameters by the operator device
92      * management entity. It sets the config item value in the provisioned storage
93      * from which the main value is derived. Synchronous blocking call.
94      *
95      * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
96      * @param value in Integer format.
97      * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants.
98      */
setProvisionedValue(int item, int value)99     public int setProvisionedValue(int item, int value) throws RemoteException {
100         return ImsConfig.OperationStatusConstants.FAILED;
101     }
102 
103     /**
104      * Sets the value for IMS service/capabilities parameters by the operator device
105      * management entity. It sets the config item value in the provisioned storage
106      * from which the main value is derived.  Synchronous blocking call.
107      *
108      * @param item as defined in com.android.ims.ImsConfig#ConfigConstants.
109      * @param value in String format.
110      * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants.
111      */
setProvisionedStringValue(int item, String value)112     public int setProvisionedStringValue(int item, String value) throws RemoteException {
113         return ImsConfig.OperationStatusConstants.FAILED;
114     }
115 
116     /**
117      * Gets the value of the specified IMS feature item for specified network type.
118      * This operation gets the feature config value from the main storage (i.e. final
119      * value). Asynchronous non-blocking call.
120      *
121      * @param feature as defined in com.android.ims.ImsConfig#FeatureConstants.
122      * @param network as defined in android.telephony.TelephonyManager#NETWORK_TYPE_XXX.
123      * @param listener feature value returned asynchronously through listener.
124      */
getFeatureValue(int feature, int network, ImsConfigListener listener)125     public void getFeatureValue(int feature, int network, ImsConfigListener listener)
126             throws RemoteException {
127     }
128 
129     /**
130      * Sets the value for IMS feature item for specified network type.
131      * This operation stores the user setting in setting db from which main db
132      * is derived.
133      *
134      * @param feature as defined in com.android.ims.ImsConfig#FeatureConstants.
135      * @param network as defined in android.telephony.TelephonyManager#NETWORK_TYPE_XXX.
136      * @param value as defined in com.android.ims.ImsConfig#FeatureValueConstants.
137      * @param listener, provided if caller needs to be notified for set result.
138      */
setFeatureValue(int feature, int network, int value, ImsConfigListener listener)139     public void setFeatureValue(int feature, int network, int value, ImsConfigListener listener)
140             throws RemoteException {
141     }
142 
143     /**
144      * Gets the value for IMS VoLTE provisioned.
145      * This should be the same as the operator provisioned value if applies.
146      */
getVolteProvisioned()147     public boolean getVolteProvisioned() throws RemoteException {
148         return false;
149     }
150 
151     /**
152      * Gets the value for IMS feature item video quality.
153      *
154      * @param listener Video quality value returned asynchronously through listener.
155      */
getVideoQuality(ImsConfigListener listener)156     public void getVideoQuality(ImsConfigListener listener) throws RemoteException {
157     }
158 
159     /**
160      * Sets the value for IMS feature item video quality.
161      *
162      * @param quality, defines the value of video quality.
163      * @param listener, provided if caller needs to be notified for set result.
164      */
setVideoQuality(int quality, ImsConfigListener listener)165     public void setVideoQuality(int quality, ImsConfigListener listener) throws RemoteException {
166     }
167 
168     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getIImsConfig()169     public IImsConfig getIImsConfig() { return mImsConfigStub; }
170 
171     /**
172      * Updates provisioning value and notifies the framework of the change.
173      * Doesn't call #setProvisionedValue and assumes the result succeeded.
174      * This should only be used by modem when they implicitly changed provisioned values.
175      *
176      * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
177      * @param value in Integer format.
178      */
notifyProvisionedValueChanged(int item, int value)179     public final void notifyProvisionedValueChanged(int item, int value) {
180         mImsConfigStub.updateCachedValue(item, value, true);
181     }
182 
183     /**
184      * Updates provisioning value and notifies the framework of the change.
185      * Doesn't call #setProvisionedValue and assumes the result succeeded.
186      * This should only be used by modem when they implicitly changed provisioned values.
187      *
188      * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
189      * @param value in String format.
190      */
notifyProvisionedValueChanged(int item, String value)191     public final void notifyProvisionedValueChanged(int item, String value) {
192         mImsConfigStub.updateCachedValue(item, value, true);
193     }
194 
195     /**
196      * Implements the IImsConfig AIDL interface, which is called by potentially many processes
197      * in order to get/set configuration parameters.
198      *
199      * It holds an object of ImsConfigImplBase class which is usually extended by ImsConfigImpl
200      * with actual implementations from vendors. This class caches provisioned values from
201      * ImsConfigImpl layer because queries through ImsConfigImpl can be slow. When query goes in,
202      * it first checks cache layer. If missed, it will call the vendor implementation of
203      * ImsConfigImplBase API.
204      * and cache the return value if the set succeeds.
205      *
206      * Provides APIs to get/set the IMS service feature/capability/parameters.
207      * The config items include:
208      * 1) Items provisioned by the operator.
209      * 2) Items configured by user. Mainly service feature class.
210      *
211      * @hide
212      */
213     @VisibleForTesting
214     static public class ImsConfigStub extends IImsConfig.Stub {
215         Context mContext;
216         WeakReference<ImsConfigImplBase> mImsConfigImplBaseWeakReference;
217         private HashMap<Integer, Integer> mProvisionedIntValue = new HashMap<>();
218         private HashMap<Integer, String> mProvisionedStringValue = new HashMap<>();
219 
220         @VisibleForTesting
ImsConfigStub(ImsConfigImplBase imsConfigImplBase, Context context)221         public ImsConfigStub(ImsConfigImplBase imsConfigImplBase, Context context) {
222             mContext = context;
223             mImsConfigImplBaseWeakReference =
224                     new WeakReference<ImsConfigImplBase>(imsConfigImplBase);
225         }
226 
227         /**
228          * Gets the value for ims service/capabilities parameters. It first checks its local cache,
229          * if missed, it will call ImsConfigImplBase.getProvisionedValue.
230          * Synchronous blocking call.
231          *
232          * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
233          * @return value in Integer format.
234          */
235         @Override
getProvisionedValue(int item)236         public synchronized int getProvisionedValue(int item) throws RemoteException {
237             if (mProvisionedIntValue.containsKey(item)) {
238                 return mProvisionedIntValue.get(item);
239             } else {
240                 int retVal = getImsConfigImpl().getProvisionedValue(item);
241                 if (retVal != ImsConfig.OperationStatusConstants.UNKNOWN) {
242                     updateCachedValue(item, retVal, false);
243                 }
244                 return retVal;
245             }
246         }
247 
248         /**
249          * Gets the value for ims service/capabilities parameters. It first checks its local cache,
250          * if missed, it will call #ImsConfigImplBase.getProvisionedValue.
251          * Synchronous blocking call.
252          *
253          * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
254          * @return value in String format.
255          */
256         @Override
getProvisionedStringValue(int item)257         public synchronized String getProvisionedStringValue(int item) throws RemoteException {
258             if (mProvisionedIntValue.containsKey(item)) {
259                 return mProvisionedStringValue.get(item);
260             } else {
261                 String retVal = getImsConfigImpl().getProvisionedStringValue(item);
262                 if (retVal != null) {
263                     updateCachedValue(item, retVal, false);
264                 }
265                 return retVal;
266             }
267         }
268 
269         /**
270          * Sets the value for IMS service/capabilities parameters by the operator device
271          * management entity. It sets the config item value in the provisioned storage
272          * from which the main value is derived, and write it into local cache.
273          * Synchronous blocking call.
274          *
275          * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
276          * @param value in Integer format.
277          * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants.
278          */
279         @Override
setProvisionedValue(int item, int value)280         public synchronized int setProvisionedValue(int item, int value) throws RemoteException {
281             mProvisionedIntValue.remove(item);
282             int retVal = getImsConfigImpl().setProvisionedValue(item, value);
283             if (retVal == ImsConfig.OperationStatusConstants.SUCCESS) {
284                 updateCachedValue(item, value, true);
285             } else {
286                 Log.d(TAG, "Set provision value of " + item +
287                         " to " + value + " failed with error code " + retVal);
288             }
289 
290             return retVal;
291         }
292 
293         /**
294          * Sets the value for IMS service/capabilities parameters by the operator device
295          * management entity. It sets the config item value in the provisioned storage
296          * from which the main value is derived, and write it into local cache.
297          * Synchronous blocking call.
298          *
299          * @param item as defined in com.android.ims.ImsConfig#ConfigConstants.
300          * @param value in String format.
301          * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants.
302          */
303         @Override
setProvisionedStringValue(int item, String value)304         public synchronized int setProvisionedStringValue(int item, String value)
305                 throws RemoteException {
306             mProvisionedStringValue.remove(item);
307             int retVal = getImsConfigImpl().setProvisionedStringValue(item, value);
308             if (retVal == ImsConfig.OperationStatusConstants.SUCCESS) {
309                 updateCachedValue(item, value, true);
310             }
311 
312             return retVal;
313         }
314 
315         /**
316          * Wrapper function to call ImsConfigImplBase.getFeatureValue.
317          */
318         @Override
getFeatureValue(int feature, int network, ImsConfigListener listener)319         public void getFeatureValue(int feature, int network, ImsConfigListener listener)
320                 throws RemoteException {
321             getImsConfigImpl().getFeatureValue(feature, network, listener);
322         }
323 
324         /**
325          * Wrapper function to call ImsConfigImplBase.setFeatureValue.
326          */
327         @Override
setFeatureValue(int feature, int network, int value, ImsConfigListener listener)328         public void setFeatureValue(int feature, int network, int value, ImsConfigListener listener)
329                 throws RemoteException {
330             getImsConfigImpl().setFeatureValue(feature, network, value, listener);
331         }
332 
333         /**
334          * Wrapper function to call ImsConfigImplBase.getVolteProvisioned.
335          */
336         @Override
getVolteProvisioned()337         public boolean getVolteProvisioned() throws RemoteException {
338             return getImsConfigImpl().getVolteProvisioned();
339         }
340 
341         /**
342          * Wrapper function to call ImsConfigImplBase.getVideoQuality.
343          */
344         @Override
getVideoQuality(ImsConfigListener listener)345         public void getVideoQuality(ImsConfigListener listener) throws RemoteException {
346             getImsConfigImpl().getVideoQuality(listener);
347         }
348 
349         /**
350          * Wrapper function to call ImsConfigImplBase.setVideoQuality.
351          */
352         @Override
setVideoQuality(int quality, ImsConfigListener listener)353         public void setVideoQuality(int quality, ImsConfigListener listener)
354                 throws RemoteException {
355             getImsConfigImpl().setVideoQuality(quality, listener);
356         }
357 
getImsConfigImpl()358         private ImsConfigImplBase getImsConfigImpl() throws RemoteException {
359             ImsConfigImplBase ref = mImsConfigImplBaseWeakReference.get();
360             if (ref == null) {
361                 throw new RemoteException("Fail to get ImsConfigImpl");
362             } else {
363                 return ref;
364             }
365         }
366 
sendImsConfigChangedIntent(int item, int value)367         private void sendImsConfigChangedIntent(int item, int value) {
368             sendImsConfigChangedIntent(item, Integer.toString(value));
369         }
370 
sendImsConfigChangedIntent(int item, String value)371         private void sendImsConfigChangedIntent(int item, String value) {
372             Intent configChangedIntent = new Intent(ImsConfig.ACTION_IMS_CONFIG_CHANGED);
373             configChangedIntent.putExtra(ImsConfig.EXTRA_CHANGED_ITEM, item);
374             configChangedIntent.putExtra(ImsConfig.EXTRA_NEW_VALUE, value);
375             if (mContext != null) {
376                 mContext.sendBroadcast(configChangedIntent);
377             }
378         }
379 
updateCachedValue(int item, int value, boolean notifyChange)380         protected synchronized void updateCachedValue(int item, int value, boolean notifyChange) {
381             mProvisionedIntValue.put(item, value);
382             if (notifyChange) {
383                 sendImsConfigChangedIntent(item, value);
384             }
385         }
386 
updateCachedValue( int item, String value, boolean notifyChange)387         protected synchronized void updateCachedValue(
388                 int item, String value, boolean notifyChange) {
389             mProvisionedStringValue.put(item, value);
390             if (notifyChange) {
391                 sendImsConfigChangedIntent(item, value);
392             }
393         }
394     }
395 }