• 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 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