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