• 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.imsserviceentitlement.utils;
18 
19 import android.content.Context;
20 import android.os.AsyncTask;
21 import android.os.PersistableBundle;
22 import android.telephony.CarrierConfigManager;
23 import android.telephony.ims.ImsMmTelManager;
24 import android.telephony.ims.ProvisioningManager;
25 import android.util.Log;
26 import android.util.SparseArray;
27 
28 import androidx.annotation.GuardedBy;
29 import androidx.annotation.Nullable;
30 
31 import com.google.common.annotations.VisibleForTesting;
32 
33 /** A helper class for IMS relevant APIs with subscription id. */
34 public class ImsUtils {
35     private static final String TAG = "IMSSE-ImsUtils";
36 
37     @Nullable private final PersistableBundle mCarrierConfigs;
38     private final ImsMmTelManager mImsMmTelManager;
39     private final ProvisioningManager mProvisioningManager;
40 
41     /**
42      * Turns Volte provisioning status ON/OFF.
43      * Value is in Integer format. ON (1), OFF(0).
44      * Key is from {@link ProvisioningManager#KEY_VOLTE_PROVISIONING_STATUS}.
45      */
46     private static final int KEY_VOLTE_PROVISIONING_STATUS = 10;
47 
48     /**
49      * Turns SMS over IP ON/OFF on the device.
50      * Value is in Integer format. ON (1), OFF(0).
51      * Key is from {@link ProvisioningManager#KEY_SMS_OVER_IP_ENABLED}.
52      */
53     private static final int KEY_SMS_OVER_IP_ENABLED = 14;
54 
55     /**
56      * Enable voice over wifi on device.
57      * Value is in Integer format. Enabled (1), or Disabled (0).
58      * Key is from {@link ProvisioningManager#KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE}.
59      */
60     private static final int KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE = 28;
61 
62     // Cache subscription id associated {@link ImsUtils} objects for reusing.
63     @GuardedBy("ImsUtils.class")
64     private static SparseArray<ImsUtils> sInstances = new SparseArray<ImsUtils>();
65 
ImsUtils(Context context, int subId)66     private ImsUtils(Context context, int subId) {
67         this(
68                 context.getSystemService(CarrierConfigManager.class).getConfigForSubId(subId),
69                 getImsMmTelManager(subId),
70                 getProvisioningManager(subId));
71     }
72 
73     @VisibleForTesting
ImsUtils( PersistableBundle carrierConfigs, ImsMmTelManager imsMmTelManager, ProvisioningManager provisioningManager)74     ImsUtils(
75             PersistableBundle carrierConfigs,
76             ImsMmTelManager imsMmTelManager,
77             ProvisioningManager provisioningManager) {
78         mCarrierConfigs = carrierConfigs;
79         mImsMmTelManager = imsMmTelManager;
80         mProvisioningManager = provisioningManager;
81     }
82 
83     /** Returns {@link ImsUtils} instance. */
getInstance(Context context, int subId)84     public static synchronized ImsUtils getInstance(Context context, int subId) {
85         ImsUtils instance = sInstances.get(subId);
86         if (instance != null) {
87             return instance;
88         }
89 
90         instance = new ImsUtils(context, subId);
91         sInstances.put(subId, instance);
92         return instance;
93     }
94 
95     /** Changes persistent WFC enabled setting. */
setWfcSetting(boolean enabled)96     private void setWfcSetting(boolean enabled) {
97         try {
98             mImsMmTelManager.setVoWiFiSettingEnabled(enabled);
99         } catch (RuntimeException e) {
100             // ignore this exception, possible exception should be NullPointerException or
101             // RemoteException.
102         }
103     }
104 
105     /** Sets whether VoWiFi is provisioned. */
setVowifiProvisioned(boolean value)106     public void setVowifiProvisioned(boolean value) {
107         try {
108             mProvisioningManager.setProvisioningIntValue(
109                     KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE, value
110                             ? ProvisioningManager.PROVISIONING_VALUE_ENABLED
111                             : ProvisioningManager.PROVISIONING_VALUE_DISABLED);
112         } catch (RuntimeException e) {
113             // ignore this exception, possible exception should be NullPointerException or
114             // RemoteException.
115         }
116     }
117 
118     /** Sets whether Volte is provisioned. */
setVolteProvisioned(boolean value)119     public void setVolteProvisioned(boolean value) {
120         try {
121             mProvisioningManager.setProvisioningIntValue(
122                     KEY_VOLTE_PROVISIONING_STATUS, value
123                             ? ProvisioningManager.PROVISIONING_VALUE_ENABLED
124                             : ProvisioningManager.PROVISIONING_VALUE_DISABLED);
125         } catch (RuntimeException e) {
126             // ignore this exception, possible exception should be NullPointerException or
127             // RemoteException.
128         }
129     }
130 
131     /** Sets whether SMSoIP is provisioned. */
setSmsoipProvisioned(boolean value)132     public void setSmsoipProvisioned(boolean value) {
133         try {
134             mProvisioningManager.setProvisioningIntValue(
135                     KEY_SMS_OVER_IP_ENABLED, value
136                             ? ProvisioningManager.PROVISIONING_VALUE_ENABLED
137                             : ProvisioningManager.PROVISIONING_VALUE_DISABLED);
138         } catch (RuntimeException e) {
139             // ignore this exception, possible exception should be NullPointerException or
140             // RemoteException.
141         }
142     }
143 
144     /** Disables WFC and reset WFC mode to carrier default value */
145     @VisibleForTesting
disableAndResetVoWiFiImsSettings()146     void disableAndResetVoWiFiImsSettings() {
147         try {
148             disableWfc();
149 
150             // Reset WFC mode to carrier default value
151             if (mCarrierConfigs != null) {
152                 mImsMmTelManager.setVoWiFiModeSetting(
153                         mCarrierConfigs.getInt(
154                                 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT));
155                 mImsMmTelManager.setVoWiFiRoamingModeSetting(
156                         mCarrierConfigs.getInt(
157                                 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT));
158             }
159         } catch (RuntimeException e) {
160             // ignore this exception, possible exception should be NullPointerException or
161             // RemoteException.
162         }
163     }
164 
165     /**
166      * Returns {@link ImsMmTelManager} with specific subscription id.
167      * Returns {@code null} if provided subscription id invalid.
168      */
169     @Nullable
getImsMmTelManager(int subId)170     private static ImsMmTelManager getImsMmTelManager(int subId) {
171         try {
172             return ImsMmTelManager.createForSubscriptionId(subId);
173         } catch (IllegalArgumentException e) {
174             Log.e(TAG, "Can't get ImsMmTelManager, IllegalArgumentException: subId = " + subId);
175         }
176 
177         return null;
178     }
179 
180     /**
181      * Returns {@link ProvisioningManager} with specific subscription id.
182      * Returns {@code null} if provided subscription id invalid.
183      */
184     @Nullable
getProvisioningManager(int subId)185     private static ProvisioningManager getProvisioningManager(int subId) {
186         try {
187             return ProvisioningManager.createForSubscriptionId(subId);
188         } catch (IllegalArgumentException e) {
189             Log.e(TAG, "Can't get ProvisioningManager, IllegalArgumentException: subId = " + subId);
190         }
191         return null;
192     }
193 
194     /** Returns whether WFC is enabled by user for current subId */
isWfcEnabledByUser()195     public boolean isWfcEnabledByUser() {
196         try {
197             return mImsMmTelManager.isVoWiFiSettingEnabled();
198         } catch (RuntimeException e) {
199             // ignore this exception, possible exception should be NullPointerException or
200             // RemoteException.
201         }
202         return false;
203     }
204 
205     /** Calls {@link #disableAndResetVoWiFiImsSettings()} in background thread. */
turnOffWfc(Runnable action)206     public void turnOffWfc(Runnable action) {
207         new AsyncTask<Void, Void, Void>() {
208             @Override
209             protected Void doInBackground(Void... params) {
210                 disableAndResetVoWiFiImsSettings();
211                 return null; // To satisfy compiler
212             }
213 
214             @Override
215             protected void onPostExecute(Void result) {
216                 action.run();
217             }
218         }.execute();
219     }
220 
221     /** Disables WFC */
disableWfc()222     public void disableWfc() {
223         setWfcSetting(false);
224     }
225 }
226