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 static com.android.imsserviceentitlement.ts43.Ts43Constants.EntitlementVersion.ENTITLEMENT_VERSION_TWO; 20 21 import android.content.Context; 22 import android.net.ConnectivityManager; 23 import android.net.NetworkInfo; 24 import android.os.PersistableBundle; 25 import android.telephony.CarrierConfigManager; 26 import android.telephony.SubscriptionInfo; 27 import android.telephony.SubscriptionManager; 28 import android.telephony.TelephonyManager; 29 import android.util.Log; 30 31 import com.google.common.collect.ImmutableSet; 32 33 import java.util.List; 34 35 /** This class implements Telephony helper methods. */ 36 public class TelephonyUtils { 37 public static final String TAG = "IMSSE-TelephonyUtils"; 38 // TODO(b/326358344) : API review for hide carrier configurations 39 private static final String KEY_ENTITLEMENT_VERSION_INT = 40 "imsserviceentitlement.entitlement_version_int"; 41 private static final String KEY_DEFAULT_SERVICE_ENTITLEMENT_STATUS_BOOL = 42 "imsserviceentitlement.default_service_entitlement_status_bool"; 43 private static final String KEY_SKIP_WFC_ACTIVATION_BOOL = 44 "imsserviceentitlement.skip_wfc_activation_bool"; 45 46 private final ConnectivityManager mConnectivityManager; 47 private final TelephonyManager mTelephonyManager; 48 TelephonyUtils(Context context)49 public TelephonyUtils(Context context) { 50 this(context, SubscriptionManager.INVALID_SUBSCRIPTION_ID); 51 } 52 TelephonyUtils(Context context, int subId)53 public TelephonyUtils(Context context, int subId) { 54 if (SubscriptionManager.isValidSubscriptionId(subId)) { 55 mTelephonyManager = 56 context.getSystemService(TelephonyManager.class).createForSubscriptionId(subId); 57 } else { 58 mTelephonyManager = context.getSystemService(TelephonyManager.class); 59 } 60 mConnectivityManager = context.getSystemService(ConnectivityManager.class); 61 } 62 63 /** Returns device timestamp in milliseconds. */ getTimeStamp()64 public long getTimeStamp() { 65 return System.currentTimeMillis(); 66 } 67 68 /** Returns device uptime in milliseconds. */ getUptimeMillis()69 public long getUptimeMillis() { 70 return android.os.SystemClock.uptimeMillis(); 71 } 72 73 /** Returns {@code true} if network is connected (cellular or WiFi). */ isNetworkConnected()74 public boolean isNetworkConnected() { 75 NetworkInfo activeNetwork = mConnectivityManager.getActiveNetworkInfo(); 76 return activeNetwork != null && activeNetwork.isConnected(); 77 } 78 79 /** Returns carrier ID. */ getCarrierId()80 public int getCarrierId() { 81 return mTelephonyManager.getSimCarrierId(); 82 } 83 84 /** Returns fine-grained carrier ID. */ getSpecificCarrierId()85 public int getSpecificCarrierId() { 86 return mTelephonyManager.getSimSpecificCarrierId(); 87 } 88 89 /** Returns SIM card application state. */ getSimApplicationState()90 public int getSimApplicationState() { 91 return mTelephonyManager.getSimApplicationState(); 92 } 93 94 /** 95 * Returns {@code true} if the {@code subId} still point to a actived SIM; {@code false} 96 * otherwise. 97 */ isActivedSubId(Context context, int subId)98 public static boolean isActivedSubId(Context context, int subId) { 99 SubscriptionManager subscriptionManager = 100 (SubscriptionManager) context.getSystemService( 101 Context.TELEPHONY_SUBSCRIPTION_SERVICE); 102 SubscriptionInfo subInfo = subscriptionManager.getActiveSubscriptionInfo(subId); 103 return subInfo != null; 104 } 105 106 /** 107 * Returns the slot index for the actived {@code subId}; {@link 108 * SubscriptionManager#INVALID_SIM_SLOT_INDEX} otherwise. 109 */ getSlotId(Context context, int subId)110 public static int getSlotId(Context context, int subId) { 111 SubscriptionManager subscriptionManager = 112 (SubscriptionManager) context.getSystemService( 113 Context.TELEPHONY_SUBSCRIPTION_SERVICE); 114 SubscriptionInfo subInfo = subscriptionManager.getActiveSubscriptionInfo(subId); 115 if (subInfo != null) { 116 return subInfo.getSimSlotIndex(); 117 } 118 Log.d(TAG, "Can't find actived subscription for " + subId); 119 return SubscriptionManager.INVALID_SIM_SLOT_INDEX; 120 } 121 122 /** Returns carrier config for the {@code subId}. */ getConfigForSubId(Context context, int subId)123 private static PersistableBundle getConfigForSubId(Context context, int subId) { 124 CarrierConfigManager carrierConfigManager = 125 context.getSystemService(CarrierConfigManager.class); 126 PersistableBundle carrierConfig = carrierConfigManager.getConfigForSubId(subId); 127 if (carrierConfig == null) { 128 Log.d(TAG, "getDefaultConfig"); 129 carrierConfig = CarrierConfigManager.getDefaultConfig(); 130 } 131 return carrierConfig; 132 } 133 134 /** 135 * Returns FCM sender id for the {@code subId} or a default empty string if it is not available. 136 */ getFcmSenderId(Context context, int subId)137 public static String getFcmSenderId(Context context, int subId) { 138 return getConfigForSubId(context, subId).getString( 139 CarrierConfigManager.ImsServiceEntitlement.KEY_FCM_SENDER_ID_STRING, 140 "" 141 ); 142 } 143 144 /** 145 * Returns entitlement server url for the {@code subId} or 146 * a default empty string if it is not available. 147 */ getEntitlementServerUrl(Context context, int subId)148 public static String getEntitlementServerUrl(Context context, int subId) { 149 return getConfigForSubId(context, subId).getString( 150 CarrierConfigManager.ImsServiceEntitlement.KEY_ENTITLEMENT_SERVER_URL_STRING, 151 "" 152 ); 153 } 154 155 /** 156 * Returns true if app needs to do IMS (VoLTE/VoNR/VoWiFi/SMSoIP) provisioning in the background 157 * or false if it doesn't need to do. 158 */ isImsProvisioningRequired(Context context, int subId)159 public static boolean isImsProvisioningRequired(Context context, int subId) { 160 return getConfigForSubId(context, subId).getBoolean( 161 CarrierConfigManager.ImsServiceEntitlement.KEY_IMS_PROVISIONING_BOOL, 162 false 163 ); 164 } 165 166 /** 167 * Returns entitlement version for the {@code subId} or {@link 168 * Ts43Constants.ENTITLEMENT_VERSION_TWO} if it is not available. 169 */ getEntitlementVersion(Context context, int subId)170 public static int getEntitlementVersion(Context context, int subId) { 171 return getConfigForSubId(context, subId).getInt( 172 KEY_ENTITLEMENT_VERSION_INT, 173 ENTITLEMENT_VERSION_TWO 174 ); 175 } 176 177 /** Returns true if app can skip wfc activation and support emergency address update only. */ isSkipWfcActivation(Context context, int subId)178 public static boolean isSkipWfcActivation(Context context, int subId) { 179 return getConfigForSubId(context, subId).getBoolean( 180 KEY_SKIP_WFC_ACTIVATION_BOOL, 181 false 182 ); 183 } 184 185 /** 186 * Returns default service entitlement status for the {@code subId} or false if it is not 187 * available. 188 */ getDefaultStatus(Context context, int subId)189 public static boolean getDefaultStatus(Context context, int subId) { 190 return getConfigForSubId(context, subId).getBoolean( 191 KEY_DEFAULT_SERVICE_ENTITLEMENT_STATUS_BOOL, 192 false 193 ); 194 } 195 196 /** Returns SubIds which support FCM. */ getSubIdsWithFcmSupported(Context context)197 public static ImmutableSet<Integer> getSubIdsWithFcmSupported(Context context) { 198 SubscriptionManager subscriptionManager = 199 context.getSystemService(SubscriptionManager.class); 200 List<SubscriptionInfo> infos = subscriptionManager.getActiveSubscriptionInfoList(); 201 if (infos == null) { 202 return ImmutableSet.of(); 203 } 204 205 ImmutableSet.Builder<Integer> builder = ImmutableSet.builder(); 206 for (SubscriptionInfo info : infos) { 207 int subId = info.getSubscriptionId(); 208 if (isFcmPushNotificationSupported(context, subId)) { 209 builder.add(subId); 210 } 211 } 212 return builder.build(); 213 } 214 isFcmPushNotificationSupported(Context context, int subId)215 private static boolean isFcmPushNotificationSupported(Context context, int subId) { 216 return !TelephonyUtils.getFcmSenderId(context, subId).isEmpty(); 217 } 218 } 219