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