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