1 /*
2  * Copyright (C) 2014 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 android.telephony;
18 
19 import static android.net.NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_CONGESTED;
20 import static android.net.NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED;
21 
22 import android.Manifest;
23 import android.annotation.CallbackExecutor;
24 import android.annotation.ColorInt;
25 import android.annotation.DurationMillisLong;
26 import android.annotation.IntDef;
27 import android.annotation.NonNull;
28 import android.annotation.Nullable;
29 import android.annotation.RequiresFeature;
30 import android.annotation.RequiresPermission;
31 import android.annotation.SdkConstant;
32 import android.annotation.SdkConstant.SdkConstantType;
33 import android.annotation.SuppressAutoDoc;
34 import android.annotation.SystemApi;
35 import android.annotation.SystemService;
36 import android.app.PendingIntent;
37 import android.app.PropertyInvalidatedCache;
38 import android.compat.annotation.UnsupportedAppUsage;
39 import android.content.Context;
40 import android.content.Intent;
41 import android.content.pm.PackageInfo;
42 import android.content.pm.PackageManager;
43 import android.content.res.Configuration;
44 import android.content.res.Resources;
45 import android.database.ContentObserver;
46 import android.net.NetworkCapabilities;
47 import android.net.NetworkPolicyManager;
48 import android.net.Uri;
49 import android.os.Binder;
50 import android.os.Build;
51 import android.os.Bundle;
52 import android.os.Handler;
53 import android.os.Looper;
54 import android.os.ParcelUuid;
55 import android.os.Process;
56 import android.os.RemoteException;
57 import android.os.UserHandle;
58 import android.provider.Telephony.SimInfo;
59 import android.telephony.euicc.EuiccManager;
60 import android.telephony.ims.ImsMmTelManager;
61 import android.text.TextUtils;
62 import android.util.Base64;
63 import android.util.Log;
64 import android.util.Pair;
65 
66 import com.android.internal.telephony.ISetOpportunisticDataCallback;
67 import com.android.internal.telephony.ISub;
68 import com.android.internal.telephony.PhoneConstants;
69 import com.android.internal.telephony.util.HandlerExecutor;
70 import com.android.internal.util.FunctionalUtils;
71 import com.android.internal.util.Preconditions;
72 import com.android.telephony.Rlog;
73 
74 import java.io.ByteArrayInputStream;
75 import java.io.ByteArrayOutputStream;
76 import java.io.IOException;
77 import java.io.ObjectInputStream;
78 import java.io.ObjectOutputStream;
79 import java.lang.annotation.Retention;
80 import java.lang.annotation.RetentionPolicy;
81 import java.util.ArrayList;
82 import java.util.Arrays;
83 import java.util.Collections;
84 import java.util.HashMap;
85 import java.util.List;
86 import java.util.Locale;
87 import java.util.Map;
88 import java.util.concurrent.ConcurrentHashMap;
89 import java.util.concurrent.Executor;
90 import java.util.function.Consumer;
91 import java.util.stream.Collectors;
92 
93 /**
94  * Subscription manager provides the mobile subscription information.
95  */
96 @SystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)
97 @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
98 public class SubscriptionManager {
99     private static final String LOG_TAG = "SubscriptionManager";
100     private static final boolean DBG = false;
101     private static final boolean VDBG = false;
102 
103     /** An invalid subscription identifier */
104     public static final int INVALID_SUBSCRIPTION_ID = -1;
105 
106     /** Base value for placeholder SUBSCRIPTION_ID's. */
107     /** @hide */
108     public static final int PLACEHOLDER_SUBSCRIPTION_ID_BASE = INVALID_SUBSCRIPTION_ID - 1;
109 
110     /** An invalid phone identifier */
111     /** @hide */
112     public static final int INVALID_PHONE_INDEX = -1;
113 
114     /** Indicates invalid sim slot. This can be returned by {@link #getSlotIndex(int)}. */
115     public static final int INVALID_SIM_SLOT_INDEX = -1;
116 
117     /** Indicates the default subscription ID in Telephony. */
118     public static final int DEFAULT_SUBSCRIPTION_ID = Integer.MAX_VALUE;
119 
120     /**
121      * Indicates the default phone id.
122      * @hide
123      */
124     public static final int DEFAULT_PHONE_INDEX = Integer.MAX_VALUE;
125 
126     /** Indicates the default slot index. */
127     /** @hide */
128     public static final int DEFAULT_SIM_SLOT_INDEX = Integer.MAX_VALUE;
129 
130     /** Minimum possible subid that represents a subscription */
131     /** @hide */
132     public static final int MIN_SUBSCRIPTION_ID_VALUE = 0;
133 
134     /** Maximum possible subid that represents a subscription */
135     /** @hide */
136     public static final int MAX_SUBSCRIPTION_ID_VALUE = DEFAULT_SUBSCRIPTION_ID - 1;
137 
138     /** @hide */
139     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
140     public static final Uri CONTENT_URI = SimInfo.CONTENT_URI;
141 
142     /** The IPC cache key shared by all subscription manager service cacheable properties. */
143     private static final String CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY =
144             "cache_key.telephony.subscription_manager_service";
145 
146     /** @hide */
147     public static final String GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME = "getSimSpecificSettings";
148 
149     /** @hide */
150     public static final String RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME =
151             "restoreSimSpecificSettings";
152 
153     /**
154      * The key of the boolean flag indicating whether restoring subscriptions actually changes
155      * the subscription database or not.
156      *
157      * @hide
158      */
159     public static final String RESTORE_SIM_SPECIFIC_SETTINGS_DATABASE_UPDATED =
160             "restoreSimSpecificSettingsDatabaseUpdated";
161 
162     /**
163      * Key to the backup & restore data byte array in the Bundle that is returned by {@link
164      * #getAllSimSpecificSettingsForBackup()} or to be pass in to {@link
165      * #restoreAllSimSpecificSettingsFromBackup(byte[])}.
166      *
167      * @hide
168      */
169     public static final String KEY_SIM_SPECIFIC_SETTINGS_DATA = "KEY_SIM_SPECIFIC_SETTINGS_DATA";
170 
171     private static final int MAX_CACHE_SIZE = 4;
172 
173     private static class VoidPropertyInvalidatedCache<T>
174             extends PropertyInvalidatedCache<Void, T> {
175         private final FunctionalUtils.ThrowingFunction<ISub, T> mInterfaceMethod;
176         private final String mCacheKeyProperty;
177         private final T mDefaultValue;
178 
VoidPropertyInvalidatedCache( FunctionalUtils.ThrowingFunction<ISub, T> subscriptionInterfaceMethod, String cacheKeyProperty, T defaultValue)179         VoidPropertyInvalidatedCache(
180                 FunctionalUtils.ThrowingFunction<ISub, T> subscriptionInterfaceMethod,
181                 String cacheKeyProperty,
182                 T defaultValue) {
183             super(MAX_CACHE_SIZE, cacheKeyProperty);
184             mInterfaceMethod = subscriptionInterfaceMethod;
185             mCacheKeyProperty = cacheKeyProperty;
186             mDefaultValue = defaultValue;
187         }
188 
189         @Override
recompute(Void query)190         public T recompute(Void query) {
191             // This always throws on any error.  The exceptions must be handled outside
192             // the cache.
193             try {
194                 return mInterfaceMethod.applyOrThrow(TelephonyManager.getSubscriptionService());
195             } catch (Exception re) {
196                 throw new RuntimeException(re);
197             }
198         }
199 
200         @Override
query(Void query)201         public T query(Void query) {
202             T result = mDefaultValue;
203 
204             try {
205                 ISub iSub = TelephonyManager.getSubscriptionService();
206                 if (iSub != null) {
207                     result = super.query(query);
208                 }
209             } catch (Exception ex) {
210                 Rlog.w(LOG_TAG, "Failed to recompute cache key for " + mCacheKeyProperty);
211             }
212 
213             if (VDBG) logd("recomputing " + mCacheKeyProperty + ", result = " + result);
214             return result;
215         }
216     }
217 
218     private static class IntegerPropertyInvalidatedCache<T>
219             extends PropertyInvalidatedCache<Integer, T> {
220         private final FunctionalUtils.ThrowingBiFunction<ISub, Integer, T> mInterfaceMethod;
221         private final String mCacheKeyProperty;
222         private final T mDefaultValue;
223 
IntegerPropertyInvalidatedCache( FunctionalUtils.ThrowingBiFunction<ISub, Integer, T> subscriptionInterfaceMethod, String cacheKeyProperty, T defaultValue)224         IntegerPropertyInvalidatedCache(
225                 FunctionalUtils.ThrowingBiFunction<ISub, Integer, T> subscriptionInterfaceMethod,
226                 String cacheKeyProperty,
227                 T defaultValue) {
228             super(MAX_CACHE_SIZE, cacheKeyProperty);
229             mInterfaceMethod = subscriptionInterfaceMethod;
230             mCacheKeyProperty = cacheKeyProperty;
231             mDefaultValue = defaultValue;
232         }
233 
234         @Override
recompute(Integer query)235         public T recompute(Integer query) {
236             // This always throws on any error.  The exceptions must be handled outside
237             // the cache.
238             try {
239                 return mInterfaceMethod.applyOrThrow(
240                     TelephonyManager.getSubscriptionService(), query);
241             } catch (Exception re) {
242                 throw new RuntimeException(re);
243             }
244         }
245 
246         @Override
query(Integer query)247         public T query(Integer query) {
248             T result = mDefaultValue;
249 
250             try {
251                 ISub iSub = TelephonyManager.getSubscriptionService();
252                 if (iSub != null) {
253                     result = super.query(query);
254                 }
255             } catch (Exception ex) {
256                 Rlog.w(LOG_TAG, "Failed to recompute cache key for " + mCacheKeyProperty);
257             }
258 
259             if (VDBG) logd("recomputing " + mCacheKeyProperty + ", result = " + result);
260             return result;
261         }
262     }
263 
264     private static VoidPropertyInvalidatedCache<Integer> sGetDefaultSubIdCache =
265             new VoidPropertyInvalidatedCache<>(ISub::getDefaultSubId,
266                     CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
267                     INVALID_SUBSCRIPTION_ID);
268 
269     private static VoidPropertyInvalidatedCache<Integer> sGetDefaultDataSubIdCache =
270             new VoidPropertyInvalidatedCache<>(ISub::getDefaultDataSubId,
271                     CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
272                     INVALID_SUBSCRIPTION_ID);
273 
274     private static VoidPropertyInvalidatedCache<Integer> sGetDefaultSmsSubIdCache =
275             new VoidPropertyInvalidatedCache<>(ISub::getDefaultSmsSubId,
276                     CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
277                     INVALID_SUBSCRIPTION_ID);
278 
279     private static VoidPropertyInvalidatedCache<Integer> sGetActiveDataSubscriptionIdCache =
280             new VoidPropertyInvalidatedCache<>(ISub::getActiveDataSubscriptionId,
281                     CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
282                     INVALID_SUBSCRIPTION_ID);
283 
284     private static IntegerPropertyInvalidatedCache<Integer> sGetSlotIndexCache =
285             new IntegerPropertyInvalidatedCache<>(ISub::getSlotIndex,
286                     CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
287                     INVALID_SIM_SLOT_INDEX);
288 
289     private static IntegerPropertyInvalidatedCache<Integer> sGetSubIdCache =
290             new IntegerPropertyInvalidatedCache<>(ISub::getSubId,
291                     CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
292                     INVALID_SUBSCRIPTION_ID);
293 
294     private static IntegerPropertyInvalidatedCache<Integer> sGetPhoneIdCache =
295             new IntegerPropertyInvalidatedCache<>(ISub::getPhoneId,
296                     CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
297                     INVALID_PHONE_INDEX);
298 
299     /**
300      * Generates a content {@link Uri} used to receive updates on simInfo change
301      * on the given subscriptionId
302      * @param subscriptionId the subscriptionId to receive updates on
303      * @return the Uri used to observe carrier identity changes
304      * @hide
305      */
getUriForSubscriptionId(int subscriptionId)306     public static Uri getUriForSubscriptionId(int subscriptionId) {
307         return Uri.withAppendedPath(CONTENT_URI, String.valueOf(subscriptionId));
308     }
309 
310     /**
311      * A content {@link Uri} used to receive updates on wfc enabled user setting.
312      * <p>
313      * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
314      * subscription wfc enabled {@link ImsMmTelManager#isVoWiFiSettingEnabled()}
315      * while your app is running. You can also use a {@link android.app.job.JobService}
316      * to ensure your app
317      * is notified of changes to the {@link Uri} even when it is not running.
318      * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
319      * delivery of updates to the {@link Uri}.
320      * To be notified of changes to a specific subId, append subId to the URI
321      * {@link Uri#withAppendedPath(Uri, String)}.
322      * @hide
323      */
324     @NonNull
325     @SystemApi
326     public static final Uri WFC_ENABLED_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc");
327 
328     /**
329      * A content {@link Uri} used to receive updates on advanced calling user setting
330      *
331      * <p>
332      * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
333      * subscription advanced calling enabled
334      * {@link ImsMmTelManager#isAdvancedCallingSettingEnabled()} while your app is running.
335      * You can also use a {@link android.app.job.JobService} to ensure your app is notified of
336      * changes to the {@link Uri} even when it is not running.
337      * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
338      * delivery of updates to the {@link Uri}.
339      * To be notified of changes to a specific subId, append subId to the URI
340      * {@link Uri#withAppendedPath(Uri, String)}.
341      *
342      * @see ImsMmTelManager#isAdvancedCallingSettingEnabled()
343      *
344      * @hide
345      */
346     @NonNull
347     @SystemApi
348     public static final Uri ADVANCED_CALLING_ENABLED_CONTENT_URI = Uri.withAppendedPath(
349             CONTENT_URI, "advanced_calling");
350 
351     /**
352      * A content {@link Uri} used to receive updates on wfc mode setting.
353      * <p>
354      * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
355      * subscription wfc mode {@link ImsMmTelManager#getVoWiFiModeSetting()}
356      * while your app is running. You can also use a {@link android.app.job.JobService} to ensure
357      * your app is notified of changes to the {@link Uri} even when it is not running.
358      * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
359      * delivery of updates to the {@link Uri}.
360      * To be notified of changes to a specific subId, append subId to the URI
361      * {@link Uri#withAppendedPath(Uri, String)}.
362      * @hide
363      */
364     @NonNull
365     @SystemApi
366     public static final Uri WFC_MODE_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc_mode");
367 
368     /**
369      * A content {@link Uri} used to receive updates on wfc roaming mode setting.
370      * <p>
371      * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
372      * subscription wfc roaming mode {@link ImsMmTelManager#getVoWiFiRoamingModeSetting()}
373      * while your app is running. You can also use a {@link android.app.job.JobService}
374      * to ensure your app is notified of changes to the {@link Uri} even when it is not running.
375      * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
376      * delivery of updates to the {@link Uri}.
377      * To be notified of changes to a specific subId, append subId to the URI
378      * {@link Uri#withAppendedPath(Uri, String)}.
379      * @hide
380      */
381     @NonNull
382     @SystemApi
383     public static final Uri WFC_ROAMING_MODE_CONTENT_URI = Uri.withAppendedPath(
384             CONTENT_URI, "wfc_roaming_mode");
385 
386     /**
387      * A content {@link Uri} used to receive updates on vt(video telephony over IMS) enabled
388      * setting.
389      * <p>
390      * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
391      * subscription vt enabled {@link ImsMmTelManager#isVtSettingEnabled()}
392      * while your app is running. You can also use a {@link android.app.job.JobService} to ensure
393      * your app is notified of changes to the {@link Uri} even when it is not running.
394      * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
395      * delivery of updates to the {@link Uri}.
396      * To be notified of changes to a specific subId, append subId to the URI
397      * {@link Uri#withAppendedPath(Uri, String)}.
398      * @hide
399      */
400     @NonNull
401     @SystemApi
402     public static final Uri VT_ENABLED_CONTENT_URI = Uri.withAppendedPath(
403             CONTENT_URI, "vt_enabled");
404 
405     /**
406      * A content {@link Uri} used to receive updates on wfc roaming enabled setting.
407      * <p>
408      * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
409      * subscription wfc roaming enabled {@link ImsMmTelManager#isVoWiFiRoamingSettingEnabled()}
410      * while your app is running. You can also use a {@link android.app.job.JobService} to ensure
411      * your app is notified of changes to the {@link Uri} even when it is not running.
412      * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
413      * delivery of updates to the {@link Uri}.
414      * To be notified of changes to a specific subId, append subId to the URI
415      * {@link Uri#withAppendedPath(Uri, String)}.
416      * @hide
417      */
418     @NonNull
419     @SystemApi
420     public static final Uri WFC_ROAMING_ENABLED_CONTENT_URI = Uri.withAppendedPath(
421             CONTENT_URI, "wfc_roaming_enabled");
422 
423 
424     /**
425      * A content {@link uri} used to call the appropriate backup or restore method for sim-specific
426      * settings
427      * <p>
428      * See {@link #GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME} and {@link
429      * #RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME} for information on what method to call.
430      * @hide
431      */
432     @NonNull
433     public static final Uri SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI = Uri.withAppendedPath(
434             CONTENT_URI, "backup_and_restore");
435 
436     /**
437      * A content {@link uri} used to notify contentobservers listening to siminfo restore during
438      * SuW.
439      * @hide
440      */
441     @NonNull
442     public static final Uri SIM_INFO_SUW_RESTORE_CONTENT_URI = Uri.withAppendedPath(
443             SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI, "suw_restore");
444 
445     /**
446      * A content {@link Uri} used to receive updates on cross sim enabled user setting.
447      * <p>
448      * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
449      * subscription cross sim calling enabled
450      * {@link ImsMmTelManager#isCrossSimCallingEnabled()}
451      * while your app is running. You can also use a {@link android.app.job.JobService}
452      * to ensure your app
453      * is notified of changes to the {@link Uri} even when it is not running.
454      * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
455      * delivery of updates to the {@link Uri}.
456      * To be notified of changes to a specific subId, append subId to the URI
457      * {@link Uri#withAppendedPath(Uri, String)}.
458      * @hide
459      */
460     @NonNull
461     @SystemApi
462     public static final Uri CROSS_SIM_ENABLED_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI,
463             SimInfo.COLUMN_CROSS_SIM_CALLING_ENABLED);
464 
465     /**
466      * TelephonyProvider unique key column name is the subscription id.
467      * <P>Type: TEXT (String)</P>
468      */
469     /** @hide */
470     public static final String UNIQUE_KEY_SUBSCRIPTION_ID =
471             SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID;
472 
473     /**
474      * TelephonyProvider column name for a unique identifier for the subscription within the
475      * specific subscription type. For example, it contains SIM ICC Identifier subscriptions
476      * on Local SIMs. and Mac-address for Remote-SIM Subscriptions for Bluetooth devices.
477      * <P>Type: TEXT (String)</P>
478      */
479     /** @hide */
480     public static final String ICC_ID = SimInfo.COLUMN_ICC_ID;
481 
482     /**
483      * TelephonyProvider column name for user SIM_SlOT_INDEX
484      * <P>Type: INTEGER (int)</P>
485      */
486     /** @hide */
487     public static final String SIM_SLOT_INDEX = SimInfo.COLUMN_SIM_SLOT_INDEX;
488 
489     /** SIM is not inserted */
490     /** @hide */
491     public static final int SIM_NOT_INSERTED = SimInfo.SIM_NOT_INSERTED;
492 
493     /**
494      * The slot-index for Bluetooth Remote-SIM subscriptions
495      * @hide
496      */
497     public static final int SLOT_INDEX_FOR_REMOTE_SIM_SUB = INVALID_SIM_SLOT_INDEX;
498 
499     /**
500      * TelephonyProvider column name Subscription-type.
501      * <P>Type: INTEGER (int)</P> {@link #SUBSCRIPTION_TYPE_LOCAL_SIM} for Local-SIM Subscriptions,
502      * {@link #SUBSCRIPTION_TYPE_REMOTE_SIM} for Remote-SIM Subscriptions.
503      * Default value is 0.
504      */
505     /** @hide */
506     public static final String SUBSCRIPTION_TYPE = SimInfo.COLUMN_SUBSCRIPTION_TYPE;
507 
508     /**
509      * TelephonyProvider column name for last used TP - message Reference
510      * <P>Type: INTEGER (int)</P> with -1 as default value
511      * TP - Message Reference valid range [0 - 255]
512      * @hide
513      */
514     public static final String TP_MESSAGE_REF = SimInfo.COLUMN_TP_MESSAGE_REF;
515 
516     /**
517      * TelephonyProvider column name enabled_mobile_data_policies.
518      * A list of mobile data policies, each of which represented by an integer and joint by ",".
519      *
520      * Default value is empty string.
521      * @hide
522      */
523     public static final String ENABLED_MOBILE_DATA_POLICIES =
524             SimInfo.COLUMN_ENABLED_MOBILE_DATA_POLICIES;
525 
526     /** @hide */
527     @Retention(RetentionPolicy.SOURCE)
528     @IntDef(prefix = {"SUBSCRIPTION_TYPE_"},
529         value = {
530             SUBSCRIPTION_TYPE_LOCAL_SIM,
531             SUBSCRIPTION_TYPE_REMOTE_SIM})
532     public @interface SubscriptionType {}
533 
534     /**
535      * This constant is to designate a subscription as a Local-SIM Subscription.
536      * <p> A Local-SIM can be a physical SIM inserted into a sim-slot in the device, or eSIM on the
537      * device.
538      * </p>
539      */
540     public static final int SUBSCRIPTION_TYPE_LOCAL_SIM = SimInfo.SUBSCRIPTION_TYPE_LOCAL_SIM;
541 
542     /**
543      * This constant is to designate a subscription as a Remote-SIM Subscription.
544      * <p>
545      * A Remote-SIM subscription is for a SIM on a phone connected to this device via some
546      * connectivity mechanism, for example bluetooth. Similar to Local SIM, this subscription can
547      * be used for SMS, Voice and data by proxying data through the connected device.
548      * Certain data of the SIM, such as IMEI, are not accessible for Remote SIMs.
549      * </p>
550      *
551      * <p>
552      * A Remote-SIM is available only as long the phone stays connected to this device.
553      * When the phone disconnects, Remote-SIM subscription is removed from this device and is
554      * no longer known. All data associated with the subscription, such as stored SMS, call logs,
555      * contacts etc, are removed from this device.
556      * </p>
557      *
558      * <p>
559      * If the phone re-connects to this device, a new Remote-SIM subscription is created for
560      * the phone. The Subscription Id associated with the new subscription is different from
561      * the Subscription Id of the previous Remote-SIM subscription created (and removed) for the
562      * phone; i.e., new Remote-SIM subscription treats the reconnected phone as a Remote-SIM that
563      * was never seen before.
564      * </p>
565      */
566     public static final int SUBSCRIPTION_TYPE_REMOTE_SIM = SimInfo.SUBSCRIPTION_TYPE_REMOTE_SIM;
567 
568     /**
569      * TelephonyProvider column name for user displayed name.
570      * <P>Type: TEXT (String)</P>
571      */
572     /** @hide */
573     public static final String DISPLAY_NAME = SimInfo.COLUMN_DISPLAY_NAME;
574 
575     /**
576      * TelephonyProvider column name for the service provider name for the SIM.
577      * <P>Type: TEXT (String)</P>
578      */
579     /** @hide */
580     public static final String CARRIER_NAME = SimInfo.COLUMN_CARRIER_NAME;
581 
582     /**
583      * Default name resource
584      * @hide
585      */
586     public static final int DEFAULT_NAME_RES = com.android.internal.R.string.unknownName;
587 
588     /**
589      * TelephonyProvider column name for source of the user displayed name.
590      * <P>Type: INT (int)</P> with one of the NAME_SOURCE_XXXX values below
591      *
592      * @hide
593      */
594     public static final String NAME_SOURCE = SimInfo.COLUMN_NAME_SOURCE;
595 
596     /**
597      * The name_source is unknown. (for initialization)
598      * @hide
599      */
600     public static final int NAME_SOURCE_UNKNOWN = SimInfo.NAME_SOURCE_UNKNOWN;
601 
602     /**
603      * The name_source is from the carrier id.
604      * @hide
605      */
606     public static final int NAME_SOURCE_CARRIER_ID = SimInfo.NAME_SOURCE_CARRIER_ID;
607 
608     /**
609      * The name_source is from SIM EF_SPN.
610      * @hide
611      */
612     public static final int NAME_SOURCE_SIM_SPN = SimInfo.NAME_SOURCE_SIM_SPN;
613 
614     /**
615      * The name_source is from user input
616      * @hide
617      */
618     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
619     public static final int NAME_SOURCE_USER_INPUT = SimInfo.NAME_SOURCE_USER_INPUT;
620 
621     /**
622      * The name_source is carrier (carrier app, carrier config, etc.)
623      * @hide
624      */
625     public static final int NAME_SOURCE_CARRIER = SimInfo.NAME_SOURCE_CARRIER;
626 
627     /**
628      * The name_source is from SIM EF_PNN.
629      * @hide
630      */
631     public static final int NAME_SOURCE_SIM_PNN = SimInfo.NAME_SOURCE_SIM_PNN;
632 
633     /** @hide */
634     @Retention(RetentionPolicy.SOURCE)
635     @IntDef(prefix = {"NAME_SOURCE_"},
636             value = {
637                     NAME_SOURCE_UNKNOWN,
638                     NAME_SOURCE_CARRIER_ID,
639                     NAME_SOURCE_SIM_SPN,
640                     NAME_SOURCE_USER_INPUT,
641                     NAME_SOURCE_CARRIER,
642                     NAME_SOURCE_SIM_PNN
643             })
644     public @interface SimDisplayNameSource {}
645 
646     /**
647      * Device status is not shared to a remote party.
648      */
649     public static final int D2D_SHARING_DISABLED = 0;
650 
651     /**
652      * Device status is shared with all numbers in the user's contacts.
653      */
654     public static final int D2D_SHARING_ALL_CONTACTS = 1;
655 
656     /**
657      * Device status is shared with all selected contacts.
658      */
659     public static final int D2D_SHARING_SELECTED_CONTACTS = 2;
660 
661     /**
662      * Device status is shared whenever possible.
663      */
664     public static final int D2D_SHARING_ALL = 3;
665 
666     /** @hide */
667     @Retention(RetentionPolicy.SOURCE)
668     @IntDef(prefix = {"D2D_SHARING_"},
669             value = {
670                     D2D_SHARING_DISABLED,
671                     D2D_SHARING_ALL_CONTACTS,
672                     D2D_SHARING_SELECTED_CONTACTS,
673                     D2D_SHARING_ALL
674             })
675     public @interface DeviceToDeviceStatusSharingPreference {}
676 
677     /**
678      * TelephonyProvider column name for device to device sharing status.
679      * <P>Type: INTEGER (int)</P>
680      */
681     public static final String D2D_STATUS_SHARING = SimInfo.COLUMN_D2D_STATUS_SHARING;
682 
683     /**
684      * TelephonyProvider column name for contacts information that allow device to device sharing.
685      * <P>Type: TEXT (String)</P>
686      */
687     public static final String D2D_STATUS_SHARING_SELECTED_CONTACTS =
688             SimInfo.COLUMN_D2D_STATUS_SHARING_SELECTED_CONTACTS;
689 
690     /**
691      * TelephonyProvider column name for the color of a SIM.
692      * <P>Type: INTEGER (int)</P>
693      */
694     /** @hide */
695     public static final String HUE = SimInfo.COLUMN_COLOR;
696 
697     /**
698      * TelephonyProvider column name for the phone number of a SIM.
699      * <P>Type: TEXT (String)</P>
700      */
701     /** @hide */
702     public static final String NUMBER = SimInfo.COLUMN_NUMBER;
703 
704     /**
705      * TelephonyProvider column name for whether data roaming is enabled.
706      * <P>Type: INTEGER (int)</P>
707      */
708     /** @hide */
709     public static final String DATA_ROAMING = SimInfo.COLUMN_DATA_ROAMING;
710 
711     /** Indicates that data roaming is enabled for a subscription */
712     public static final int DATA_ROAMING_ENABLE = SimInfo.DATA_ROAMING_ENABLE;
713 
714     /** Indicates that data roaming is disabled for a subscription */
715     public static final int DATA_ROAMING_DISABLE = SimInfo.DATA_ROAMING_DISABLE;
716 
717     /** @hide */
718     @Retention(RetentionPolicy.SOURCE)
719     @IntDef(prefix = {"DATA_ROAMING_"},
720             value = {
721                     DATA_ROAMING_ENABLE,
722                     DATA_ROAMING_DISABLE
723             })
724     public @interface DataRoamingMode {}
725 
726     /**
727      * TelephonyProvider column name for subscription carrier id.
728      * @see TelephonyManager#getSimCarrierId()
729      * <p>Type: INTEGER (int) </p>
730      * @hide
731      */
732     public static final String CARRIER_ID = SimInfo.COLUMN_CARRIER_ID;
733 
734     /**
735      * @hide A comma-separated list of EHPLMNs associated with the subscription
736      * <P>Type: TEXT (String)</P>
737      */
738     public static final String EHPLMNS = SimInfo.COLUMN_EHPLMNS;
739 
740     /**
741      * @hide A comma-separated list of HPLMNs associated with the subscription
742      * <P>Type: TEXT (String)</P>
743      */
744     public static final String HPLMNS = SimInfo.COLUMN_HPLMNS;
745 
746     /**
747      * TelephonyProvider column name for the MCC associated with a SIM, stored as a string.
748      * <P>Type: TEXT (String)</P>
749      * @hide
750      */
751     public static final String MCC_STRING = SimInfo.COLUMN_MCC_STRING;
752 
753     /**
754      * TelephonyProvider column name for the MNC associated with a SIM, stored as a string.
755      * <P>Type: TEXT (String)</P>
756      * @hide
757      */
758     public static final String MNC_STRING = SimInfo.COLUMN_MNC_STRING;
759 
760     /**
761      * TelephonyProvider column name for the MCC associated with a SIM.
762      * <P>Type: INTEGER (int)</P>
763      * @hide
764      */
765     public static final String MCC = SimInfo.COLUMN_MCC;
766 
767     /**
768      * TelephonyProvider column name for the MNC associated with a SIM.
769      * <P>Type: INTEGER (int)</P>
770      * @hide
771      */
772     public static final String MNC = SimInfo.COLUMN_MNC;
773 
774     /**
775      * TelephonyProvider column name for the iso country code associated with a SIM.
776      * <P>Type: TEXT (String)</P>
777      * @hide
778      */
779     public static final String ISO_COUNTRY_CODE = SimInfo.COLUMN_ISO_COUNTRY_CODE;
780 
781     /**
782      * TelephonyProvider column name for whether a subscription is embedded (that is, present on an
783      * eSIM).
784      * <p>Type: INTEGER (int), 1 for embedded or 0 for non-embedded.
785      * @hide
786      */
787     public static final String IS_EMBEDDED = SimInfo.COLUMN_IS_EMBEDDED;
788 
789     /**
790      * TelephonyProvider column name for SIM card identifier. For UICC card it is the ICCID of the
791      * current enabled profile on the card, while for eUICC card it is the EID of the card.
792      * <P>Type: TEXT (String)</P>
793      * @hide
794      */
795     public static final String CARD_ID = SimInfo.COLUMN_CARD_ID;
796 
797     /**
798      * TelephonyProvider column name for the encoded {@link UiccAccessRule}s from
799      * {@link UiccAccessRule#encodeRules}. Only present if {@link #IS_EMBEDDED} is 1.
800      * <p>TYPE: BLOB
801      * @hide
802      */
803     public static final String ACCESS_RULES = SimInfo.COLUMN_ACCESS_RULES;
804 
805     /**
806      * TelephonyProvider column name for the encoded {@link UiccAccessRule}s from
807      * {@link UiccAccessRule#encodeRules} but for the rules that come from CarrierConfigs.
808      * Only present if there are access rules in CarrierConfigs
809      * <p>TYPE: BLOB
810      * @hide
811      */
812     public static final String ACCESS_RULES_FROM_CARRIER_CONFIGS =
813             SimInfo.COLUMN_ACCESS_RULES_FROM_CARRIER_CONFIGS;
814 
815     /**
816      * TelephonyProvider column name identifying whether an embedded subscription is on a removable
817      * card. Such subscriptions are marked inaccessible as soon as the current card is removed.
818      * Otherwise, they will remain accessible unless explicitly deleted. Only present if
819      * {@link #IS_EMBEDDED} is 1.
820      * <p>TYPE: INTEGER (int), 1 for removable or 0 for non-removable.
821      * @hide
822      */
823     public static final String IS_REMOVABLE = SimInfo.COLUMN_IS_REMOVABLE;
824 
825     /**
826      *  TelephonyProvider column name for extreme threat in CB settings
827      * @hide
828      */
829     public static final String CB_EXTREME_THREAT_ALERT =
830             SimInfo.COLUMN_CB_EXTREME_THREAT_ALERT;
831 
832     /**
833      * TelephonyProvider column name for severe threat in CB settings
834      *@hide
835      */
836     public static final String CB_SEVERE_THREAT_ALERT = SimInfo.COLUMN_CB_SEVERE_THREAT_ALERT;
837 
838     /**
839      * TelephonyProvider column name for amber alert in CB settings
840      *@hide
841      */
842     public static final String CB_AMBER_ALERT = SimInfo.COLUMN_CB_AMBER_ALERT;
843 
844     /**
845      * TelephonyProvider column name for emergency alert in CB settings
846      *@hide
847      */
848     public static final String CB_EMERGENCY_ALERT = SimInfo.COLUMN_CB_EMERGENCY_ALERT;
849 
850     /**
851      * TelephonyProvider column name for alert sound duration in CB settings
852      *@hide
853      */
854     public static final String CB_ALERT_SOUND_DURATION =
855             SimInfo.COLUMN_CB_ALERT_SOUND_DURATION;
856 
857     /**
858      * TelephonyProvider column name for alert reminder interval in CB settings
859      *@hide
860      */
861     public static final String CB_ALERT_REMINDER_INTERVAL =
862             SimInfo.COLUMN_CB_ALERT_REMINDER_INTERVAL;
863 
864     /**
865      * TelephonyProvider column name for enabling vibrate in CB settings
866      *@hide
867      */
868     public static final String CB_ALERT_VIBRATE = SimInfo.COLUMN_CB_ALERT_VIBRATE;
869 
870     /**
871      * TelephonyProvider column name for enabling alert speech in CB settings
872      *@hide
873      */
874     public static final String CB_ALERT_SPEECH = SimInfo.COLUMN_CB_ALERT_SPEECH;
875 
876     /**
877      * TelephonyProvider column name for ETWS test alert in CB settings
878      *@hide
879      */
880     public static final String CB_ETWS_TEST_ALERT = SimInfo.COLUMN_CB_ETWS_TEST_ALERT;
881 
882     /**
883      * TelephonyProvider column name for enable channel50 alert in CB settings
884      *@hide
885      */
886     public static final String CB_CHANNEL_50_ALERT = SimInfo.COLUMN_CB_CHANNEL_50_ALERT;
887 
888     /**
889      * TelephonyProvider column name for CMAS test alert in CB settings
890      *@hide
891      */
892     public static final String CB_CMAS_TEST_ALERT = SimInfo.COLUMN_CB_CMAS_TEST_ALERT;
893 
894     /**
895      * TelephonyProvider column name for Opt out dialog in CB settings
896      *@hide
897      */
898     public static final String CB_OPT_OUT_DIALOG = SimInfo.COLUMN_CB_OPT_OUT_DIALOG;
899 
900     /**
901      * TelephonyProvider column name for enable Volte.
902      *
903      * If this setting is not initialized (set to -1)  then we use the Carrier Config value
904      * {@link CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL}.
905      *@hide
906      */
907     public static final String ENHANCED_4G_MODE_ENABLED =
908             SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED;
909 
910     /**
911      * TelephonyProvider column name for enable VT (Video Telephony over IMS)
912      *@hide
913      */
914     public static final String VT_IMS_ENABLED = SimInfo.COLUMN_VT_IMS_ENABLED;
915 
916     /**
917      * TelephonyProvider column name for enable Wifi calling
918      *@hide
919      */
920     public static final String WFC_IMS_ENABLED = SimInfo.COLUMN_WFC_IMS_ENABLED;
921 
922     /**
923      * TelephonyProvider column name for Wifi calling mode
924      *@hide
925      */
926     public static final String WFC_IMS_MODE = SimInfo.COLUMN_WFC_IMS_MODE;
927 
928     /**
929      * TelephonyProvider column name for Wifi calling mode in roaming
930      *@hide
931      */
932     public static final String WFC_IMS_ROAMING_MODE = SimInfo.COLUMN_WFC_IMS_ROAMING_MODE;
933 
934     /**
935      * TelephonyProvider column name for enable Wifi calling in roaming
936      *@hide
937      */
938     public static final String WFC_IMS_ROAMING_ENABLED = SimInfo.COLUMN_WFC_IMS_ROAMING_ENABLED;
939 
940     /**
941      * Determines if the user has enabled IMS RCS User Capability Exchange (UCE) for this
942      * subscription.
943      * @hide
944      */
945     public static final String IMS_RCS_UCE_ENABLED = SimInfo.COLUMN_IMS_RCS_UCE_ENABLED;
946 
947     /**
948      * Determines if the user has enabled cross SIM calling for this subscription.
949      *
950      * @hide
951      */
952     public static final String CROSS_SIM_CALLING_ENABLED = SimInfo.COLUMN_CROSS_SIM_CALLING_ENABLED;
953 
954     /**
955      * TelephonyProvider column name for whether a subscription is opportunistic, that is,
956      * whether the network it connects to is limited in functionality or coverage.
957      * For example, CBRS.
958      * <p>Type: INTEGER (int), 1 for opportunistic or 0 for non-opportunistic.
959      * @hide
960      */
961     public static final String IS_OPPORTUNISTIC = SimInfo.COLUMN_IS_OPPORTUNISTIC;
962 
963     /**
964      * TelephonyProvider column name for group ID. Subscriptions with same group ID
965      * are considered bundled together, and should behave as a single subscription at
966      * certain scenarios.
967      *
968      * @hide
969      */
970     public static final String GROUP_UUID = SimInfo.COLUMN_GROUP_UUID;
971 
972     /**
973      * TelephonyProvider column name for group owner. It's the package name who created
974      * the subscription group.
975      *
976      * @hide
977      */
978     public static final String GROUP_OWNER = SimInfo.COLUMN_GROUP_OWNER;
979 
980     /**
981      * TelephonyProvider column name for the profile class of a subscription
982      * Only present if {@link #IS_EMBEDDED} is 1.
983      * <P>Type: INTEGER (int)</P>
984      * @hide
985      */
986     public static final String PROFILE_CLASS = SimInfo.COLUMN_PROFILE_CLASS;
987 
988     /**
989      * TelephonyProvider column name for the port index of the active UICC port.
990      * <P>Type: INTEGER (int)</P>
991      * @hide
992      */
993     public static final String PORT_INDEX = SimInfo.COLUMN_PORT_INDEX;
994 
995     /**
996      * TelephonyProvider column name for VoIMS opt-in status.
997      *
998      * <P>Type: INTEGER (int)</P>
999      * @hide
1000      */
1001     public static final String VOIMS_OPT_IN_STATUS = SimInfo.COLUMN_VOIMS_OPT_IN_STATUS;
1002 
1003     /**
1004      * TelephonyProvider column name for NR Advanced calling
1005      * Determines if the user has enabled VoNR settings for this subscription.
1006      *
1007      * @hide
1008      */
1009     public static final String NR_ADVANCED_CALLING_ENABLED =
1010             SimInfo.COLUMN_NR_ADVANCED_CALLING_ENABLED;
1011 
1012     /**
1013      * Profile class of the subscription
1014      * @hide
1015      */
1016     @Retention(RetentionPolicy.SOURCE)
1017     @IntDef(prefix = { "PROFILE_CLASS_" }, value = {
1018             SimInfo.PROFILE_CLASS_TESTING,
1019             SimInfo.PROFILE_CLASS_PROVISIONING,
1020             SimInfo.PROFILE_CLASS_OPERATIONAL,
1021             SimInfo.PROFILE_CLASS_UNSET,
1022     })
1023     public @interface ProfileClass {}
1024 
1025     /**
1026      * A testing profile can be pre-loaded or downloaded onto
1027      * the eUICC and provides connectivity to test equipment
1028      * for the purpose of testing the device and the eUICC. It
1029      * is not intended to store any operator credentials.
1030      * @hide
1031      */
1032     @SystemApi
1033     public static final int PROFILE_CLASS_TESTING = SimInfo.PROFILE_CLASS_TESTING;
1034 
1035     /**
1036      * A provisioning profile is pre-loaded onto the eUICC and
1037      * provides connectivity to a mobile network solely for the
1038      * purpose of provisioning profiles.
1039      * @hide
1040      */
1041     @SystemApi
1042     public static final int PROFILE_CLASS_PROVISIONING = SimInfo.PROFILE_CLASS_PROVISIONING;
1043 
1044     /**
1045      * An operational profile can be pre-loaded or downloaded
1046      * onto the eUICC and provides services provided by the
1047      * operator.
1048      * @hide
1049      */
1050     @SystemApi
1051     public static final int PROFILE_CLASS_OPERATIONAL = SimInfo.PROFILE_CLASS_OPERATIONAL;
1052 
1053     /**
1054      * The profile class is unset. This occurs when profile class
1055      * info is not available. The subscription either has no profile
1056      * metadata or the profile metadata did not encode profile class.
1057      * @hide
1058      */
1059     @SystemApi
1060     public static final int PROFILE_CLASS_UNSET = SimInfo.PROFILE_CLASS_UNSET;
1061 
1062     /**
1063      * Default profile class
1064      * @hide
1065      */
1066     @SystemApi
1067     @Deprecated
1068     public static final int PROFILE_CLASS_DEFAULT = SimInfo.PROFILE_CLASS_UNSET;
1069 
1070     /**
1071      * IMSI (International Mobile Subscriber Identity).
1072      * <P>Type: TEXT </P>
1073      * @hide
1074      */
1075     //TODO: add @SystemApi
1076     public static final String IMSI = SimInfo.COLUMN_IMSI;
1077 
1078     /**
1079      * Whether uicc applications is set to be enabled or disabled. By default it's enabled.
1080      * @hide
1081      */
1082     public static final String UICC_APPLICATIONS_ENABLED = SimInfo.COLUMN_UICC_APPLICATIONS_ENABLED;
1083 
1084     /**
1085      * Indicate which network type is allowed.
1086      * @hide
1087      */
1088     public static final String ALLOWED_NETWORK_TYPES =
1089             SimInfo.COLUMN_ALLOWED_NETWORK_TYPES_FOR_REASONS;
1090 
1091     /**
1092      * TelephonyProvider column name for user handle associated with a sim.
1093      * <P>Type: INTEGER (int)</P>
1094      * @hide
1095      */
1096     public static final String USER_HANDLE = SimInfo.COLUMN_USER_HANDLE;
1097 
1098     /**
1099      * TelephonyProvider column name for satellite enabled.
1100      * By default, it's disabled.
1101      * <P>Type: INTEGER (int)</P>
1102      * @hide
1103      */
1104     public static final String SATELLITE_ENABLED = SimInfo.COLUMN_SATELLITE_ENABLED;
1105 
1106     /** @hide */
1107     @Retention(RetentionPolicy.SOURCE)
1108     @IntDef(prefix = {"USAGE_SETTING_"},
1109         value = {
1110             USAGE_SETTING_UNKNOWN,
1111             USAGE_SETTING_DEFAULT,
1112             USAGE_SETTING_VOICE_CENTRIC,
1113             USAGE_SETTING_DATA_CENTRIC})
1114     public @interface UsageSetting {}
1115 
1116     /**
1117      * The usage setting is unknown.
1118      *
1119      * This will be the usage setting returned on devices that do not support querying the
1120      * or setting the usage setting.
1121      *
1122      * It may also be provided by a carrier that wishes to provide a value to avoid making any
1123      * settings changes.
1124      */
1125     public static final int USAGE_SETTING_UNKNOWN = -1;
1126 
1127     /**
1128      * Subscription uses the default setting.
1129      *
1130      * The value is based upon device capability and the other properties of the subscription.
1131      *
1132      * Most subscriptions will default to voice-centric when in a phone.
1133      *
1134      * An opportunistic subscription will default to data-centric.
1135      *
1136      * @see SubscriptionInfo#isOpportunistic
1137      */
1138     public static final int USAGE_SETTING_DEFAULT = 0;
1139 
1140     /**
1141      * This subscription is forced to voice-centric mode
1142      *
1143      * <p>Refer to voice-centric mode in 3gpp 24.301 sec 4.3 and 3gpp 24.501 sec 4.3.
1144      * Also refer to "UE's usage setting" as defined in 3gpp 24.301 section 3.1 and 3gpp 23.221
1145      * Annex A.
1146      *
1147      * <p>Devices that support {@link PackageManager#FEATURE_TELEPHONY_CALLING} and support usage
1148      * setting configuration must support setting this value via
1149      * {@link CarrierConfigManager#KEY_CELLULAR_USAGE_SETTING_INT}.
1150      */
1151     public static final int USAGE_SETTING_VOICE_CENTRIC = 1;
1152 
1153     /**
1154      * This subscription is forced to data-centric mode
1155      *
1156      * <p>Refer to data-centric mode in 3gpp 24.301 sec 4.3 and 3gpp 24.501 sec 4.3.
1157      * Also refer to "UE's usage setting" as defined in 3gpp 24.301 section 3.1 and 3gpp 23.221
1158      * Annex A.
1159      *
1160      * <p>Devices that support {@link PackageManager#FEATURE_TELEPHONY_DATA} and support usage
1161      * setting configuration must support setting this value via.
1162      * {@link CarrierConfigManager#KEY_CELLULAR_USAGE_SETTING_INT}.
1163      */
1164     public static final int USAGE_SETTING_DATA_CENTRIC = 2;
1165 
1166     /**
1167      * Indicate the preferred usage setting for the subscription.
1168      *
1169      * 0 - Default - If the value has not been explicitly set, it will be "default"
1170      * 1 - Voice-centric
1171      * 2 - Data-centric
1172      *
1173      * @hide
1174      */
1175     public static final String USAGE_SETTING = SimInfo.COLUMN_USAGE_SETTING;
1176 
1177     /**
1178      * Broadcast Action: The user has changed one of the default subs related to
1179      * data, phone calls, or sms</p>
1180      *
1181      * TODO: Change to a listener
1182      * @hide
1183      */
1184     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1185     public static final String SUB_DEFAULT_CHANGED_ACTION =
1186             "android.intent.action.SUB_DEFAULT_CHANGED";
1187 
1188     /**
1189      * Broadcast Action: The default subscription has changed.  This has the following
1190      * extra values:</p>
1191      * The {@link #EXTRA_SUBSCRIPTION_INDEX} extra indicates the current default subscription index
1192      */
1193     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1194     public static final String ACTION_DEFAULT_SUBSCRIPTION_CHANGED
1195             = "android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED";
1196 
1197     /**
1198      * Broadcast Action: The default sms subscription has changed.  This has the following
1199      * extra values:</p>
1200      * {@link #EXTRA_SUBSCRIPTION_INDEX} extra indicates the current default sms
1201      * subscription index
1202      */
1203     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1204     public static final String ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED
1205             = "android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED";
1206 
1207     /**
1208      * Activity Action: Display UI for managing the billing relationship plans
1209      * between a carrier and a specific subscriber.
1210      * <p>
1211      * Carrier apps are encouraged to implement this activity, and the OS will
1212      * provide an affordance to quickly enter this activity, typically via
1213      * Settings. This affordance will only be shown when the carrier app is
1214      * actively providing subscription plan information via
1215      * {@link #setSubscriptionPlans(int, List)}.
1216      * <p>
1217      * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
1218      * the user is interested in.
1219      */
1220     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
1221     public static final String ACTION_MANAGE_SUBSCRIPTION_PLANS
1222             = "android.telephony.action.MANAGE_SUBSCRIPTION_PLANS";
1223 
1224     /**
1225      * Broadcast Action: Request a refresh of the billing relationship plans
1226      * between a carrier and a specific subscriber.
1227      * <p>
1228      * Carrier apps are encouraged to implement this receiver, and the OS will
1229      * provide an affordance to request a refresh. This affordance will only be
1230      * shown when the carrier app is actively providing subscription plan
1231      * information via {@link #setSubscriptionPlans(int, List)}.
1232      * <p>
1233      * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
1234      * the user is interested in.
1235      * <p>
1236      * Receivers should protect themselves by checking that the sender holds the
1237      * {@code android.permission.MANAGE_SUBSCRIPTION_PLANS} permission.
1238      */
1239     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1240     public static final String ACTION_REFRESH_SUBSCRIPTION_PLANS
1241             = "android.telephony.action.REFRESH_SUBSCRIPTION_PLANS";
1242 
1243     /**
1244      * Broadcast Action: The billing relationship plans between a carrier and a
1245      * specific subscriber has changed.
1246      * <p>
1247      * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
1248      * changed.
1249      * @hide
1250      */
1251     @SystemApi
1252     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1253     @RequiresPermission(android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS)
1254     public static final String ACTION_SUBSCRIPTION_PLANS_CHANGED
1255             = "android.telephony.action.SUBSCRIPTION_PLANS_CHANGED";
1256 
1257     /**
1258      * Integer extra used with {@link #ACTION_DEFAULT_SUBSCRIPTION_CHANGED} and
1259      * {@link #ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED} to indicate the subscription
1260      * which has changed.
1261      */
1262     public static final String EXTRA_SUBSCRIPTION_INDEX = "android.telephony.extra.SUBSCRIPTION_INDEX";
1263 
1264     /**
1265      * Integer extra to specify SIM slot index.
1266      */
1267     public static final String EXTRA_SLOT_INDEX = "android.telephony.extra.SLOT_INDEX";
1268 
1269     /**
1270      * A source of phone number: the EF-MSISDN (see 3GPP TS 31.102),
1271      * or EF-MDN for CDMA (see 3GPP2 C.P0065-B), from UICC application.
1272      *
1273      * <p>The availability and a of the number depends on the carrier.
1274      * The number may be updated by over-the-air update to UICC applications
1275      * from the carrier, or by other means with physical access to the SIM.
1276      */
1277     public static final int PHONE_NUMBER_SOURCE_UICC = 1;
1278 
1279     /**
1280      * A source of phone number: provided by an app that has carrier privilege.
1281      *
1282      * <p>The number is intended to be set by a carrier app knowing the correct number
1283      * which is, for example, different from the number in {@link #PHONE_NUMBER_SOURCE_UICC UICC}
1284      * for some reason.
1285      * The number is not available until a carrier app sets one via
1286      * {@link #setCarrierPhoneNumber(int, String)}.
1287      * The app can update the number with the same API should the number change.
1288      */
1289     public static final int PHONE_NUMBER_SOURCE_CARRIER = 2;
1290 
1291     /**
1292      * A source of phone number: provided by IMS (IP Multimedia Subsystem) implementation.
1293      * When IMS service is registered (as indicated by
1294      * {@link android.telephony.ims.RegistrationManager.RegistrationCallback#onRegistered(int)})
1295      * the IMS implementation may return P-Associated-Uri SIP headers (RFC 3455). The URIs
1296      * are the user’s public user identities known to the network (see 3GPP TS 24.229 5.4.1.2),
1297      * and the phone number is typically one of them (see “global number” in 3GPP TS 23.003 13.4).
1298      *
1299      * <p>This source provides the phone number from the last IMS registration.
1300      * IMS registration may happen on every device reboot or other network condition changes.
1301      * The number will be updated should the associated URI change after an IMS registration.
1302      */
1303     public static final int PHONE_NUMBER_SOURCE_IMS = 3;
1304 
1305     /** @hide */
1306     @Retention(RetentionPolicy.SOURCE)
1307     @IntDef(prefix = {"PHONE_NUMBER_SOURCE"},
1308             value = {
1309                     PHONE_NUMBER_SOURCE_UICC,
1310                     PHONE_NUMBER_SOURCE_CARRIER,
1311                     PHONE_NUMBER_SOURCE_IMS,
1312             })
1313     public @interface PhoneNumberSource {}
1314 
1315     private final Context mContext;
1316 
1317     // Cache of Resource that has been created in getResourcesForSubId. Key is a Pair containing
1318     // the Context and subId.
1319     private static final Map<Pair<Context, Integer>, Resources> sResourcesCache =
1320             new ConcurrentHashMap<>();
1321 
1322     /**
1323      * A listener class for monitoring changes to {@link SubscriptionInfo} records.
1324      * <p>
1325      * Override the onSubscriptionsChanged method in the object that extends this
1326      * class and pass it to {@link #addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener)}
1327      * to register your listener and to unregister invoke
1328      * {@link #removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener)}
1329      * <p>
1330      * Permissions android.Manifest.permission.READ_PHONE_STATE is required
1331      * for #onSubscriptionsChanged to be invoked.
1332      */
1333     public static class OnSubscriptionsChangedListener {
1334         private class OnSubscriptionsChangedListenerHandler extends Handler {
OnSubscriptionsChangedListenerHandler()1335             OnSubscriptionsChangedListenerHandler() {
1336                 super();
1337             }
1338 
OnSubscriptionsChangedListenerHandler(Looper looper)1339             OnSubscriptionsChangedListenerHandler(Looper looper) {
1340                 super(looper);
1341             }
1342         }
1343 
1344         /**
1345          * Posted executor callback on the handler associated with a given looper.
1346          * The looper can be the calling thread's looper or the looper passed from the
1347          * constructor {@link #OnSubscriptionsChangedListener(Looper)}.
1348          */
1349         private final HandlerExecutor mExecutor;
1350 
1351         /**
1352          * @hide
1353          */
getHandlerExecutor()1354         public HandlerExecutor getHandlerExecutor() {
1355             return mExecutor;
1356         }
1357 
OnSubscriptionsChangedListener()1358         public OnSubscriptionsChangedListener() {
1359             mExecutor = new HandlerExecutor(new OnSubscriptionsChangedListenerHandler());
1360         }
1361 
1362         /**
1363          * Allow a listener to be created with a custom looper
1364          * @param looper the looper that the underlining handler should run on
1365          * @hide
1366          */
OnSubscriptionsChangedListener(Looper looper)1367         public OnSubscriptionsChangedListener(Looper looper) {
1368             mExecutor = new HandlerExecutor(new OnSubscriptionsChangedListenerHandler(looper));
1369         }
1370 
1371         /**
1372          * Callback invoked when there is any change to any SubscriptionInfo, as well as once on
1373          * registering for changes with {@link #addOnSubscriptionsChangedListener}. Typically
1374          * this method would invoke {@link #getActiveSubscriptionInfoList}
1375          */
onSubscriptionsChanged()1376         public void onSubscriptionsChanged() {
1377             if (DBG) log("onSubscriptionsChanged: NOT OVERRIDDEN");
1378         }
1379 
1380         /**
1381          * Callback invoked when {@link SubscriptionManager#addOnSubscriptionsChangedListener(
1382          * Executor, OnSubscriptionsChangedListener)} or
1383          * {@link SubscriptionManager#addOnSubscriptionsChangedListener(
1384          * OnSubscriptionsChangedListener)} fails to complete due to the
1385          * {@link Context#TELEPHONY_REGISTRY_SERVICE} being unavailable.
1386          * @hide
1387          */
onAddListenerFailed()1388         public void onAddListenerFailed() {
1389             Rlog.w(LOG_TAG, "onAddListenerFailed not overridden");
1390         }
1391 
log(String s)1392         private void log(String s) {
1393             Rlog.d(LOG_TAG, s);
1394         }
1395     }
1396 
1397     /** @hide */
1398     @UnsupportedAppUsage
SubscriptionManager(Context context)1399     public SubscriptionManager(Context context) {
1400         if (DBG) logd("SubscriptionManager created");
1401         mContext = context;
1402     }
1403 
getNetworkPolicyManager()1404     private NetworkPolicyManager getNetworkPolicyManager() {
1405         return (NetworkPolicyManager) mContext
1406                 .getSystemService(Context.NETWORK_POLICY_SERVICE);
1407     }
1408 
1409     /**
1410      * @deprecated developers should always obtain references directly from
1411      *             {@link Context#getSystemService(Class)}.
1412      */
1413     @Deprecated
from(Context context)1414     public static SubscriptionManager from(Context context) {
1415         return (SubscriptionManager) context
1416                 .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
1417     }
1418 
1419     /**
1420      * Register for changes to the list of active {@link SubscriptionInfo} records or to the
1421      * individual records themselves. When a change occurs the onSubscriptionsChanged method of
1422      * the listener will be invoked immediately if there has been a notification. The
1423      * onSubscriptionChanged method will also be triggered once initially when calling this
1424      * function. The callback will be invoked on the looper specified in the listener's constructor.
1425      *
1426      * @param listener an instance of {@link OnSubscriptionsChangedListener} with
1427      *                 onSubscriptionsChanged overridden.
1428      *
1429      * @deprecated Will get exception if the parameter listener is not initialized with a Looper.
1430      * Use {@link #addOnSubscriptionsChangedListener(Executor, OnSubscriptionsChangedListener)}.
1431      */
1432     @Deprecated
addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener)1433     public void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
1434         if (listener == null) return;
1435         addOnSubscriptionsChangedListener(listener.mExecutor, listener);
1436     }
1437 
1438     /**
1439      * Register for changes to the list of active {@link SubscriptionInfo} records or to the
1440      * individual records themselves. When a change occurs the onSubscriptionsChanged method of
1441      * the listener will be invoked immediately if there has been a notification. The
1442      * onSubscriptionChanged method will also be triggered once initially when calling this
1443      * function.
1444      *
1445      * @param listener an instance of {@link OnSubscriptionsChangedListener} with
1446      *                 onSubscriptionsChanged overridden.
1447      * @param executor the executor that will execute callbacks.
1448      */
addOnSubscriptionsChangedListener( @onNull @allbackExecutor Executor executor, @NonNull OnSubscriptionsChangedListener listener)1449     public void addOnSubscriptionsChangedListener(
1450             @NonNull @CallbackExecutor Executor executor,
1451             @NonNull OnSubscriptionsChangedListener listener) {
1452         String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>";
1453         if (DBG) {
1454             logd("register OnSubscriptionsChangedListener pkgName=" + pkgName
1455                     + " listener=" + listener);
1456         }
1457         // We use the TelephonyRegistry as it runs in the system and thus is always
1458         // available.
1459         TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
1460                 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
1461         if (telephonyRegistryManager != null) {
1462             telephonyRegistryManager.addOnSubscriptionsChangedListener(listener,
1463                     executor);
1464         } else {
1465             // If the telephony registry isn't available, we will inform the caller on their
1466             // listener that it failed so they can try to re-register.
1467             loge("addOnSubscriptionsChangedListener: pkgname=" + pkgName + " failed to be added "
1468                     + " due to TELEPHONY_REGISTRY_SERVICE being unavailable.");
1469             executor.execute(() -> listener.onAddListenerFailed());
1470         }
1471     }
1472 
1473     /**
1474      * Unregister the {@link OnSubscriptionsChangedListener}. This is not strictly necessary
1475      * as the listener will automatically be unregistered if an attempt to invoke the listener
1476      * fails.
1477      *
1478      * @param listener that is to be unregistered.
1479      */
removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener)1480     public void removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
1481         if (listener == null) return;
1482         String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
1483         if (DBG) {
1484             logd("unregister OnSubscriptionsChangedListener pkgForDebug=" + pkgForDebug
1485                     + " listener=" + listener);
1486         }
1487         // We use the TelephonyRegistry as it runs in the system and thus is always
1488         // available.
1489         TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
1490                 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
1491         if (telephonyRegistryManager != null) {
1492             telephonyRegistryManager.removeOnSubscriptionsChangedListener(listener);
1493         }
1494     }
1495 
1496     /**
1497      * A listener class for monitoring changes to {@link SubscriptionInfo} records of opportunistic
1498      * subscriptions.
1499      * <p>
1500      * Override the onOpportunisticSubscriptionsChanged method in the object that extends this
1501      * or {@link #addOnOpportunisticSubscriptionsChangedListener(
1502      * Executor, OnOpportunisticSubscriptionsChangedListener)}
1503      * to register your listener and to unregister invoke
1504      * {@link #removeOnOpportunisticSubscriptionsChangedListener(
1505      * OnOpportunisticSubscriptionsChangedListener)}
1506      * <p>
1507      * Permissions android.Manifest.permission.READ_PHONE_STATE is required
1508      * for #onOpportunisticSubscriptionsChanged to be invoked.
1509      */
1510     public static class OnOpportunisticSubscriptionsChangedListener {
1511         /**
1512          * Callback invoked when there is any change to any SubscriptionInfo. Typically
1513          * this method would invoke {@link #getActiveSubscriptionInfoList}
1514          */
onOpportunisticSubscriptionsChanged()1515         public void onOpportunisticSubscriptionsChanged() {
1516             if (DBG) log("onOpportunisticSubscriptionsChanged: NOT OVERRIDDEN");
1517         }
1518 
log(String s)1519         private void log(String s) {
1520             Rlog.d(LOG_TAG, s);
1521         }
1522     }
1523 
1524     /**
1525      * Register for changes to the list of opportunistic subscription records or to the
1526      * individual records themselves. When a change occurs the onOpportunisticSubscriptionsChanged
1527      * method of the listener will be invoked immediately if there has been a notification.
1528      *
1529      * @param listener an instance of {@link OnOpportunisticSubscriptionsChangedListener} with
1530      *                 onOpportunisticSubscriptionsChanged overridden.
1531      */
addOnOpportunisticSubscriptionsChangedListener( @onNull @allbackExecutor Executor executor, @NonNull OnOpportunisticSubscriptionsChangedListener listener)1532     public void addOnOpportunisticSubscriptionsChangedListener(
1533             @NonNull @CallbackExecutor Executor executor,
1534             @NonNull OnOpportunisticSubscriptionsChangedListener listener) {
1535         if (executor == null || listener == null) {
1536             return;
1537         }
1538 
1539         String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>";
1540         if (DBG) {
1541             logd("register addOnOpportunisticSubscriptionsChangedListener pkgName=" + pkgName
1542                     + " listener=" + listener);
1543         }
1544 
1545         // We use the TelephonyRegistry as it runs in the system and thus is always
1546         // available.
1547         TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
1548                 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
1549         if (telephonyRegistryManager != null) {
1550             telephonyRegistryManager.addOnOpportunisticSubscriptionsChangedListener(
1551                     listener, executor);
1552         }
1553     }
1554 
1555     /**
1556      * Unregister the {@link OnOpportunisticSubscriptionsChangedListener} that is currently
1557      * listening opportunistic subscriptions change. This is not strictly necessary
1558      * as the listener will automatically be unregistered if an attempt to invoke the listener
1559      * fails.
1560      *
1561      * @param listener that is to be unregistered.
1562      */
removeOnOpportunisticSubscriptionsChangedListener( @onNull OnOpportunisticSubscriptionsChangedListener listener)1563     public void removeOnOpportunisticSubscriptionsChangedListener(
1564             @NonNull OnOpportunisticSubscriptionsChangedListener listener) {
1565         Preconditions.checkNotNull(listener, "listener cannot be null");
1566         String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
1567         if (DBG) {
1568             logd("unregister OnOpportunisticSubscriptionsChangedListener pkgForDebug="
1569                     + pkgForDebug + " listener=" + listener);
1570         }
1571         TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
1572                 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
1573         if (telephonyRegistryManager != null) {
1574             telephonyRegistryManager.removeOnOpportunisticSubscriptionsChangedListener(listener);
1575         }
1576     }
1577 
1578     /**
1579      * Get the active SubscriptionInfo with the input subId.
1580      *
1581      * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1582      * or that the calling app has carrier privileges (see
1583      * {@link TelephonyManager#hasCarrierPrivileges}).
1584      *
1585      * @param subId The unique SubscriptionInfo key in database.
1586      * @return SubscriptionInfo, maybe null if its not active.
1587      */
1588     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
1589     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
getActiveSubscriptionInfo(int subId)1590     public SubscriptionInfo getActiveSubscriptionInfo(int subId) {
1591         if (VDBG) logd("[getActiveSubscriptionInfo]+ subId=" + subId);
1592         if (!isValidSubscriptionId(subId)) {
1593             if (DBG) {
1594                 logd("[getActiveSubscriptionInfo]- invalid subId");
1595             }
1596             return null;
1597         }
1598 
1599         SubscriptionInfo subInfo = null;
1600 
1601         try {
1602             ISub iSub = TelephonyManager.getSubscriptionService();
1603             if (iSub != null) {
1604                 subInfo = iSub.getActiveSubscriptionInfo(subId, mContext.getOpPackageName(),
1605                         mContext.getAttributionTag());
1606             }
1607         } catch (RemoteException ex) {
1608             // ignore it
1609         }
1610 
1611         return subInfo;
1612     }
1613 
1614     /**
1615      * Gets an active SubscriptionInfo {@link SubscriptionInfo} associated with the Sim IccId.
1616      *
1617      * @param iccId the IccId of SIM card
1618      * @return SubscriptionInfo, maybe null if its not active
1619      *
1620      * @hide
1621      */
1622     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
1623     @Nullable
1624     @SystemApi
getActiveSubscriptionInfoForIcc(@onNull String iccId)1625     public SubscriptionInfo getActiveSubscriptionInfoForIcc(@NonNull String iccId) {
1626         if (VDBG) logd("[getActiveSubscriptionInfoForIccIndex]+ iccId=" + iccId);
1627         if (iccId == null) {
1628             logd("[getActiveSubscriptionInfoForIccIndex]- null iccid");
1629             return null;
1630         }
1631 
1632         SubscriptionInfo result = null;
1633 
1634         try {
1635             ISub iSub = TelephonyManager.getSubscriptionService();
1636             if (iSub != null) {
1637                 result = iSub.getActiveSubscriptionInfoForIccId(iccId, mContext.getOpPackageName(),
1638                         mContext.getAttributionTag());
1639             }
1640         } catch (RemoteException ex) {
1641             // ignore it
1642         }
1643 
1644         return result;
1645     }
1646 
1647     /**
1648      * Get the active SubscriptionInfo associated with the slotIndex
1649      *
1650      * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1651      * or that the calling app has carrier privileges (see
1652      * {@link TelephonyManager#hasCarrierPrivileges}).
1653      *
1654      * @param slotIndex the slot which the subscription is inserted
1655      * @return SubscriptionInfo, maybe null if its not active
1656      */
1657     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
1658     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
getActiveSubscriptionInfoForSimSlotIndex(int slotIndex)1659     public SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex) {
1660         if (VDBG) logd("[getActiveSubscriptionInfoForSimSlotIndex]+ slotIndex=" + slotIndex);
1661         if (!isValidSlotIndex(slotIndex)) {
1662             logd("[getActiveSubscriptionInfoForSimSlotIndex]- invalid slotIndex");
1663             return null;
1664         }
1665 
1666         SubscriptionInfo result = null;
1667 
1668         try {
1669             ISub iSub = TelephonyManager.getSubscriptionService();
1670             if (iSub != null) {
1671                 result = iSub.getActiveSubscriptionInfoForSimSlotIndex(slotIndex,
1672                         mContext.getOpPackageName(), mContext.getAttributionTag());
1673             }
1674         } catch (RemoteException ex) {
1675             // ignore it
1676         }
1677 
1678         return result;
1679     }
1680 
1681     /**
1682      * Get all subscription info records from SIMs that are inserted now or previously inserted.
1683      *
1684      * <p>
1685      * If the caller does not have {@link Manifest.permission#READ_PHONE_NUMBERS} permission,
1686      * {@link SubscriptionInfo#getNumber()} will return empty string.
1687      * If the caller does not have {@link Manifest.permission#USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER},
1688      * {@link SubscriptionInfo#getIccId()} will return an empty string, and
1689      * {@link SubscriptionInfo#getGroupUuid()} will return {@code null}.
1690      *
1691      * <p>
1692      * The carrier app will only get the list of subscriptions that it has carrier privilege on,
1693      * but will have non-stripped {@link SubscriptionInfo} in the list.
1694      *
1695      * @return List of all {@link SubscriptionInfo} records from SIMs that are inserted or
1696      * previously inserted. Sorted by {@link SubscriptionInfo#getSimSlotIndex()}, then
1697      * {@link SubscriptionInfo#getSubscriptionId()}.
1698      *
1699      * @throws SecurityException if callers do not hold the required permission.
1700      */
1701     @NonNull
1702     @RequiresPermission(anyOf = {
1703             Manifest.permission.READ_PHONE_STATE,
1704             "carrier privileges",
1705     })
getAllSubscriptionInfoList()1706     public List<SubscriptionInfo> getAllSubscriptionInfoList() {
1707         List<SubscriptionInfo> result = null;
1708         try {
1709             ISub iSub = TelephonyManager.getSubscriptionService();
1710             if (iSub != null) {
1711                 result = iSub.getAllSubInfoList(mContext.getOpPackageName(),
1712                         mContext.getAttributionTag());
1713             }
1714         } catch (RemoteException ex) {
1715             // ignore it
1716         }
1717 
1718         if (result == null) {
1719             result = Collections.emptyList();
1720         }
1721         return result;
1722     }
1723 
1724     /**
1725      * Get the SubscriptionInfo(s) of the currently active SIM(s). The records will be sorted
1726      * by {@link SubscriptionInfo#getSimSlotIndex} then by {@link SubscriptionInfo#getSubscriptionId}.
1727      *
1728      * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1729      * or that the calling app has carrier privileges (see
1730      * {@link TelephonyManager#hasCarrierPrivileges}).
1731      *
1732      * @return Sorted list of the currently {@link SubscriptionInfo} records available on the device.
1733      * <ul>
1734      * <li>
1735      * If null is returned the current state is unknown but if a {@link OnSubscriptionsChangedListener}
1736      * has been registered {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be
1737      * invoked in the future.
1738      * </li>
1739      * <li>
1740      * If the list is empty then there are no {@link SubscriptionInfo} records currently available.
1741      * </li>
1742      * <li>
1743      * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
1744      * then by {@link SubscriptionInfo#getSubscriptionId}.
1745      * </li>
1746      * </ul>
1747      */
1748     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
getActiveSubscriptionInfoList()1749     public List<SubscriptionInfo> getActiveSubscriptionInfoList() {
1750         return getActiveSubscriptionInfoList(/* userVisibleonly */true);
1751     }
1752 
1753     /**
1754      * Get both hidden and visible SubscriptionInfo(s) of the currently active SIM(s).
1755      * The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex}
1756      * then by {@link SubscriptionInfo#getSubscriptionId}.
1757      *
1758      * Hidden subscriptions refer to those are not meant visible to the users.
1759      * For example, an opportunistic subscription that is grouped with other
1760      * subscriptions should remain invisible to users as they are only functionally
1761      * supplementary to primary ones.
1762      *
1763      * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1764      * or that the calling app has carrier privileges (see
1765      * {@link TelephonyManager#hasCarrierPrivileges}). In the latter case, only records accessible
1766      * to the calling app are returned.
1767      *
1768      * @return Sorted list of the currently available {@link SubscriptionInfo}
1769      * records on the device.
1770      * This is similar to {@link #getActiveSubscriptionInfoList} except that it will return
1771      * both active and hidden SubscriptionInfos.
1772      *
1773      */
getCompleteActiveSubscriptionInfoList()1774     public @NonNull List<SubscriptionInfo> getCompleteActiveSubscriptionInfoList() {
1775         List<SubscriptionInfo> completeList = getActiveSubscriptionInfoList(
1776                 /* userVisibleonly */false);
1777         if (completeList == null) {
1778             completeList = new ArrayList<>();
1779         }
1780         return completeList;
1781     }
1782 
1783     /**
1784     * This is similar to {@link #getActiveSubscriptionInfoList()}, but if userVisibleOnly
1785     * is true, it will filter out the hidden subscriptions.
1786     *
1787     * @hide
1788     */
getActiveSubscriptionInfoList(boolean userVisibleOnly)1789     public @Nullable List<SubscriptionInfo> getActiveSubscriptionInfoList(boolean userVisibleOnly) {
1790         List<SubscriptionInfo> activeList = null;
1791 
1792         try {
1793             ISub iSub = TelephonyManager.getSubscriptionService();
1794             if (iSub != null) {
1795                 activeList = iSub.getActiveSubscriptionInfoList(mContext.getOpPackageName(),
1796                         mContext.getAttributionTag());
1797             }
1798         } catch (RemoteException ex) {
1799             // ignore it
1800         }
1801 
1802         if (!userVisibleOnly || activeList == null) {
1803             return activeList;
1804         } else {
1805             return activeList.stream().filter(subInfo -> isSubscriptionVisible(subInfo))
1806                     .collect(Collectors.toList());
1807         }
1808     }
1809 
1810     /**
1811      * Gets the SubscriptionInfo(s) of all available subscriptions, if any.
1812      *
1813      * <p>Available subscriptions include active ones (those with a non-negative
1814      * {@link SubscriptionInfo#getSimSlotIndex()}) as well as inactive but installed embedded
1815      * subscriptions.
1816      *
1817      * <p>The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by
1818      * {@link SubscriptionInfo#getSubscriptionId}.
1819      *
1820      * @return Sorted list of the current {@link SubscriptionInfo} records available on the
1821      * device.
1822      * <ul>
1823      * <li>
1824      * If null is returned the current state is unknown but if a
1825      * {@link OnSubscriptionsChangedListener} has been registered
1826      * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be invoked in the future.
1827      * <li>
1828      * If the list is empty then there are no {@link SubscriptionInfo} records currently available.
1829      * <li>
1830      * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
1831      * then by {@link SubscriptionInfo#getSubscriptionId}.
1832      * </ul>
1833      *
1834      * <p>
1835      * Permissions android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE is required
1836      * for #getAvailableSubscriptionInfoList to be invoked.
1837      * @hide
1838      */
1839     @SystemApi
getAvailableSubscriptionInfoList()1840     public List<SubscriptionInfo> getAvailableSubscriptionInfoList() {
1841         List<SubscriptionInfo> result = null;
1842 
1843         try {
1844             ISub iSub = TelephonyManager.getSubscriptionService();
1845             if (iSub != null) {
1846                 result = iSub.getAvailableSubscriptionInfoList(mContext.getOpPackageName(),
1847                         mContext.getAttributionTag());
1848             }
1849         } catch (RemoteException ex) {
1850             // ignore it
1851         }
1852         return result;
1853     }
1854 
1855     /**
1856      * Gets the SubscriptionInfo(s) of all embedded subscriptions accessible to the calling app, if
1857      * any.
1858      *
1859      * <p>Only those subscriptions for which the calling app has carrier privileges per the
1860      * subscription metadata, if any, will be included in the returned list.
1861      *
1862      * <p>The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by
1863      * {@link SubscriptionInfo#getSubscriptionId}.
1864      *
1865      * @return Sorted list of the current embedded {@link SubscriptionInfo} records available on the
1866      * device which are accessible to the caller.
1867      * <ul>
1868      * <li>
1869      * If null is returned the current state is unknown but if a
1870      * {@link OnSubscriptionsChangedListener} has been registered
1871      * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be invoked in the future.
1872      * <li>
1873      * If the list is empty then there are no {@link SubscriptionInfo} records currently available.
1874      * <li>
1875      * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
1876      * then by {@link SubscriptionInfo#getSubscriptionId}.
1877      * </ul>
1878      */
getAccessibleSubscriptionInfoList()1879     public List<SubscriptionInfo> getAccessibleSubscriptionInfoList() {
1880         List<SubscriptionInfo> result = null;
1881 
1882         try {
1883             ISub iSub = TelephonyManager.getSubscriptionService();
1884             if (iSub != null) {
1885                 result = iSub.getAccessibleSubscriptionInfoList(mContext.getOpPackageName());
1886             }
1887         } catch (RemoteException ex) {
1888             // ignore it
1889         }
1890         return result;
1891     }
1892 
1893     /**
1894      * Request a refresh of the platform cache of profile information for the eUICC which
1895      * corresponds to the card ID returned by {@link TelephonyManager#getCardIdForDefaultEuicc()}.
1896      *
1897      * <p>Should be called by the EuiccService implementation whenever this information changes due
1898      * to an operation done outside the scope of a request initiated by the platform to the
1899      * EuiccService. There is no need to refresh for downloads, deletes, or other operations that
1900      * were made through the EuiccService.
1901      *
1902      * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
1903      *
1904      * @see TelephonyManager#getCardIdForDefaultEuicc() for more information on the card ID.
1905      *
1906      * @hide
1907      */
1908     @SystemApi
requestEmbeddedSubscriptionInfoListRefresh()1909     public void requestEmbeddedSubscriptionInfoListRefresh() {
1910         int cardId = TelephonyManager.from(mContext).getCardIdForDefaultEuicc();
1911         try {
1912             ISub iSub = TelephonyManager.getSubscriptionService();
1913             if (iSub != null) {
1914                 iSub.requestEmbeddedSubscriptionInfoListRefresh(cardId);
1915             }
1916         } catch (RemoteException ex) {
1917             logd("requestEmbeddedSubscriptionInfoListFresh for card = " + cardId + " failed.");
1918         }
1919     }
1920 
1921     /**
1922      * Request a refresh of the platform cache of profile information for the eUICC with the given
1923      * {@code cardId}.
1924      *
1925      * <p>Should be called by the EuiccService implementation whenever this information changes due
1926      * to an operation done outside the scope of a request initiated by the platform to the
1927      * EuiccService. There is no need to refresh for downloads, deletes, or other operations that
1928      * were made through the EuiccService.
1929      *
1930      * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
1931      *
1932      * @param cardId the card ID of the eUICC.
1933      *
1934      * @see TelephonyManager#getCardIdForDefaultEuicc() for more information on the card ID.
1935      *
1936      * @hide
1937      */
1938     @SystemApi
requestEmbeddedSubscriptionInfoListRefresh(int cardId)1939     public void requestEmbeddedSubscriptionInfoListRefresh(int cardId) {
1940         try {
1941             ISub iSub = TelephonyManager.getSubscriptionService();
1942             if (iSub != null) {
1943                 iSub.requestEmbeddedSubscriptionInfoListRefresh(cardId);
1944             }
1945         } catch (RemoteException ex) {
1946             logd("requestEmbeddedSubscriptionInfoListFresh for card = " + cardId + " failed.");
1947         }
1948     }
1949 
1950     /**
1951      * Get the active subscription count.
1952      *
1953      * @return The current number of active subscriptions.
1954      *
1955      * @see #getActiveSubscriptionInfoList()
1956      */
1957     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
getActiveSubscriptionInfoCount()1958     public int getActiveSubscriptionInfoCount() {
1959         int result = 0;
1960 
1961         try {
1962             ISub iSub = TelephonyManager.getSubscriptionService();
1963             if (iSub != null) {
1964                 result = iSub.getActiveSubInfoCount(mContext.getOpPackageName(),
1965                         mContext.getAttributionTag());
1966             }
1967         } catch (RemoteException ex) {
1968             // ignore it
1969         }
1970 
1971         return result;
1972     }
1973 
1974     /**
1975      * @return the maximum number of active subscriptions that will be returned by
1976      * {@link #getActiveSubscriptionInfoList} and the value returned by
1977      * {@link #getActiveSubscriptionInfoCount}.
1978      */
getActiveSubscriptionInfoCountMax()1979     public int getActiveSubscriptionInfoCountMax() {
1980         int result = 0;
1981 
1982         try {
1983             ISub iSub = TelephonyManager.getSubscriptionService();
1984             if (iSub != null) {
1985                 result = iSub.getActiveSubInfoCountMax();
1986             }
1987         } catch (RemoteException ex) {
1988             // ignore it
1989         }
1990 
1991         return result;
1992     }
1993 
1994     /**
1995      * Add a new SubscriptionInfo to SubscriptionInfo database if needed
1996      * @param iccId the IccId of the SIM card
1997      * @param slotIndex the slot which the SIM is inserted
1998      * @return the URL of the newly created row or the updated row
1999      * @hide
2000      */
addSubscriptionInfoRecord(String iccId, int slotIndex)2001     public Uri addSubscriptionInfoRecord(String iccId, int slotIndex) {
2002         if (VDBG) logd("[addSubscriptionInfoRecord]+ iccId:" + iccId + " slotIndex:" + slotIndex);
2003         if (iccId == null) {
2004             logd("[addSubscriptionInfoRecord]- null iccId");
2005         }
2006         if (!isValidSlotIndex(slotIndex)) {
2007             logd("[addSubscriptionInfoRecord]- invalid slotIndex");
2008         }
2009 
2010         addSubscriptionInfoRecord(iccId, null, slotIndex, SUBSCRIPTION_TYPE_LOCAL_SIM);
2011 
2012         // FIXME: Always returns null?
2013         return null;
2014 
2015     }
2016 
2017     /**
2018      * Add a new SubscriptionInfo to SubscriptionInfo database if needed
2019      * @param uniqueId This is the unique identifier for the subscription within the
2020      *                 specific subscription type.
2021      * @param displayName human-readable name of the device the subscription corresponds to.
2022      * @param slotIndex the slot assigned to this subscription. It is ignored for subscriptionType
2023      *                  of {@link #SUBSCRIPTION_TYPE_REMOTE_SIM}.
2024      * @param subscriptionType the {@link #SUBSCRIPTION_TYPE}
2025      * @hide
2026      */
2027     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
addSubscriptionInfoRecord(@onNull String uniqueId, @Nullable String displayName, int slotIndex, @SubscriptionType int subscriptionType)2028     public void addSubscriptionInfoRecord(@NonNull String uniqueId, @Nullable String displayName,
2029             int slotIndex, @SubscriptionType int subscriptionType) {
2030         if (VDBG) {
2031             logd("[addSubscriptionInfoRecord]+ uniqueId:" + uniqueId
2032                     + ", displayName:" + displayName + ", slotIndex:" + slotIndex
2033                     + ", subscriptionType: " + subscriptionType);
2034         }
2035         if (uniqueId == null) {
2036             Log.e(LOG_TAG, "[addSubscriptionInfoRecord]- uniqueId is null");
2037             return;
2038         }
2039 
2040         try {
2041             ISub iSub = TelephonyManager.getSubscriptionService();
2042             if (iSub == null) {
2043                 Log.e(LOG_TAG, "[addSubscriptionInfoRecord]- ISub service is null");
2044                 return;
2045             }
2046             int result = iSub.addSubInfo(uniqueId, displayName, slotIndex, subscriptionType);
2047             if (result < 0) {
2048                 Log.e(LOG_TAG, "Adding of subscription didn't succeed: error = " + result);
2049             } else {
2050                 logd("successfully added new subscription");
2051             }
2052         } catch (RemoteException ex) {
2053             // ignore it
2054         }
2055     }
2056 
2057     /**
2058      * Remove subscription info record from the subscription database.
2059      *
2060      * @param uniqueId This is the unique identifier for the subscription within the specific
2061      * subscription type.
2062      * @param subscriptionType the type of subscription to be removed.
2063      *
2064      * @throws NullPointerException if {@code uniqueId} is {@code null}.
2065      * @throws SecurityException if callers do not hold the required permission.
2066      *
2067      * @hide
2068      */
2069     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
removeSubscriptionInfoRecord(@onNull String uniqueId, @SubscriptionType int subscriptionType)2070     public void removeSubscriptionInfoRecord(@NonNull String uniqueId,
2071             @SubscriptionType int subscriptionType) {
2072         if (VDBG) {
2073             logd("[removeSubscriptionInfoRecord]+ uniqueId:" + uniqueId
2074                     + ", subscriptionType: " + subscriptionType);
2075         }
2076         if (uniqueId == null) {
2077             Log.e(LOG_TAG, "[addSubscriptionInfoRecord]- uniqueId is null");
2078             return;
2079         }
2080 
2081         try {
2082             ISub iSub = TelephonyManager.getSubscriptionService();
2083             if (iSub == null) {
2084                 Log.e(LOG_TAG, "[removeSubscriptionInfoRecord]- ISub service is null");
2085                 return;
2086             }
2087             boolean result = iSub.removeSubInfo(uniqueId, subscriptionType);
2088             if (!result) {
2089                 Log.e(LOG_TAG, "Removal of subscription didn't succeed");
2090             } else {
2091                 logd("successfully removed subscription");
2092             }
2093         } catch (RemoteException ex) {
2094             // ignore it
2095         }
2096     }
2097 
2098     /**
2099      * Set SIM icon tint color for subscription ID
2100      * @param tint the RGB value of icon tint color of the SIM
2101      * @param subId the unique subscription ID in database
2102      * @return the number of records updated
2103      * @hide
2104      */
2105     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setIconTint(@olorInt int tint, int subId)2106     public int setIconTint(@ColorInt int tint, int subId) {
2107         if (VDBG) logd("[setIconTint]+ tint:" + tint + " subId:" + subId);
2108         return setSubscriptionPropertyHelper(subId, "setIconTint",
2109                 (iSub)-> iSub.setIconTint(subId, tint)
2110         );
2111     }
2112 
2113     /**
2114      * Set the display name for a subscription ID
2115      * @param displayName the display name of SIM card
2116      * @param subId the unique Subscritpion ID in database
2117      * @param nameSource SIM display name source
2118      * @return the number of records updated or < 0 if invalid subId
2119      * @hide
2120      */
2121     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setDisplayName(@ullable String displayName, int subId, @SimDisplayNameSource int nameSource)2122     public int setDisplayName(@Nullable String displayName, int subId,
2123             @SimDisplayNameSource int nameSource) {
2124         if (VDBG) {
2125             logd("[setDisplayName]+  displayName:" + displayName + " subId:" + subId
2126                     + " nameSource:" + nameSource);
2127         }
2128         return setSubscriptionPropertyHelper(subId, "setDisplayName",
2129                 (iSub)-> iSub.setDisplayNameUsingSrc(displayName, subId, nameSource)
2130         );
2131     }
2132 
2133     /**
2134      * Set phone number by subId
2135      * @param number the phone number of the SIM
2136      * @param subId the unique SubscriptionInfo index in database
2137      * @return the number of records updated
2138      * @hide
2139      */
2140     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
setDisplayNumber(String number, int subId)2141     public int setDisplayNumber(String number, int subId) {
2142         if (number == null) {
2143             logd("[setDisplayNumber]- fail");
2144             return -1;
2145         }
2146         return setSubscriptionPropertyHelper(subId, "setDisplayNumber",
2147                 (iSub)-> iSub.setDisplayNumber(number, subId)
2148         );
2149     }
2150 
2151     /**
2152      * Set data roaming by simInfo index
2153      * @param roaming 0:Don't allow data when roaming, 1:Allow data when roaming
2154      * @param subId the unique SubscriptionInfo index in database
2155      * @return the number of records updated
2156      * @hide
2157      */
2158     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
setDataRoaming(int roaming, int subId)2159     public int setDataRoaming(int roaming, int subId) {
2160         if (VDBG) logd("[setDataRoaming]+ roaming:" + roaming + " subId:" + subId);
2161         return setSubscriptionPropertyHelper(subId, "setDataRoaming",
2162                 (iSub)->iSub.setDataRoaming(roaming, subId)
2163         );
2164     }
2165 
2166     /**
2167      * Get slotIndex associated with the subscription.
2168      *
2169      * @param subscriptionId the unique SubscriptionInfo index in database
2170      * @return slotIndex as a positive integer or {@link #INVALID_SIM_SLOT_INDEX} if the supplied
2171      * subscriptionId doesn't have an associated slot index.
2172      */
getSlotIndex(int subscriptionId)2173     public static int getSlotIndex(int subscriptionId) {
2174         return sGetSlotIndexCache.query(subscriptionId);
2175     }
2176 
2177     /**
2178      * Get an array of subscription ids for the specified logical SIM slot Index. The maximum size
2179      * of the array is 1. This API was mistakenly designed to return multiple subscription ids,
2180      * which is not possible in the current Android telephony architecture.
2181      *
2182      * @param slotIndex The logical SIM slot index.
2183      *
2184      * @return Subscription id of the active subscription on the specified logical SIM slot index.
2185      * If SIM is absent on the slot, a single element array of {@link #INVALID_SUBSCRIPTION_ID} will
2186      * be returned. {@code null} if the provided {@code slotIndex} is not valid.
2187      *
2188      * @deprecated Use {@link #getSubscriptionId(int)} instead.
2189      */
2190     @Deprecated
2191     @Nullable
getSubscriptionIds(int slotIndex)2192     public int[] getSubscriptionIds(int slotIndex) {
2193         if (!isValidSlotIndex(slotIndex)) {
2194             return null;
2195         }
2196         return new int[]{getSubscriptionId(slotIndex)};
2197     }
2198 
2199     /**
2200      * Get an array of subscription ids for the specified logical SIM slot Index. The maximum size
2201      * of the array is 1. This API was mistakenly designed to return multiple subscription ids,
2202      * which is not possible in the current Android telephony architecture.
2203      *
2204      * @param slotIndex The logical SIM slot index.
2205      *
2206      * @return Subscription id of the active subscription on the specified logical SIM slot index.
2207      * If SIM is absent on the slot, a single element array of {@link #INVALID_SUBSCRIPTION_ID} will
2208      * be returned. {@code null} if the provided {@code slotIndex} is not valid.
2209      *
2210      * @deprecated Use {@link #getSubscriptionId(int)} instead.
2211      * @hide
2212      */
getSubId(int slotIndex)2213     public static int[] getSubId(int slotIndex) {
2214         if (!isValidSlotIndex(slotIndex)) {
2215             return null;
2216         }
2217         return new int[]{getSubscriptionId(slotIndex)};
2218     }
2219 
2220     /**
2221      * Get the subscription id for specified logical SIM slot index.
2222      *
2223      * @param slotIndex The logical SIM slot index.
2224      * @return The subscription id. {@link #INVALID_SUBSCRIPTION_ID} if SIM is absent.
2225      */
getSubscriptionId(int slotIndex)2226     public static int getSubscriptionId(int slotIndex) {
2227         if (!isValidSlotIndex(slotIndex)) {
2228             return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2229         }
2230 
2231         return sGetSubIdCache.query(slotIndex);
2232     }
2233 
2234     /** @hide */
2235     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
getPhoneId(int subId)2236     public static int getPhoneId(int subId) {
2237         return sGetPhoneIdCache.query(subId);
2238     }
2239 
logd(String msg)2240     private static void logd(String msg) {
2241         Rlog.d(LOG_TAG, msg);
2242     }
2243 
loge(String msg)2244     private static void loge(String msg) {
2245         Rlog.e(LOG_TAG, msg);
2246     }
2247 
2248     /**
2249      * Returns the system's default subscription id.
2250      *
2251      * For a voice capable device, it will return getDefaultVoiceSubscriptionId.
2252      * For a data only device, it will return the getDefaultDataSubscriptionId.
2253      * May return an INVALID_SUBSCRIPTION_ID on error.
2254      *
2255      * @return the "system" default subscription id.
2256      */
getDefaultSubscriptionId()2257     public static int getDefaultSubscriptionId() {
2258         return sGetDefaultSubIdCache.query(null);
2259     }
2260 
2261     /**
2262      * Returns the system's default voice subscription id.
2263      *
2264      * On a data only device or on error, will return INVALID_SUBSCRIPTION_ID.
2265      *
2266      * @return the default voice subscription Id.
2267      */
getDefaultVoiceSubscriptionId()2268     public static int getDefaultVoiceSubscriptionId() {
2269         int subId = INVALID_SUBSCRIPTION_ID;
2270 
2271         try {
2272             ISub iSub = TelephonyManager.getSubscriptionService();
2273             if (iSub != null) {
2274                 subId = iSub.getDefaultVoiceSubId();
2275             }
2276         } catch (RemoteException ex) {
2277             // ignore it
2278         }
2279 
2280         if (VDBG) logd("getDefaultVoiceSubscriptionId, sub id = " + subId);
2281         return subId;
2282     }
2283 
2284     /**
2285      * Sets the system's default voice subscription id.
2286      *
2287      * On a data-only device, this is a no-op.
2288      *
2289      * May throw a {@link RuntimeException} if the provided subscription id is equal to
2290      * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}
2291      *
2292      * @param subscriptionId A valid subscription ID to set as the system default, or
2293      *                       {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}
2294      * @hide
2295      */
2296     @SystemApi
2297     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setDefaultVoiceSubscriptionId(int subscriptionId)2298     public void setDefaultVoiceSubscriptionId(int subscriptionId) {
2299         if (VDBG) logd("setDefaultVoiceSubId sub id = " + subscriptionId);
2300         try {
2301             ISub iSub = TelephonyManager.getSubscriptionService();
2302             if (iSub != null) {
2303                 iSub.setDefaultVoiceSubId(subscriptionId);
2304             }
2305         } catch (RemoteException ex) {
2306             // ignore it
2307         }
2308     }
2309 
2310     /**
2311      * Same as {@link #setDefaultVoiceSubscriptionId(int)}, but preserved for backwards
2312      * compatibility.
2313      * @hide
2314      */
setDefaultVoiceSubId(int subId)2315     public void setDefaultVoiceSubId(int subId) {
2316         setDefaultVoiceSubscriptionId(subId);
2317     }
2318 
2319     /**
2320      * Return the SubscriptionInfo for default voice subscription.
2321      *
2322      * Will return null on data only devices, or on error.
2323      *
2324      * @return the SubscriptionInfo for the default voice subscription.
2325      * @hide
2326      */
2327     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getDefaultVoiceSubscriptionInfo()2328     public SubscriptionInfo getDefaultVoiceSubscriptionInfo() {
2329         return getActiveSubscriptionInfo(getDefaultVoiceSubscriptionId());
2330     }
2331 
2332     /** @hide */
2333     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getDefaultVoicePhoneId()2334     public static int getDefaultVoicePhoneId() {
2335         return getPhoneId(getDefaultVoiceSubscriptionId());
2336     }
2337 
2338     /**
2339      * Returns the system's default SMS subscription id.
2340      *
2341      * On a data only device or on error, will return INVALID_SUBSCRIPTION_ID.
2342      *
2343      * @return the default SMS subscription Id.
2344      */
getDefaultSmsSubscriptionId()2345     public static int getDefaultSmsSubscriptionId() {
2346         return sGetDefaultSmsSubIdCache.query(null);
2347     }
2348 
2349     /**
2350      * Set the subscription which will be used by default for SMS, with the subscription which
2351      * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied
2352      * subscription ID is not usable (check with {@link #isUsableSubscriptionId(int)}).
2353      *
2354      * @param subscriptionId the supplied subscription ID
2355      *
2356      * @hide
2357      */
2358     @SystemApi
2359     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
setDefaultSmsSubId(int subscriptionId)2360     public void setDefaultSmsSubId(int subscriptionId) {
2361         if (VDBG) logd("setDefaultSmsSubId sub id = " + subscriptionId);
2362         try {
2363             ISub iSub = TelephonyManager.getSubscriptionService();
2364             if (iSub != null) {
2365                 iSub.setDefaultSmsSubId(subscriptionId);
2366             }
2367         } catch (RemoteException ex) {
2368             ex.rethrowFromSystemServer();
2369         }
2370     }
2371 
2372     /**
2373      * Returns the system's default data subscription id.
2374      *
2375      * On a voice only device or on error, will return INVALID_SUBSCRIPTION_ID.
2376      *
2377      * @return the default data subscription Id.
2378      */
getDefaultDataSubscriptionId()2379     public static int getDefaultDataSubscriptionId() {
2380         return sGetDefaultDataSubIdCache.query(null);
2381     }
2382 
2383     /**
2384      * Set the subscription which will be used by default for data, with the subscription which
2385      * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied
2386      * subscription ID is not usable (check with {@link #isUsableSubscriptionId(int)}).
2387      *
2388      * @param subscriptionId the supplied subscription ID
2389      *
2390      * @hide
2391      */
2392     @SystemApi
2393     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
setDefaultDataSubId(int subscriptionId)2394     public void setDefaultDataSubId(int subscriptionId) {
2395         if (VDBG) logd("setDataSubscription sub id = " + subscriptionId);
2396         try {
2397             ISub iSub = TelephonyManager.getSubscriptionService();
2398             if (iSub != null) {
2399                 iSub.setDefaultDataSubId(subscriptionId);
2400             }
2401         } catch (RemoteException ex) {
2402             // ignore it
2403         }
2404     }
2405 
2406     /**
2407      * Return the SubscriptionInfo for default data subscription.
2408      *
2409      * Will return null on voice only devices, or on error.
2410      *
2411      * @return the SubscriptionInfo for the default data subscription.
2412      * @hide
2413      */
2414     @UnsupportedAppUsage
getDefaultDataSubscriptionInfo()2415     public SubscriptionInfo getDefaultDataSubscriptionInfo() {
2416         return getActiveSubscriptionInfo(getDefaultDataSubscriptionId());
2417     }
2418 
2419     /**
2420      * Check if the supplied subscription ID is valid.
2421      *
2422      * <p>A valid subscription ID is not necessarily an active subscription ID
2423      * (see {@link #isActiveSubscriptionId(int)}) or an usable subscription ID
2424      * (see {@link #isUsableSubscriptionId(int)}). Unless specifically noted, subscription
2425      * APIs work with a valid subscription ID.
2426      *
2427      * @param subscriptionId The subscription ID.
2428      * @return {@code true} if the supplied subscriptionId is valid; {@code false} otherwise.
2429      */
isValidSubscriptionId(int subscriptionId)2430     public static boolean isValidSubscriptionId(int subscriptionId) {
2431         return subscriptionId > INVALID_SUBSCRIPTION_ID;
2432     }
2433 
2434     /**
2435      * Check if the supplied subscription ID is usable.
2436      *
2437      * <p>A usable subscription ID is a valid subscription ID, but not necessarily an active
2438      * subscription ID (see {@link #isActiveSubscriptionId(int)}). Some subscription APIs
2439      * require a usable subscription ID, and this is noted in their documentation; otherwise, a
2440      * subscription ID does not need to be usable for subscription functions, only valid.
2441      *
2442      * @param subscriptionId the subscription ID
2443      * @return {@code true} if the subscription ID is usable; {@code false} otherwise.
2444      */
isUsableSubscriptionId(int subscriptionId)2445     public static boolean isUsableSubscriptionId(int subscriptionId) {
2446         return isUsableSubIdValue(subscriptionId);
2447     }
2448 
2449     /**
2450      * @return true if subId is an usable subId value else false. A
2451      * usable subId means its neither a INVALID_SUBSCRIPTION_ID nor a DEFAULT_SUB_ID.
2452      * @hide
2453      */
2454     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
isUsableSubIdValue(int subId)2455     public static boolean isUsableSubIdValue(int subId) {
2456         return subId >= MIN_SUBSCRIPTION_ID_VALUE && subId <= MAX_SUBSCRIPTION_ID_VALUE;
2457     }
2458 
2459     /** @hide */
2460     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
isValidSlotIndex(int slotIndex)2461     public static boolean isValidSlotIndex(int slotIndex) {
2462         return slotIndex >= 0 && slotIndex < TelephonyManager.getDefault().getActiveModemCount();
2463     }
2464 
2465     /** @hide */
2466     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
isValidPhoneId(int phoneId)2467     public static boolean isValidPhoneId(int phoneId) {
2468         return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getActiveModemCount();
2469     }
2470 
2471     /** @hide */
2472     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
putPhoneIdAndSubIdExtra(Intent intent, int phoneId)2473     public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId) {
2474         int subId = SubscriptionManager.getSubscriptionId(phoneId);
2475         if (isValidSubscriptionId(subId)) {
2476             putPhoneIdAndSubIdExtra(intent, phoneId, subId);
2477         } else {
2478             logd("putPhoneIdAndSubIdExtra: no valid subs");
2479             intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
2480             intent.putExtra(EXTRA_SLOT_INDEX, phoneId);
2481         }
2482     }
2483 
2484     /** @hide */
2485     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
putPhoneIdAndSubIdExtra(Intent intent, int phoneId, int subId)2486     public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId, int subId) {
2487         if (VDBG) logd("putPhoneIdAndSubIdExtra: phoneId=" + phoneId + " subId=" + subId);
2488         intent.putExtra(EXTRA_SLOT_INDEX, phoneId);
2489         intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
2490         putSubscriptionIdExtra(intent, subId);
2491     }
2492 
2493     /**
2494      * Get visible subscription Id(s) of the currently active SIM(s).
2495      *
2496      * @return the list of subId's that are active,
2497      *         is never null but the length may be 0.
2498      * @hide
2499      */
2500     @SystemApi
2501     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
getActiveSubscriptionIdList()2502     public @NonNull int[] getActiveSubscriptionIdList() {
2503         return getActiveSubscriptionIdList(/* visibleOnly */ true);
2504     }
2505 
2506     /**
2507      * Get both hidden and visible subscription Id(s) of the currently active SIM(s).
2508      *
2509      * Hidden subscriptions refer to those are not meant visible to the users.
2510      * For example, an opportunistic subscription that is grouped with other
2511      * subscriptions should remain invisible to users as they are only functionally
2512      * supplementary to primary ones.
2513      *
2514      * @return the list of subId's that are active,
2515      *         is never null but the length may be 0.
2516      * @hide
2517      */
2518     @SystemApi
2519     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
getCompleteActiveSubscriptionIdList()2520     public @NonNull int[] getCompleteActiveSubscriptionIdList() {
2521         return getActiveSubscriptionIdList(/* visibleOnly */false);
2522     }
2523 
2524     /**
2525      * @return a non-null list of subId's that are active.
2526      *
2527      * @hide
2528      */
getActiveSubscriptionIdList(boolean visibleOnly)2529     public @NonNull int[] getActiveSubscriptionIdList(boolean visibleOnly) {
2530         try {
2531             ISub iSub = TelephonyManager.getSubscriptionService();
2532             if (iSub != null) {
2533                 int[] subId = iSub.getActiveSubIdList(visibleOnly);
2534                 if (subId != null) return subId;
2535             }
2536         } catch (RemoteException ex) {
2537             // ignore it
2538         }
2539 
2540         return new int[0];
2541     }
2542 
2543     /**
2544      * Returns true if the device is considered roaming on the current
2545      * network for a subscription.
2546      * <p>
2547      * Availability: Only when user registered to a network.
2548      *
2549      * @param subId The subscription ID
2550      * @return true if the network for the subscription is roaming, false otherwise
2551      */
isNetworkRoaming(int subId)2552     public boolean isNetworkRoaming(int subId) {
2553         final int phoneId = getPhoneId(subId);
2554         if (phoneId < 0) {
2555             // What else can we do?
2556             return false;
2557         }
2558         return TelephonyManager.getDefault().isNetworkRoaming(subId);
2559     }
2560 
2561     /**
2562      * Set a field in the subscription database. Note not all fields are supported.
2563      *
2564      * @param subscriptionId Subscription Id of Subscription.
2565      * @param columnName Column name in the database. Note not all fields are supported.
2566      * @param value Value to store in the database.
2567      *
2568      * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not
2569      * exposed.
2570      * @throws SecurityException if callers do not hold the required permission.
2571      *
2572      * @see android.provider.Telephony.SimInfo for all the columns.
2573      *
2574      * @hide
2575      */
2576     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setSubscriptionProperty(int subscriptionId, @NonNull String columnName, @NonNull String value)2577     public static void setSubscriptionProperty(int subscriptionId, @NonNull String columnName,
2578             @NonNull String value) {
2579         try {
2580             ISub iSub = TelephonyManager.getSubscriptionService();
2581             if (iSub != null) {
2582                 iSub.setSubscriptionProperty(subscriptionId, columnName, value);
2583             }
2584         } catch (RemoteException ex) {
2585             // ignore it
2586         }
2587     }
2588 
2589     /**
2590      * Serialize list of contacts uri to string
2591      * @hide
2592      */
serializeUriLists(List<Uri> uris)2593     public static String serializeUriLists(List<Uri> uris) {
2594         List<String> contacts = new ArrayList<>();
2595         for (Uri uri : uris) {
2596             contacts.add(uri.toString());
2597         }
2598         try {
2599             ByteArrayOutputStream bos = new ByteArrayOutputStream();
2600             ObjectOutputStream oos = new ObjectOutputStream(bos);
2601             oos.writeObject(contacts);
2602             oos.flush();
2603             return Base64.encodeToString(bos.toByteArray(), Base64.DEFAULT);
2604         } catch (IOException e) {
2605             logd("serializeUriLists IO exception");
2606         }
2607         return "";
2608     }
2609 
2610     /**
2611      * Get specific field in string format from the subscription info database.
2612      *
2613      * @param context The calling context.
2614      * @param subscriptionId Subscription id of the subscription.
2615      * @param columnName Column name in subscription database.
2616      *
2617      * @return Value in string format associated with {@code subscriptionId} and {@code columnName}
2618      * from the database. Empty string if the {@code subscriptionId} is invalid (for backward
2619      * compatible).
2620      *
2621      * @throws IllegalArgumentException if the field is not exposed.
2622      *
2623      * @see android.provider.Telephony.SimInfo for all the columns.
2624      *
2625      * @hide
2626      */
2627     @NonNull
2628     @RequiresPermission(anyOf = {
2629             Manifest.permission.READ_PHONE_STATE,
2630             Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
2631             "carrier privileges",
2632     })
getStringSubscriptionProperty(@onNull Context context, int subscriptionId, @NonNull String columnName)2633     private static String getStringSubscriptionProperty(@NonNull Context context,
2634             int subscriptionId, @NonNull String columnName) {
2635         String resultValue = null;
2636         try {
2637             ISub iSub = TelephonyManager.getSubscriptionService();
2638             if (iSub != null) {
2639                 resultValue = iSub.getSubscriptionProperty(subscriptionId, columnName,
2640                         context.getOpPackageName(), context.getAttributionTag());
2641             }
2642         } catch (RemoteException ex) {
2643             // ignore it
2644         }
2645         return TextUtils.emptyIfNull(resultValue);
2646     }
2647 
2648     /**
2649      * Get specific field in {@code boolean} format from the subscription info database.
2650      *
2651      * @param subscriptionId Subscription id of the subscription.
2652      * @param columnName Column name in subscription database.
2653      * @param defaultValue Default value in case not found or error.
2654      * @param context The calling context.
2655      *
2656      * @return Value in {@code boolean} format associated with {@code subscriptionId} and
2657      * {@code columnName} from the database, or {@code defaultValue} if not found or error.
2658      *
2659      * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not
2660      * exposed.
2661      *
2662      * @see android.provider.Telephony.SimInfo for all the columns.
2663      *
2664      * @hide
2665      */
2666     @RequiresPermission(anyOf = {
2667             Manifest.permission.READ_PHONE_STATE,
2668             Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
2669             "carrier privileges",
2670     })
getBooleanSubscriptionProperty(int subscriptionId, @NonNull String columnName, boolean defaultValue, @NonNull Context context)2671     public static boolean getBooleanSubscriptionProperty(int subscriptionId,
2672             @NonNull String columnName, boolean defaultValue, @NonNull Context context) {
2673         String result = getStringSubscriptionProperty(context, subscriptionId, columnName);
2674         if (!result.isEmpty()) {
2675             try {
2676                 return Integer.parseInt(result) == 1;
2677             } catch (NumberFormatException err) {
2678                 logd("getBooleanSubscriptionProperty NumberFormat exception");
2679             }
2680         }
2681         return defaultValue;
2682     }
2683 
2684     /**
2685      * Get specific field in {@code integer} format from the subscription info database.
2686      *
2687      * @param subscriptionId Subscription id of the subscription.
2688      * @param columnName Column name in subscription database.
2689      * @param defaultValue Default value in case not found or error.
2690      * @param context The calling context.
2691      *
2692      * @return Value in {@code integer} format associated with {@code subscriptionId} and
2693      * {@code columnName} from the database, or {@code defaultValue} if not found or error.
2694      *
2695      * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not
2696      * exposed.
2697      *
2698      * @see android.provider.Telephony.SimInfo for all the columns.
2699      *
2700      * @hide
2701      */
2702     @RequiresPermission(anyOf = {
2703             Manifest.permission.READ_PHONE_STATE,
2704             Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
2705             "carrier privileges",
2706     })
getIntegerSubscriptionProperty(int subscriptionId, @NonNull String columnName, int defaultValue, @NonNull Context context)2707     public static int getIntegerSubscriptionProperty(int subscriptionId, @NonNull String columnName,
2708             int defaultValue, @NonNull Context context) {
2709         String result = getStringSubscriptionProperty(context, subscriptionId, columnName);
2710         if (!result.isEmpty()) {
2711             try {
2712                 return Integer.parseInt(result);
2713             } catch (NumberFormatException err) {
2714                 logd("getIntegerSubscriptionProperty NumberFormat exception");
2715             }
2716         }
2717         return defaultValue;
2718     }
2719 
2720     /**
2721      * Get specific field in {@code long} format from the subscription info database.
2722      *
2723      * @param subscriptionId Subscription id of the subscription.
2724      * @param columnName Column name in subscription database.
2725      * @param defaultValue Default value in case not found or error.
2726      * @param context The calling context.
2727      *
2728      * @return Value in {@code long} format associated with {@code subscriptionId} and
2729      * {@code columnName} from the database, or {@code defaultValue} if not found or error.
2730      *
2731      * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not
2732      * exposed.
2733      *
2734      * @see android.provider.Telephony.SimInfo for all the columns.
2735      *
2736      * @hide
2737      */
2738     @RequiresPermission(anyOf = {
2739             Manifest.permission.READ_PHONE_STATE,
2740             Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
2741             "carrier privileges",
2742     })
getLongSubscriptionProperty(int subscriptionId, @NonNull String columnName, long defaultValue, @NonNull Context context)2743     public static long getLongSubscriptionProperty(int subscriptionId, @NonNull String columnName,
2744             long defaultValue, @NonNull Context context) {
2745         String result = getStringSubscriptionProperty(context, subscriptionId, columnName);
2746         if (!result.isEmpty()) {
2747             try {
2748                 return Long.parseLong(result);
2749             } catch (NumberFormatException err) {
2750                 logd("getLongSubscriptionProperty NumberFormat exception");
2751             }
2752         }
2753         return defaultValue;
2754     }
2755 
2756     /**
2757      * Returns the {@link Resources} from the given {@link Context} for the MCC/MNC associated with
2758      * the subscription. If the subscription ID is invalid, the base resources are returned instead.
2759      *
2760      * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
2761      *
2762      * @param context Context object
2763      * @param subId Subscription Id of Subscription whose resources are required
2764      * @return Resources associated with Subscription.
2765      * @hide
2766      */
2767     @NonNull
2768     @SystemApi
getResourcesForSubId(@onNull Context context, int subId)2769     public static Resources getResourcesForSubId(@NonNull Context context, int subId) {
2770         return getResourcesForSubId(context, subId, false);
2771     }
2772 
2773     /**
2774      * Returns the resources associated with Subscription.
2775      * @param context Context object
2776      * @param subId Subscription Id of Subscription who's resources are required
2777      * @param useRootLocale if root locale should be used. Localized locale is used if false.
2778      * @return Resources associated with Subscription.
2779      * @hide
2780      */
2781     @NonNull
getResourcesForSubId(Context context, int subId, boolean useRootLocale)2782     public static Resources getResourcesForSubId(Context context, int subId,
2783             boolean useRootLocale) {
2784         // Check if resources for this context and subId already exist in the resource cache.
2785         // Resources that use the root locale are not cached.
2786         Pair<Context, Integer> cacheKey = null;
2787         if (isValidSubscriptionId(subId) && !useRootLocale) {
2788             cacheKey = Pair.create(context, subId);
2789             if (sResourcesCache.containsKey(cacheKey)) {
2790                 // Cache hit. Use cached Resources.
2791                 return sResourcesCache.get(cacheKey);
2792             }
2793         }
2794 
2795         final SubscriptionInfo subInfo =
2796                 SubscriptionManager.from(context).getActiveSubscriptionInfo(subId);
2797 
2798         Configuration overrideConfig = new Configuration();
2799         if (subInfo != null) {
2800             overrideConfig.mcc = subInfo.getMcc();
2801             overrideConfig.mnc = subInfo.getMnc();
2802             if (overrideConfig.mnc == 0) {
2803                 overrideConfig.mnc = Configuration.MNC_ZERO;
2804                 cacheKey = null;
2805             }
2806         } else {
2807             cacheKey = null;
2808         }
2809 
2810         if (useRootLocale) {
2811             overrideConfig.setLocale(Locale.ROOT);
2812         }
2813 
2814         // Create new context with new configuration so that we can avoid modifying the passed in
2815         // context.
2816         // Note that if the original context configuration changes, the resources here will also
2817         // change for all values except those overridden by newConfig (e.g. if the device has an
2818         // orientation change).
2819         Context newContext = context.createConfigurationContext(overrideConfig);
2820         Resources res = newContext.getResources();
2821 
2822         if (cacheKey != null) {
2823             // Save the newly created Resources in the resource cache.
2824             sResourcesCache.put(cacheKey, res);
2825         }
2826         return res;
2827     }
2828 
2829     /**
2830      * Checks if the supplied subscription ID corresponds to a subscription which is actively in
2831      * use on the device. An active subscription ID is a valid and usable subscription ID.
2832      *
2833      * @param subscriptionId the subscription ID.
2834      * @return {@code true} if the supplied subscription ID corresponds to an active subscription;
2835      * {@code false} if it does not correspond to an active subscription; or throw a
2836      * SecurityException if the caller hasn't got the right permission.
2837      */
2838     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
isActiveSubscriptionId(int subscriptionId)2839     public boolean isActiveSubscriptionId(int subscriptionId) {
2840         return isActiveSubId(subscriptionId);
2841     }
2842 
2843     /**
2844      * @return true if the sub ID is active. i.e. The sub ID corresponds to a known subscription
2845      * and the SIM providing the subscription is present in a slot and in "LOADED" state.
2846      * @hide
2847      */
2848     @UnsupportedAppUsage
isActiveSubId(int subId)2849     public boolean isActiveSubId(int subId) {
2850         try {
2851             ISub iSub = TelephonyManager.getSubscriptionService();
2852             if (iSub != null) {
2853                 return iSub.isActiveSubId(subId, mContext.getOpPackageName(),
2854                         mContext.getAttributionTag());
2855             }
2856         } catch (RemoteException ex) {
2857         }
2858         return false;
2859     }
2860 
2861     /**
2862      * Get the description of the billing relationship plan between a carrier
2863      * and a specific subscriber.
2864      * <p>
2865      * This method is only accessible to the following narrow set of apps:
2866      * <ul>
2867      * <li>The carrier app for this subscriberId, as determined by
2868      * {@link TelephonyManager#hasCarrierPrivileges()}.
2869      * <li>The carrier app explicitly delegated access through
2870      * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2871      * </ul>
2872      *
2873      * @param subId the subscriber this relationship applies to
2874      * @throws SecurityException if the caller doesn't meet the requirements
2875      *             outlined above.
2876      */
getSubscriptionPlans(int subId)2877     public @NonNull List<SubscriptionPlan> getSubscriptionPlans(int subId) {
2878         SubscriptionPlan[] subscriptionPlans =
2879                 getNetworkPolicyManager().getSubscriptionPlans(subId, mContext.getOpPackageName());
2880         return subscriptionPlans == null
2881                 ? Collections.emptyList() : Arrays.asList(subscriptionPlans);
2882     }
2883 
2884     /**
2885      * Set the description of the billing relationship plan between a carrier
2886      * and a specific subscriber.
2887      * <p>
2888      * This method is only accessible to the following narrow set of apps:
2889      * <ul>
2890      * <li>The carrier app for this subscriberId, as determined by
2891      * {@link TelephonyManager#hasCarrierPrivileges()}.
2892      * <li>The carrier app explicitly delegated access through
2893      * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2894      * </ul>
2895      *
2896      * @param subId the subscriber this relationship applies to. An empty list
2897      *            may be sent to clear any existing plans.
2898      * @param plans the list of plans. The first plan is always the primary and
2899      *            most important plan. Any additional plans are secondary and
2900      *            may not be displayed or used by decision making logic.
2901      * @throws SecurityException if the caller doesn't meet the requirements
2902      *             outlined above.
2903      * @throws IllegalArgumentException if plans don't meet the requirements
2904      *             defined in {@link SubscriptionPlan}.
2905      * @deprecated use {@link #setSubscriptionPlans(int, List, long)} instead.
2906      */
2907     @Deprecated
setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans)2908     public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans) {
2909         setSubscriptionPlans(subId, plans, 0);
2910     }
2911 
2912     /**
2913      * Set the description of the billing relationship plan between a carrier
2914      * and a specific subscriber.
2915      * <p>
2916      * This method is only accessible to the following narrow set of apps:
2917      * <ul>
2918      * <li>The carrier app for this subscriberId, as determined by
2919      * {@link TelephonyManager#hasCarrierPrivileges()}.
2920      * <li>The carrier app explicitly delegated access through
2921      * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2922      * </ul>
2923      *
2924      * @param subId the subscriber this relationship applies to. An empty list
2925      *            may be sent to clear any existing plans.
2926      * @param plans the list of plans. The first plan is always the primary and
2927      *            most important plan. Any additional plans are secondary and
2928      *            may not be displayed or used by decision making logic.
2929      * @param expirationDurationMillis the duration after which the subscription plans
2930      *            will be automatically cleared, or {@code 0} to leave the plans until
2931      *            explicitly cleared, or the next reboot, whichever happens first.
2932      * @throws SecurityException if the caller doesn't meet the requirements
2933      *             outlined above.
2934      * @throws IllegalArgumentException if plans don't meet the requirements
2935      *             defined in {@link SubscriptionPlan}.
2936      */
setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans, @DurationMillisLong long expirationDurationMillis)2937     public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans,
2938             @DurationMillisLong long expirationDurationMillis) {
2939         getNetworkPolicyManager().setSubscriptionPlans(subId,
2940                 plans.toArray(new SubscriptionPlan[0]), expirationDurationMillis,
2941                 mContext.getOpPackageName());
2942     }
2943 
2944     /**
2945      * Temporarily override the billing relationship plan between a carrier and
2946      * a specific subscriber to be considered unmetered. This will be reflected
2947      * to apps via {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED}.
2948      * <p>
2949      * This method is only accessible to the following narrow set of apps:
2950      * <ul>
2951      * <li>The carrier app for this subscriberId, as determined by
2952      * {@link TelephonyManager#hasCarrierPrivileges()}.
2953      * <li>The carrier app explicitly delegated access through
2954      * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2955      * </ul>
2956      *
2957      * @param subId the subscriber this override applies to.
2958      * @param overrideUnmetered set if the billing relationship should be
2959      *            considered unmetered.
2960      * @param expirationDurationMillis the duration after which the requested override
2961      *            will be automatically cleared, or {@code 0} to leave in the
2962      *            requested state until explicitly cleared, or the next reboot,
2963      *            whichever happens first.
2964      * @throws SecurityException if the caller doesn't meet the requirements
2965      *            outlined above.
2966      */
setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered, @DurationMillisLong long expirationDurationMillis)2967     public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered,
2968             @DurationMillisLong long expirationDurationMillis) {
2969         setSubscriptionOverrideUnmetered(subId, overrideUnmetered,
2970                 TelephonyManager.getAllNetworkTypes(), expirationDurationMillis);
2971     }
2972 
2973     /**
2974      * Temporarily override the billing relationship plan between a carrier and
2975      * a specific subscriber to be considered unmetered. This will be reflected
2976      * to apps via {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED}.
2977      * <p>
2978      * This method is only accessible to the following narrow set of apps:
2979      * <ul>
2980      * <li>The carrier app for this subscriberId, as determined by
2981      * {@link TelephonyManager#hasCarrierPrivileges()}.
2982      * <li>The carrier app explicitly delegated access through
2983      * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2984      * </ul>
2985      *
2986      * @param subId the subscriber this override applies to.
2987      * @param overrideUnmetered set if the billing relationship should be
2988      *            considered unmetered.
2989      * @param networkTypes the network types this override applies to. If no
2990      *            network types are specified, override values will be ignored.
2991      * @param expirationDurationMillis the duration after which the requested override
2992      *            will be automatically cleared, or {@code 0} to leave in the
2993      *            requested state until explicitly cleared, or the next reboot,
2994      *            whichever happens first.
2995      * @throws SecurityException if the caller doesn't meet the requirements
2996      *            outlined above.
2997      */
setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered, @NonNull @Annotation.NetworkType int[] networkTypes, @DurationMillisLong long expirationDurationMillis)2998     public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered,
2999             @NonNull @Annotation.NetworkType int[] networkTypes,
3000             @DurationMillisLong long expirationDurationMillis) {
3001         final int overrideValue = overrideUnmetered ? SUBSCRIPTION_OVERRIDE_UNMETERED : 0;
3002         getNetworkPolicyManager().setSubscriptionOverride(subId, SUBSCRIPTION_OVERRIDE_UNMETERED,
3003                 overrideValue, networkTypes, expirationDurationMillis, mContext.getOpPackageName());
3004     }
3005 
3006     /**
3007      * Temporarily override the billing relationship plan between a carrier and
3008      * a specific subscriber to be considered congested. This will cause the
3009      * device to delay certain network requests when possible, such as developer
3010      * jobs that are willing to run in a flexible time window.
3011      * <p>
3012      * This method is only accessible to the following narrow set of apps:
3013      * <ul>
3014      * <li>The carrier app for this subscriberId, as determined by
3015      * {@link TelephonyManager#hasCarrierPrivileges()}.
3016      * <li>The carrier app explicitly delegated access through
3017      * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
3018      * </ul>
3019      *
3020      * @param subId the subscriber this override applies to.
3021      * @param overrideCongested set if the subscription should be considered
3022      *            congested.
3023      * @param expirationDurationMillis the duration after which the requested override
3024      *            will be automatically cleared, or {@code 0} to leave in the
3025      *            requested state until explicitly cleared, or the next reboot,
3026      *            whichever happens first.
3027      * @throws SecurityException if the caller doesn't meet the requirements
3028      *            outlined above.
3029      */
setSubscriptionOverrideCongested(int subId, boolean overrideCongested, @DurationMillisLong long expirationDurationMillis)3030     public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested,
3031             @DurationMillisLong long expirationDurationMillis) {
3032         setSubscriptionOverrideCongested(subId, overrideCongested,
3033                 TelephonyManager.getAllNetworkTypes(), expirationDurationMillis);
3034     }
3035 
3036     /**
3037      * Temporarily override the billing relationship plan between a carrier and
3038      * a specific subscriber to be considered congested. This will cause the
3039      * device to delay certain network requests when possible, such as developer
3040      * jobs that are willing to run in a flexible time window.
3041      * <p>
3042      * This method is only accessible to the following narrow set of apps:
3043      * <ul>
3044      * <li>The carrier app for this subscriberId, as determined by
3045      * {@link TelephonyManager#hasCarrierPrivileges()}.
3046      * <li>The carrier app explicitly delegated access through
3047      * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
3048      * </ul>
3049      *
3050      * @param subId the subscriber this override applies to.
3051      * @param overrideCongested set if the subscription should be considered congested.
3052      * @param networkTypes the network types this override applies to. If no network types are
3053      * specified, override values will be ignored.
3054      * @param expirationDurationMillis the duration after which the requested override
3055      * will be automatically cleared, or {@code 0} to leave in the requested state until explicitly
3056      * cleared, or the next reboot, whichever happens first.
3057      *
3058      * @throws SecurityException if the caller doesn't meet the requirements outlined above.
3059      */
setSubscriptionOverrideCongested(int subId, boolean overrideCongested, @NonNull @Annotation.NetworkType int[] networkTypes, @DurationMillisLong long expirationDurationMillis)3060     public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested,
3061             @NonNull @Annotation.NetworkType int[] networkTypes,
3062             @DurationMillisLong long expirationDurationMillis) {
3063         final int overrideValue = overrideCongested ? SUBSCRIPTION_OVERRIDE_CONGESTED : 0;
3064         getNetworkPolicyManager().setSubscriptionOverride(subId, SUBSCRIPTION_OVERRIDE_CONGESTED,
3065                 overrideValue, networkTypes, expirationDurationMillis, mContext.getOpPackageName());
3066     }
3067 
3068     /**
3069      * Checks whether the app with the given context is authorized to manage the given subscription
3070      * according to its metadata.
3071      *
3072      * Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded} returns
3073      * true). To check for permissions for non-embedded subscription as well,
3074      * see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}.
3075      *
3076      * @param info The subscription to check.
3077      * @return whether the app is authorized to manage this subscription per its metadata.
3078      * @see android.telephony.TelephonyManager#hasCarrierPrivileges
3079      */
canManageSubscription(SubscriptionInfo info)3080     public boolean canManageSubscription(SubscriptionInfo info) {
3081         return canManageSubscription(info, mContext.getPackageName());
3082     }
3083 
3084     /**
3085      * Checks whether the given app is authorized to manage the given subscription. An app can only
3086      * be authorized if it is included in the {@link android.telephony.UiccAccessRule} of the
3087      * {@link android.telephony.SubscriptionInfo} with the access status.
3088      *
3089      * Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded} returns
3090      * true). To check for permissions for non-embedded subscription as well,
3091      * see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}.
3092      *
3093      * @param info The subscription to check.
3094      * @param packageName Package name of the app to check.
3095      *
3096      * @return whether the app is authorized to manage this subscription per its access rules.
3097      * @see android.telephony.TelephonyManager#hasCarrierPrivileges
3098      * @hide
3099      */
3100     @SystemApi
canManageSubscription(@onNull SubscriptionInfo info, @NonNull String packageName)3101     public boolean canManageSubscription(@NonNull SubscriptionInfo info,
3102             @NonNull String packageName) {
3103         if (info == null || info.getAccessRules() == null || packageName == null) {
3104             return false;
3105         }
3106         PackageManager packageManager = mContext.getPackageManager();
3107         PackageInfo packageInfo;
3108         try {
3109             packageInfo = packageManager.getPackageInfo(packageName,
3110                 PackageManager.GET_SIGNING_CERTIFICATES);
3111         } catch (PackageManager.NameNotFoundException e) {
3112             logd("Unknown package: " + packageName);
3113             return false;
3114         }
3115         for (UiccAccessRule rule : info.getAccessRules()) {
3116             if (rule.getCarrierPrivilegeStatus(packageInfo)
3117                     == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
3118                 return true;
3119             }
3120         }
3121         return false;
3122     }
3123 
3124     /**
3125      * Set which subscription is preferred for cellular data.
3126      * It's also usually the subscription we set up internet connection on.
3127      *
3128      * PreferredData overwrites user setting of default data subscription. And it's used
3129      * by AlternativeNetworkService or carrier apps to switch primary and CBRS
3130      * subscription dynamically in multi-SIM devices.
3131      *
3132      * @param subId which subscription is preferred to for cellular data. If it's
3133      *              {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}, it means
3134      *              it's unset and {@link SubscriptionManager#getDefaultDataSubscriptionId()}
3135      *              is used to determine which modem is preferred.
3136      * @param needValidation whether Telephony will wait until the network is validated by
3137      *              connectivity service before switching data to it. More details see
3138      *              {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED}.
3139      * @param executor The executor of where the callback will execute.
3140      * @param callback Callback will be triggered once it succeeds or failed.
3141      *                 Pass null if don't care about the result.
3142      *
3143      * @throws IllegalStateException when subscription manager service is not available.
3144      * @throws SecurityException when clients do not have MODIFY_PHONE_STATE permission.
3145      * @hide
3146      */
3147     @SystemApi
3148     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
setPreferredDataSubscriptionId(int subId, boolean needValidation, @Nullable @CallbackExecutor Executor executor, @Nullable @TelephonyManager.SetOpportunisticSubscriptionResult Consumer<Integer> callback)3149     public void setPreferredDataSubscriptionId(int subId, boolean needValidation,
3150             @Nullable @CallbackExecutor Executor executor, @Nullable
3151             @TelephonyManager.SetOpportunisticSubscriptionResult Consumer<Integer> callback) {
3152         if (VDBG) logd("[setPreferredDataSubscriptionId]+ subId:" + subId);
3153         try {
3154             ISub iSub = TelephonyManager.getSubscriptionService();
3155             if (iSub == null) {
3156                 throw new IllegalStateException("subscription manager service is null.");
3157             }
3158 
3159             ISetOpportunisticDataCallback callbackStub = new ISetOpportunisticDataCallback.Stub() {
3160                 @Override
3161                 public void onComplete(int result) {
3162                     if (executor == null || callback == null) {
3163                         return;
3164                     }
3165                     final long identity = Binder.clearCallingIdentity();
3166                     try {
3167                         executor.execute(() -> {
3168                             callback.accept(result);
3169                         });
3170                     } finally {
3171                         Binder.restoreCallingIdentity(identity);
3172                     }
3173                 }
3174             };
3175             iSub.setPreferredDataSubscriptionId(subId, needValidation, callbackStub);
3176         } catch (RemoteException ex) {
3177             loge("setPreferredDataSubscriptionId RemoteException=" + ex);
3178             ex.rethrowFromSystemServer();
3179         }
3180     }
3181 
3182     /**
3183      * Get which subscription is preferred for cellular data.
3184      * It's also usually the subscription we set up internet connection on.
3185      *
3186      * PreferredData overwrites user setting of default data subscription. And it's used
3187      * by AlternativeNetworkService or carrier apps to switch primary and CBRS
3188      * subscription dynamically in multi-SIM devices.
3189      *
3190      * @return preferred subscription id for cellular data. {@link DEFAULT_SUBSCRIPTION_ID} if
3191      * there's no prefered subscription.
3192      *
3193      * @hide
3194      *
3195      */
3196     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
getPreferredDataSubscriptionId()3197     public int getPreferredDataSubscriptionId() {
3198         int preferredSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
3199         try {
3200             ISub iSub = TelephonyManager.getSubscriptionService();
3201             if (iSub != null) {
3202                 preferredSubId = iSub.getPreferredDataSubscriptionId();
3203             }
3204         } catch (RemoteException ex) {
3205             // ignore it
3206         }
3207 
3208         return preferredSubId;
3209     }
3210 
3211     /**
3212      * Return opportunistic subscriptions that can be visible to the caller.
3213      * Opportunistic subscriptions are for opportunistic networks, which are cellular
3214      * networks with limited capabilities and coverage, for example, CBRS.
3215      *
3216      * <p>Requires Permission:
3217      * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
3218      * or that the calling app has carrier privileges (see
3219      * {@link TelephonyManager#hasCarrierPrivileges}).
3220      *
3221      * @return the list of opportunistic subscription info. If none exists, an empty list.
3222      */
3223     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
3224     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
getOpportunisticSubscriptions()3225     public @NonNull List<SubscriptionInfo> getOpportunisticSubscriptions() {
3226         String contextPkg = mContext != null ? mContext.getOpPackageName() : "<unknown>";
3227         String contextAttributionTag = mContext != null ? mContext.getAttributionTag() : null;
3228         List<SubscriptionInfo> subInfoList = null;
3229 
3230         try {
3231             ISub iSub = TelephonyManager.getSubscriptionService();
3232             if (iSub != null) {
3233                 subInfoList = iSub.getOpportunisticSubscriptions(contextPkg,
3234                         contextAttributionTag);
3235             }
3236         } catch (RemoteException ex) {
3237             // ignore it
3238         }
3239 
3240         if (subInfoList == null) {
3241             subInfoList = new ArrayList<>();
3242         }
3243 
3244         return subInfoList;
3245     }
3246 
3247     /**
3248      * Switch to a certain subscription
3249      *
3250      *  @param subId sub id
3251      *  @param callbackIntent pending intent that will be sent after operation is done.
3252      *
3253      *  @deprecated this API is a duplicate of {@link EuiccManager#switchToSubscription(int,
3254      *  PendingIntent)} and does not support Multiple Enabled Profile(MEP). Apps should use
3255      *  {@link EuiccManager#switchToSubscription(int, PendingIntent)} or
3256      *  {@link EuiccManager#switchToSubscription(int, int, PendingIntent)} instead.
3257      */
3258     @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
3259     @Deprecated
switchToSubscription(int subId, @NonNull PendingIntent callbackIntent)3260     public void switchToSubscription(int subId, @NonNull PendingIntent callbackIntent) {
3261         Preconditions.checkNotNull(callbackIntent, "callbackIntent cannot be null");
3262         EuiccManager euiccManager = new EuiccManager(mContext);
3263         euiccManager.switchToSubscription(subId, callbackIntent);
3264     }
3265 
3266     /**
3267      * Set whether a subscription is opportunistic, that is, whether the network it connects
3268      * to has limited coverage. For example, CBRS. Setting a subscription opportunistic has
3269      * following impacts:
3270      *  1) Even if it's active, it will be dormant most of the time. The modem will not try
3271      *     to scan or camp until it knows an available network is nearby to save power.
3272      *  2) Telephony relies on system app or carrier input to notify nearby available networks.
3273      *     See {@link TelephonyManager#updateAvailableNetworks(List, Executor, Consumer)}
3274      *     for more information.
3275      *  3) In multi-SIM devices, when the network is nearby and camped, system may automatically
3276      *     switch internet data between it and default data subscription, based on carrier
3277      *     recommendation and its signal strength and metered-ness, etc.
3278      *
3279      *
3280      * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE} or carrier
3281      * privilege permission of the subscription.
3282      *
3283      * @param opportunistic whether it’s opportunistic subscription.
3284      * @param subId the unique SubscriptionInfo index in database
3285      * @return {@code true} if the operation is succeed, {@code false} otherwise.
3286      */
3287     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
3288     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
setOpportunistic(boolean opportunistic, int subId)3289     public boolean setOpportunistic(boolean opportunistic, int subId) {
3290         if (VDBG) logd("[setOpportunistic]+ opportunistic:" + opportunistic + " subId:" + subId);
3291         return setSubscriptionPropertyHelper(subId, "setOpportunistic",
3292                 (iSub)-> iSub.setOpportunistic(
3293                         opportunistic, subId, mContext.getOpPackageName())) == 1;
3294     }
3295 
3296     /**
3297      * Inform SubscriptionManager that subscriptions in the list are bundled
3298      * as a group. It can be multiple primary (non-opportunistic) subscriptions,
3299      * or one or more primary plus one or more opportunistic subscriptions.
3300      *
3301      * This API will always create a new immutable group and assign group UUID to all the
3302      * subscriptions, regardless whether they are in a group already or not.
3303      *
3304      * Grouped subscriptions will have below behaviors:
3305      * 1) They will share the same user settings.
3306      * 2) The opportunistic subscriptions in the group is considered invisible and will not
3307      *    return from {@link #getActiveSubscriptionInfoList()}, unless caller has carrier
3308      *    privilege permission of the subscriptions.
3309      * 3) The opportunistic subscriptions in the group can't be active by itself. If all other
3310      *    non-opportunistic ones are deactivated (unplugged or disabled in Settings),
3311      *    the opportunistic ones will be deactivated automatically.
3312      *
3313      * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
3314      * permission or had carrier privilege permission on the subscriptions:
3315      * {@link TelephonyManager#hasCarrierPrivileges()} or
3316      * {@link #canManageSubscription(SubscriptionInfo)}
3317      *
3318      * @throws SecurityException if the caller doesn't meet the requirements
3319      *             outlined above.
3320      * @throws IllegalArgumentException if any of the subscriptions in the list doesn't exist.
3321      * @throws IllegalStateException if Telephony service is in bad state.
3322      *
3323      * @param subIdList list of subId that will be in the same group
3324      * @return groupUUID a UUID assigned to the subscription group.
3325      *
3326      */
3327     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
3328     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
createSubscriptionGroup(@onNull List<Integer> subIdList)3329     public @NonNull ParcelUuid createSubscriptionGroup(@NonNull List<Integer> subIdList) {
3330         Preconditions.checkNotNull(subIdList, "can't create group for null subId list");
3331         String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
3332         if (VDBG) {
3333             logd("[createSubscriptionGroup]");
3334         }
3335 
3336         ParcelUuid groupUuid = null;
3337         int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray();
3338         try {
3339             ISub iSub = TelephonyManager.getSubscriptionService();
3340             if (iSub != null) {
3341                 groupUuid = iSub.createSubscriptionGroup(subIdArray, pkgForDebug);
3342             } else {
3343                 if (!isSystemProcess()) {
3344                     throw new IllegalStateException("telephony service is null.");
3345                 }
3346             }
3347         } catch (RemoteException ex) {
3348             loge("createSubscriptionGroup RemoteException " + ex);
3349             if (!isSystemProcess()) {
3350                 ex.rethrowAsRuntimeException();
3351             }
3352         }
3353 
3354         return groupUuid;
3355     }
3356 
3357     /**
3358      * Add a list of subscriptions into a group.
3359      * See {@link #createSubscriptionGroup(List)} for more details.
3360      *
3361      * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
3362      * permission or had carrier privilege permission on the subscriptions:
3363      * {@link TelephonyManager#hasCarrierPrivileges()} or
3364      * {@link #canManageSubscription(SubscriptionInfo)}
3365      *
3366      * @throws SecurityException if the caller doesn't meet the requirements
3367      *             outlined above.
3368      * @throws IllegalArgumentException if the some subscriptions in the list doesn't exist.
3369      * @throws IllegalStateException if Telephony service is in bad state.
3370      *
3371      * @param subIdList list of subId that need adding into the group
3372      * @param groupUuid the groupUuid the subscriptions are being added to.
3373      *
3374      */
3375     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
3376     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
addSubscriptionsIntoGroup(@onNull List<Integer> subIdList, @NonNull ParcelUuid groupUuid)3377     public void addSubscriptionsIntoGroup(@NonNull List<Integer> subIdList,
3378             @NonNull ParcelUuid groupUuid) {
3379         Preconditions.checkNotNull(subIdList, "subIdList can't be null.");
3380         Preconditions.checkNotNull(groupUuid, "groupUuid can't be null.");
3381         String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
3382         if (VDBG) {
3383             logd("[addSubscriptionsIntoGroup]");
3384         }
3385 
3386         int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray();
3387 
3388         try {
3389             ISub iSub = TelephonyManager.getSubscriptionService();
3390             if (iSub != null) {
3391                 iSub.addSubscriptionsIntoGroup(subIdArray, groupUuid, pkgForDebug);
3392             } else {
3393                 if (!isSystemProcess()) {
3394                     throw new IllegalStateException("telephony service is null.");
3395                 }
3396             }
3397         } catch (RemoteException ex) {
3398             loge("addSubscriptionsIntoGroup RemoteException " + ex);
3399             if (!isSystemProcess()) {
3400                 ex.rethrowAsRuntimeException();
3401             }
3402         }
3403     }
3404 
isSystemProcess()3405     private boolean isSystemProcess() {
3406         return Process.myUid() == Process.SYSTEM_UID;
3407     }
3408 
3409     /**
3410      * Remove a list of subscriptions from their subscription group.
3411      *
3412      * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
3413      * permission or has carrier privilege permission on all of the subscriptions provided in
3414      * {@code subIdList}.
3415      *
3416      * @param subIdList list of subId that need removing from their groups.
3417      * @param groupUuid The UUID of the subscription group.
3418      *
3419      * @throws SecurityException if the caller doesn't meet the requirements outlined above.
3420      * @throws IllegalArgumentException if the some subscriptions in the list doesn't belong the
3421      * specified group.
3422      * @throws IllegalStateException if Telephony service is in bad state.
3423      *
3424      * @see #createSubscriptionGroup(List)
3425      */
3426     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
3427     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
removeSubscriptionsFromGroup(@onNull List<Integer> subIdList, @NonNull ParcelUuid groupUuid)3428     public void removeSubscriptionsFromGroup(@NonNull List<Integer> subIdList,
3429             @NonNull ParcelUuid groupUuid) {
3430         Preconditions.checkNotNull(subIdList, "subIdList can't be null.");
3431         Preconditions.checkNotNull(groupUuid, "groupUuid can't be null.");
3432         String callingPackage = mContext != null ? mContext.getOpPackageName() : "<unknown>";
3433         if (VDBG) {
3434             logd("[removeSubscriptionsFromGroup]");
3435         }
3436 
3437         int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray();
3438 
3439         try {
3440             ISub iSub = TelephonyManager.getSubscriptionService();
3441             if (iSub != null) {
3442                 iSub.removeSubscriptionsFromGroup(subIdArray, groupUuid, callingPackage);
3443             } else {
3444                 if (!isSystemProcess()) {
3445                     throw new IllegalStateException("telephony service is null.");
3446                 }
3447             }
3448         } catch (RemoteException ex) {
3449             loge("removeSubscriptionsFromGroup RemoteException " + ex);
3450             if (!isSystemProcess()) {
3451                 ex.rethrowAsRuntimeException();
3452             }
3453         }
3454     }
3455 
3456     /**
3457      * Get subscriptionInfo list of subscriptions that are in the same group of given subId.
3458      *
3459      * Caller must have {@link android.Manifest.permission#READ_PHONE_STATE}
3460      * or carrier privilege permission on the subscription.
3461      * {@link TelephonyManager#hasCarrierPrivileges()}
3462      *
3463      * <p>Starting with API level 33, the caller also needs permission to access device identifiers
3464      * to get the list of subscriptions associated with a group UUID.
3465      * This method can be invoked if one of the following requirements is met:
3466      * <ul>
3467      *     <li>If the app has carrier privilege permission.
3468      *     {@link TelephonyManager#hasCarrierPrivileges()}
3469      *     <li>If the app has {@link android.Manifest.permission#READ_PHONE_STATE} permission and
3470      *     access to device identifiers.
3471      * </ul>
3472      *
3473      * @throws IllegalStateException if Telephony service is in bad state.
3474      * @throws SecurityException if the caller doesn't meet the requirements
3475      *             outlined above.
3476      *
3477      * @param groupUuid of which list of subInfo will be returned.
3478      * @return list of subscriptionInfo that belong to the same group, including the given
3479      * subscription itself. It will return an empty list if no subscription belongs to the group.
3480      */
3481     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
3482     @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
getSubscriptionsInGroup(@onNull ParcelUuid groupUuid)3483     public @NonNull List<SubscriptionInfo> getSubscriptionsInGroup(@NonNull ParcelUuid groupUuid) {
3484         Preconditions.checkNotNull(groupUuid, "groupUuid can't be null");
3485         String contextPkg = mContext != null ? mContext.getOpPackageName() : "<unknown>";
3486         String contextAttributionTag = mContext != null ? mContext.getAttributionTag() : null;
3487         if (VDBG) {
3488             logd("[getSubscriptionsInGroup]+ groupUuid:" + groupUuid);
3489         }
3490 
3491         List<SubscriptionInfo> result = null;
3492         try {
3493             ISub iSub = TelephonyManager.getSubscriptionService();
3494             if (iSub != null) {
3495                 result = iSub.getSubscriptionsInGroup(groupUuid, contextPkg,
3496                         contextAttributionTag);
3497             } else {
3498                 if (!isSystemProcess()) {
3499                     throw new IllegalStateException("telephony service is null.");
3500                 }
3501             }
3502         } catch (RemoteException ex) {
3503             loge("removeSubscriptionsFromGroup RemoteException " + ex);
3504             if (!isSystemProcess()) {
3505                 ex.rethrowAsRuntimeException();
3506             }
3507         }
3508 
3509         return result;
3510     }
3511 
3512     /**
3513      * Whether a subscription is visible to API caller. If it's a bundled opportunistic
3514      * subscription, it should be hidden anywhere in Settings, dialer, status bar etc.
3515      * Exception is if caller owns carrier privilege, in which case they will
3516      * want to see their own hidden subscriptions.
3517      *
3518      * @param info the subscriptionInfo to check against.
3519      *
3520      * @return {@code true} if this subscription should be visible to the API caller.
3521      *
3522      * @hide
3523      */
isSubscriptionVisible(SubscriptionInfo info)3524     public boolean isSubscriptionVisible(SubscriptionInfo info) {
3525         if (info == null) return false;
3526         // If subscription is NOT grouped opportunistic subscription, it's visible.
3527         if (info.getGroupUuid() == null || !info.isOpportunistic()) return true;
3528 
3529         // If the caller is the carrier app and owns the subscription, it should be visible
3530         // to the caller.
3531         boolean hasCarrierPrivilegePermission = TelephonyManager.from(mContext)
3532                 .hasCarrierPrivileges(info.getSubscriptionId())
3533                 || canManageSubscription(info);
3534         return hasCarrierPrivilegePermission;
3535     }
3536 
3537     /**
3538      * Return a list of subscriptions that are available and visible to the user.
3539      * Used by Settings app to show a list of subscriptions for user to pick.
3540      *
3541      * <p>
3542      * Permissions android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE is required
3543      * for getSelectableSubscriptionInfoList to be invoked.
3544      * @return list of user selectable subscriptions.
3545      *
3546      * @hide
3547      */
getSelectableSubscriptionInfoList()3548     public @Nullable List<SubscriptionInfo> getSelectableSubscriptionInfoList() {
3549         List<SubscriptionInfo> availableList = getAvailableSubscriptionInfoList();
3550         if (availableList == null) {
3551             return null;
3552         } else {
3553             // Multiple subscriptions in a group should only have one representative.
3554             // It should be the current active primary subscription if any, or any
3555             // primary subscription.
3556             List<SubscriptionInfo> selectableList = new ArrayList<>();
3557             Map<ParcelUuid, SubscriptionInfo> groupMap = new HashMap<>();
3558 
3559             for (SubscriptionInfo info : availableList) {
3560                 // Opportunistic subscriptions are considered invisible
3561                 // to users so they should never be returned.
3562                 if (!isSubscriptionVisible(info)) continue;
3563 
3564                 ParcelUuid groupUuid = info.getGroupUuid();
3565                 if (groupUuid == null) {
3566                     // Doesn't belong to any group. Add in the list.
3567                     selectableList.add(info);
3568                 } else if (!groupMap.containsKey(groupUuid)
3569                         || (groupMap.get(groupUuid).getSimSlotIndex() == INVALID_SIM_SLOT_INDEX
3570                         && info.getSimSlotIndex() != INVALID_SIM_SLOT_INDEX)) {
3571                     // If it belongs to a group that has never been recorded or it's the current
3572                     // active subscription, add it in the list.
3573                     selectableList.remove(groupMap.get(groupUuid));
3574                     selectableList.add(info);
3575                     groupMap.put(groupUuid, info);
3576                 }
3577 
3578             }
3579             return selectableList;
3580         }
3581     }
3582 
3583     /**
3584      * Enable or disable a subscription. This method is same as
3585      * {@link #setUiccApplicationsEnabled(int, boolean)}.
3586      *
3587      * @param subscriptionId Subscription to be enabled or disabled.
3588      * @param enable whether user is turning it on or off.
3589      *
3590      * @return whether the operation is successful.
3591      *
3592      * @hide
3593      */
3594     @SystemApi
3595     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
setSubscriptionEnabled(int subscriptionId, boolean enable)3596     public boolean setSubscriptionEnabled(int subscriptionId, boolean enable) {
3597         try {
3598             ISub iSub = TelephonyManager.getSubscriptionService();
3599             if (iSub != null) {
3600                 iSub.setUiccApplicationsEnabled(enable, subscriptionId);
3601             }
3602         } catch (RemoteException ex) {
3603             return false;
3604         }
3605         return true;
3606     }
3607 
3608     /**
3609      * Set uicc applications being enabled or disabled.
3610      * The value will be remembered on the subscription and will be applied whenever it's present.
3611      * If the subscription in currently present, it will also apply the setting to modem
3612      * immediately (the setting in the modem will not change until the modem receives and responds
3613      * to the request, but typically this should only take a few seconds. The user visible setting
3614      * available from SubscriptionInfo.areUiccApplicationsEnabled() will be updated
3615      * immediately.)
3616      *
3617      * @param subscriptionId which subscription to operate on.
3618      * @param enabled whether uicc applications are enabled or disabled.
3619      * @hide
3620      */
3621     @SystemApi
3622     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setUiccApplicationsEnabled(int subscriptionId, boolean enabled)3623     public void setUiccApplicationsEnabled(int subscriptionId, boolean enabled) {
3624         if (VDBG) {
3625             logd("setUiccApplicationsEnabled subId= " + subscriptionId + " enable " + enabled);
3626         }
3627         try {
3628             ISub iSub = TelephonyManager.getSubscriptionService();
3629             if (iSub != null) {
3630                 iSub.setUiccApplicationsEnabled(enabled, subscriptionId);
3631             }
3632         } catch (RemoteException ex) {
3633             // ignore it
3634         }
3635     }
3636 
3637     /**
3638      * Whether it's supported to disable / re-enable a subscription on a physical (non-euicc) SIM.
3639      *
3640      * Physical SIM refers non-euicc, or aka non-programmable SIM.
3641      *
3642      * It provides whether a physical SIM card can be disabled without taking it out, which is done
3643      * via {@link #setSubscriptionEnabled(int, boolean)} API.
3644      *
3645      * @return whether can disable subscriptions on physical SIMs.
3646      *
3647      * @hide
3648      */
3649     @SystemApi
3650     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
canDisablePhysicalSubscription()3651     public boolean canDisablePhysicalSubscription() {
3652         if (VDBG) {
3653             logd("canDisablePhysicalSubscription");
3654         }
3655         try {
3656             ISub iSub = TelephonyManager.getSubscriptionService();
3657             if (iSub != null) {
3658                 return iSub.canDisablePhysicalSubscription();
3659             }
3660         } catch (RemoteException ex) {
3661             // ignore it
3662         }
3663 
3664         return false;
3665     }
3666 
3667     /**
3668      * Check if the subscription is currently active in any slot.
3669      *
3670      * @param subscriptionId The subscription id.
3671      *
3672      * @hide
3673      */
3674     @SystemApi
3675     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
isSubscriptionEnabled(int subscriptionId)3676     public boolean isSubscriptionEnabled(int subscriptionId) {
3677         try {
3678             ISub iSub = TelephonyManager.getSubscriptionService();
3679             if (iSub != null) {
3680                 return iSub.isSubscriptionEnabled(subscriptionId);
3681             }
3682         } catch (RemoteException ex) {
3683             // ignore it
3684         }
3685 
3686         return false;
3687     }
3688 
3689     /**
3690      * Set the device to device status sharing user preference for a subscription id. The setting
3691      * app uses this method to indicate with whom they wish to share device to device status
3692      * information.
3693      *
3694      * @param subscriptionId The subscription id.
3695      * @param sharing The status sharing preference.
3696      *
3697      * @throws SecurityException if the caller doesn't have permissions required.
3698      */
3699     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setDeviceToDeviceStatusSharingPreference(int subscriptionId, @DeviceToDeviceStatusSharingPreference int sharing)3700     public void setDeviceToDeviceStatusSharingPreference(int subscriptionId,
3701             @DeviceToDeviceStatusSharingPreference int sharing) {
3702         if (VDBG) {
3703             logd("[setDeviceToDeviceStatusSharing] + sharing: " + sharing + " subId: "
3704                     + subscriptionId);
3705         }
3706         setSubscriptionPropertyHelper(subscriptionId, "setDeviceToDeviceSharingStatus",
3707                 (iSub)->iSub.setDeviceToDeviceStatusSharing(sharing, subscriptionId));
3708     }
3709 
3710     /**
3711      * Returns the user-chosen device to device status sharing preference
3712      * @param subscriptionId Subscription id of subscription
3713      * @return The device to device status sharing preference
3714      *
3715      * @throws SecurityException if the caller doesn't have permissions required.
3716      */
getDeviceToDeviceStatusSharingPreference( int subscriptionId)3717     public @DeviceToDeviceStatusSharingPreference int getDeviceToDeviceStatusSharingPreference(
3718             int subscriptionId) {
3719         if (VDBG) {
3720             logd("[getDeviceToDeviceStatusSharing] + subId: " + subscriptionId);
3721         }
3722         return getIntegerSubscriptionProperty(subscriptionId, D2D_STATUS_SHARING,
3723                 D2D_SHARING_DISABLED, mContext);
3724     }
3725 
3726     /**
3727      * Set the list of contacts that allow device to device status sharing for a subscription id.
3728      * The setting app uses this method to indicate with whom they wish to share device to device
3729      * status information.
3730      *
3731      * @param subscriptionId The subscription id.
3732      * @param contacts The list of contacts that allow device to device status sharing.
3733      *
3734      * @throws SecurityException if the caller doesn't have permissions required.
3735      */
3736     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setDeviceToDeviceStatusSharingContacts(int subscriptionId, @NonNull List<Uri> contacts)3737     public void setDeviceToDeviceStatusSharingContacts(int subscriptionId,
3738             @NonNull List<Uri> contacts) {
3739         String contactString = serializeUriLists(contacts);
3740         if (VDBG) {
3741             logd("[setDeviceToDeviceStatusSharingContacts] + contacts: " + contactString
3742                     + " subId: " + subscriptionId);
3743         }
3744         setSubscriptionPropertyHelper(subscriptionId, "setDeviceToDeviceSharingStatus",
3745                 (iSub)->iSub.setDeviceToDeviceStatusSharingContacts(serializeUriLists(contacts),
3746                         subscriptionId));
3747     }
3748 
3749     /**
3750      * Get the list of contacts that allow device to device status sharing.
3751      *
3752      * @param subscriptionId Subscription id.
3753      *
3754      * @return The list of contacts that allow device to device status sharing.
3755      */
getDeviceToDeviceStatusSharingContacts(int subscriptionId)3756     public @NonNull List<Uri> getDeviceToDeviceStatusSharingContacts(int subscriptionId) {
3757         String result = getStringSubscriptionProperty(mContext, subscriptionId,
3758                 D2D_STATUS_SHARING_SELECTED_CONTACTS);
3759         if (result != null) {
3760             try {
3761                 byte[] b = Base64.decode(result, Base64.DEFAULT);
3762                 ByteArrayInputStream bis = new ByteArrayInputStream(b);
3763                 ObjectInputStream ois = new ObjectInputStream(bis);
3764                 List<String> contacts = ArrayList.class.cast(ois.readObject());
3765                 List<Uri> uris = new ArrayList<>();
3766                 for (String contact : contacts) {
3767                     uris.add(Uri.parse(contact));
3768                 }
3769                 return uris;
3770             } catch (IOException e) {
3771                 logd("getDeviceToDeviceStatusSharingContacts IO exception");
3772             } catch (ClassNotFoundException e) {
3773                 logd("getDeviceToDeviceStatusSharingContacts ClassNotFound exception");
3774             }
3775         }
3776         return new ArrayList<>();
3777     }
3778 
3779     /**
3780      * Get the active subscription id by logical SIM slot index.
3781      *
3782      * @param slotIndex The logical SIM slot index.
3783      * @return The active subscription id.
3784      *
3785      * @throws IllegalArgumentException if the provided slot index is invalid.
3786      * @throws SecurityException if callers do not hold the required permission.
3787      *
3788      * @hide
3789      */
3790     @SystemApi
3791     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
getEnabledSubscriptionId(int slotIndex)3792     public int getEnabledSubscriptionId(int slotIndex) {
3793         int subId = INVALID_SUBSCRIPTION_ID;
3794 
3795         try {
3796             ISub iSub = TelephonyManager.getSubscriptionService();
3797             if (iSub != null) {
3798                 subId = iSub.getEnabledSubscriptionId(slotIndex);
3799             }
3800         } catch (RemoteException ex) {
3801             // ignore it
3802         }
3803 
3804         if (VDBG) logd("getEnabledSubscriptionId, subId = " + subId);
3805         return subId;
3806     }
3807 
3808     private interface CallISubMethodHelper {
callMethod(ISub iSub)3809         int callMethod(ISub iSub) throws RemoteException;
3810     }
3811 
setSubscriptionPropertyHelper(int subId, String methodName, CallISubMethodHelper helper)3812     private int setSubscriptionPropertyHelper(int subId, String methodName,
3813             CallISubMethodHelper helper) {
3814         if (!isValidSubscriptionId(subId)) {
3815             logd("[" + methodName + "]" + "- fail");
3816             return -1;
3817         }
3818 
3819         int result = 0;
3820 
3821         try {
3822             ISub iSub = TelephonyManager.getSubscriptionService();
3823             if (iSub != null) {
3824                 result = helper.callMethod(iSub);
3825             }
3826         } catch (RemoteException ex) {
3827             // ignore it
3828         }
3829 
3830         return result;
3831     }
3832 
3833     /**
3834      * Get active data subscription id. Active data subscription refers to the subscription
3835      * currently chosen to provide cellular internet connection to the user. This may be
3836      * different from {@link #getDefaultDataSubscriptionId()}.
3837      *
3838      * @return Active data subscription id if any is chosen, or {@link #INVALID_SUBSCRIPTION_ID} if
3839      * not.
3840      *
3841      * @see TelephonyCallback.ActiveDataSubscriptionIdListener
3842      */
getActiveDataSubscriptionId()3843     public static int getActiveDataSubscriptionId() {
3844         return sGetActiveDataSubscriptionIdCache.query(null);
3845     }
3846 
3847     /**
3848      * Helper method that puts a subscription id on an intent with the constants:
3849      * PhoneConstant.SUBSCRIPTION_KEY and SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX.
3850      * Both constants are used to support backwards compatibility.  Once we know we got all places,
3851      * we can remove PhoneConstants.SUBSCRIPTION_KEY.
3852      * @param intent Intent to put sub id on.
3853      * @param subId SubscriptionId to put on intent.
3854      *
3855      * @hide
3856      */
putSubscriptionIdExtra(Intent intent, int subId)3857     public static void putSubscriptionIdExtra(Intent intent, int subId) {
3858         intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
3859         intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
3860     }
3861 
3862     /** @hide */
invalidateSubscriptionManagerServiceCaches()3863     public static void invalidateSubscriptionManagerServiceCaches() {
3864         PropertyInvalidatedCache.invalidateCache(CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY);
3865     }
3866 
3867     /**
3868      * Allows a test process to disable client-side caching operations.
3869      *
3870      * @hide
3871      */
disableCaching()3872     public static void disableCaching() {
3873         sGetDefaultSubIdCache.disableLocal();
3874         sGetDefaultDataSubIdCache.disableLocal();
3875         sGetActiveDataSubscriptionIdCache.disableLocal();
3876         sGetDefaultSmsSubIdCache.disableLocal();
3877         sGetSlotIndexCache.disableLocal();
3878         sGetSubIdCache.disableLocal();
3879         sGetPhoneIdCache.disableLocal();
3880     }
3881 
3882     /**
3883      * Clears all process-local binder caches.
3884      *
3885      * @hide */
clearCaches()3886     public static void clearCaches() {
3887         sGetDefaultSubIdCache.clear();
3888         sGetDefaultDataSubIdCache.clear();
3889         sGetActiveDataSubscriptionIdCache.clear();
3890         sGetDefaultSmsSubIdCache.clear();
3891         sGetSlotIndexCache.clear();
3892         sGetSubIdCache.clear();
3893         sGetPhoneIdCache.clear();
3894     }
3895 
3896     /**
3897      * Called to retrieve SIM-specific settings data to be backed up.
3898      *
3899      * @return data in byte[] to be backed up.
3900      *
3901      * @hide
3902      */
3903     @NonNull
3904     @SystemApi
3905     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
getAllSimSpecificSettingsForBackup()3906     public byte[] getAllSimSpecificSettingsForBackup() {
3907         Bundle bundle =  mContext.getContentResolver().call(
3908                 SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
3909                 GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME, null, null);
3910         return bundle.getByteArray(SubscriptionManager.KEY_SIM_SPECIFIC_SETTINGS_DATA);
3911     }
3912 
3913     /**
3914      * Called during setup wizard restore flow to attempt to restore the backed up sim-specific
3915      * configs to device for all existing SIMs in the subscription database {@link SimInfo}.
3916      * Internally, it will store the backup data in an internal file. This file will persist on
3917      * device for device's lifetime and will be used later on when a SIM is inserted to restore that
3918      * specific SIM's settings. End result is subscription database is modified to match any backed
3919      * up configs for the appropriate inserted SIMs.
3920      *
3921      * <p>
3922      * The {@link Uri} {@link #SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI} is notified if any
3923      * {@link SimInfo} entry is updated as the result of this method call.
3924      *
3925      * @param data with the sim specific configs to be backed up.
3926      *
3927      * @hide
3928      */
3929     @SystemApi
3930     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
restoreAllSimSpecificSettingsFromBackup(@onNull byte[] data)3931     public void restoreAllSimSpecificSettingsFromBackup(@NonNull byte[] data) {
3932         try {
3933             ISub iSub = TelephonyManager.getSubscriptionService();
3934             if (iSub != null) {
3935                 iSub.restoreAllSimSpecificSettingsFromBackup(data);
3936             } else {
3937                 throw new IllegalStateException("subscription service unavailable.");
3938             }
3939         } catch (RemoteException ex) {
3940             if (!isSystemProcess()) {
3941                 ex.rethrowAsRuntimeException();
3942             }
3943         }
3944     }
3945 
3946     /**
3947      * Returns the phone number for the given {@code subscriptionId} and {@code source},
3948      * or an empty string if not available.
3949      *
3950      * <p>General apps that need to know the phone number should use {@link #getPhoneNumber(int)}
3951      * instead. This API may be suitable specific apps that needs to know the phone number from
3952      * a specific source. For example, a carrier app needs to know exactly what's on
3953      * {@link #PHONE_NUMBER_SOURCE_UICC UICC} and decide if the previously set phone number
3954      * of source {@link #PHONE_NUMBER_SOURCE_CARRIER carrier} should be updated.
3955      *
3956      * <p>The API provides no guarantees of what format the number is in: the format can vary
3957      * depending on the {@code source} and the network etc. Programmatic parsing should be done
3958      * cautiously, for example, after formatting the number to a consistent format with
3959      * {@link android.telephony.PhoneNumberUtils#formatNumberToE164(String, String)}.
3960      *
3961      * <p>Note the assumption is that one subscription (which usually means one SIM) has
3962      * only one phone number. The multiple sources backup each other so hopefully at least one
3963      * is availavle. For example, for a carrier that doesn't typically set phone numbers
3964      * on {@link #PHONE_NUMBER_SOURCE_UICC UICC}, the source {@link #PHONE_NUMBER_SOURCE_IMS IMS}
3965      * may provide one. Or, a carrier may decide to provide the phone number via source
3966      * {@link #PHONE_NUMBER_SOURCE_CARRIER carrier} if neither source UICC nor IMS is available.
3967      *
3968      * <p>The availability and correctness of the phone number depends on the underlying source
3969      * and the network etc. Additional verification is needed to use this number for
3970      * security-related or other sensitive scenarios.
3971      *
3972      * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID}
3973      * for the default one.
3974      * @param source the source of the phone number, one of the PHONE_NUMBER_SOURCE_* constants.
3975      *
3976      * @return the phone number, or an empty string if not available.
3977      *
3978      * @throws IllegalArgumentException if {@code source} is invalid.
3979      * @throws IllegalStateException if the telephony process is not currently available.
3980      * @throws SecurityException if the caller doesn't have permissions required.
3981      *
3982      * @see #PHONE_NUMBER_SOURCE_UICC
3983      * @see #PHONE_NUMBER_SOURCE_CARRIER
3984      * @see #PHONE_NUMBER_SOURCE_IMS
3985      */
3986     @RequiresPermission(anyOf = {
3987             android.Manifest.permission.READ_PHONE_NUMBERS,
3988             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
3989             "carrier privileges",
3990     })
3991     @NonNull
getPhoneNumber(int subscriptionId, @PhoneNumberSource int source)3992     public String getPhoneNumber(int subscriptionId, @PhoneNumberSource int source) {
3993         if (subscriptionId == DEFAULT_SUBSCRIPTION_ID) {
3994             subscriptionId = getDefaultSubscriptionId();
3995         }
3996         if (source != PHONE_NUMBER_SOURCE_UICC
3997                 && source != PHONE_NUMBER_SOURCE_CARRIER
3998                 && source != PHONE_NUMBER_SOURCE_IMS) {
3999             throw new IllegalArgumentException("invalid source " + source);
4000         }
4001         try {
4002             ISub iSub = TelephonyManager.getSubscriptionService();
4003             if (iSub != null) {
4004                 return iSub.getPhoneNumber(subscriptionId, source,
4005                         mContext.getOpPackageName(), mContext.getAttributionTag());
4006             } else {
4007                 throw new IllegalStateException("subscription service unavailable.");
4008             }
4009         } catch (RemoteException ex) {
4010             throw ex.rethrowAsRuntimeException();
4011         }
4012     }
4013 
4014     /**
4015      * Returns the phone number for the given {@code subId}, or an empty string if
4016      * not available.
4017      *
4018      * <p>This API is suitable for general apps that needs to know the phone number.
4019      * For specific apps that needs to know the phone number provided by a specific source,
4020      * {@link #getPhoneNumber(int, int)} may be suitable.
4021      *
4022      * <p>This API is built up on {@link #getPhoneNumber(int, int)}, but picks
4023      * from available sources in the following order: {@link #PHONE_NUMBER_SOURCE_CARRIER}
4024      * > {@link #PHONE_NUMBER_SOURCE_UICC} > {@link #PHONE_NUMBER_SOURCE_IMS}.
4025      *
4026      * <p>The API provides no guarantees of what format the number is in: the format can vary
4027      * depending on the underlying source and the network etc. Programmatic parsing should be done
4028      * cautiously, for example, after formatting the number to a consistent format with
4029      * {@link android.telephony.PhoneNumberUtils#formatNumberToE164(String, String)}.
4030      *
4031      * <p>The availability and correctness of the phone number depends on the underlying source
4032      * and the network etc. Additional verification is needed to use this number for
4033      * security-related or other sensitive scenarios.
4034      *
4035      * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID}
4036      *                       for the default one.
4037      * @return the phone number, or an empty string if not available.
4038      *
4039      * @throws IllegalStateException if the telephony process is not currently available.
4040      * @throws SecurityException if the caller doesn't have permissions required.
4041      *
4042      * @see #getPhoneNumber(int, int)
4043      */
4044     @RequiresPermission(anyOf = {
4045             android.Manifest.permission.READ_PHONE_NUMBERS,
4046             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
4047             "carrier privileges",
4048     })
4049     @NonNull
getPhoneNumber(int subscriptionId)4050     public String getPhoneNumber(int subscriptionId) {
4051         if (subscriptionId == DEFAULT_SUBSCRIPTION_ID) {
4052             subscriptionId = getDefaultSubscriptionId();
4053         }
4054         try {
4055             ISub iSub = TelephonyManager.getSubscriptionService();
4056             if (iSub != null) {
4057                 return iSub.getPhoneNumberFromFirstAvailableSource(subscriptionId,
4058                         mContext.getOpPackageName(), mContext.getAttributionTag());
4059             } else {
4060                 throw new IllegalStateException("subscription service unavailable.");
4061             }
4062         } catch (RemoteException ex) {
4063             throw ex.rethrowAsRuntimeException();
4064         }
4065     }
4066 
4067     /**
4068      * Sets the phone number for the given {@code subId} for source
4069      * {@link #PHONE_NUMBER_SOURCE_CARRIER carrier}.
4070      * Sets an empty string to remove the previously set phone number.
4071      *
4072      * <p>The API is suitable for carrier apps to provide a phone number, for example when
4073      * it's not possible to update {@link #PHONE_NUMBER_SOURCE_UICC UICC} directly.
4074      *
4075      * <p>It's recommended that the phone number is formatted to well-known formats,
4076      * for example, by {@link PhoneNumberUtils} {@code formatNumber*} methods.
4077      *
4078      * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID}
4079      *                       for the default one.
4080      * @param number the phone number, or an empty string to remove the previously set number.
4081      * @throws IllegalStateException if the telephony process is not currently available.
4082      * @throws NullPointerException if {@code number} is {@code null}.
4083      * @throws SecurityException if the caller doesn't have permissions required.
4084      */
4085     @RequiresPermission("carrier privileges")
setCarrierPhoneNumber(int subscriptionId, @NonNull String number)4086     public void setCarrierPhoneNumber(int subscriptionId, @NonNull String number) {
4087         if (subscriptionId == DEFAULT_SUBSCRIPTION_ID) {
4088             subscriptionId = getDefaultSubscriptionId();
4089         }
4090         if (number == null) {
4091             throw new NullPointerException("invalid number null");
4092         }
4093         try {
4094             ISub iSub = TelephonyManager.getSubscriptionService();
4095             if (iSub != null) {
4096                 iSub.setPhoneNumber(subscriptionId, PHONE_NUMBER_SOURCE_CARRIER, number,
4097                         mContext.getOpPackageName(), mContext.getAttributionTag());
4098             } else {
4099                 throw new IllegalStateException("subscription service unavailable.");
4100             }
4101         } catch (RemoteException ex) {
4102             throw ex.rethrowAsRuntimeException();
4103         }
4104     }
4105 
4106     /**
4107      * Set the preferred usage setting.
4108      *
4109      * The cellular usage setting is a switch which controls the mode of operation for the cellular
4110      * radio to either require or not require voice service. It is not managed via Android’s
4111      * Settings.
4112      *
4113      * @param subscriptionId the subId of the subscription.
4114      * @param usageSetting the requested usage setting.
4115      *
4116      * @throws IllegalStateException if a specific mode or setting the mode is not supported on a
4117      * particular device.
4118      *
4119      * <p>Requires {@link android.Manifest.permission#MODIFY_PHONE_STATE}
4120      * or that the calling app has CarrierPrivileges for the given subscription.
4121      *
4122      * Note: This method will not allow the setting of USAGE_SETTING_UNKNOWN.
4123      *
4124      * @hide
4125      */
4126     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setUsageSetting(int subscriptionId, @UsageSetting int usageSetting)4127     void setUsageSetting(int subscriptionId, @UsageSetting int usageSetting) {
4128         if (VDBG) logd("[setUsageSetting]+ setting:" + usageSetting + " subId:" + subscriptionId);
4129         setSubscriptionPropertyHelper(subscriptionId, "setUsageSetting",
4130                 (iSub)-> iSub.setUsageSetting(
4131                         usageSetting, subscriptionId, mContext.getOpPackageName()));
4132     }
4133 
4134     /**
4135      * Convert phone number source to string.
4136      *
4137      * @param source The phone name source.
4138      *
4139      * @return The phone name source in string format.
4140      *
4141      * @hide
4142      */
4143     @NonNull
phoneNumberSourceToString(@honeNumberSource int source)4144     public static String phoneNumberSourceToString(@PhoneNumberSource int source) {
4145         switch (source) {
4146             case SubscriptionManager.PHONE_NUMBER_SOURCE_UICC: return "UICC";
4147             case SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER: return "CARRIER";
4148             case SubscriptionManager.PHONE_NUMBER_SOURCE_IMS: return "IMS";
4149             default:
4150                 return "UNKNOWN(" + source + ")";
4151         }
4152     }
4153 
4154     /**
4155      * Convert display name source to string.
4156      *
4157      * @param source The display name source.
4158      * @return The display name source in string format.
4159      *
4160      * @hide
4161      */
4162     @NonNull
displayNameSourceToString( @ubscriptionManager.SimDisplayNameSource int source)4163     public static String displayNameSourceToString(
4164             @SubscriptionManager.SimDisplayNameSource int source) {
4165         switch (source) {
4166             case SubscriptionManager.NAME_SOURCE_UNKNOWN: return "UNKNOWN";
4167             case SubscriptionManager.NAME_SOURCE_CARRIER_ID: return "CARRIER_ID";
4168             case SubscriptionManager.NAME_SOURCE_SIM_SPN: return "SIM_SPN";
4169             case SubscriptionManager.NAME_SOURCE_USER_INPUT: return "USER_INPUT";
4170             case SubscriptionManager.NAME_SOURCE_CARRIER: return "CARRIER";
4171             case SubscriptionManager.NAME_SOURCE_SIM_PNN: return "SIM_PNN";
4172             default:
4173                 return "UNKNOWN(" + source + ")";
4174         }
4175     }
4176 
4177     /**
4178      * Convert subscription type to string.
4179      *
4180      * @param type The subscription type.
4181      * @return The subscription type in string format.
4182      *
4183      * @hide
4184      */
4185     @NonNull
subscriptionTypeToString(@ubscriptionManager.SubscriptionType int type)4186     public static String subscriptionTypeToString(@SubscriptionManager.SubscriptionType int type) {
4187         switch (type) {
4188             case SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM: return "LOCAL_SIM";
4189             case SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM: return "REMOTE_SIM";
4190             default:
4191                 return "UNKNOWN(" + type + ")";
4192         }
4193     }
4194 
4195     /**
4196      * Convert usage setting to string.
4197      *
4198      * @param usageSetting Usage setting.
4199      * @return The usage setting in string format.
4200      *
4201      * @hide
4202      */
4203     @NonNull
usageSettingToString(@ubscriptionManager.UsageSetting int usageSetting)4204     public static String usageSettingToString(@SubscriptionManager.UsageSetting int usageSetting) {
4205         switch (usageSetting) {
4206             case SubscriptionManager.USAGE_SETTING_UNKNOWN: return "UNKNOWN";
4207             case SubscriptionManager.USAGE_SETTING_DEFAULT: return "DEFAULT";
4208             case SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC: return "VOICE_CENTRIC";
4209             case SubscriptionManager.USAGE_SETTING_DATA_CENTRIC: return "DATA_CENTRIC";
4210             default:
4211                 return "UNKNOWN(" + usageSetting + ")";
4212         }
4213     }
4214 
4215     /**
4216      * Set userHandle for a subscription.
4217      *
4218      * Used to set an association between a subscription and a user on the device so that voice
4219      * calling and SMS from that subscription can be associated with that user.
4220      * Data services are always shared between users on the device.
4221      *
4222      * @param subscriptionId the subId of the subscription.
4223      * @param userHandle the userHandle associated with the subscription.
4224      * Pass {@code null} user handle to clear the association.
4225      *
4226      * @throws IllegalArgumentException if subscription is invalid.
4227      * @throws SecurityException if the caller doesn't have permissions required.
4228      * @throws IllegalStateException if subscription service is not available.
4229      *
4230      * @hide
4231      */
4232     @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION)
setSubscriptionUserHandle(int subscriptionId, @Nullable UserHandle userHandle)4233     public void setSubscriptionUserHandle(int subscriptionId, @Nullable UserHandle userHandle) {
4234         if (!isValidSubscriptionId(subscriptionId)) {
4235             throw new IllegalArgumentException("[setSubscriptionUserHandle]: "
4236                     + "Invalid subscriptionId: " + subscriptionId);
4237         }
4238 
4239         try {
4240             ISub iSub = TelephonyManager.getSubscriptionService();
4241             if (iSub != null) {
4242                 iSub.setSubscriptionUserHandle(userHandle, subscriptionId);
4243             } else {
4244                 throw new IllegalStateException("[setSubscriptionUserHandle]: "
4245                         + "subscription service unavailable");
4246             }
4247         } catch (RemoteException ex) {
4248             ex.rethrowAsRuntimeException();
4249         }
4250     }
4251 
4252     /**
4253      * Get UserHandle of this subscription.
4254      *
4255      * Used to get user handle associated with this subscription.
4256      *
4257      * @param subscriptionId the subId of the subscription.
4258      * @return userHandle associated with this subscription
4259      * or {@code null} if subscription is not associated with any user.
4260      *
4261      * @throws IllegalArgumentException if subscription is invalid.
4262      * @throws SecurityException if the caller doesn't have permissions required.
4263      *
4264      * @hide
4265      */
4266     @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION)
getSubscriptionUserHandle(int subscriptionId)4267     public @Nullable UserHandle getSubscriptionUserHandle(int subscriptionId) {
4268         if (!isValidSubscriptionId(subscriptionId)) {
4269             throw new IllegalArgumentException("[getSubscriptionUserHandle]: "
4270                     + "Invalid subscriptionId: " + subscriptionId);
4271         }
4272 
4273         try {
4274             ISub iSub = TelephonyManager.getSubscriptionService();
4275             if (iSub != null) {
4276                 return iSub.getSubscriptionUserHandle(subscriptionId);
4277             } else {
4278                 Log.e(LOG_TAG, "[getSubscriptionUserHandle]: subscription service unavailable");
4279             }
4280         } catch (RemoteException ex) {
4281             ex.rethrowAsRuntimeException();
4282         }
4283         return null;
4284     }
4285 
4286     /**
4287      * Check if subscription and user are associated with each other.
4288      *
4289      * @param subscriptionId the subId of the subscription
4290      * @param userHandle user handle of the user
4291      * @return {@code true} if subscription is associated with user
4292      * {code true} if there are no subscriptions on device
4293      * else {@code false} if subscription is not associated with user.
4294      *
4295      * @throws IllegalArgumentException if subscription is invalid.
4296      * @throws SecurityException if the caller doesn't have permissions required.
4297      *
4298      * @hide
4299      */
4300     @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION)
isSubscriptionAssociatedWithUser(int subscriptionId, @NonNull UserHandle userHandle)4301     public boolean isSubscriptionAssociatedWithUser(int subscriptionId,
4302             @NonNull UserHandle userHandle) {
4303         if (!isValidSubscriptionId(subscriptionId)) {
4304             throw new IllegalArgumentException("[isSubscriptionAssociatedWithUser]: "
4305                     + "Invalid subscriptionId: " + subscriptionId);
4306         }
4307 
4308         try {
4309             ISub iSub = TelephonyManager.getSubscriptionService();
4310             if (iSub != null) {
4311                 return iSub.isSubscriptionAssociatedWithUser(subscriptionId, userHandle);
4312             } else {
4313                 Log.e(LOG_TAG, "[isSubscriptionAssociatedWithUser]: subscription service "
4314                         + "unavailable");
4315             }
4316         } catch (RemoteException ex) {
4317             ex.rethrowAsRuntimeException();
4318         }
4319         return false;
4320     }
4321 
4322     /**
4323      * Get list of subscriptions associated with user.
4324      *
4325      * @param userHandle user handle of the user
4326      * @return list of subscriptionInfo associated with the user.
4327      *
4328      * @throws SecurityException if the caller doesn't have permissions required.
4329      * @throws IllegalStateException if subscription service is not available.
4330      *
4331      * @hide
4332      */
4333     @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION)
getSubscriptionInfoListAssociatedWithUser( @onNull UserHandle userHandle)4334     public @NonNull List<SubscriptionInfo> getSubscriptionInfoListAssociatedWithUser(
4335             @NonNull UserHandle userHandle) {
4336         try {
4337             ISub iSub = TelephonyManager.getSubscriptionService();
4338             if (iSub != null) {
4339                 return iSub.getSubscriptionInfoListAssociatedWithUser(userHandle);
4340             } else {
4341                 Log.e(LOG_TAG, "[getSubscriptionInfoListAssociatedWithUser]: "
4342                         + "subscription service unavailable");
4343             }
4344         } catch (RemoteException ex) {
4345             ex.rethrowAsRuntimeException();
4346         }
4347         return new ArrayList<>();
4348     }
4349 }
4350