• 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_ONLY_NTN = SimInfo.COLUMN_IS_ONLY_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     /**
1171      * TelephonyProvider column name to indicate the satellite ESOS supported. The value of this
1172      * column is set based on {@link CarrierConfigManager#KEY_SATELLITE_ESOS_SUPPORTED_BOOL}.
1173      * By default, it's disabled.
1174      * <P>Type: INTEGER (int)</P>
1175      *
1176      * @hide
1177      */
1178     public static final String SATELLITE_ESOS_SUPPORTED = SimInfo.COLUMN_SATELLITE_ESOS_SUPPORTED;
1179 
1180     /**
1181      * TelephonyProvider column name for satellite provisioned status. The value of this
1182      * column is set based on whether carrier roaming NB-IOT satellite service is provisioned or
1183      * not. By default, it's disabled.
1184      *
1185      * @hide
1186      */
1187     public static final String IS_SATELLITE_PROVISIONED_FOR_NON_IP_DATAGRAM =
1188             SimInfo.COLUMN_IS_SATELLITE_PROVISIONED_FOR_NON_IP_DATAGRAM;
1189 
1190     /**
1191      * TelephonyProvider column name for satellite entitlement barred plmns. The value of this
1192      * column is set based on entitlement query result for satellite configuration.
1193      * By default, it's empty.
1194      * <P>Type: TEXT </P>
1195      *
1196      * @hide
1197      */
1198     public static final String SATELLITE_ENTITLEMENT_BARRED_PLMNS =
1199             SimInfo.COLUMN_SATELLITE_ENTITLEMENT_BARRED_PLMNS;
1200 
1201     /**
1202      * TelephonyProvider column name for satellite entitlement data plan for plmns. The value
1203      * of this column is set based on entitlement query result for satellite configuration.
1204      * By default, it's empty.
1205      * <P>Type: TEXT </P>
1206      *
1207      * @hide
1208      */
1209     public static final String SATELLITE_ENTITLEMENT_DATA_PLAN_PLMNS =
1210             SimInfo.COLUMN_SATELLITE_ENTITLEMENT_DATA_PLAN_PLMNS;
1211 
1212     /**
1213      * TelephonyProvider column name for satellite entitlement service type map. The value of
1214      * this column is set based on entitlement query result for satellite configuration.
1215      * By default, it's empty.
1216      * <P>Type: TEXT </P>
1217      *
1218      * @hide
1219      */
1220     public static final String SATELLITE_ENTITLEMENT_SERVICE_TYPE_MAP =
1221             SimInfo.COLUMN_SATELLITE_ENTITLEMENT_SERVICE_TYPE_MAP;
1222 
1223     /**
1224      * TelephonyProvider column name for satellite entitlement data service policy. The value
1225      * of this column is set based on entitlement query result for satellite configuration.
1226      * By default, it's empty.
1227      * <P>Type: TEXT </P>
1228      *
1229      * @hide
1230      */
1231     public static final String SATELLITE_ENTITLEMENT_DATA_SERVICE_POLICY =
1232             SimInfo.COLUMN_SATELLITE_ENTITLEMENT_DATA_SERVICE_POLICY;
1233 
1234     /**
1235      * TelephonyProvider column name for satellite entitlement voice service policy. The value
1236      * of this column is set based on entitlement query result for satellite configuration.
1237      * By default, it's empty.
1238      * <P>Type: TEXT </P>
1239      *
1240      * @hide
1241      */
1242     public static final String SATELLITE_ENTITLEMENT_VOICE_SERVICE_POLICY =
1243             SimInfo.COLUMN_SATELLITE_ENTITLEMENT_VOICE_SERVICE_POLICY;
1244 
1245     /** @hide */
1246     @Retention(RetentionPolicy.SOURCE)
1247     @IntDef(prefix = {"USAGE_SETTING_"},
1248         value = {
1249             USAGE_SETTING_UNKNOWN,
1250             USAGE_SETTING_DEFAULT,
1251             USAGE_SETTING_VOICE_CENTRIC,
1252             USAGE_SETTING_DATA_CENTRIC})
1253     public @interface UsageSetting {}
1254 
1255     /**
1256      * The usage setting is unknown.
1257      *
1258      * This will be the usage setting returned on devices that do not support querying the
1259      * or setting the usage setting.
1260      *
1261      * It may also be provided by a carrier that wishes to provide a value to avoid making any
1262      * settings changes.
1263      */
1264     public static final int USAGE_SETTING_UNKNOWN = -1;
1265 
1266     /**
1267      * Subscription uses the default setting.
1268      *
1269      * The value is based upon device capability and the other properties of the subscription.
1270      *
1271      * Most subscriptions will default to voice-centric when in a phone.
1272      *
1273      * An opportunistic subscription will default to data-centric.
1274      *
1275      * @see SubscriptionInfo#isOpportunistic
1276      */
1277     public static final int USAGE_SETTING_DEFAULT = 0;
1278 
1279     /**
1280      * This subscription is forced to voice-centric mode
1281      *
1282      * <p>Refer to voice-centric mode in 3gpp 24.301 sec 4.3 and 3gpp 24.501 sec 4.3.
1283      * Also refer to "UE's usage setting" as defined in 3gpp 24.301 section 3.1 and 3gpp 23.221
1284      * Annex A.
1285      *
1286      * <p>Devices that support {@link PackageManager#FEATURE_TELEPHONY_CALLING} and support usage
1287      * setting configuration must support setting this value via
1288      * {@link CarrierConfigManager#KEY_CELLULAR_USAGE_SETTING_INT}.
1289      */
1290     public static final int USAGE_SETTING_VOICE_CENTRIC = 1;
1291 
1292     /**
1293      * This subscription is forced to data-centric mode
1294      *
1295      * <p>Refer to data-centric mode in 3gpp 24.301 sec 4.3 and 3gpp 24.501 sec 4.3.
1296      * Also refer to "UE's usage setting" as defined in 3gpp 24.301 section 3.1 and 3gpp 23.221
1297      * Annex A.
1298      *
1299      * <p>Devices that support {@link PackageManager#FEATURE_TELEPHONY_DATA} and support usage
1300      * setting configuration must support setting this value via.
1301      * {@link CarrierConfigManager#KEY_CELLULAR_USAGE_SETTING_INT}.
1302      */
1303     public static final int USAGE_SETTING_DATA_CENTRIC = 2;
1304 
1305     /**
1306      * Indicate the preferred usage setting for the subscription.
1307      *
1308      * 0 - Default - If the value has not been explicitly set, it will be "default"
1309      * 1 - Voice-centric
1310      * 2 - Data-centric
1311      *
1312      * @hide
1313      */
1314     public static final String USAGE_SETTING = SimInfo.COLUMN_USAGE_SETTING;
1315 
1316     /**
1317      * Broadcast Action: The user has changed one of the default subs related to
1318      * data, phone calls, or sms</p>
1319      *
1320      * TODO: Change to a listener
1321      * @hide
1322      */
1323     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1324     public static final String SUB_DEFAULT_CHANGED_ACTION =
1325             "android.intent.action.SUB_DEFAULT_CHANGED";
1326 
1327     /**
1328      * Broadcast Action: The default subscription has changed.  This has the following
1329      * extra values:</p>
1330      * The {@link #EXTRA_SUBSCRIPTION_INDEX} extra indicates the current default subscription index
1331      */
1332     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1333     public static final String ACTION_DEFAULT_SUBSCRIPTION_CHANGED
1334             = "android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED";
1335 
1336     /**
1337      * Broadcast Action: The default sms subscription has changed.  This has the following
1338      * extra values:</p>
1339      * {@link #EXTRA_SUBSCRIPTION_INDEX} extra indicates the current default sms
1340      * subscription index
1341      */
1342     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1343     public static final String ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED
1344             = "android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED";
1345 
1346     /**
1347      * Activity Action: Display UI for managing the billing relationship plans
1348      * between a carrier and a specific subscriber.
1349      * <p>
1350      * Carrier apps are encouraged to implement this activity, and the OS will
1351      * provide an affordance to quickly enter this activity, typically via
1352      * Settings. This affordance will only be shown when the carrier app is
1353      * actively providing subscription plan information via
1354      * {@link #setSubscriptionPlans(int, List)}.
1355      * <p>
1356      * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
1357      * the user is interested in.
1358      */
1359     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
1360     public static final String ACTION_MANAGE_SUBSCRIPTION_PLANS
1361             = "android.telephony.action.MANAGE_SUBSCRIPTION_PLANS";
1362 
1363     /**
1364      * Broadcast Action: Request a refresh of the billing relationship plans
1365      * between a carrier and a specific subscriber.
1366      * <p>
1367      * Carrier apps are encouraged to implement this receiver, and the OS will
1368      * provide an affordance to request a refresh. This affordance will only be
1369      * shown when the carrier app is actively providing subscription plan
1370      * information via {@link #setSubscriptionPlans(int, List)}.
1371      * <p>
1372      * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
1373      * the user is interested in.
1374      * <p>
1375      * Receivers should protect themselves by checking that the sender holds the
1376      * {@code android.permission.MANAGE_SUBSCRIPTION_PLANS} permission.
1377      */
1378     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1379     public static final String ACTION_REFRESH_SUBSCRIPTION_PLANS
1380             = "android.telephony.action.REFRESH_SUBSCRIPTION_PLANS";
1381 
1382     /**
1383      * Broadcast Action: The billing relationship plans between a carrier and a
1384      * specific subscriber has changed.
1385      * <p>
1386      * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
1387      * changed.
1388      * @hide
1389      */
1390     @SystemApi
1391     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1392     @RequiresPermission(android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS)
1393     public static final String ACTION_SUBSCRIPTION_PLANS_CHANGED
1394             = "android.telephony.action.SUBSCRIPTION_PLANS_CHANGED";
1395 
1396     /**
1397      * Integer extra used with {@link #ACTION_DEFAULT_SUBSCRIPTION_CHANGED} and
1398      * {@link #ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED} to indicate the subscription
1399      * which has changed.
1400      */
1401     public static final String EXTRA_SUBSCRIPTION_INDEX = "android.telephony.extra.SUBSCRIPTION_INDEX";
1402 
1403     /**
1404      * Integer extra to specify SIM slot index.
1405      */
1406     public static final String EXTRA_SLOT_INDEX = "android.telephony.extra.SLOT_INDEX";
1407 
1408     /**
1409      * A source of phone number: the EF-MSISDN (see 3GPP TS 31.102),
1410      * or EF-MDN for CDMA (see 3GPP2 C.P0065-B), from UICC application.
1411      *
1412      * <p>The availability and accuracy of the number depends on the carrier.
1413      * The number may be updated by over-the-air update to UICC applications
1414      * from the carrier, or by other means with physical access to the SIM.
1415      */
1416     public static final int PHONE_NUMBER_SOURCE_UICC = 1;
1417 
1418     /**
1419      * A source of phone number: provided by an app that has carrier privilege.
1420      *
1421      * <p>The number is intended to be set by a carrier app knowing the correct number
1422      * which is, for example, different from the number in {@link #PHONE_NUMBER_SOURCE_UICC UICC}
1423      * for some reason.
1424      * The number is not available until a carrier app sets one via
1425      * {@link #setCarrierPhoneNumber(int, String)}.
1426      * The app can update the number with the same API should the number change.
1427      */
1428     public static final int PHONE_NUMBER_SOURCE_CARRIER = 2;
1429 
1430     /**
1431      * A source of phone number: provided by IMS (IP Multimedia Subsystem) implementation.
1432      * When IMS service is registered (as indicated by
1433      * {@link android.telephony.ims.RegistrationManager.RegistrationCallback#onRegistered(int)})
1434      * the IMS implementation may return P-Associated-Uri SIP headers (RFC 3455). The URIs
1435      * are the user’s public user identities known to the network (see 3GPP TS 24.229 5.4.1.2),
1436      * and the phone number is typically one of them (see “global number” in 3GPP TS 23.003 13.4).
1437      *
1438      * <p>This source provides the phone number from the last IMS registration.
1439      * IMS registration may happen on every device reboot or other network condition changes.
1440      * The number will be updated should the associated URI change after an IMS registration.
1441      */
1442     public static final int PHONE_NUMBER_SOURCE_IMS = 3;
1443 
1444     /** @hide */
1445     @Retention(RetentionPolicy.SOURCE)
1446     @IntDef(prefix = {"PHONE_NUMBER_SOURCE"},
1447             value = {
1448                     PHONE_NUMBER_SOURCE_UICC,
1449                     PHONE_NUMBER_SOURCE_CARRIER,
1450                     PHONE_NUMBER_SOURCE_IMS,
1451             })
1452     public @interface PhoneNumberSource {}
1453 
1454     /** @hide */
1455     @Retention(RetentionPolicy.SOURCE)
1456     @IntDef(prefix = {"SERVICE_CAPABILITY"},
1457             value = {
1458                     SERVICE_CAPABILITY_VOICE,
1459                     SERVICE_CAPABILITY_SMS,
1460                     SERVICE_CAPABILITY_DATA,
1461             })
1462     public @interface ServiceCapability {
1463     }
1464 
1465     /**
1466      * Represents a value indicating the voice calling capabilities of a subscription.
1467      *
1468      * <p>This value identifies whether the subscription supports various voice calling services.
1469      * These services can include circuit-switched (CS) calling, packet-switched (PS) IMS (IP
1470      * Multimedia Subsystem) calling, and over-the-top (OTT) calling options.
1471      *
1472      * <p>Note: The availability of emergency calling services is not solely dependent on this
1473      * voice capability. Emergency services may be accessible even if the subscription lacks
1474      * standard voice capabilities. However, the device's ability to support emergency calls
1475      * can be influenced by its inherent voice capabilities, as determined by
1476      * {@link TelephonyManager#isDeviceVoiceCapable()}.
1477      *
1478      * @see TelephonyManager#isDeviceVoiceCapable()
1479      */
1480     public static final int SERVICE_CAPABILITY_VOICE = 1;
1481 
1482     /**
1483      * Represents a value indicating the SMS capabilities of a subscription.
1484      *
1485      * <p>This value identifies whether the subscription supports various sms services.
1486      * These services can include circuit-switched (CS) SMS, packet-switched (PS) IMS (IP
1487      * Multimedia Subsystem) SMS, and over-the-top (OTT) SMS options.
1488      *
1489      * <p>Note: The availability of emergency SMS services is not solely dependent on this
1490      * sms capability. Emergency services may be accessible even if the subscription lacks
1491      * standard sms capabilities. However, the device's ability to support emergency sms
1492      * can be influenced by its inherent sms capabilities, as determined by
1493      * {@link TelephonyManager#isDeviceSmsCapable()}.
1494      *
1495      * @see TelephonyManager#isDeviceSmsCapable()
1496      */
1497     public static final int SERVICE_CAPABILITY_SMS = 2;
1498 
1499     /**
1500      * Represents a value indicating the data calling capabilities of a subscription.
1501      */
1502     public static final int SERVICE_CAPABILITY_DATA = 3;
1503 
1504     /**
1505      * Maximum value of service capabilities supported so far.
1506      * @hide
1507      */
1508     public static final int SERVICE_CAPABILITY_MAX = SERVICE_CAPABILITY_DATA;
1509 
1510     /**
1511      * Bitmask for {@link #SERVICE_CAPABILITY_VOICE}.
1512      * @hide
1513      */
1514     public static final int SERVICE_CAPABILITY_VOICE_BITMASK =
1515             serviceCapabilityToBitmask(SERVICE_CAPABILITY_VOICE);
1516 
1517     /**
1518      * Bitmask for {@link #SERVICE_CAPABILITY_SMS}.
1519      * @hide
1520      */
1521     public static final int SERVICE_CAPABILITY_SMS_BITMASK =
1522             serviceCapabilityToBitmask(SERVICE_CAPABILITY_SMS);
1523 
1524     /**
1525      * Bitmask for {@link #SERVICE_CAPABILITY_DATA}.
1526      * @hide
1527      */
1528     public static final int SERVICE_CAPABILITY_DATA_BITMASK =
1529             serviceCapabilityToBitmask(SERVICE_CAPABILITY_DATA);
1530 
1531     private final Context mContext;
1532 
1533     /**
1534      * In order to prevent the overflow of the heap size due to an indiscriminate increase in the
1535      * cache, the heap size of the resource cache is set sufficiently large.
1536      */
1537     private static final int MAX_RESOURCE_CACHE_ENTRY_COUNT = 1_000;
1538 
1539     /**
1540      * Cache of Resources that has been created in getResourcesForSubId. Key contains package name,
1541      * and Configuration of Resources. If more than the maximum number of resources are stored in
1542      * this cache, the least recently used Resources will be removed to maintain the maximum size.
1543      */
1544     private static final LruCache<Pair<String, Configuration>, Resources> sResourcesCache =
1545             new LruCache<>(MAX_RESOURCE_CACHE_ENTRY_COUNT);
1546 
1547 
1548     /**
1549      * The profile has not been transferred or converted to an eSIM.
1550      * @hide
1551      */
1552     @FlaggedApi(Flags.FLAG_SUPPORT_PSIM_TO_ESIM_CONVERSION)
1553     @SystemApi
1554     public static final int TRANSFER_STATUS_NONE = 0;
1555 
1556     /**
1557      * The existing profile of the old device has been transferred to an eSIM of the new device.
1558      * @hide
1559      */
1560     @FlaggedApi(Flags.FLAG_SUPPORT_PSIM_TO_ESIM_CONVERSION)
1561     @SystemApi
1562     public static final int TRANSFER_STATUS_TRANSFERRED_OUT = 1;
1563 
1564     /**
1565      * The existing profile of the same device has been converted to an eSIM of the same device
1566      * @hide
1567      */
1568     @FlaggedApi(Flags.FLAG_SUPPORT_PSIM_TO_ESIM_CONVERSION)
1569     @SystemApi
1570     public static final int TRANSFER_STATUS_CONVERTED = 2;
1571     /** @hide */
1572     @Retention(RetentionPolicy.SOURCE)
1573     @IntDef(prefix = {"TRANSFER_STATUS"},
1574             value = {
1575                     TRANSFER_STATUS_NONE,
1576                     TRANSFER_STATUS_TRANSFERRED_OUT,
1577                     TRANSFER_STATUS_CONVERTED,
1578             })
1579     public @interface TransferStatus {}
1580 
1581 
1582     /**
1583      * A listener class for monitoring changes to {@link SubscriptionInfo} records.
1584      * <p>
1585      * Override the onSubscriptionsChanged method in the object that extends this
1586      * class and pass it to {@link #addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener)}
1587      * to register your listener and to unregister invoke
1588      * {@link #removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener)}
1589      * <p>
1590      * Permissions android.Manifest.permission.READ_PHONE_STATE is required
1591      * for #onSubscriptionsChanged to be invoked.
1592      */
1593     public static class OnSubscriptionsChangedListener {
1594 
1595         /**
1596          * After {@link Build.VERSION_CODES#Q}, it is no longer necessary to instantiate a
1597          * Handler inside of the OnSubscriptionsChangedListener in all cases, so it will only
1598          * be done for callers that do not supply an Executor.
1599          */
1600         @ChangeId
1601         @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
1602         private static final long LAZY_INITIALIZE_SUBSCRIPTIONS_CHANGED_HANDLER = 278814050L;
1603 
1604         /**
1605          * For backwards compatibility reasons, stashes the Looper associated with the thread
1606          * context in which this listener was created.
1607          */
1608         private final Looper mCreatorLooper;
1609 
1610         /**
1611          * @hide
1612          */
getCreatorLooper()1613         public Looper getCreatorLooper() {
1614             return mCreatorLooper;
1615         }
1616 
1617         /**
1618          * Create an OnSubscriptionsChangedListener.
1619          *
1620          * For callers targeting {@link Build.VERSION_CODES#P} or earlier, this can only be called
1621          * on a thread that already has a prepared Looper. Callers targeting Q or later should
1622          * subsequently use {@link SubscriptionManager#addOnSubscriptionsChangedListener(
1623          * Executor, OnSubscriptionsChangedListener)}.
1624          *
1625          * On OS versions prior to {@link Build.VERSION_CODES#VANILLA_ICE_CREAM} callers should
1626          * assume that this call will fail if invoked on a thread that does not already have a
1627          * prepared looper.
1628          */
OnSubscriptionsChangedListener()1629         public OnSubscriptionsChangedListener() {
1630             mCreatorLooper = Looper.myLooper();
1631             if (mCreatorLooper == null
1632                     && !Compatibility.isChangeEnabled(
1633                             LAZY_INITIALIZE_SUBSCRIPTIONS_CHANGED_HANDLER)) {
1634                 // matches the implementation of Handler
1635                 throw new RuntimeException(
1636                         "Can't create handler inside thread "
1637                         + Thread.currentThread()
1638                         + " that has not called Looper.prepare()");
1639             }
1640         }
1641 
1642         /**
1643          * Allow a listener to be created with a custom looper
1644          * @param looper the non-null Looper that the underlining handler should run on
1645          * @hide
1646          */
OnSubscriptionsChangedListener(@onNull Looper looper)1647         public OnSubscriptionsChangedListener(@NonNull Looper looper) {
1648             Objects.requireNonNull(looper);
1649             mCreatorLooper = looper;
1650         }
1651 
1652         /**
1653          * Callback invoked when there is any change to any SubscriptionInfo, as well as once on
1654          * registering for changes with {@link #addOnSubscriptionsChangedListener}. Typically
1655          * this method would invoke {@link #getActiveSubscriptionInfoList}
1656          */
onSubscriptionsChanged()1657         public void onSubscriptionsChanged() {
1658             if (DBG) log("onSubscriptionsChanged: NOT OVERRIDDEN");
1659         }
1660 
1661         /**
1662          * Callback invoked when {@link SubscriptionManager#addOnSubscriptionsChangedListener(
1663          * Executor, OnSubscriptionsChangedListener)} or
1664          * {@link SubscriptionManager#addOnSubscriptionsChangedListener(
1665          * OnSubscriptionsChangedListener)} fails to complete due to the
1666          * {@link Context#TELEPHONY_REGISTRY_SERVICE} being unavailable.
1667          * @hide
1668          */
onAddListenerFailed()1669         public void onAddListenerFailed() {
1670             Rlog.w(LOG_TAG, "onAddListenerFailed not overridden");
1671         }
1672 
log(String s)1673         private void log(String s) {
1674             Rlog.d(LOG_TAG, s);
1675         }
1676     }
1677 
1678     /**
1679      * {@code true} if the SubscriptionManager instance should see all subscriptions regardless its
1680      * association with particular user profile.
1681      *
1682      * <p> It only applies to Android SDK 35(V) and above. For Android SDK 34(U) and below, the
1683      * caller can see all subscription across user profiles as it does today today even if it's
1684      * {@code false}.
1685      */
1686     private final boolean mIsForAllUserProfiles;
1687 
1688     /** @hide */
1689     @UnsupportedAppUsage
SubscriptionManager(Context context)1690     public SubscriptionManager(Context context) {
1691         this(context, false /*isForAllUserProfiles*/);
1692     }
1693 
1694     /**  Constructor */
SubscriptionManager(Context context, boolean isForAllUserProfiles)1695     private SubscriptionManager(Context context, boolean isForAllUserProfiles) {
1696         if (DBG) {
1697             logd("SubscriptionManager created "
1698                     + (isForAllUserProfiles ? "for all user profile" : ""));
1699         }
1700         mIsForAllUserProfiles = isForAllUserProfiles;
1701         mContext = context;
1702     }
1703 
getNetworkPolicyManager()1704     private NetworkPolicyManager getNetworkPolicyManager() {
1705         return (NetworkPolicyManager) mContext
1706                 .getSystemService(Context.NETWORK_POLICY_SERVICE);
1707     }
1708 
1709     /**
1710      * @deprecated developers should always obtain references directly from
1711      *             {@link Context#getSystemService(Class)}.
1712      */
1713     @Deprecated
from(Context context)1714     public static SubscriptionManager from(Context context) {
1715         return (SubscriptionManager) context
1716                 .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
1717     }
1718 
1719     /**
1720      * Register for changes to the list of active {@link SubscriptionInfo} records or to the
1721      * individual records themselves. When a change occurs the onSubscriptionsChanged method of
1722      * the listener will be invoked immediately if there has been a notification. The
1723      * onSubscriptionChanged method will also be triggered once initially when calling this
1724      * function. The callback will be invoked on the looper specified in the listener's constructor.
1725      *
1726      * @param listener an instance of {@link OnSubscriptionsChangedListener} with
1727      *                 onSubscriptionsChanged overridden.
1728      *
1729      * @deprecated Will get exception if the parameter listener is not initialized with a Looper.
1730      * Use {@link #addOnSubscriptionsChangedListener(Executor, OnSubscriptionsChangedListener)}.
1731      */
1732     @Deprecated
addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener)1733     public void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
1734         if (listener == null) return;
1735 
1736         Looper looper = listener.getCreatorLooper();
1737         if (looper == null) {
1738             throw new RuntimeException(
1739                     "Can't create handler inside thread " + Thread.currentThread()
1740                     + " that has not called Looper.prepare()");
1741         }
1742 
1743         addOnSubscriptionsChangedListener(new HandlerExecutor(new Handler(looper)), listener);
1744     }
1745 
1746     /**
1747      * Register for changes to the list of {@link SubscriptionInfo} records or to the
1748      * individual records (active or inactive) themselves. When a change occurs, the
1749      * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged()} method of
1750      * the listener will be invoked immediately. The
1751      * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged()} method will also be invoked
1752      * once initially when calling this method.
1753      *
1754      * @param listener an instance of {@link OnSubscriptionsChangedListener} with
1755      * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged()} overridden.
1756      * @param executor the executor that will execute callbacks.
1757      */
addOnSubscriptionsChangedListener( @onNull @allbackExecutor Executor executor, @NonNull OnSubscriptionsChangedListener listener)1758     public void addOnSubscriptionsChangedListener(
1759             @NonNull @CallbackExecutor Executor executor,
1760             @NonNull OnSubscriptionsChangedListener listener) {
1761         String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>";
1762         if (DBG) {
1763             logd("register OnSubscriptionsChangedListener pkgName=" + pkgName
1764                     + " listener=" + listener);
1765         }
1766         // We use the TelephonyRegistry as it runs in the system and thus is always
1767         // available.
1768         TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
1769                 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
1770         if (telephonyRegistryManager != null) {
1771             telephonyRegistryManager.addOnSubscriptionsChangedListener(listener,
1772                     executor);
1773         } else {
1774             // If the telephony registry isn't available, we will inform the caller on their
1775             // listener that it failed so they can try to re-register.
1776             loge("addOnSubscriptionsChangedListener: pkgname=" + pkgName + " failed to be added "
1777                     + " due to TELEPHONY_REGISTRY_SERVICE being unavailable.");
1778             executor.execute(() -> listener.onAddListenerFailed());
1779         }
1780     }
1781 
1782     /**
1783      * Unregister the {@link OnSubscriptionsChangedListener}. This is not strictly necessary
1784      * as the listener will automatically be unregistered if an attempt to invoke the listener
1785      * fails.
1786      *
1787      * @param listener that is to be unregistered.
1788      */
removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener)1789     public void removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
1790         if (listener == null) return;
1791         String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
1792         if (DBG) {
1793             logd("unregister OnSubscriptionsChangedListener pkgForDebug=" + pkgForDebug
1794                     + " listener=" + listener);
1795         }
1796         // We use the TelephonyRegistry as it runs in the system and thus is always
1797         // available.
1798         TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
1799                 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
1800         if (telephonyRegistryManager != null) {
1801             telephonyRegistryManager.removeOnSubscriptionsChangedListener(listener);
1802         }
1803     }
1804 
1805     /**
1806      * A listener class for monitoring changes to {@link SubscriptionInfo} records of opportunistic
1807      * subscriptions.
1808      * <p>
1809      * Override the onOpportunisticSubscriptionsChanged method in the object that extends this
1810      * or {@link #addOnOpportunisticSubscriptionsChangedListener(
1811      * Executor, OnOpportunisticSubscriptionsChangedListener)}
1812      * to register your listener and to unregister invoke
1813      * {@link #removeOnOpportunisticSubscriptionsChangedListener(
1814      * OnOpportunisticSubscriptionsChangedListener)}
1815      * <p>
1816      * Permissions android.Manifest.permission.READ_PHONE_STATE is required
1817      * for #onOpportunisticSubscriptionsChanged to be invoked.
1818      */
1819     public static class OnOpportunisticSubscriptionsChangedListener {
1820         /**
1821          * Callback invoked when there is any change to any SubscriptionInfo. Typically
1822          * this method would invoke {@link #getActiveSubscriptionInfoList}
1823          */
onOpportunisticSubscriptionsChanged()1824         public void onOpportunisticSubscriptionsChanged() {
1825             if (DBG) log("onOpportunisticSubscriptionsChanged: NOT OVERRIDDEN");
1826         }
1827 
log(String s)1828         private void log(String s) {
1829             Rlog.d(LOG_TAG, s);
1830         }
1831     }
1832 
1833     /**
1834      * Register for changes to the list of opportunistic subscription records or to the
1835      * individual records themselves. When a change occurs the onOpportunisticSubscriptionsChanged
1836      * method of the listener will be invoked immediately if there has been a notification.
1837      *
1838      * @param listener an instance of {@link OnOpportunisticSubscriptionsChangedListener} with
1839      *                 onOpportunisticSubscriptionsChanged overridden.
1840      */
addOnOpportunisticSubscriptionsChangedListener( @onNull @allbackExecutor Executor executor, @NonNull OnOpportunisticSubscriptionsChangedListener listener)1841     public void addOnOpportunisticSubscriptionsChangedListener(
1842             @NonNull @CallbackExecutor Executor executor,
1843             @NonNull OnOpportunisticSubscriptionsChangedListener listener) {
1844         if (executor == null || listener == null) {
1845             return;
1846         }
1847 
1848         String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>";
1849         if (DBG) {
1850             logd("register addOnOpportunisticSubscriptionsChangedListener pkgName=" + pkgName
1851                     + " listener=" + listener);
1852         }
1853 
1854         // We use the TelephonyRegistry as it runs in the system and thus is always
1855         // available.
1856         TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
1857                 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
1858         if (telephonyRegistryManager != null) {
1859             telephonyRegistryManager.addOnOpportunisticSubscriptionsChangedListener(
1860                     listener, executor);
1861         }
1862     }
1863 
1864     /**
1865      * Unregister the {@link OnOpportunisticSubscriptionsChangedListener} that is currently
1866      * listening opportunistic subscriptions change. This is not strictly necessary
1867      * as the listener will automatically be unregistered if an attempt to invoke the listener
1868      * fails.
1869      *
1870      * @param listener that is to be unregistered.
1871      */
removeOnOpportunisticSubscriptionsChangedListener( @onNull OnOpportunisticSubscriptionsChangedListener listener)1872     public void removeOnOpportunisticSubscriptionsChangedListener(
1873             @NonNull OnOpportunisticSubscriptionsChangedListener listener) {
1874         Preconditions.checkNotNull(listener, "listener cannot be null");
1875         String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
1876         if (DBG) {
1877             logd("unregister OnOpportunisticSubscriptionsChangedListener pkgForDebug="
1878                     + pkgForDebug + " listener=" + listener);
1879         }
1880         TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
1881                 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
1882         if (telephonyRegistryManager != null) {
1883             telephonyRegistryManager.removeOnOpportunisticSubscriptionsChangedListener(listener);
1884         }
1885     }
1886 
1887     /**
1888      * Get the active SubscriptionInfo with the input subId.
1889      *
1890      * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1891      * or that the calling app has carrier privileges (see
1892      * {@link TelephonyManager#hasCarrierPrivileges}).
1893      *
1894      * @param subId The unique SubscriptionInfo key in database.
1895      * @return SubscriptionInfo, maybe null if its not active.
1896      *
1897      * @throws UnsupportedOperationException If the device does not have
1898      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
1899      */
1900     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
1901     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
getActiveSubscriptionInfo(int subId)1902     public SubscriptionInfo getActiveSubscriptionInfo(int subId) {
1903         if (VDBG) logd("[getActiveSubscriptionInfo]+ subId=" + subId);
1904         if (!isValidSubscriptionId(subId)) {
1905             if (DBG) {
1906                 logd("[getActiveSubscriptionInfo]- invalid subId");
1907             }
1908             return null;
1909         }
1910 
1911         SubscriptionInfo subInfo = null;
1912 
1913         try {
1914             ISub iSub = TelephonyManager.getSubscriptionService();
1915             if (iSub != null) {
1916                 subInfo = iSub.getActiveSubscriptionInfo(subId, mContext.getOpPackageName(),
1917                         mContext.getAttributionTag());
1918             }
1919         } catch (RemoteException ex) {
1920             // ignore it
1921         }
1922 
1923         return subInfo;
1924     }
1925 
1926     /**
1927      * Gets an active SubscriptionInfo {@link SubscriptionInfo} associated with the Sim IccId.
1928      *
1929      * @param iccId the IccId of SIM card
1930      * @return SubscriptionInfo, maybe null if its not active
1931      *
1932      * @throws UnsupportedOperationException If the device does not have
1933      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
1934      * @hide
1935      */
1936     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
1937     @Nullable
1938     @SystemApi
getActiveSubscriptionInfoForIcc(@onNull String iccId)1939     public SubscriptionInfo getActiveSubscriptionInfoForIcc(@NonNull String iccId) {
1940         if (VDBG) logd("[getActiveSubscriptionInfoForIccIndex]+ iccId=" + iccId);
1941         if (iccId == null) {
1942             logd("[getActiveSubscriptionInfoForIccIndex]- null iccid");
1943             return null;
1944         }
1945 
1946         SubscriptionInfo result = null;
1947 
1948         try {
1949             ISub iSub = TelephonyManager.getSubscriptionService();
1950             if (iSub != null) {
1951                 result = iSub.getActiveSubscriptionInfoForIccId(iccId, mContext.getOpPackageName(),
1952                         mContext.getAttributionTag());
1953             }
1954         } catch (RemoteException ex) {
1955             // ignore it
1956         }
1957 
1958         return result;
1959     }
1960 
1961     /**
1962      * Get the active SubscriptionInfo associated with the slotIndex
1963      *
1964      * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1965      * or that the calling app has carrier privileges (see
1966      * {@link TelephonyManager#hasCarrierPrivileges}).
1967      *
1968      * @param slotIndex the slot which the subscription is inserted
1969      * @return SubscriptionInfo, maybe null if its not active
1970      *
1971      * @throws UnsupportedOperationException If the device does not have
1972      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
1973      */
1974     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
1975     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
getActiveSubscriptionInfoForSimSlotIndex(int slotIndex)1976     public SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex) {
1977         if (VDBG) logd("[getActiveSubscriptionInfoForSimSlotIndex]+ slotIndex=" + slotIndex);
1978         if (!isValidSlotIndex(slotIndex)) {
1979             logd("[getActiveSubscriptionInfoForSimSlotIndex]- invalid slotIndex");
1980             return null;
1981         }
1982 
1983         SubscriptionInfo result = null;
1984 
1985         try {
1986             ISub iSub = TelephonyManager.getSubscriptionService();
1987             if (iSub != null) {
1988                 result = iSub.getActiveSubscriptionInfoForSimSlotIndex(slotIndex,
1989                         mContext.getOpPackageName(), mContext.getAttributionTag());
1990             }
1991         } catch (RemoteException ex) {
1992             // ignore it
1993         }
1994 
1995         return result;
1996     }
1997 
1998     /**
1999      * Get all subscription info records from SIMs that are inserted now or previously inserted.
2000      *
2001      * <p>
2002      * If the caller does not have {@link Manifest.permission#READ_PHONE_NUMBERS} permission,
2003      * {@link SubscriptionInfo#getNumber()} will return empty string.
2004      * If the caller does not have {@link Manifest.permission#USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER},
2005      * {@link SubscriptionInfo#getIccId()} will return an empty string, and
2006      * {@link SubscriptionInfo#getGroupUuid()} will return {@code null}.
2007      *
2008      * <p>
2009      * The carrier app will only get the list of subscriptions that it has carrier privilege on,
2010      * but will have non-stripped {@link SubscriptionInfo} in the list.
2011      *
2012      * @return List of all {@link SubscriptionInfo} records from SIMs that are inserted or
2013      * previously inserted. Sorted by {@link SubscriptionInfo#getSimSlotIndex()}, then
2014      * {@link SubscriptionInfo#getSubscriptionId()}.
2015      *
2016      * @throws SecurityException if callers do not hold the required permission.
2017      * @throws UnsupportedOperationException If the device does not have
2018      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
2019      */
2020     @NonNull
2021     @RequiresPermission(anyOf = {
2022             Manifest.permission.READ_PHONE_STATE,
2023             "carrier privileges",
2024     })
getAllSubscriptionInfoList()2025     public List<SubscriptionInfo> getAllSubscriptionInfoList() {
2026         List<SubscriptionInfo> result = null;
2027         try {
2028             ISub iSub = TelephonyManager.getSubscriptionService();
2029             if (iSub != null) {
2030                 result = iSub.getAllSubInfoList(mContext.getOpPackageName(),
2031                         mContext.getAttributionTag());
2032             }
2033         } catch (RemoteException ex) {
2034             // ignore it
2035         }
2036 
2037         if (result == null) {
2038             result = Collections.emptyList();
2039         }
2040         return result;
2041     }
2042 
2043     /**
2044      * Get the SubscriptionInfo(s) of the currently active SIM(s).
2045      *
2046      * <p> Returned records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by
2047      * {@link SubscriptionInfo#getSubscriptionId}. Beginning with Android SDK 35, this method will
2048      * never return null.
2049      *
2050      * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
2051      * or that the calling app has carrier privileges (see
2052      * {@link TelephonyManager#hasCarrierPrivileges}).
2053      *
2054      * @return a list of the active {@link SubscriptionInfo} that is visible to the caller. If
2055      *         an empty list or null is returned, then there are no active subscriptions that
2056      *         are visible to the caller. If the number of active subscriptions available to
2057      *         any caller changes, then this change will be indicated by
2058      *         {@link OnSubscriptionsChangedListener#onSubscriptionsChanged}.
2059      *
2060      * @throws UnsupportedOperationException If the device does not have
2061      *         {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
2062      */
2063     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
getActiveSubscriptionInfoList()2064     public @Nullable List<SubscriptionInfo> getActiveSubscriptionInfoList() {
2065         List<SubscriptionInfo> activeList = null;
2066 
2067         try {
2068             ISub iSub = TelephonyManager.getSubscriptionService();
2069             if (iSub != null) {
2070                 activeList = iSub.getActiveSubscriptionInfoList(mContext.getOpPackageName(),
2071                         mContext.getAttributionTag(), mIsForAllUserProfiles);
2072             }
2073         } catch (RemoteException ex) {
2074             // ignore it
2075         }
2076 
2077         if (activeList != null) {
2078             activeList = activeList.stream().filter(subInfo -> isSubscriptionVisible(subInfo))
2079                     .collect(Collectors.toList());
2080         } else {
2081             activeList = Collections.emptyList();
2082         }
2083         return activeList;
2084     }
2085 
2086     /**
2087      * Get both hidden and visible SubscriptionInfo(s) of the currently active SIM(s).
2088      * The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex}
2089      * then by {@link SubscriptionInfo#getSubscriptionId}.
2090      *
2091      * Hidden subscriptions refer to those are not meant visible to the users.
2092      * For example, an opportunistic subscription that is grouped with other
2093      * subscriptions should remain invisible to users as they are only functionally
2094      * supplementary to primary ones.
2095      *
2096      * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
2097      * or that the calling app has carrier privileges (see
2098      * {@link TelephonyManager#hasCarrierPrivileges}). In the latter case, only records accessible
2099      * to the calling app are returned.
2100      *
2101      * @return Sorted list of the currently available {@link SubscriptionInfo}
2102      * records on the device.
2103      * This is similar to {@link #getActiveSubscriptionInfoList} except that it will return
2104      * both active and hidden SubscriptionInfos.
2105      *
2106      * @throws UnsupportedOperationException If the device does not have
2107      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
2108      */
getCompleteActiveSubscriptionInfoList()2109     public @NonNull List<SubscriptionInfo> getCompleteActiveSubscriptionInfoList() {
2110         return getActiveSubscriptionInfoList(/* userVisibleonly */ false);
2111     }
2112 
2113     /**
2114      * Create a new subscription manager instance that can see all subscriptions across
2115      * user profiles.
2116      *
2117      * The permission check for accessing all subscriptions will be enforced upon calling the
2118      * individual APIs linked below.
2119      *
2120      * @return a SubscriptionManager that can see all subscriptions regardless its user profile
2121      * association.
2122      *
2123      * @see #getActiveSubscriptionInfoList
2124      * @see #getActiveSubscriptionInfoCount
2125      * @see UserHandle
2126      */
2127     @FlaggedApi(Flags.FLAG_ENFORCE_SUBSCRIPTION_USER_FILTER)
2128     @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_PROFILES)
createForAllUserProfiles()2129     @NonNull public SubscriptionManager createForAllUserProfiles() {
2130         return new SubscriptionManager(mContext, true/*isForAllUserProfiles*/);
2131     }
2132 
2133     /**
2134     * This is similar to {@link #getActiveSubscriptionInfoList()}, but if userVisibleOnly
2135     * is true, it will filter out the hidden subscriptions.
2136     *
2137     * @hide
2138     */
getActiveSubscriptionInfoList(boolean userVisibleOnly)2139     public @NonNull List<SubscriptionInfo> getActiveSubscriptionInfoList(boolean userVisibleOnly) {
2140         List<SubscriptionInfo> activeList = null;
2141 
2142         try {
2143             ISub iSub = TelephonyManager.getSubscriptionService();
2144             if (iSub != null) {
2145                 activeList = iSub.getActiveSubscriptionInfoList(mContext.getOpPackageName(),
2146                         mContext.getAttributionTag(), true /*isForAllUserProfiles*/);
2147             }
2148         } catch (RemoteException ex) {
2149             // ignore it
2150         }
2151 
2152         if (activeList == null || activeList.isEmpty()) {
2153             return Collections.emptyList();
2154         } else if (userVisibleOnly) {
2155             return activeList.stream().filter(subInfo -> isSubscriptionVisible(subInfo))
2156                     .collect(Collectors.toList());
2157         } else {
2158             return activeList;
2159         }
2160     }
2161 
2162     /**
2163      * Gets the SubscriptionInfo(s) of all available subscriptions, if any.
2164      *
2165      * <p>Available subscriptions include active ones (those with a non-negative
2166      * {@link SubscriptionInfo#getSimSlotIndex()}) as well as inactive but installed embedded
2167      * subscriptions.
2168      *
2169      * <p>The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by
2170      * {@link SubscriptionInfo#getSubscriptionId}.
2171      *
2172      * @return Sorted list of the current {@link SubscriptionInfo} records available on the
2173      * device.
2174      * <ul>
2175      * <li>
2176      * If null is returned the current state is unknown but if a
2177      * {@link OnSubscriptionsChangedListener} has been registered
2178      * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be invoked in the future.
2179      * <li>
2180      * If the list is empty then there are no {@link SubscriptionInfo} records currently available.
2181      * <li>
2182      * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
2183      * then by {@link SubscriptionInfo#getSubscriptionId}.
2184      * </ul>
2185      *
2186      * <p>
2187      * Permissions android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE is required
2188      * for #getAvailableSubscriptionInfoList to be invoked.
2189      *
2190      * @throws UnsupportedOperationException If the device does not have
2191      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
2192      * @hide
2193      */
2194     @SystemApi
getAvailableSubscriptionInfoList()2195     public @Nullable List<SubscriptionInfo> getAvailableSubscriptionInfoList() {
2196         List<SubscriptionInfo> result = null;
2197 
2198         try {
2199             ISub iSub = TelephonyManager.getSubscriptionService();
2200             if (iSub != null) {
2201                 result = iSub.getAvailableSubscriptionInfoList(mContext.getOpPackageName(),
2202                         mContext.getAttributionTag());
2203             }
2204         } catch (RemoteException ex) {
2205             // ignore it
2206         }
2207         return (result == null) ? Collections.emptyList() : result;
2208     }
2209 
2210     /**
2211      * Gets the SubscriptionInfo(s) of all embedded subscriptions accessible to the calling app, if
2212      * any.
2213      *
2214      * <p>Only those subscriptions for which the calling app has carrier privileges per the
2215      * subscription metadata, if any, will be included in the returned list.
2216      *
2217      * <p>The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by
2218      * {@link SubscriptionInfo#getSubscriptionId}.
2219      *
2220      * @return Sorted list of the current embedded {@link SubscriptionInfo} records available on the
2221      * device which are accessible to the caller.
2222      * <ul>
2223      * <li>
2224      * If null is returned the current state is unknown but if a
2225      * {@link OnSubscriptionsChangedListener} has been registered
2226      * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be invoked in the future.
2227      * <li>
2228      * If the list is empty then there are no {@link SubscriptionInfo} records currently available.
2229      * <li>
2230      * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
2231      * then by {@link SubscriptionInfo#getSubscriptionId}.
2232      * </ul>
2233      *
2234      * @throws UnsupportedOperationException If the device does not have
2235      *          {@link PackageManager#FEATURE_TELEPHONY_EUICC}.
2236      */
getAccessibleSubscriptionInfoList()2237     public @Nullable List<SubscriptionInfo> getAccessibleSubscriptionInfoList() {
2238         List<SubscriptionInfo> result = null;
2239 
2240         try {
2241             ISub iSub = TelephonyManager.getSubscriptionService();
2242             if (iSub != null) {
2243                 result = iSub.getAccessibleSubscriptionInfoList(mContext.getOpPackageName());
2244             }
2245         } catch (RemoteException ex) {
2246             // ignore it
2247         }
2248         return (result == null) ? Collections.emptyList() : result;
2249     }
2250 
2251     /**
2252      * Request a refresh of the platform cache of profile information for the eUICC which
2253      * corresponds to the card ID returned by {@link TelephonyManager#getCardIdForDefaultEuicc()}.
2254      *
2255      * <p>Should be called by the EuiccService implementation whenever this information changes due
2256      * to an operation done outside the scope of a request initiated by the platform to the
2257      * EuiccService. There is no need to refresh for downloads, deletes, or other operations that
2258      * were made through the EuiccService.
2259      *
2260      * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
2261      *
2262      * @see TelephonyManager#getCardIdForDefaultEuicc() for more information on the card ID.
2263      *
2264      * @throws UnsupportedOperationException If the device does not have
2265      *          {@link PackageManager#FEATURE_TELEPHONY_EUICC}.
2266      * @hide
2267      */
2268     @SystemApi
requestEmbeddedSubscriptionInfoListRefresh()2269     public void requestEmbeddedSubscriptionInfoListRefresh() {
2270         int cardId = TelephonyManager.from(mContext).getCardIdForDefaultEuicc();
2271         try {
2272             ISub iSub = TelephonyManager.getSubscriptionService();
2273             if (iSub != null) {
2274                 iSub.requestEmbeddedSubscriptionInfoListRefresh(cardId);
2275             }
2276         } catch (RemoteException ex) {
2277             logd("requestEmbeddedSubscriptionInfoListFresh for card = " + cardId + " failed.");
2278         }
2279     }
2280 
2281     /**
2282      * Request a refresh of the platform cache of profile information for the eUICC with the given
2283      * {@code cardId}.
2284      *
2285      * <p>Should be called by the EuiccService implementation whenever this information changes due
2286      * to an operation done outside the scope of a request initiated by the platform to the
2287      * EuiccService. There is no need to refresh for downloads, deletes, or other operations that
2288      * were made through the EuiccService.
2289      *
2290      * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
2291      *
2292      * @param cardId the card ID of the eUICC.
2293      *
2294      * @see TelephonyManager#getCardIdForDefaultEuicc() for more information on the card ID.
2295      *
2296      * @throws UnsupportedOperationException If the device does not have
2297      *          {@link PackageManager#FEATURE_TELEPHONY_EUICC}.
2298      * @hide
2299      */
2300     @SystemApi
requestEmbeddedSubscriptionInfoListRefresh(int cardId)2301     public void requestEmbeddedSubscriptionInfoListRefresh(int cardId) {
2302         try {
2303             ISub iSub = TelephonyManager.getSubscriptionService();
2304             if (iSub != null) {
2305                 iSub.requestEmbeddedSubscriptionInfoListRefresh(cardId);
2306             }
2307         } catch (RemoteException ex) {
2308             logd("requestEmbeddedSubscriptionInfoListFresh for card = " + cardId + " failed.");
2309         }
2310     }
2311 
2312     /**
2313      * Get the active subscription count.
2314      *
2315      * @return The current number of active subscriptions.
2316      *
2317      * @see #getActiveSubscriptionInfoList()
2318      *
2319      * @throws UnsupportedOperationException If the device does not have
2320      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
2321      */
2322     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
getActiveSubscriptionInfoCount()2323     public int getActiveSubscriptionInfoCount() {
2324         int result = 0;
2325 
2326         try {
2327             ISub iSub = TelephonyManager.getSubscriptionService();
2328             if (iSub != null) {
2329                 result = iSub.getActiveSubInfoCount(mContext.getOpPackageName(),
2330                         mContext.getAttributionTag(), mIsForAllUserProfiles);
2331             }
2332         } catch (RemoteException ex) {
2333             // ignore it
2334         }
2335 
2336         return result;
2337     }
2338 
2339     /**
2340      * @return the maximum number of active subscriptions that will be returned by
2341      * {@link #getActiveSubscriptionInfoList} and the value returned by
2342      * {@link #getActiveSubscriptionInfoCount}.
2343      */
getActiveSubscriptionInfoCountMax()2344     public int getActiveSubscriptionInfoCountMax() {
2345         int result = 0;
2346 
2347         try {
2348             ISub iSub = TelephonyManager.getSubscriptionService();
2349             if (iSub != null) {
2350                 result = iSub.getActiveSubInfoCountMax();
2351             }
2352         } catch (RemoteException ex) {
2353             // ignore it
2354         }
2355 
2356         return result;
2357     }
2358 
2359     /**
2360      * Add a new SubscriptionInfo to SubscriptionInfo database if needed
2361      * @param iccId the IccId of the SIM card
2362      * @param slotIndex the slot which the SIM is inserted
2363      * @return the URL of the newly created row or the updated row
2364      * @hide
2365      */
addSubscriptionInfoRecord(String iccId, int slotIndex)2366     public Uri addSubscriptionInfoRecord(String iccId, int slotIndex) {
2367         if (VDBG) logd("[addSubscriptionInfoRecord]+ iccId:" + iccId + " slotIndex:" + slotIndex);
2368         if (iccId == null) {
2369             logd("[addSubscriptionInfoRecord]- null iccId");
2370         }
2371         if (!isValidSlotIndex(slotIndex)) {
2372             logd("[addSubscriptionInfoRecord]- invalid slotIndex");
2373         }
2374 
2375         addSubscriptionInfoRecord(iccId, null, slotIndex, SUBSCRIPTION_TYPE_LOCAL_SIM);
2376 
2377         // FIXME: Always returns null?
2378         return null;
2379 
2380     }
2381 
2382     /**
2383      * Add a new SubscriptionInfo to SubscriptionInfo database if needed
2384      * @param uniqueId This is the unique identifier for the subscription within the
2385      *                 specific subscription type.
2386      * @param displayName human-readable name of the device the subscription corresponds to.
2387      * @param slotIndex the slot assigned to this subscription. It is ignored for subscriptionType
2388      *                  of {@link #SUBSCRIPTION_TYPE_REMOTE_SIM}.
2389      * @param subscriptionType the {@link #SUBSCRIPTION_TYPE}
2390      *
2391      * @throws UnsupportedOperationException If the device does not have
2392      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
2393      * @hide
2394      */
2395     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
addSubscriptionInfoRecord(@onNull String uniqueId, @Nullable String displayName, int slotIndex, @SubscriptionType int subscriptionType)2396     public void addSubscriptionInfoRecord(@NonNull String uniqueId, @Nullable String displayName,
2397             int slotIndex, @SubscriptionType int subscriptionType) {
2398         if (VDBG) {
2399             logd("[addSubscriptionInfoRecord]+ uniqueId:" + uniqueId
2400                     + ", displayName:" + displayName + ", slotIndex:" + slotIndex
2401                     + ", subscriptionType: " + subscriptionType);
2402         }
2403         if (uniqueId == null) {
2404             Log.e(LOG_TAG, "[addSubscriptionInfoRecord]- uniqueId is null");
2405             return;
2406         }
2407 
2408         try {
2409             ISub iSub = TelephonyManager.getSubscriptionService();
2410             if (iSub == null) {
2411                 Log.e(LOG_TAG, "[addSubscriptionInfoRecord]- ISub service is null");
2412                 return;
2413             }
2414             int result = iSub.addSubInfo(uniqueId, displayName, slotIndex, subscriptionType);
2415             if (result < 0) {
2416                 Log.e(LOG_TAG, "Adding of subscription didn't succeed: error = " + result);
2417             } else {
2418                 logd("successfully added new subscription");
2419             }
2420         } catch (RemoteException ex) {
2421             // ignore it
2422         }
2423     }
2424 
2425     /**
2426      * Remove subscription info record from the subscription database.
2427      *
2428      * @param uniqueId This is the unique identifier for the subscription within the specific
2429      * subscription type.
2430      * @param subscriptionType the type of subscription to be removed.
2431      *
2432      * @throws NullPointerException if {@code uniqueId} is {@code null}.
2433      * @throws SecurityException if callers do not hold the required permission.
2434      *
2435      * @throws UnsupportedOperationException If the device does not have
2436      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
2437      * @hide
2438      */
2439     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
removeSubscriptionInfoRecord(@onNull String uniqueId, @SubscriptionType int subscriptionType)2440     public void removeSubscriptionInfoRecord(@NonNull String uniqueId,
2441             @SubscriptionType int subscriptionType) {
2442         if (VDBG) {
2443             logd("[removeSubscriptionInfoRecord]+ uniqueId:" + uniqueId
2444                     + ", subscriptionType: " + subscriptionType);
2445         }
2446         if (uniqueId == null) {
2447             Log.e(LOG_TAG, "[addSubscriptionInfoRecord]- uniqueId is null");
2448             return;
2449         }
2450 
2451         try {
2452             ISub iSub = TelephonyManager.getSubscriptionService();
2453             if (iSub == null) {
2454                 Log.e(LOG_TAG, "[removeSubscriptionInfoRecord]- ISub service is null");
2455                 return;
2456             }
2457             boolean result = iSub.removeSubInfo(uniqueId, subscriptionType);
2458             if (!result) {
2459                 Log.e(LOG_TAG, "Removal of subscription didn't succeed");
2460             } else {
2461                 logd("successfully removed subscription");
2462             }
2463         } catch (RemoteException ex) {
2464             // ignore it
2465         }
2466     }
2467 
2468     /**
2469      * Set SIM icon tint color for subscription ID
2470      * @param tint the RGB value of icon tint color of the SIM
2471      * @param subId the unique subscription ID in database
2472      * @return the number of records updated
2473      * @hide
2474      */
2475     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setIconTint(@olorInt int tint, int subId)2476     public int setIconTint(@ColorInt int tint, int subId) {
2477         if (VDBG) logd("[setIconTint]+ tint:" + tint + " subId:" + subId);
2478         return setSubscriptionPropertyHelper(subId, "setIconTint",
2479                 (iSub)-> iSub.setIconTint(subId, tint)
2480         );
2481     }
2482 
2483     /**
2484      * Set the display name for a subscription ID
2485      * @param displayName the display name of SIM card
2486      * @param subId the unique Subscritpion ID in database
2487      * @param nameSource SIM display name source
2488      * @return the number of records updated or < 0 if invalid subId
2489      * @hide
2490      */
2491     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setDisplayName(@ullable String displayName, int subId, @SimDisplayNameSource int nameSource)2492     public int setDisplayName(@Nullable String displayName, int subId,
2493             @SimDisplayNameSource int nameSource) {
2494         if (VDBG) {
2495             logd("[setDisplayName]+  displayName:" + displayName + " subId:" + subId
2496                     + " nameSource:" + nameSource);
2497         }
2498         return setSubscriptionPropertyHelper(subId, "setDisplayName",
2499                 (iSub)-> iSub.setDisplayNameUsingSrc(displayName, subId, nameSource)
2500         );
2501     }
2502 
2503     /**
2504      * Set phone number by subId
2505      * @param number the phone number of the SIM
2506      * @param subId the unique SubscriptionInfo index in database
2507      * @return the number of records updated
2508      * @hide
2509      */
2510     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
setDisplayNumber(String number, int subId)2511     public int setDisplayNumber(String number, int subId) {
2512         if (number == null) {
2513             logd("[setDisplayNumber]- fail");
2514             return -1;
2515         }
2516         return setSubscriptionPropertyHelper(subId, "setDisplayNumber",
2517                 (iSub)-> iSub.setDisplayNumber(number, subId)
2518         );
2519     }
2520 
2521     /**
2522      * Set data roaming by simInfo index
2523      * @param roaming 0:Don't allow data when roaming, 1:Allow data when roaming
2524      * @param subId the unique SubscriptionInfo index in database
2525      * @return the number of records updated
2526      * @hide
2527      */
2528     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
setDataRoaming(int roaming, int subId)2529     public int setDataRoaming(int roaming, int subId) {
2530         if (VDBG) logd("[setDataRoaming]+ roaming:" + roaming + " subId:" + subId);
2531         return setSubscriptionPropertyHelper(subId, "setDataRoaming",
2532                 (iSub)->iSub.setDataRoaming(roaming, subId)
2533         );
2534     }
2535 
2536     /**
2537      * Get slotIndex associated with the subscription.
2538      *
2539      * @param subscriptionId the unique SubscriptionInfo index in database
2540      * @return slotIndex as a positive integer or {@link #INVALID_SIM_SLOT_INDEX} if the supplied
2541      * subscriptionId doesn't have an associated slot index.
2542      */
getSlotIndex(int subscriptionId)2543     public static int getSlotIndex(int subscriptionId) {
2544         return sGetSlotIndexCache.query(subscriptionId);
2545     }
2546 
2547     /**
2548      * Get an array of subscription ids for the specified logical SIM slot Index. The maximum size
2549      * of the array is 1. This API was mistakenly designed to return multiple subscription ids,
2550      * which is not possible in the current Android telephony architecture.
2551      *
2552      * @param slotIndex The logical SIM slot index.
2553      *
2554      * @return Subscription id of the active subscription on the specified logical SIM slot index.
2555      * If SIM is absent on the slot, a single element array of {@link #INVALID_SUBSCRIPTION_ID} will
2556      * be returned. {@code null} if the provided {@code slotIndex} is not valid.
2557      *
2558      * @deprecated Use {@link #getSubscriptionId(int)} instead.
2559      */
2560     @Deprecated
2561     @Nullable
getSubscriptionIds(int slotIndex)2562     public int[] getSubscriptionIds(int slotIndex) {
2563         if (!isValidSlotIndex(slotIndex)) {
2564             return null;
2565         }
2566         return new int[]{getSubscriptionId(slotIndex)};
2567     }
2568 
2569     /**
2570      * Get an array of subscription ids for the specified logical SIM slot Index. The maximum size
2571      * of the array is 1. This API was mistakenly designed to return multiple subscription ids,
2572      * which is not possible in the current Android telephony architecture.
2573      *
2574      * @param slotIndex The logical SIM slot index.
2575      *
2576      * @return Subscription id of the active subscription on the specified logical SIM slot index.
2577      * If SIM is absent on the slot, a single element array of {@link #INVALID_SUBSCRIPTION_ID} will
2578      * be returned. {@code null} if the provided {@code slotIndex} is not valid.
2579      *
2580      * @deprecated Use {@link #getSubscriptionId(int)} instead.
2581      * @hide
2582      */
2583     @Deprecated
getSubId(int slotIndex)2584     public static int[] getSubId(int slotIndex) {
2585         if (!isValidSlotIndex(slotIndex)) {
2586             return null;
2587         }
2588         return new int[]{getSubscriptionId(slotIndex)};
2589     }
2590 
2591     /**
2592      * Get the subscription id for specified logical SIM slot index.
2593      *
2594      * @param slotIndex The logical SIM slot index.
2595      * @return The subscription id. {@link #INVALID_SUBSCRIPTION_ID} if SIM is absent.
2596      */
getSubscriptionId(int slotIndex)2597     public static int getSubscriptionId(int slotIndex) {
2598         if (!isValidSlotIndex(slotIndex)) {
2599             return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2600         }
2601 
2602         return sGetSubIdCache.query(slotIndex);
2603     }
2604 
2605     /** @hide */
2606     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
getPhoneId(int subId)2607     public static int getPhoneId(int subId) {
2608         return sGetPhoneIdCache.query(subId);
2609     }
2610 
logd(String msg)2611     private static void logd(String msg) {
2612         Rlog.d(LOG_TAG, msg);
2613     }
2614 
loge(String msg)2615     private static void loge(String msg) {
2616         Rlog.e(LOG_TAG, msg);
2617     }
2618 
2619     /**
2620      * Returns the system's default subscription id.
2621      *
2622      * For a voice capable device, it will return getDefaultVoiceSubscriptionId.
2623      * For a data only device, it will return the getDefaultDataSubscriptionId.
2624      * May return an INVALID_SUBSCRIPTION_ID on error.
2625      *
2626      * @return the "system" default subscription id.
2627      */
getDefaultSubscriptionId()2628     public static int getDefaultSubscriptionId() {
2629         return sGetDefaultSubIdCacheAsUser.query(Process.myUserHandle().getIdentifier());
2630     }
2631 
2632     /**
2633      * Returns the system's default voice subscription id.
2634      *
2635      * On a data only device or on error, will return INVALID_SUBSCRIPTION_ID.
2636      *
2637      * @return the default voice subscription Id.
2638      *
2639      * @throws UnsupportedOperationException If the device does not have
2640      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
2641      */
getDefaultVoiceSubscriptionId()2642     public static int getDefaultVoiceSubscriptionId() {
2643         int subId = INVALID_SUBSCRIPTION_ID;
2644 
2645         try {
2646             ISub iSub = TelephonyManager.getSubscriptionService();
2647             if (iSub != null) {
2648                 subId = iSub.getDefaultVoiceSubIdAsUser(Process.myUserHandle().getIdentifier());
2649             }
2650         } catch (RemoteException ex) {
2651             // ignore it
2652         }
2653 
2654         if (VDBG) logd("getDefaultVoiceSubscriptionId, sub id = " + subId);
2655         return subId;
2656     }
2657 
2658     /**
2659      * Sets the system's default voice subscription id.
2660      *
2661      * On a data-only device, this is a no-op.
2662      *
2663      * May throw a {@link RuntimeException} if the provided subscription id is equal to
2664      * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}
2665      *
2666      * @param subscriptionId A valid subscription ID to set as the system default, or
2667      *                       {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}
2668      *
2669      * @throws UnsupportedOperationException If the device does not have
2670      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
2671      * @hide
2672      */
2673     @SystemApi
2674     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setDefaultVoiceSubscriptionId(int subscriptionId)2675     public void setDefaultVoiceSubscriptionId(int subscriptionId) {
2676         if (VDBG) logd("setDefaultVoiceSubId sub id = " + subscriptionId);
2677         try {
2678             ISub iSub = TelephonyManager.getSubscriptionService();
2679             if (iSub != null) {
2680                 iSub.setDefaultVoiceSubId(subscriptionId);
2681             }
2682         } catch (RemoteException ex) {
2683             // ignore it
2684         }
2685     }
2686 
2687     /**
2688      * Same as {@link #setDefaultVoiceSubscriptionId(int)}, but preserved for backwards
2689      * compatibility.
2690      *
2691      * @throws UnsupportedOperationException If the device does not have
2692      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
2693      * @hide
2694      */
setDefaultVoiceSubId(int subId)2695     public void setDefaultVoiceSubId(int subId) {
2696         setDefaultVoiceSubscriptionId(subId);
2697     }
2698 
2699     /**
2700      * Return the SubscriptionInfo for default voice subscription.
2701      *
2702      * Will return null on data only devices, or on error.
2703      *
2704      * @return the SubscriptionInfo for the default voice subscription.
2705      * @hide
2706      */
2707     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getDefaultVoiceSubscriptionInfo()2708     public SubscriptionInfo getDefaultVoiceSubscriptionInfo() {
2709         return getActiveSubscriptionInfo(getDefaultVoiceSubscriptionId());
2710     }
2711 
2712     /** @hide */
2713     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getDefaultVoicePhoneId()2714     public static int getDefaultVoicePhoneId() {
2715         return getPhoneId(getDefaultVoiceSubscriptionId());
2716     }
2717 
2718     /**
2719      * Returns the system's default SMS subscription id.
2720      *
2721      * On a data only device or on error, will return INVALID_SUBSCRIPTION_ID.
2722      *
2723      * @return the default SMS subscription Id.
2724      */
getDefaultSmsSubscriptionId()2725     public static int getDefaultSmsSubscriptionId() {
2726         return sGetDefaultSmsSubIdCacheAsUser.query(Process.myUserHandle().getIdentifier());
2727     }
2728 
2729     /**
2730      * Set the subscription which will be used by default for SMS, with the subscription which
2731      * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied
2732      * subscription ID is not usable (check with {@link #isUsableSubscriptionId(int)}).
2733      *
2734      * @param subscriptionId the supplied subscription ID
2735      *
2736      * @throws UnsupportedOperationException If the device does not have
2737      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
2738      * @hide
2739      */
2740     @SystemApi
2741     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
setDefaultSmsSubId(int subscriptionId)2742     public void setDefaultSmsSubId(int subscriptionId) {
2743         if (VDBG) logd("setDefaultSmsSubId sub id = " + subscriptionId);
2744         try {
2745             ISub iSub = TelephonyManager.getSubscriptionService();
2746             if (iSub != null) {
2747                 iSub.setDefaultSmsSubId(subscriptionId);
2748             }
2749         } catch (RemoteException ex) {
2750             ex.rethrowFromSystemServer();
2751         }
2752     }
2753 
2754     /**
2755      * Returns the system's default data subscription id.
2756      *
2757      * On a voice only device or on error, will return INVALID_SUBSCRIPTION_ID.
2758      *
2759      * @return the default data subscription Id.
2760      */
getDefaultDataSubscriptionId()2761     public static int getDefaultDataSubscriptionId() {
2762         return sGetDefaultDataSubIdCache.query(null);
2763     }
2764 
2765     /**
2766      * Set the subscription which will be used by default for data, with the subscription which
2767      * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied
2768      * subscription ID is not usable (check with {@link #isUsableSubscriptionId(int)}).
2769      *
2770      * @param subscriptionId the supplied subscription ID
2771      *
2772      * @throws UnsupportedOperationException If the device does not have
2773      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
2774      * @hide
2775      */
2776     @SystemApi
2777     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
setDefaultDataSubId(int subscriptionId)2778     public void setDefaultDataSubId(int subscriptionId) {
2779         if (VDBG) logd("setDataSubscription sub id = " + subscriptionId);
2780         try {
2781             ISub iSub = TelephonyManager.getSubscriptionService();
2782             if (iSub != null) {
2783                 iSub.setDefaultDataSubId(subscriptionId);
2784             }
2785         } catch (RemoteException ex) {
2786             // ignore it
2787         }
2788     }
2789 
2790     /**
2791      * Return the SubscriptionInfo for default data subscription.
2792      *
2793      * Will return null on voice only devices, or on error.
2794      *
2795      * @return the SubscriptionInfo for the default data subscription.
2796      *
2797      * @throws UnsupportedOperationException If the device does not have
2798      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
2799      * @hide
2800      */
2801     @UnsupportedAppUsage
getDefaultDataSubscriptionInfo()2802     public SubscriptionInfo getDefaultDataSubscriptionInfo() {
2803         return getActiveSubscriptionInfo(getDefaultDataSubscriptionId());
2804     }
2805 
2806     /**
2807      * Check if the supplied subscription ID is valid.
2808      *
2809      * <p>A valid subscription ID is not necessarily an active subscription ID
2810      * (see {@link #isActiveSubscriptionId(int)}) or an usable subscription ID
2811      * (see {@link #isUsableSubscriptionId(int)}). Unless specifically noted, subscription
2812      * APIs work with a valid subscription ID.
2813      *
2814      * @param subscriptionId The subscription ID.
2815      * @return {@code true} if the supplied subscriptionId is valid; {@code false} otherwise.
2816      */
isValidSubscriptionId(int subscriptionId)2817     public static boolean isValidSubscriptionId(int subscriptionId) {
2818         return subscriptionId > INVALID_SUBSCRIPTION_ID;
2819     }
2820 
2821     /**
2822      * Check if the supplied subscription ID is usable.
2823      *
2824      * <p>A usable subscription ID is a valid subscription ID, but not necessarily an active
2825      * subscription ID (see {@link #isActiveSubscriptionId(int)}). Some subscription APIs
2826      * require a usable subscription ID, and this is noted in their documentation; otherwise, a
2827      * subscription ID does not need to be usable for subscription functions, only valid.
2828      *
2829      * @param subscriptionId the subscription ID
2830      * @return {@code true} if the subscription ID is usable; {@code false} otherwise.
2831      */
isUsableSubscriptionId(int subscriptionId)2832     public static boolean isUsableSubscriptionId(int subscriptionId) {
2833         return isUsableSubIdValue(subscriptionId);
2834     }
2835 
2836     /**
2837      * @return true if subId is an usable subId value else false. A
2838      * usable subId means its neither a INVALID_SUBSCRIPTION_ID nor a DEFAULT_SUB_ID.
2839      * @hide
2840      */
2841     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
isUsableSubIdValue(int subId)2842     public static boolean isUsableSubIdValue(int subId) {
2843         return subId >= MIN_SUBSCRIPTION_ID_VALUE && subId <= MAX_SUBSCRIPTION_ID_VALUE;
2844     }
2845 
2846     /** @hide */
2847     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
isValidSlotIndex(int slotIndex)2848     public static boolean isValidSlotIndex(int slotIndex) {
2849         return slotIndex >= 0 && slotIndex < TelephonyManager.getDefault().getActiveModemCount();
2850     }
2851 
2852     /** @hide */
2853     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
isValidPhoneId(int phoneId)2854     public static boolean isValidPhoneId(int phoneId) {
2855         return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getActiveModemCount();
2856     }
2857 
2858     /**
2859      * Puts phone ID and subscription ID into the {@code intent}.
2860      *
2861      * <p>If the subscription ID is not valid, only puts phone ID into the {@code intent}.
2862      *
2863      * @hide
2864      */
2865     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
putPhoneIdAndSubIdExtra(Intent intent, int phoneId)2866     public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId) {
2867         int subId = SubscriptionManager.getSubscriptionId(phoneId);
2868         putPhoneIdAndMaybeSubIdExtra(intent, phoneId, subId);
2869     }
2870 
2871     /** @hide */
2872     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
putPhoneIdAndSubIdExtra(Intent intent, int phoneId, int subId)2873     public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId, int subId) {
2874         if (VDBG) logd("putPhoneIdAndSubIdExtra: phoneId=" + phoneId + " subId=" + subId);
2875         intent.putExtra(EXTRA_SLOT_INDEX, phoneId);
2876         intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
2877         putSubscriptionIdExtra(intent, subId);
2878     }
2879 
2880     /**
2881      * Puts phone ID and subscription ID into the {@code intent}.
2882      *
2883      * <p>If the subscription ID is not valid, only puts phone ID into the {@code intent}.
2884      *
2885      * @hide
2886      */
putPhoneIdAndMaybeSubIdExtra(Intent intent, int phoneId, int subId)2887     public static void putPhoneIdAndMaybeSubIdExtra(Intent intent, int phoneId, int subId) {
2888         if (isValidSubscriptionId(subId)) {
2889             putPhoneIdAndSubIdExtra(intent, phoneId, subId);
2890         } else {
2891             if (VDBG) logd("putPhoneIdAndMaybeSubIdExtra: invalid subId");
2892             intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
2893             intent.putExtra(EXTRA_SLOT_INDEX, phoneId);
2894         }
2895     }
2896 
2897     /**
2898      * Get visible subscription Id(s) of the currently active SIM(s).
2899      *
2900      * @return the list of subId's that are active,
2901      *         is never null but the length may be 0.
2902      *
2903      * @throws UnsupportedOperationException If the device does not have
2904      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
2905      * @hide
2906      */
2907     @SystemApi
2908     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
getActiveSubscriptionIdList()2909     public @NonNull int[] getActiveSubscriptionIdList() {
2910         return getActiveSubscriptionIdList(/* visibleOnly */ true);
2911     }
2912 
2913     /**
2914      * Get both hidden and visible subscription Id(s) of the currently active SIM(s).
2915      *
2916      * Hidden subscriptions refer to those are not meant visible to the users.
2917      * For example, an opportunistic subscription that is grouped with other
2918      * subscriptions should remain invisible to users as they are only functionally
2919      * supplementary to primary ones.
2920      *
2921      * @return the list of subId's that are active,
2922      *         is never null but the length may be 0.
2923      *
2924      * @throws UnsupportedOperationException If the device does not have
2925      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
2926      * @hide
2927      */
2928     @SystemApi
2929     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
getCompleteActiveSubscriptionIdList()2930     public @NonNull int[] getCompleteActiveSubscriptionIdList() {
2931         return getActiveSubscriptionIdList(/* visibleOnly */false);
2932     }
2933 
2934     /**
2935      * @return a non-null list of subId's that are active.
2936      *
2937      * @hide
2938      */
getActiveSubscriptionIdList(boolean visibleOnly)2939     public @NonNull int[] getActiveSubscriptionIdList(boolean visibleOnly) {
2940         try {
2941             ISub iSub = TelephonyManager.getSubscriptionService();
2942             if (iSub != null) {
2943                 int[] subId = iSub.getActiveSubIdList(visibleOnly);
2944                 if (subId != null) return subId;
2945             }
2946         } catch (RemoteException ex) {
2947             // ignore it
2948         }
2949 
2950         return new int[0];
2951     }
2952 
2953     /**
2954      * Returns true if the device is considered roaming on the current
2955      * network for a subscription.
2956      * <p>
2957      * Availability: Only when user registered to a network.
2958      *
2959      * @param subId The subscription ID
2960      * @return true if the network for the subscription is roaming, false otherwise
2961      */
isNetworkRoaming(int subId)2962     public boolean isNetworkRoaming(int subId) {
2963         final int phoneId = getPhoneId(subId);
2964         if (phoneId < 0) {
2965             // What else can we do?
2966             return false;
2967         }
2968         return TelephonyManager.getDefault().isNetworkRoaming(subId);
2969     }
2970 
2971     /**
2972      * Set a field in the subscription database. Note not all fields are supported.
2973      *
2974      * @param subscriptionId Subscription Id of Subscription.
2975      * @param columnName Column name in the database. Note not all fields are supported.
2976      * @param value Value to store in the database.
2977      *
2978      * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not
2979      * exposed.
2980      * @throws SecurityException if callers do not hold the required permission.
2981      *
2982      * @see android.provider.Telephony.SimInfo for all the columns.
2983      *
2984      * @hide
2985      */
2986     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setSubscriptionProperty(int subscriptionId, @NonNull String columnName, @NonNull String value)2987     public static void setSubscriptionProperty(int subscriptionId, @NonNull String columnName,
2988             @NonNull String value) {
2989         try {
2990             ISub iSub = TelephonyManager.getSubscriptionService();
2991             if (iSub != null) {
2992                 iSub.setSubscriptionProperty(subscriptionId, columnName, value);
2993             }
2994         } catch (RemoteException ex) {
2995             // ignore it
2996         }
2997     }
2998 
2999     /**
3000      * Serialize list of contacts uri to string
3001      * @hide
3002      */
serializeUriLists(List<Uri> uris)3003     public static String serializeUriLists(List<Uri> uris) {
3004         List<String> contacts = new ArrayList<>();
3005         for (Uri uri : uris) {
3006             contacts.add(uri.toString());
3007         }
3008         try {
3009             ByteArrayOutputStream bos = new ByteArrayOutputStream();
3010             ObjectOutputStream oos = new ObjectOutputStream(bos);
3011             oos.writeObject(contacts);
3012             oos.flush();
3013             return Base64.encodeToString(bos.toByteArray(), Base64.DEFAULT);
3014         } catch (IOException e) {
3015             logd("serializeUriLists IO exception");
3016         }
3017         return "";
3018     }
3019 
3020     /**
3021      * Get specific field in string format from the subscription info database.
3022      *
3023      * @param context The calling context.
3024      * @param subscriptionId Subscription id of the subscription.
3025      * @param columnName Column name in subscription database.
3026      *
3027      * @return Value in string format associated with {@code subscriptionId} and {@code columnName}
3028      * from the database. Empty string if the {@code subscriptionId} is invalid (for backward
3029      * compatible).
3030      *
3031      * @throws IllegalArgumentException if the field is not exposed.
3032      *
3033      * @see android.provider.Telephony.SimInfo for all the columns.
3034      *
3035      * @hide
3036      */
3037     @NonNull
3038     @RequiresPermission(anyOf = {
3039             Manifest.permission.READ_PHONE_STATE,
3040             Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
3041             "carrier privileges",
3042     })
getStringSubscriptionProperty(@onNull Context context, int subscriptionId, @NonNull String columnName)3043     private static String getStringSubscriptionProperty(@NonNull Context context,
3044             int subscriptionId, @NonNull String columnName) {
3045         String resultValue = null;
3046         try {
3047             ISub iSub = TelephonyManager.getSubscriptionService();
3048             if (iSub != null) {
3049                 resultValue = iSub.getSubscriptionProperty(subscriptionId, columnName,
3050                         context.getOpPackageName(), context.getAttributionTag());
3051             }
3052         } catch (RemoteException ex) {
3053             // ignore it
3054         }
3055         return TextUtils.emptyIfNull(resultValue);
3056     }
3057 
3058     /**
3059      * Get specific field in {@code boolean} format from the subscription info database.
3060      *
3061      * @param subscriptionId Subscription id of the subscription.
3062      * @param columnName Column name in subscription database.
3063      * @param defaultValue Default value in case not found or error.
3064      * @param context The calling context.
3065      *
3066      * @return Value in {@code boolean} format associated with {@code subscriptionId} and
3067      * {@code columnName} from the database, or {@code defaultValue} if not found or error.
3068      *
3069      * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not
3070      * exposed.
3071      *
3072      * @see android.provider.Telephony.SimInfo for all the columns.
3073      *
3074      * @hide
3075      */
3076     @RequiresPermission(anyOf = {
3077             Manifest.permission.READ_PHONE_STATE,
3078             Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
3079             "carrier privileges",
3080     })
getBooleanSubscriptionProperty(int subscriptionId, @NonNull String columnName, boolean defaultValue, @NonNull Context context)3081     public static boolean getBooleanSubscriptionProperty(int subscriptionId,
3082             @NonNull String columnName, boolean defaultValue, @NonNull Context context) {
3083         String result = getStringSubscriptionProperty(context, subscriptionId, columnName);
3084         if (!result.isEmpty()) {
3085             try {
3086                 return Integer.parseInt(result) == 1;
3087             } catch (NumberFormatException err) {
3088                 logd("getBooleanSubscriptionProperty NumberFormat exception");
3089             }
3090         }
3091         return defaultValue;
3092     }
3093 
3094     /**
3095      * Get specific field in {@code integer} format from the subscription info database.
3096      *
3097      * @param subscriptionId Subscription id of the subscription.
3098      * @param columnName Column name in subscription database.
3099      * @param defaultValue Default value in case not found or error.
3100      * @param context The calling context.
3101      *
3102      * @return Value in {@code integer} format associated with {@code subscriptionId} and
3103      * {@code columnName} from the database, or {@code defaultValue} if not found or error.
3104      *
3105      * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not
3106      * exposed.
3107      *
3108      * @see android.provider.Telephony.SimInfo for all the columns.
3109      *
3110      * @hide
3111      */
3112     @RequiresPermission(anyOf = {
3113             Manifest.permission.READ_PHONE_STATE,
3114             Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
3115             "carrier privileges",
3116     })
getIntegerSubscriptionProperty(int subscriptionId, @NonNull String columnName, int defaultValue, @NonNull Context context)3117     public static int getIntegerSubscriptionProperty(int subscriptionId, @NonNull String columnName,
3118             int defaultValue, @NonNull Context context) {
3119         String result = getStringSubscriptionProperty(context, subscriptionId, columnName);
3120         if (!result.isEmpty()) {
3121             try {
3122                 return Integer.parseInt(result);
3123             } catch (NumberFormatException err) {
3124                 logd("getIntegerSubscriptionProperty NumberFormat exception");
3125             }
3126         }
3127         return defaultValue;
3128     }
3129 
3130     /**
3131      * Get specific field in {@code long} format from the subscription info database.
3132      *
3133      * @param subscriptionId Subscription id of the subscription.
3134      * @param columnName Column name in subscription database.
3135      * @param defaultValue Default value in case not found or error.
3136      * @param context The calling context.
3137      *
3138      * @return Value in {@code long} format associated with {@code subscriptionId} and
3139      * {@code columnName} from the database, or {@code defaultValue} if not found or error.
3140      *
3141      * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not
3142      * exposed.
3143      *
3144      * @see android.provider.Telephony.SimInfo for all the columns.
3145      *
3146      * @hide
3147      */
3148     @RequiresPermission(anyOf = {
3149             Manifest.permission.READ_PHONE_STATE,
3150             Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
3151             "carrier privileges",
3152     })
getLongSubscriptionProperty(int subscriptionId, @NonNull String columnName, long defaultValue, @NonNull Context context)3153     public static long getLongSubscriptionProperty(int subscriptionId, @NonNull String columnName,
3154             long defaultValue, @NonNull Context context) {
3155         String result = getStringSubscriptionProperty(context, subscriptionId, columnName);
3156         if (!result.isEmpty()) {
3157             try {
3158                 return Long.parseLong(result);
3159             } catch (NumberFormatException err) {
3160                 logd("getLongSubscriptionProperty NumberFormat exception");
3161             }
3162         }
3163         return defaultValue;
3164     }
3165 
3166     /**
3167      * Returns the {@link Resources} from the given {@link Context} for the MCC/MNC associated with
3168      * the subscription. If the subscription ID is invalid, the base resources are returned instead.
3169      *
3170      * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
3171      *
3172      * @param context Context object
3173      * @param subId Subscription Id of Subscription whose resources are required
3174      * @return Resources associated with Subscription.
3175      *
3176      * @throws UnsupportedOperationException If the device does not have
3177      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
3178      * @hide
3179      */
3180     @NonNull
3181     @SystemApi
getResourcesForSubId(@onNull Context context, int subId)3182     public static Resources getResourcesForSubId(@NonNull Context context, int subId) {
3183         return getResourcesForSubId(context, subId, false);
3184     }
3185 
3186     /**
3187      * Returns the resources associated with Subscription.
3188      * @param context Context object
3189      * @param subId Subscription Id of Subscription who's resources are required
3190      * @param useRootLocale if root locale should be used. Localized locale is used if false.
3191      * @return Resources associated with Subscription.
3192      * @hide
3193      */
3194     @NonNull
getResourcesForSubId(Context context, int subId, boolean useRootLocale)3195     public static Resources getResourcesForSubId(Context context, int subId,
3196             boolean useRootLocale) {
3197         // Check if the Resources already exists in the cache based on the given context. Find a
3198         // Resource that match Configuration.
3199         Pair<String, Configuration> cacheKey = null;
3200         if (isValidSubscriptionId(subId)) {
3201             Configuration configurationKey =
3202                     new Configuration(context.getResources().getConfiguration());
3203             if (useRootLocale) {
3204                 configurationKey.setLocale(Locale.ROOT);
3205             }
3206             cacheKey = Pair.create(context.getPackageName() + ", subid=" + subId, configurationKey);
3207             synchronized (sResourcesCache) {
3208                 Resources cached = sResourcesCache.get(cacheKey);
3209                 if (cached != null) {
3210                     // Cache hit. Use cached Resources.
3211                     return cached;
3212                 }
3213             }
3214         }
3215 
3216         final SubscriptionInfo subInfo =
3217                 SubscriptionManager.from(context).getActiveSubscriptionInfo(subId);
3218 
3219         Configuration overrideConfig = new Configuration();
3220         if (subInfo != null) {
3221             overrideConfig.mcc = subInfo.getMcc();
3222             overrideConfig.mnc = subInfo.getMnc();
3223             if (overrideConfig.mnc == 0) {
3224                 overrideConfig.mnc = Configuration.MNC_ZERO;
3225                 cacheKey = null;
3226             }
3227         } else {
3228             cacheKey = null;
3229         }
3230 
3231         if (useRootLocale) {
3232             overrideConfig.setLocale(Locale.ROOT);
3233         }
3234 
3235         // Create new context with new configuration so that we can avoid modifying the passed in
3236         // context.
3237         // Note that if the original context configuration changes, the resources here will also
3238         // change for all values except those overridden by newConfig (e.g. if the device has an
3239         // orientation change).
3240         Context newContext = context.createConfigurationContext(overrideConfig);
3241         Resources res = newContext.getResources();
3242 
3243         if (cacheKey != null) {
3244             synchronized (sResourcesCache) {
3245                 // Save the newly created Resources in the resource cache.
3246                 sResourcesCache.put(cacheKey, res);
3247             }
3248         }
3249         return res;
3250     }
3251 
3252     /**
3253      * Checks if the supplied subscription ID corresponds to a subscription which is actively in
3254      * use on the device. An active subscription ID is a valid and usable subscription ID.
3255      *
3256      * @param subscriptionId the subscription ID.
3257      * @return {@code true} if the supplied subscription ID corresponds to an active subscription;
3258      * {@code false} if it does not correspond to an active subscription; or throw a
3259      * SecurityException if the caller hasn't got the right permission.
3260      *i
3261      * @throws UnsupportedOperationException If the device does not have
3262      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
3263      */
3264     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
isActiveSubscriptionId(int subscriptionId)3265     public boolean isActiveSubscriptionId(int subscriptionId) {
3266         return isActiveSubId(subscriptionId);
3267     }
3268 
3269     /**
3270      * @return true if the sub ID is active. i.e. The sub ID corresponds to a known subscription
3271      * and the SIM providing the subscription is present in a slot and in "LOADED" state.
3272      * @hide
3273      */
3274     @UnsupportedAppUsage
isActiveSubId(int subId)3275     public boolean isActiveSubId(int subId) {
3276         try {
3277             ISub iSub = TelephonyManager.getSubscriptionService();
3278             if (iSub != null) {
3279                 return iSub.isActiveSubId(subId, mContext.getOpPackageName(),
3280                         mContext.getAttributionTag());
3281             }
3282         } catch (RemoteException ex) {
3283         }
3284         return false;
3285     }
3286 
3287     /**
3288      * Get the description of the billing relationship plan between a carrier
3289      * and a specific subscriber.
3290      * <p>
3291      * This method is only accessible to the following narrow set of apps:
3292      * <ul>
3293      * <li>The carrier app for this subscriberId, as determined by
3294      * {@link TelephonyManager#hasCarrierPrivileges()}.
3295      * <li>The carrier app explicitly delegated access through
3296      * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
3297      * </ul>
3298      *
3299      * @param subId the subscriber this relationship applies to
3300      * @throws SecurityException if the caller doesn't meet the requirements
3301      *             outlined above.
3302      */
getSubscriptionPlans(int subId)3303     public @NonNull List<SubscriptionPlan> getSubscriptionPlans(int subId) {
3304         SubscriptionPlan[] subscriptionPlans =
3305                 getNetworkPolicyManager().getSubscriptionPlans(subId, mContext.getOpPackageName());
3306         return subscriptionPlans == null
3307                 ? Collections.emptyList() : Arrays.asList(subscriptionPlans);
3308     }
3309 
3310     /**
3311      * Set the description of the billing relationship plan between a carrier
3312      * and a specific subscriber.
3313      * <p>
3314      * This method is only accessible to the following narrow set of apps:
3315      * <ul>
3316      * <li>The carrier app for this subscriberId, as determined by
3317      * {@link TelephonyManager#hasCarrierPrivileges()}.
3318      * <li>The carrier app explicitly delegated access through
3319      * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
3320      * </ul>
3321      *
3322      * @param subId the subscriber this relationship applies to. An empty list
3323      *            may be sent to clear any existing plans.
3324      * @param plans the list of plans. The first plan is always the primary and
3325      *            most important plan. Any additional plans are secondary and
3326      *            may not be displayed or used by decision making logic.
3327      * @throws SecurityException if the caller doesn't meet the requirements
3328      *             outlined above.
3329      * @throws IllegalArgumentException if plans don't meet the requirements
3330      *             defined in {@link SubscriptionPlan}.
3331      * @deprecated use {@link #setSubscriptionPlans(int, List, long)} instead.
3332      */
3333     @Deprecated
setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans)3334     public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans) {
3335         setSubscriptionPlans(subId, plans, 0);
3336     }
3337 
3338     /**
3339      * Set the description of the billing relationship plan between a carrier
3340      * and a specific subscriber.
3341      * <p>
3342      * This method is only accessible to the following narrow set of apps:
3343      * <ul>
3344      * <li>The carrier app for this subscriberId, as determined by
3345      * {@link TelephonyManager#hasCarrierPrivileges()}.
3346      * <li>The carrier app explicitly delegated access through
3347      * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
3348      * </ul>
3349      *
3350      * @param subId the subscriber this relationship applies to. An empty list
3351      *            may be sent to clear any existing plans.
3352      * @param plans the list of plans. The first plan is always the primary and
3353      *            most important plan. Any additional plans are secondary and
3354      *            may not be displayed or used by decision making logic.
3355      * @param expirationDurationMillis the duration after which the subscription plans
3356      *            will be automatically cleared, or {@code 0} to leave the plans until
3357      *            explicitly cleared, or the next reboot, whichever happens first.
3358      * @throws SecurityException if the caller doesn't meet the requirements
3359      *             outlined above.
3360      * @throws IllegalArgumentException if plans don't meet the requirements
3361      *             defined in {@link SubscriptionPlan}.
3362      */
setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans, @DurationMillisLong long expirationDurationMillis)3363     public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans,
3364             @DurationMillisLong long expirationDurationMillis) {
3365         getNetworkPolicyManager().setSubscriptionPlans(subId,
3366                 plans.toArray(new SubscriptionPlan[0]), expirationDurationMillis,
3367                 mContext.getOpPackageName());
3368     }
3369 
3370     /**
3371      * Temporarily override the billing relationship plan between a carrier and
3372      * a specific subscriber to be considered unmetered. This will be reflected
3373      * to apps via {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED}.
3374      * <p>
3375      * This method is only accessible to the following narrow set of apps:
3376      * <ul>
3377      * <li>The carrier app for this subscriberId, as determined by
3378      * {@link TelephonyManager#hasCarrierPrivileges()}.
3379      * <li>The carrier app explicitly delegated access through
3380      * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
3381      * </ul>
3382      *
3383      * @param subId the subscriber this override applies to.
3384      * @param overrideUnmetered set if the billing relationship should be
3385      *            considered unmetered.
3386      * @param expirationDurationMillis the duration after which the requested override
3387      *            will be automatically cleared, or {@code 0} to leave in the
3388      *            requested state until explicitly cleared, or the next reboot,
3389      *            whichever happens first.
3390      * @throws SecurityException if the caller doesn't meet the requirements
3391      *            outlined above.
3392      */
setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered, @DurationMillisLong long expirationDurationMillis)3393     public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered,
3394             @DurationMillisLong long expirationDurationMillis) {
3395         setSubscriptionOverrideUnmetered(subId, overrideUnmetered,
3396                 TelephonyManager.getAllNetworkTypes(), expirationDurationMillis);
3397     }
3398 
3399     /**
3400      * Temporarily override the billing relationship plan between a carrier and
3401      * a specific subscriber to be considered unmetered. This will be reflected
3402      * to apps via {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED}.
3403      * <p>
3404      * This method is only accessible to the following narrow set of apps:
3405      * <ul>
3406      * <li>The carrier app for this subscriberId, as determined by
3407      * {@link TelephonyManager#hasCarrierPrivileges()}.
3408      * <li>The carrier app explicitly delegated access through
3409      * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
3410      * </ul>
3411      *
3412      * @param subId the subscriber this override applies to.
3413      * @param overrideUnmetered set if the billing relationship should be
3414      *            considered unmetered.
3415      * @param networkTypes the network types this override applies to. If no
3416      *            network types are specified, override values will be ignored.
3417      * @param expirationDurationMillis the duration after which the requested override
3418      *            will be automatically cleared, or {@code 0} to leave in the
3419      *            requested state until explicitly cleared, or the next reboot,
3420      *            whichever happens first.
3421      * @throws SecurityException if the caller doesn't meet the requirements
3422      *            outlined above.
3423      */
setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered, @NonNull @Annotation.NetworkType int[] networkTypes, @DurationMillisLong long expirationDurationMillis)3424     public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered,
3425             @NonNull @Annotation.NetworkType int[] networkTypes,
3426             @DurationMillisLong long expirationDurationMillis) {
3427         final int overrideValue = overrideUnmetered ? SUBSCRIPTION_OVERRIDE_UNMETERED : 0;
3428         getNetworkPolicyManager().setSubscriptionOverride(subId, SUBSCRIPTION_OVERRIDE_UNMETERED,
3429                 overrideValue, networkTypes, expirationDurationMillis, mContext.getOpPackageName());
3430     }
3431 
3432     /**
3433      * Temporarily override the billing relationship plan between a carrier and
3434      * a specific subscriber to be considered congested. This will cause the
3435      * device to delay certain network requests when possible, such as developer
3436      * jobs that are willing to run in a flexible time window.
3437      * <p>
3438      * This method is only accessible to the following narrow set of apps:
3439      * <ul>
3440      * <li>The carrier app for this subscriberId, as determined by
3441      * {@link TelephonyManager#hasCarrierPrivileges()}.
3442      * <li>The carrier app explicitly delegated access through
3443      * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
3444      * </ul>
3445      *
3446      * @param subId the subscriber this override applies to.
3447      * @param overrideCongested set if the subscription should be considered
3448      *            congested.
3449      * @param expirationDurationMillis the duration after which the requested override
3450      *            will be automatically cleared, or {@code 0} to leave in the
3451      *            requested state until explicitly cleared, or the next reboot,
3452      *            whichever happens first.
3453      * @throws SecurityException if the caller doesn't meet the requirements
3454      *            outlined above.
3455      */
setSubscriptionOverrideCongested(int subId, boolean overrideCongested, @DurationMillisLong long expirationDurationMillis)3456     public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested,
3457             @DurationMillisLong long expirationDurationMillis) {
3458         setSubscriptionOverrideCongested(subId, overrideCongested,
3459                 TelephonyManager.getAllNetworkTypes(), expirationDurationMillis);
3460     }
3461 
3462     /**
3463      * Temporarily override the billing relationship plan between a carrier and
3464      * a specific subscriber to be considered congested. This will cause the
3465      * device to delay certain network requests when possible, such as developer
3466      * jobs that are willing to run in a flexible time window.
3467      * <p>
3468      * This method is only accessible to the following narrow set of apps:
3469      * <ul>
3470      * <li>The carrier app for this subscriberId, as determined by
3471      * {@link TelephonyManager#hasCarrierPrivileges()}.
3472      * <li>The carrier app explicitly delegated access through
3473      * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
3474      * </ul>
3475      *
3476      * @param subId the subscriber this override applies to.
3477      * @param overrideCongested set if the subscription should be considered congested.
3478      * @param networkTypes the network types this override applies to. If no network types are
3479      * specified, override values will be ignored.
3480      * @param expirationDurationMillis the duration after which the requested override
3481      * will be automatically cleared, or {@code 0} to leave in the requested state until explicitly
3482      * cleared, or the next reboot, whichever happens first.
3483      *
3484      * @throws SecurityException if the caller doesn't meet the requirements outlined above.
3485      */
setSubscriptionOverrideCongested(int subId, boolean overrideCongested, @NonNull @Annotation.NetworkType int[] networkTypes, @DurationMillisLong long expirationDurationMillis)3486     public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested,
3487             @NonNull @Annotation.NetworkType int[] networkTypes,
3488             @DurationMillisLong long expirationDurationMillis) {
3489         final int overrideValue = overrideCongested ? SUBSCRIPTION_OVERRIDE_CONGESTED : 0;
3490         getNetworkPolicyManager().setSubscriptionOverride(subId, SUBSCRIPTION_OVERRIDE_CONGESTED,
3491                 overrideValue, networkTypes, expirationDurationMillis, mContext.getOpPackageName());
3492     }
3493 
3494     /**
3495      * Checks whether the app with the given context is authorized to manage the given subscription
3496      * according to its metadata.
3497      *
3498      * Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded} returns
3499      * true). To check for permissions for non-embedded subscription as well,
3500      * see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}.
3501      *
3502      * @param info The subscription to check.
3503      * @return whether the app is authorized to manage this subscription per its metadata.
3504      * @see android.telephony.TelephonyManager#hasCarrierPrivileges
3505      */
canManageSubscription(SubscriptionInfo info)3506     public boolean canManageSubscription(SubscriptionInfo info) {
3507         return canManageSubscription(info, mContext.getPackageName());
3508     }
3509 
3510     /**
3511      * Checks whether the given app is authorized to manage the given subscription. An app can only
3512      * be authorized if it is included in the {@link android.telephony.UiccAccessRule} of the
3513      * {@link android.telephony.SubscriptionInfo} with the access status.
3514      *
3515      * Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded} returns
3516      * true). To check for permissions for non-embedded subscription as well,
3517      * see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}.
3518      *
3519      * @param info The subscription to check.
3520      * @param packageName Package name of the app to check.
3521      *
3522      * @return whether the app is authorized to manage this subscription per its access rules.
3523      * @see android.telephony.TelephonyManager#hasCarrierPrivileges
3524      * @hide
3525      */
3526     @SystemApi
canManageSubscription(@onNull SubscriptionInfo info, @NonNull String packageName)3527     public boolean canManageSubscription(@NonNull SubscriptionInfo info,
3528             @NonNull String packageName) {
3529         if (Flags.hsumPackageManager()) {
3530             return canManageSubscriptionAsUser(info, packageName, mContext.getUser());
3531         } else {
3532             if (info == null || info.getAccessRules() == null || packageName == null) {
3533                 return false;
3534             }
3535             PackageManager packageManager = mContext.getPackageManager();
3536             PackageInfo packageInfo;
3537             try {
3538                 packageInfo = packageManager.getPackageInfo(packageName,
3539                         PackageManager.GET_SIGNING_CERTIFICATES);
3540             } catch (PackageManager.NameNotFoundException e) {
3541                 logd("Unknown package: " + packageName);
3542                 return false;
3543             }
3544             for (UiccAccessRule rule : info.getAccessRules()) {
3545                 if (rule.getCarrierPrivilegeStatus(packageInfo)
3546                         == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
3547                     return true;
3548                 }
3549             }
3550             return false;
3551         }
3552     }
3553 
3554     /**
3555      * Checks whether the given app is authorized to manage the given subscription for given user.
3556      *
3557      * <p>An app can only be authorized if it is available to the given user and included in the
3558      * {@link android.telephony.UiccAccessRule} of the {@link android.telephony.SubscriptionInfo}
3559      * with the access status.
3560      *
3561      * <p>Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded} returns
3562      * true). To check for permissions for non-embedded subscription as well,
3563      * see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}.
3564      *
3565      * @param info        The subscription to check.
3566      * @param packageName Package name of the app to check.
3567      * @param user        UserHandle to check
3568      * @return whether the app is authorized to manage this subscription per its access rules.
3569      *
3570      * @see android.telephony.TelephonyManager#hasCarrierPrivileges
3571      * @hide
3572      */
canManageSubscriptionAsUser(@onNull SubscriptionInfo info, @NonNull String packageName, @NonNull UserHandle user)3573     public boolean canManageSubscriptionAsUser(@NonNull SubscriptionInfo info,
3574             @NonNull String packageName, @NonNull UserHandle user) {
3575         if (info == null || info.getAccessRules() == null || packageName == null) {
3576             return false;
3577         }
3578         PackageManager pm = mContext.getUser().equals(user)
3579                 ? mContext.getPackageManager()
3580                 : mContext.createContextAsUser(user, 0).getPackageManager();
3581         PackageInfo packageInfo;
3582         try {
3583             packageInfo = pm.getPackageInfo(packageName,
3584                     PackageManager.GET_SIGNING_CERTIFICATES);
3585         } catch (PackageManager.NameNotFoundException e) {
3586             logd("Unknown package: " + packageName);
3587             return false;
3588         }
3589         for (UiccAccessRule rule : info.getAccessRules()) {
3590             if (rule.getCarrierPrivilegeStatus(packageInfo)
3591                     == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
3592                 return true;
3593             }
3594         }
3595         return false;
3596     }
3597 
3598     /**
3599      * Set which subscription is preferred for cellular data.
3600      * It's also usually the subscription we set up internet connection on.
3601      *
3602      * PreferredData overwrites user setting of default data subscription. And it's used
3603      * by AlternativeNetworkService or carrier apps to switch primary and CBRS
3604      * subscription dynamically in multi-SIM devices.
3605      *
3606      * @param subId which subscription is preferred to for cellular data. If it's
3607      *              {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}, it means
3608      *              it's unset and {@link SubscriptionManager#getDefaultDataSubscriptionId()}
3609      *              is used to determine which modem is preferred.
3610      * @param needValidation whether Telephony will wait until the network is validated by
3611      *              connectivity service before switching data to it. More details see
3612      *              {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED}.
3613      * @param executor The executor of where the callback will execute.
3614      * @param callback Callback will be triggered once it succeeds or failed.
3615      *                 Pass null if don't care about the result.
3616      *
3617      * @throws IllegalStateException when subscription manager service is not available.
3618      * @throws SecurityException when clients do not have MODIFY_PHONE_STATE permission.
3619      * @throws UnsupportedOperationException If the device does not have
3620      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
3621      * @hide
3622      */
3623     @SystemApi
3624     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
setPreferredDataSubscriptionId(int subId, boolean needValidation, @Nullable @CallbackExecutor Executor executor, @Nullable @TelephonyManager.SetOpportunisticSubscriptionResult Consumer<Integer> callback)3625     public void setPreferredDataSubscriptionId(int subId, boolean needValidation,
3626             @Nullable @CallbackExecutor Executor executor, @Nullable
3627             @TelephonyManager.SetOpportunisticSubscriptionResult Consumer<Integer> callback) {
3628         if (VDBG) logd("[setPreferredDataSubscriptionId]+ subId:" + subId);
3629         try {
3630             ISub iSub = TelephonyManager.getSubscriptionService();
3631             if (iSub == null) {
3632                 throw new IllegalStateException("subscription manager service is null.");
3633             }
3634 
3635             ISetOpportunisticDataCallback callbackStub = new ISetOpportunisticDataCallback.Stub() {
3636                 @Override
3637                 public void onComplete(int result) {
3638                     if (executor == null || callback == null) {
3639                         return;
3640                     }
3641                     final long identity = Binder.clearCallingIdentity();
3642                     try {
3643                         executor.execute(() -> {
3644                             callback.accept(result);
3645                         });
3646                     } finally {
3647                         Binder.restoreCallingIdentity(identity);
3648                     }
3649                 }
3650             };
3651             iSub.setPreferredDataSubscriptionId(subId, needValidation, callbackStub);
3652         } catch (RemoteException ex) {
3653             loge("setPreferredDataSubscriptionId RemoteException=" + ex);
3654             ex.rethrowFromSystemServer();
3655         }
3656     }
3657 
3658     /**
3659      * Get which subscription is preferred for cellular data.
3660      * It's also usually the subscription we set up internet connection on.
3661      *
3662      * PreferredData overwrites user setting of default data subscription. And it's used
3663      * by AlternativeNetworkService or carrier apps to switch primary and CBRS
3664      * subscription dynamically in multi-SIM devices.
3665      *
3666      * @return preferred subscription id for cellular data. {@link DEFAULT_SUBSCRIPTION_ID} if
3667      * there's no prefered subscription.
3668      *
3669      * @hide
3670      *
3671      */
3672     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
getPreferredDataSubscriptionId()3673     public int getPreferredDataSubscriptionId() {
3674         int preferredSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
3675         try {
3676             ISub iSub = TelephonyManager.getSubscriptionService();
3677             if (iSub != null) {
3678                 preferredSubId = iSub.getPreferredDataSubscriptionId();
3679             }
3680         } catch (RemoteException ex) {
3681             // ignore it
3682         }
3683 
3684         return preferredSubId;
3685     }
3686 
3687     /**
3688      * Return opportunistic subscriptions that can be visible to the caller.
3689      * Opportunistic subscriptions are for opportunistic networks, which are cellular
3690      * networks with limited capabilities and coverage, for example, CBRS.
3691      *
3692      * <p>Requires Permission:
3693      * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
3694      * or that the calling app has carrier privileges (see
3695      * {@link TelephonyManager#hasCarrierPrivileges}).
3696      *
3697      * @return the list of opportunistic subscription info. If none exists, an empty list.
3698      *
3699      * @throws UnsupportedOperationException If the device does not have
3700      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
3701      */
3702     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
3703     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
getOpportunisticSubscriptions()3704     public @NonNull List<SubscriptionInfo> getOpportunisticSubscriptions() {
3705         String contextPkg = mContext != null ? mContext.getOpPackageName() : "<unknown>";
3706         String contextAttributionTag = mContext != null ? mContext.getAttributionTag() : null;
3707         List<SubscriptionInfo> subInfoList = null;
3708 
3709         try {
3710             ISub iSub = TelephonyManager.getSubscriptionService();
3711             if (iSub != null) {
3712                 subInfoList = iSub.getOpportunisticSubscriptions(contextPkg,
3713                         contextAttributionTag);
3714             }
3715         } catch (RemoteException ex) {
3716             // ignore it
3717         }
3718 
3719         if (subInfoList == null) {
3720             subInfoList = new ArrayList<>();
3721         }
3722 
3723         return subInfoList;
3724     }
3725 
3726     /**
3727      * Switch to a certain subscription
3728      *
3729      *  @param subId sub id
3730      *  @param callbackIntent pending intent that will be sent after operation is done.
3731      *
3732      *  @deprecated this API is a duplicate of {@link EuiccManager#switchToSubscription(int,
3733      *  PendingIntent)} and does not support Multiple Enabled Profile(MEP). Apps should use
3734      *  {@link EuiccManager#switchToSubscription(int, PendingIntent)} or
3735      *  {@link EuiccManager#switchToSubscription(int, int, PendingIntent)} instead.
3736      *
3737      * @throws UnsupportedOperationException If the device does not have
3738      *          {@link PackageManager#FEATURE_TELEPHONY_EUICC}.
3739      */
3740     @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
3741     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_EUICC)
3742     @Deprecated
switchToSubscription(int subId, @NonNull PendingIntent callbackIntent)3743     public void switchToSubscription(int subId, @NonNull PendingIntent callbackIntent) {
3744         Preconditions.checkNotNull(callbackIntent, "callbackIntent cannot be null");
3745         EuiccManager euiccManager = new EuiccManager(mContext);
3746         euiccManager.switchToSubscription(subId, callbackIntent);
3747     }
3748 
3749     /**
3750      * Set whether a subscription is opportunistic, that is, whether the network it connects
3751      * to has limited coverage. For example, CBRS. Setting a subscription opportunistic has
3752      * following impacts:
3753      *  1) Even if it's active, it will be dormant most of the time. The modem will not try
3754      *     to scan or camp until it knows an available network is nearby to save power.
3755      *  2) Telephony relies on system app or carrier input to notify nearby available networks.
3756      *     See {@link TelephonyManager#updateAvailableNetworks(List, Executor, Consumer)}
3757      *     for more information.
3758      *  3) In multi-SIM devices, when the network is nearby and camped, system may automatically
3759      *     switch internet data between it and default data subscription, based on carrier
3760      *     recommendation and its signal strength and metered-ness, etc.
3761      *
3762      *
3763      * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE} or carrier
3764      * privilege permission of the subscription.
3765      *
3766      * @param opportunistic whether it's an opportunistic subscription.
3767      * @param subId the unique SubscriptionInfo index in database
3768      * @return {@code true} if the operation is succeed, {@code false} otherwise.
3769      *
3770      * @throws UnsupportedOperationException If the device does not have
3771      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
3772      */
3773     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
3774     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
setOpportunistic(boolean opportunistic, int subId)3775     public boolean setOpportunistic(boolean opportunistic, int subId) {
3776         if (VDBG) logd("[setOpportunistic]+ opportunistic:" + opportunistic + " subId:" + subId);
3777         return setSubscriptionPropertyHelper(subId, "setOpportunistic",
3778                 (iSub)-> iSub.setOpportunistic(
3779                         opportunistic, subId, mContext.getOpPackageName())) == 1;
3780     }
3781 
3782     /**
3783      * Inform SubscriptionManager that subscriptions in the list are bundled
3784      * as a group. It can be multiple primary (non-opportunistic) subscriptions,
3785      * or one or more primary plus one or more opportunistic subscriptions.
3786      *
3787      * This API will always create a new immutable group and assign group UUID to all the
3788      * subscriptions, regardless whether they are in a group already or not.
3789      *
3790      * Grouped subscriptions will have below behaviors:
3791      * 1) They will share the same user settings.
3792      * 2) The opportunistic subscriptions in the group is considered invisible and will not
3793      *    return from {@link #getActiveSubscriptionInfoList()}, unless caller has carrier
3794      *    privilege permission of the subscriptions.
3795      * 3) The opportunistic subscriptions in the group can't be active by itself. If all other
3796      *    non-opportunistic ones are deactivated (unplugged or disabled in Settings),
3797      *    the opportunistic ones will be deactivated automatically.
3798      *
3799      * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
3800      * permission or had carrier privilege permission on the subscriptions:
3801      * {@link TelephonyManager#hasCarrierPrivileges()} or
3802      * {@link #canManageSubscription(SubscriptionInfo)}
3803      *
3804      * @throws SecurityException if the caller doesn't meet the requirements
3805      *             outlined above.
3806      * @throws IllegalArgumentException if any of the subscriptions in the list doesn't exist.
3807      * @throws IllegalStateException if Telephony service is in bad state.
3808      * @throws UnsupportedOperationException If the device does not have
3809      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
3810      *
3811      * @param subIdList list of subId that will be in the same group
3812      * @return groupUUID a UUID assigned to the subscription group.
3813      *
3814      */
3815     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
3816     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
createSubscriptionGroup(@onNull List<Integer> subIdList)3817     public @NonNull ParcelUuid createSubscriptionGroup(@NonNull List<Integer> subIdList) {
3818         Preconditions.checkNotNull(subIdList, "can't create group for null subId list");
3819         String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
3820         if (VDBG) {
3821             logd("[createSubscriptionGroup]");
3822         }
3823 
3824         ParcelUuid groupUuid = null;
3825         int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray();
3826         try {
3827             ISub iSub = TelephonyManager.getSubscriptionService();
3828             if (iSub != null) {
3829                 groupUuid = iSub.createSubscriptionGroup(subIdArray, pkgForDebug);
3830             } else {
3831                 throw new IllegalStateException("telephony service is null.");
3832             }
3833         } catch (RemoteException ex) {
3834             loge("createSubscriptionGroup RemoteException " + ex);
3835             ex.rethrowAsRuntimeException();
3836         }
3837 
3838         return groupUuid;
3839     }
3840 
3841     /**
3842      * Add a list of subscriptions into a group.
3843      * See {@link #createSubscriptionGroup(List)} for more details.
3844      *
3845      * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
3846      * permission or had carrier privilege permission on the subscriptions:
3847      * {@link TelephonyManager#hasCarrierPrivileges()} or
3848      * {@link #canManageSubscription(SubscriptionInfo)}
3849      *
3850      * @throws SecurityException if the caller doesn't meet the requirements
3851      *             outlined above.
3852      * @throws IllegalArgumentException if the some subscriptions in the list doesn't exist.
3853      * @throws IllegalStateException if Telephony service is in bad state.
3854      * @throws UnsupportedOperationException If the device does not have
3855      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
3856      *
3857      * @param subIdList list of subId that need adding into the group
3858      * @param groupUuid the groupUuid the subscriptions are being added to.
3859      *
3860      */
3861     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
3862     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
addSubscriptionsIntoGroup(@onNull List<Integer> subIdList, @NonNull ParcelUuid groupUuid)3863     public void addSubscriptionsIntoGroup(@NonNull List<Integer> subIdList,
3864             @NonNull ParcelUuid groupUuid) {
3865         Preconditions.checkNotNull(subIdList, "subIdList can't be null.");
3866         Preconditions.checkNotNull(groupUuid, "groupUuid can't be null.");
3867         String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
3868         if (VDBG) {
3869             logd("[addSubscriptionsIntoGroup]");
3870         }
3871 
3872         int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray();
3873 
3874         try {
3875             ISub iSub = TelephonyManager.getSubscriptionService();
3876             if (iSub != null) {
3877                 iSub.addSubscriptionsIntoGroup(subIdArray, groupUuid, pkgForDebug);
3878             } else {
3879                 throw new IllegalStateException("telephony service is null.");
3880             }
3881         } catch (RemoteException ex) {
3882             loge("addSubscriptionsIntoGroup RemoteException " + ex);
3883             ex.rethrowAsRuntimeException();
3884         }
3885     }
3886 
isSystemProcess()3887     private boolean isSystemProcess() {
3888         return UserHandle.isSameApp(Process.myUid(), Process.SYSTEM_UID);
3889     }
3890 
3891     /**
3892      * Remove a list of subscriptions from their subscription group.
3893      *
3894      * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
3895      * permission or has carrier privilege permission on all of the subscriptions provided in
3896      * {@code subIdList}.
3897      *
3898      * @param subIdList list of subId that need removing from their groups.
3899      * @param groupUuid The UUID of the subscription group.
3900      *
3901      * @throws SecurityException if the caller doesn't meet the requirements outlined above.
3902      * @throws IllegalArgumentException if the some subscriptions in the list doesn't belong the
3903      * specified group.
3904      * @throws IllegalStateException if Telephony service is in bad state.
3905      * @throws UnsupportedOperationException If the device does not have
3906      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
3907      *
3908      * @see #createSubscriptionGroup(List)
3909      */
3910     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
3911     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
removeSubscriptionsFromGroup(@onNull List<Integer> subIdList, @NonNull ParcelUuid groupUuid)3912     public void removeSubscriptionsFromGroup(@NonNull List<Integer> subIdList,
3913             @NonNull ParcelUuid groupUuid) {
3914         Preconditions.checkNotNull(subIdList, "subIdList can't be null.");
3915         Preconditions.checkNotNull(groupUuid, "groupUuid can't be null.");
3916         String callingPackage = mContext != null ? mContext.getOpPackageName() : "<unknown>";
3917         if (VDBG) {
3918             logd("[removeSubscriptionsFromGroup]");
3919         }
3920 
3921         int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray();
3922 
3923         try {
3924             ISub iSub = TelephonyManager.getSubscriptionService();
3925             if (iSub != null) {
3926                 iSub.removeSubscriptionsFromGroup(subIdArray, groupUuid, callingPackage);
3927             } else {
3928                 throw new IllegalStateException("telephony service is null.");
3929             }
3930         } catch (RemoteException ex) {
3931             loge("removeSubscriptionsFromGroup RemoteException " + ex);
3932             ex.rethrowAsRuntimeException();
3933         }
3934     }
3935 
3936     /**
3937      * Get subscriptionInfo list of subscriptions that are in the same group of given subId.
3938      *
3939      * Caller must have {@link android.Manifest.permission#READ_PHONE_STATE}
3940      * or carrier privilege permission on the subscription.
3941      * {@link TelephonyManager#hasCarrierPrivileges()}
3942      *
3943      * <p>Starting with API level 33, the caller also needs permission to access device identifiers
3944      * to get the list of subscriptions associated with a group UUID.
3945      * This method can be invoked if one of the following requirements is met:
3946      * <ul>
3947      *     <li>If the app has carrier privilege permission.
3948      *     {@link TelephonyManager#hasCarrierPrivileges()}
3949      *     <li>If the app has {@link android.Manifest.permission#READ_PHONE_STATE} permission and
3950      *     access to device identifiers.
3951      * </ul>
3952      *
3953      * @throws IllegalStateException if Telephony service is in bad state.
3954      * @throws SecurityException if the caller doesn't meet the requirements
3955      *             outlined above.
3956      * @throws UnsupportedOperationException If the device does not have
3957      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
3958      *
3959      * @param groupUuid of which list of subInfo will be returned.
3960      * @return list of subscriptionInfo that belong to the same group, including the given
3961      * subscription itself. It will return an empty list if no subscription belongs to the group.
3962      */
3963     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
3964     @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
getSubscriptionsInGroup(@onNull ParcelUuid groupUuid)3965     public @NonNull List<SubscriptionInfo> getSubscriptionsInGroup(@NonNull ParcelUuid groupUuid) {
3966         Preconditions.checkNotNull(groupUuid, "groupUuid can't be null");
3967         String contextPkg = mContext != null ? mContext.getOpPackageName() : "<unknown>";
3968         String contextAttributionTag = mContext != null ? mContext.getAttributionTag() : null;
3969         if (VDBG) {
3970             logd("[getSubscriptionsInGroup]+ groupUuid:" + groupUuid);
3971         }
3972 
3973         List<SubscriptionInfo> result = null;
3974         try {
3975             ISub iSub = TelephonyManager.getSubscriptionService();
3976             if (iSub != null) {
3977                 result = iSub.getSubscriptionsInGroup(groupUuid, contextPkg,
3978                         contextAttributionTag);
3979             } else {
3980                 if (!isSystemProcess()) {
3981                     throw new IllegalStateException("telephony service is null.");
3982                 }
3983             }
3984         } catch (RemoteException ex) {
3985             loge("removeSubscriptionsFromGroup RemoteException " + ex);
3986             if (!isSystemProcess()) {
3987                 ex.rethrowAsRuntimeException();
3988             }
3989         }
3990 
3991         // TODO(b/296125268) Really this method should throw, but it's common enough that for
3992         // system callers it's worth having a little magic for the system process until it's
3993         // made safer.
3994         if (result == null) result = Collections.emptyList();
3995 
3996         return result;
3997     }
3998 
3999     /**
4000      * Whether a subscription is visible to API caller. If it's a bundled opportunistic
4001      * subscription, it should be hidden anywhere in Settings, dialer, status bar etc.
4002      * Exception is if caller owns carrier privilege, in which case they will
4003      * want to see their own hidden subscriptions.
4004      *
4005      * @param info the subscriptionInfo to check against.
4006      *
4007      * @return {@code true} if this subscription should be visible to the API caller.
4008      *
4009      * @hide
4010      */
isSubscriptionVisible(SubscriptionInfo info)4011     public boolean isSubscriptionVisible(SubscriptionInfo info) {
4012         if (info == null) return false;
4013         // If subscription is NOT grouped opportunistic subscription, it's visible.
4014         if (info.getGroupUuid() == null || !info.isOpportunistic()) return true;
4015 
4016         // If the caller is the carrier app and owns the subscription, it should be visible
4017         // to the caller.
4018         boolean hasCarrierPrivilegePermission = TelephonyManager.from(mContext)
4019                 .hasCarrierPrivileges(info.getSubscriptionId())
4020                 || canManageSubscription(info);
4021         return hasCarrierPrivilegePermission;
4022     }
4023 
4024     /**
4025      * Return a list of subscriptions that are available and visible to the user.
4026      * Used by Settings app to show a list of subscriptions for user to pick.
4027      *
4028      * <p>
4029      * Permissions android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE is required
4030      * for getSelectableSubscriptionInfoList to be invoked.
4031      * @return list of user selectable subscriptions.
4032      *
4033      * @hide
4034      */
getSelectableSubscriptionInfoList()4035     public @Nullable List<SubscriptionInfo> getSelectableSubscriptionInfoList() {
4036         List<SubscriptionInfo> availableList = getAvailableSubscriptionInfoList();
4037         if (availableList == null) {
4038             return null;
4039         } else {
4040             // Multiple subscriptions in a group should only have one representative.
4041             // It should be the current active primary subscription if any, or any
4042             // primary subscription.
4043             List<SubscriptionInfo> selectableList = new ArrayList<>();
4044             Map<ParcelUuid, SubscriptionInfo> groupMap = new HashMap<>();
4045 
4046             for (SubscriptionInfo info : availableList) {
4047                 // Grouped opportunistic subscriptions are considered invisible
4048                 // to users so they should never be returned.
4049                 if (info.getGroupUuid() != null && info.isOpportunistic()) continue;
4050 
4051                 ParcelUuid groupUuid = info.getGroupUuid();
4052                 if (groupUuid == null) {
4053                     // Doesn't belong to any group. Add in the list.
4054                     selectableList.add(info);
4055                 } else if (!groupMap.containsKey(groupUuid)
4056                         || (groupMap.get(groupUuid).getSimSlotIndex() == INVALID_SIM_SLOT_INDEX
4057                         && info.getSimSlotIndex() != INVALID_SIM_SLOT_INDEX)) {
4058                     // If it belongs to a group that has never been recorded or it's the current
4059                     // active subscription, add it in the list.
4060                     selectableList.remove(groupMap.get(groupUuid));
4061                     selectableList.add(info);
4062                     groupMap.put(groupUuid, info);
4063                 }
4064 
4065             }
4066             return selectableList;
4067         }
4068     }
4069 
4070     /**
4071      * Enable or disable a subscription. This method is same as
4072      * {@link #setUiccApplicationsEnabled(int, boolean)}.
4073      *
4074      * @param subscriptionId Subscription to be enabled or disabled.
4075      * @param enable whether user is turning it on or off.
4076      *
4077      * @return whether the operation is successful.
4078      *
4079      * @throws UnsupportedOperationException If the device does not have
4080      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
4081      * @hide
4082      */
4083     @SystemApi
4084     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
setSubscriptionEnabled(int subscriptionId, boolean enable)4085     public boolean setSubscriptionEnabled(int subscriptionId, boolean enable) {
4086         try {
4087             ISub iSub = TelephonyManager.getSubscriptionService();
4088             if (iSub != null) {
4089                 iSub.setUiccApplicationsEnabled(enable, subscriptionId);
4090             }
4091         } catch (RemoteException ex) {
4092             return false;
4093         }
4094         return true;
4095     }
4096 
4097     /**
4098      * Set uicc applications being enabled or disabled.
4099      * The value will be remembered on the subscription and will be applied whenever it's present.
4100      * If the subscription in currently present, it will also apply the setting to modem
4101      * immediately (the setting in the modem will not change until the modem receives and responds
4102      * to the request, but typically this should only take a few seconds. The user visible setting
4103      * available from SubscriptionInfo.areUiccApplicationsEnabled() will be updated
4104      * immediately.)
4105      *
4106      * @param subscriptionId which subscription to operate on.
4107      * @param enabled whether uicc applications are enabled or disabled.
4108      *
4109      * @throws UnsupportedOperationException If the device does not have
4110      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
4111      * @hide
4112      */
4113     @SystemApi
4114     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setUiccApplicationsEnabled(int subscriptionId, boolean enabled)4115     public void setUiccApplicationsEnabled(int subscriptionId, boolean enabled) {
4116         if (VDBG) {
4117             logd("setUiccApplicationsEnabled subId= " + subscriptionId + " enable " + enabled);
4118         }
4119         try {
4120             ISub iSub = TelephonyManager.getSubscriptionService();
4121             if (iSub != null) {
4122                 iSub.setUiccApplicationsEnabled(enabled, subscriptionId);
4123             }
4124         } catch (RemoteException ex) {
4125             // ignore it
4126         }
4127     }
4128 
4129     /**
4130      * Whether it's supported to disable / re-enable a subscription on a physical (non-euicc) SIM.
4131      *
4132      * Physical SIM refers non-euicc, or aka non-programmable SIM.
4133      *
4134      * It provides whether a physical SIM card can be disabled without taking it out, which is done
4135      * via {@link #setSubscriptionEnabled(int, boolean)} API.
4136      *
4137      * @return whether can disable subscriptions on physical SIMs.
4138      *
4139      * @throws UnsupportedOperationException If the device does not have
4140      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
4141      * @hide
4142      */
4143     @SystemApi
4144     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
canDisablePhysicalSubscription()4145     public boolean canDisablePhysicalSubscription() {
4146         if (VDBG) {
4147             logd("canDisablePhysicalSubscription");
4148         }
4149         try {
4150             ISub iSub = TelephonyManager.getSubscriptionService();
4151             if (iSub != null) {
4152                 return iSub.canDisablePhysicalSubscription();
4153             }
4154         } catch (RemoteException ex) {
4155             // ignore it
4156         }
4157 
4158         return false;
4159     }
4160 
4161     /**
4162      * Check if the subscription is currently active in any slot.
4163      *
4164      * @param subscriptionId The subscription id.
4165      *
4166      * @throws UnsupportedOperationException If the device does not have
4167      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
4168      * @hide
4169      */
4170     @SystemApi
4171     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
isSubscriptionEnabled(int subscriptionId)4172     public boolean isSubscriptionEnabled(int subscriptionId) {
4173         try {
4174             ISub iSub = TelephonyManager.getSubscriptionService();
4175             if (iSub != null) {
4176                 return iSub.isSubscriptionEnabled(subscriptionId);
4177             }
4178         } catch (RemoteException ex) {
4179             // ignore it
4180         }
4181 
4182         return false;
4183     }
4184 
4185     /**
4186      * Set the device to device status sharing user preference for a subscription id. The setting
4187      * app uses this method to indicate with whom they wish to share device to device status
4188      * information.
4189      *
4190      * @param subscriptionId The subscription id.
4191      * @param sharing The status sharing preference.
4192      *
4193      * @throws SecurityException if the caller doesn't have permissions required.
4194      * @throws UnsupportedOperationException If the device does not have
4195      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
4196      */
4197     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setDeviceToDeviceStatusSharingPreference(int subscriptionId, @DeviceToDeviceStatusSharingPreference int sharing)4198     public void setDeviceToDeviceStatusSharingPreference(int subscriptionId,
4199             @DeviceToDeviceStatusSharingPreference int sharing) {
4200         if (VDBG) {
4201             logd("[setDeviceToDeviceStatusSharing] + sharing: " + sharing + " subId: "
4202                     + subscriptionId);
4203         }
4204         setSubscriptionPropertyHelper(subscriptionId, "setDeviceToDeviceSharingStatus",
4205                 (iSub)->iSub.setDeviceToDeviceStatusSharing(sharing, subscriptionId));
4206     }
4207 
4208     /**
4209      * Returns the user-chosen device to device status sharing preference
4210      * @param subscriptionId Subscription id of subscription
4211      * @return The device to device status sharing preference
4212      *
4213      * @throws SecurityException if the caller doesn't have permissions required.
4214      * @throws UnsupportedOperationException If the device does not have
4215      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
4216      */
getDeviceToDeviceStatusSharingPreference( int subscriptionId)4217     public @DeviceToDeviceStatusSharingPreference int getDeviceToDeviceStatusSharingPreference(
4218             int subscriptionId) {
4219         if (VDBG) {
4220             logd("[getDeviceToDeviceStatusSharing] + subId: " + subscriptionId);
4221         }
4222         return getIntegerSubscriptionProperty(subscriptionId, D2D_STATUS_SHARING,
4223                 D2D_SHARING_DISABLED, mContext);
4224     }
4225 
4226     /**
4227      * Set the list of contacts that allow device to device status sharing for a subscription id.
4228      * The setting app uses this method to indicate with whom they wish to share device to device
4229      * status information.
4230      *
4231      * @param subscriptionId The subscription id.
4232      * @param contacts The list of contacts that allow device to device status sharing.
4233      *
4234      * @throws SecurityException if the caller doesn't have permissions required.
4235      * @throws UnsupportedOperationException If the device does not have
4236      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
4237      */
4238     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setDeviceToDeviceStatusSharingContacts(int subscriptionId, @NonNull List<Uri> contacts)4239     public void setDeviceToDeviceStatusSharingContacts(int subscriptionId,
4240             @NonNull List<Uri> contacts) {
4241         String contactString = serializeUriLists(contacts);
4242         if (VDBG) {
4243             logd("[setDeviceToDeviceStatusSharingContacts] + contacts: " + contactString
4244                     + " subId: " + subscriptionId);
4245         }
4246         setSubscriptionPropertyHelper(subscriptionId, "setDeviceToDeviceSharingStatus",
4247                 (iSub)->iSub.setDeviceToDeviceStatusSharingContacts(serializeUriLists(contacts),
4248                         subscriptionId));
4249     }
4250 
4251     /**
4252      * Get the list of contacts that allow device to device status sharing.
4253      *
4254      * @param subscriptionId Subscription id.
4255      *
4256      * @return The list of contacts that allow device to device status sharing.
4257      *
4258      * @throws UnsupportedOperationException If the device does not have
4259      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
4260      */
getDeviceToDeviceStatusSharingContacts(int subscriptionId)4261     public @NonNull List<Uri> getDeviceToDeviceStatusSharingContacts(int subscriptionId) {
4262         String result = getStringSubscriptionProperty(mContext, subscriptionId,
4263                 D2D_STATUS_SHARING_SELECTED_CONTACTS);
4264         if (result != null) {
4265             try {
4266                 byte[] b = Base64.decode(result, Base64.DEFAULT);
4267                 ByteArrayInputStream bis = new ByteArrayInputStream(b);
4268                 ObjectInputStream ois = new ObjectInputStream(bis);
4269                 List<String> contacts = ArrayList.class.cast(ois.readObject());
4270                 List<Uri> uris = new ArrayList<>();
4271                 for (String contact : contacts) {
4272                     uris.add(Uri.parse(contact));
4273                 }
4274                 return uris;
4275             } catch (IOException e) {
4276                 logd("getDeviceToDeviceStatusSharingContacts IO exception");
4277             } catch (ClassNotFoundException e) {
4278                 logd("getDeviceToDeviceStatusSharingContacts ClassNotFound exception");
4279             }
4280         }
4281         return new ArrayList<>();
4282     }
4283 
4284     /**
4285      * Get the active subscription id by logical SIM slot index.
4286      *
4287      * @param slotIndex The logical SIM slot index.
4288      * @return The active subscription id.
4289      *
4290      * @throws IllegalArgumentException if the provided slot index is invalid.
4291      * @throws SecurityException if callers do not hold the required permission.
4292      * @throws UnsupportedOperationException If the device does not have
4293      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
4294      *
4295      * @hide
4296      */
4297     @SystemApi
4298     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
getEnabledSubscriptionId(int slotIndex)4299     public int getEnabledSubscriptionId(int slotIndex) {
4300         int subId = INVALID_SUBSCRIPTION_ID;
4301 
4302         try {
4303             ISub iSub = TelephonyManager.getSubscriptionService();
4304             if (iSub != null) {
4305                 subId = iSub.getEnabledSubscriptionId(slotIndex);
4306             }
4307         } catch (RemoteException ex) {
4308             // ignore it
4309         }
4310 
4311         if (VDBG) logd("getEnabledSubscriptionId, subId = " + subId);
4312         return subId;
4313     }
4314 
4315     private interface CallISubMethodHelper {
callMethod(ISub iSub)4316         int callMethod(ISub iSub) throws RemoteException;
4317     }
4318 
setSubscriptionPropertyHelper(int subId, String methodName, CallISubMethodHelper helper)4319     private int setSubscriptionPropertyHelper(int subId, String methodName,
4320             CallISubMethodHelper helper) {
4321         if (!isValidSubscriptionId(subId)) {
4322             logd("[" + methodName + "]" + "- fail");
4323             return -1;
4324         }
4325 
4326         int result = 0;
4327 
4328         try {
4329             ISub iSub = TelephonyManager.getSubscriptionService();
4330             if (iSub != null) {
4331                 result = helper.callMethod(iSub);
4332             }
4333         } catch (RemoteException ex) {
4334             // ignore it
4335         }
4336 
4337         return result;
4338     }
4339 
4340     /**
4341      * Get active data subscription id. Active data subscription refers to the subscription
4342      * currently chosen to provide cellular internet connection to the user. This may be
4343      * different from {@link #getDefaultDataSubscriptionId()}.
4344      *
4345      * @return Active data subscription id if any is chosen, or {@link #INVALID_SUBSCRIPTION_ID} if
4346      * not.
4347      *
4348      * @see TelephonyCallback.ActiveDataSubscriptionIdListener
4349      */
getActiveDataSubscriptionId()4350     public static int getActiveDataSubscriptionId() {
4351         return sGetActiveDataSubscriptionIdCache.query(null);
4352     }
4353 
4354     /**
4355      * Helper method that puts a subscription id on an intent with the constants:
4356      * PhoneConstant.SUBSCRIPTION_KEY and SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX.
4357      * Both constants are used to support backwards compatibility.  Once we know we got all places,
4358      * we can remove PhoneConstants.SUBSCRIPTION_KEY.
4359      * @param intent Intent to put sub id on.
4360      * @param subId SubscriptionId to put on intent.
4361      *
4362      * @hide
4363      */
putSubscriptionIdExtra(Intent intent, int subId)4364     public static void putSubscriptionIdExtra(Intent intent, int subId) {
4365         intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
4366         intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
4367     }
4368 
4369     /** @hide */
invalidateSubscriptionManagerServiceCaches()4370     public static void invalidateSubscriptionManagerServiceCaches() {
4371         PropertyInvalidatedCache.invalidateCache(CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY);
4372     }
4373 
4374     /**
4375      * Allows a test process to disable client-side caching operations.
4376      *
4377      * @hide
4378      */
disableCaching()4379     public static void disableCaching() {
4380         sGetDefaultSubIdCacheAsUser.disableLocal();
4381         sGetDefaultDataSubIdCache.disableLocal();
4382         sGetActiveDataSubscriptionIdCache.disableLocal();
4383         sGetDefaultSmsSubIdCacheAsUser.disableLocal();
4384         sGetSlotIndexCache.disableLocal();
4385         sGetSubIdCache.disableLocal();
4386         sGetPhoneIdCache.disableLocal();
4387     }
4388 
4389     /**
4390      * Clears all process-local binder caches.
4391      *
4392      * @hide */
clearCaches()4393     public static void clearCaches() {
4394         sGetDefaultSubIdCacheAsUser.clear();
4395         sGetDefaultDataSubIdCache.clear();
4396         sGetActiveDataSubscriptionIdCache.clear();
4397         sGetDefaultSmsSubIdCacheAsUser.clear();
4398         sGetSlotIndexCache.clear();
4399         sGetSubIdCache.clear();
4400         sGetPhoneIdCache.clear();
4401     }
4402 
4403     /**
4404      * Called to retrieve SIM-specific settings data to be backed up.
4405      *
4406      * @return data in byte[] to be backed up.
4407      *
4408      * @hide
4409      */
4410     @NonNull
4411     @SystemApi
4412     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
getAllSimSpecificSettingsForBackup()4413     public byte[] getAllSimSpecificSettingsForBackup() {
4414         Bundle bundle =  mContext.getContentResolver().call(
4415                 SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
4416                 GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME, null, null);
4417         return bundle.getByteArray(SubscriptionManager.KEY_SIM_SPECIFIC_SETTINGS_DATA);
4418     }
4419 
4420     /**
4421      * Called during setup wizard restore flow to attempt to restore the backed up sim-specific
4422      * configs to device for all existing SIMs in the subscription database {@link SimInfo}.
4423      * Internally, it will store the backup data in an internal file. This file will persist on
4424      * device for device's lifetime and will be used later on when a SIM is inserted to restore that
4425      * specific SIM's settings. End result is subscription database is modified to match any backed
4426      * up configs for the appropriate inserted SIMs.
4427      *
4428      * <p>
4429      * The {@link Uri} {@link #SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI} is notified if any
4430      * {@link SimInfo} entry is updated as the result of this method call.
4431      *
4432      * @param data with the sim specific configs to be backed up.
4433      *
4434      * @throws UnsupportedOperationException If the device does not have
4435      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
4436      * @hide
4437      */
4438     @SystemApi
4439     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
restoreAllSimSpecificSettingsFromBackup(@onNull byte[] data)4440     public void restoreAllSimSpecificSettingsFromBackup(@NonNull byte[] data) {
4441         try {
4442             ISub iSub = TelephonyManager.getSubscriptionService();
4443             if (iSub != null) {
4444                 iSub.restoreAllSimSpecificSettingsFromBackup(data);
4445             } else {
4446                 throw new IllegalStateException("subscription service unavailable.");
4447             }
4448         } catch (RemoteException ex) {
4449             if (!isSystemProcess()) {
4450                 ex.rethrowAsRuntimeException();
4451             }
4452         }
4453     }
4454 
4455     /**
4456      * Returns the phone number for the given {@code subscriptionId} and {@code source},
4457      * or an empty string if not available.
4458      *
4459      * <p>General apps that need to know the phone number should use {@link #getPhoneNumber(int)}
4460      * instead. This API may be suitable specific apps that needs to know the phone number from
4461      * a specific source. For example, a carrier app needs to know exactly what's on
4462      * {@link #PHONE_NUMBER_SOURCE_UICC UICC} and decide if the previously set phone number
4463      * of source {@link #PHONE_NUMBER_SOURCE_CARRIER carrier} should be updated.
4464      *
4465      * <p>The API provides no guarantees of what format the number is in: the format can vary
4466      * depending on the {@code source} and the network etc. Programmatic parsing should be done
4467      * cautiously, for example, after formatting the number to a consistent format with
4468      * {@link android.telephony.PhoneNumberUtils#formatNumberToE164(String, String)}.
4469      *
4470      * <p>Note the assumption is that one subscription (which usually means one SIM) has
4471      * only one phone number. The multiple sources backup each other so hopefully at least one
4472      * is available. For example, for a carrier that doesn't typically set phone numbers
4473      * on {@link #PHONE_NUMBER_SOURCE_UICC UICC}, the source {@link #PHONE_NUMBER_SOURCE_IMS IMS}
4474      * may provide one. Or, a carrier may decide to provide the phone number via source
4475      * {@link #PHONE_NUMBER_SOURCE_CARRIER carrier} if neither source UICC nor IMS is available.
4476      *
4477      * <p>The availability and correctness of the phone number depends on the underlying source
4478      * and the network etc. Additional verification is needed to use this number for
4479      * security-related or other sensitive scenarios.
4480      *
4481      * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID}
4482      * for the default one.
4483      * @param source the source of the phone number, one of the PHONE_NUMBER_SOURCE_* constants.
4484      *
4485      * @return the phone number, or an empty string if not available.
4486      *
4487      * @throws IllegalArgumentException if {@code source} is invalid.
4488      * @throws IllegalStateException if the telephony process is not currently available.
4489      * @throws SecurityException if the caller doesn't have permissions required.
4490      * @throws UnsupportedOperationException If the device does not have
4491      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
4492      *
4493      * @see #PHONE_NUMBER_SOURCE_UICC
4494      * @see #PHONE_NUMBER_SOURCE_CARRIER
4495      * @see #PHONE_NUMBER_SOURCE_IMS
4496      */
4497     @RequiresPermission(anyOf = {
4498             android.Manifest.permission.READ_PHONE_NUMBERS,
4499             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
4500             "carrier privileges",
4501     })
4502     @NonNull
getPhoneNumber(int subscriptionId, @PhoneNumberSource int source)4503     public String getPhoneNumber(int subscriptionId, @PhoneNumberSource int source) {
4504         if (subscriptionId == DEFAULT_SUBSCRIPTION_ID) {
4505             subscriptionId = getDefaultSubscriptionId();
4506         }
4507         if (source != PHONE_NUMBER_SOURCE_UICC
4508                 && source != PHONE_NUMBER_SOURCE_CARRIER
4509                 && source != PHONE_NUMBER_SOURCE_IMS) {
4510             throw new IllegalArgumentException("invalid source " + source);
4511         }
4512         try {
4513             ISub iSub = TelephonyManager.getSubscriptionService();
4514             if (iSub != null) {
4515                 return iSub.getPhoneNumber(subscriptionId, source,
4516                         mContext.getOpPackageName(), mContext.getAttributionTag());
4517             } else {
4518                 throw new IllegalStateException("subscription service unavailable.");
4519             }
4520         } catch (RemoteException ex) {
4521             throw ex.rethrowAsRuntimeException();
4522         }
4523     }
4524 
4525     /**
4526      * Returns the phone number for the given {@code subId}, or an empty string if
4527      * not available.
4528      *
4529      * <p>This API is suitable for general apps that needs to know the phone number.
4530      * For specific apps that needs to know the phone number provided by a specific source,
4531      * {@link #getPhoneNumber(int, int)} may be suitable.
4532      *
4533      * <p>This API is built up on {@link #getPhoneNumber(int, int)}, but picks
4534      * from available sources in the following order: {@link #PHONE_NUMBER_SOURCE_CARRIER}
4535      * > {@link #PHONE_NUMBER_SOURCE_UICC} > {@link #PHONE_NUMBER_SOURCE_IMS}.
4536      *
4537      * <p>The API provides no guarantees of what format the number is in: the format can vary
4538      * depending on the underlying source and the network etc. Programmatic parsing should be done
4539      * cautiously, for example, after formatting the number to a consistent format with
4540      * {@link android.telephony.PhoneNumberUtils#formatNumberToE164(String, String)}.
4541      *
4542      * <p>The availability and correctness of the phone number depends on the underlying source
4543      * and the network etc. Additional verification is needed to use this number for
4544      * security-related or other sensitive scenarios.
4545      *
4546      * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID}
4547      *                       for the default one.
4548      * @return the phone number, or an empty string if not available.
4549      *
4550      * @throws IllegalStateException if the telephony process is not currently available.
4551      * @throws SecurityException if the caller doesn't have permissions required.
4552      * @throws UnsupportedOperationException If the device does not have
4553      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
4554      *
4555      * @see #getPhoneNumber(int, int)
4556      */
4557     @RequiresPermission(anyOf = {
4558             android.Manifest.permission.READ_PHONE_NUMBERS,
4559             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
4560             "carrier privileges",
4561     })
4562     @NonNull
getPhoneNumber(int subscriptionId)4563     public String getPhoneNumber(int subscriptionId) {
4564         if (subscriptionId == DEFAULT_SUBSCRIPTION_ID) {
4565             subscriptionId = getDefaultSubscriptionId();
4566         }
4567         try {
4568             ISub iSub = TelephonyManager.getSubscriptionService();
4569             if (iSub != null) {
4570                 return iSub.getPhoneNumberFromFirstAvailableSource(subscriptionId,
4571                         mContext.getOpPackageName(), mContext.getAttributionTag());
4572             } else {
4573                 throw new IllegalStateException("subscription service unavailable.");
4574             }
4575         } catch (RemoteException ex) {
4576             throw ex.rethrowAsRuntimeException();
4577         }
4578     }
4579 
4580     /**
4581      * Sets the phone number for the given {@code subId} for source
4582      * {@link #PHONE_NUMBER_SOURCE_CARRIER carrier}.
4583      * Sets an empty string to remove the previously set phone number.
4584      *
4585      * <p>The API is suitable for carrier apps to provide a phone number, for example when
4586      * it's not possible to update {@link #PHONE_NUMBER_SOURCE_UICC UICC} directly.
4587      *
4588      * <p>It's recommended that the phone number is formatted to well-known formats,
4589      * for example, by {@link PhoneNumberUtils} {@code formatNumber*} methods.
4590      *
4591      * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID}
4592      *                       for the default one.
4593      * @param number the phone number, or an empty string to remove the previously set number.
4594      * @throws IllegalStateException if the telephony process is not currently available.
4595      * @throws NullPointerException if {@code number} is {@code null}.
4596      * @throws SecurityException if the caller doesn't have permissions required.
4597      * @throws UnsupportedOperationException If the device does not have
4598      *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
4599      */
4600     @RequiresPermission("carrier privileges")
setCarrierPhoneNumber(int subscriptionId, @NonNull String number)4601     public void setCarrierPhoneNumber(int subscriptionId, @NonNull String number) {
4602         if (subscriptionId == DEFAULT_SUBSCRIPTION_ID) {
4603             subscriptionId = getDefaultSubscriptionId();
4604         }
4605         if (number == null) {
4606             throw new NullPointerException("invalid number null");
4607         }
4608         try {
4609             ISub iSub = TelephonyManager.getSubscriptionService();
4610             if (iSub != null) {
4611                 iSub.setPhoneNumber(subscriptionId, PHONE_NUMBER_SOURCE_CARRIER, number,
4612                         mContext.getOpPackageName(), mContext.getAttributionTag());
4613             } else {
4614                 throw new IllegalStateException("subscription service unavailable.");
4615             }
4616         } catch (RemoteException ex) {
4617             throw ex.rethrowAsRuntimeException();
4618         }
4619     }
4620 
4621     /**
4622      * Set the preferred usage setting.
4623      *
4624      * The cellular usage setting is a switch which controls the mode of operation for the cellular
4625      * radio to either require or not require voice service. It is not managed via Android’s
4626      * Settings.
4627      *
4628      * @param subscriptionId the subId of the subscription.
4629      * @param usageSetting the requested usage setting.
4630      *
4631      * @throws IllegalStateException if a specific mode or setting the mode is not supported on a
4632      * particular device.
4633      *
4634      * <p>Requires {@link android.Manifest.permission#MODIFY_PHONE_STATE}
4635      * or that the calling app has CarrierPrivileges for the given subscription.
4636      *
4637      * Note: This method will not allow the setting of USAGE_SETTING_UNKNOWN.
4638      *
4639      * @hide
4640      */
4641     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setUsageSetting(int subscriptionId, @UsageSetting int usageSetting)4642     void setUsageSetting(int subscriptionId, @UsageSetting int usageSetting) {
4643         if (VDBG) logd("[setUsageSetting]+ setting:" + usageSetting + " subId:" + subscriptionId);
4644         setSubscriptionPropertyHelper(subscriptionId, "setUsageSetting",
4645                 (iSub)-> iSub.setUsageSetting(
4646                         usageSetting, subscriptionId, mContext.getOpPackageName()));
4647     }
4648 
4649     /**
4650      * Convert phone number source to string.
4651      *
4652      * @param source The phone name source.
4653      *
4654      * @return The phone name source in string format.
4655      *
4656      * @hide
4657      */
4658     @NonNull
phoneNumberSourceToString(@honeNumberSource int source)4659     public static String phoneNumberSourceToString(@PhoneNumberSource int source) {
4660         switch (source) {
4661             case SubscriptionManager.PHONE_NUMBER_SOURCE_UICC: return "UICC";
4662             case SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER: return "CARRIER";
4663             case SubscriptionManager.PHONE_NUMBER_SOURCE_IMS: return "IMS";
4664             default:
4665                 return "UNKNOWN(" + source + ")";
4666         }
4667     }
4668 
4669     /**
4670      * Convert display name source to string.
4671      *
4672      * @param source The display name source.
4673      * @return The display name source in string format.
4674      *
4675      * @hide
4676      */
4677     @NonNull
displayNameSourceToString( @ubscriptionManager.SimDisplayNameSource int source)4678     public static String displayNameSourceToString(
4679             @SubscriptionManager.SimDisplayNameSource int source) {
4680         switch (source) {
4681             case SubscriptionManager.NAME_SOURCE_UNKNOWN: return "UNKNOWN";
4682             case SubscriptionManager.NAME_SOURCE_CARRIER_ID: return "CARRIER_ID";
4683             case SubscriptionManager.NAME_SOURCE_SIM_SPN: return "SIM_SPN";
4684             case SubscriptionManager.NAME_SOURCE_USER_INPUT: return "USER_INPUT";
4685             case SubscriptionManager.NAME_SOURCE_CARRIER: return "CARRIER";
4686             case SubscriptionManager.NAME_SOURCE_SIM_PNN: return "SIM_PNN";
4687             default:
4688                 return "UNKNOWN(" + source + ")";
4689         }
4690     }
4691 
4692     /**
4693      * Convert subscription type to string.
4694      *
4695      * @param type The subscription type.
4696      * @return The subscription type in string format.
4697      *
4698      * @hide
4699      */
4700     @NonNull
subscriptionTypeToString(@ubscriptionManager.SubscriptionType int type)4701     public static String subscriptionTypeToString(@SubscriptionManager.SubscriptionType int type) {
4702         switch (type) {
4703             case SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM: return "LOCAL_SIM";
4704             case SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM: return "REMOTE_SIM";
4705             default:
4706                 return "UNKNOWN(" + type + ")";
4707         }
4708     }
4709 
4710     /**
4711      * Convert usage setting to string.
4712      *
4713      * @param usageSetting Usage setting.
4714      * @return The usage setting in string format.
4715      *
4716      * @hide
4717      */
4718     @NonNull
usageSettingToString(@ubscriptionManager.UsageSetting int usageSetting)4719     public static String usageSettingToString(@SubscriptionManager.UsageSetting int usageSetting) {
4720         switch (usageSetting) {
4721             case SubscriptionManager.USAGE_SETTING_UNKNOWN: return "UNKNOWN";
4722             case SubscriptionManager.USAGE_SETTING_DEFAULT: return "DEFAULT";
4723             case SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC: return "VOICE_CENTRIC";
4724             case SubscriptionManager.USAGE_SETTING_DATA_CENTRIC: return "DATA_CENTRIC";
4725             default:
4726                 return "UNKNOWN(" + usageSetting + ")";
4727         }
4728     }
4729 
4730     /**
4731      * Set owner for this subscription.
4732      *
4733      * @param subscriptionId the subId of the subscription.
4734      * @param groupOwner The group owner to assign to the subscription
4735      *
4736      * @throws SecurityException if caller is not authorized.
4737      *
4738      * @hide
4739      */
4740     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
setGroupOwner(int subscriptionId, @NonNull String groupOwner)4741     public void setGroupOwner(int subscriptionId, @NonNull String groupOwner) {
4742         try {
4743             ISub iSub = TelephonyManager.getSubscriptionService();
4744             if (iSub != null) {
4745                 iSub.setGroupOwner(subscriptionId, groupOwner);
4746             } else {
4747                 throw new IllegalStateException("[setGroupOwner]: "
4748                         + "subscription service unavailable");
4749             }
4750         } catch (RemoteException ex) {
4751             ex.rethrowAsRuntimeException();
4752         }
4753     }
4754 
4755     /**
4756      * Set userHandle for a subscription.
4757      *
4758      * Used to set an association between a subscription and a user on the device so that voice
4759      * calling and SMS from that subscription can be associated with that user.
4760      * Data services are always shared between users on the device.
4761      *
4762      * @param subscriptionId the subId of the subscription.
4763      * @param userHandle the userHandle associated with the subscription.
4764      * Pass {@code null} user handle to clear the association.
4765      *
4766      * @throws IllegalArgumentException if subscription is invalid.
4767      * @throws SecurityException if the caller doesn't have permissions required.
4768      * @throws IllegalStateException if subscription service is not available.
4769      *
4770      * @hide
4771      */
4772     @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION)
setSubscriptionUserHandle(int subscriptionId, @Nullable UserHandle userHandle)4773     public void setSubscriptionUserHandle(int subscriptionId, @Nullable UserHandle userHandle) {
4774         if (!isValidSubscriptionId(subscriptionId)) {
4775             throw new IllegalArgumentException("[setSubscriptionUserHandle]: "
4776                     + "Invalid subscriptionId: " + subscriptionId);
4777         }
4778 
4779         try {
4780             ISub iSub = TelephonyManager.getSubscriptionService();
4781             if (iSub != null) {
4782                 iSub.setSubscriptionUserHandle(userHandle, subscriptionId);
4783             } else {
4784                 throw new IllegalStateException("[setSubscriptionUserHandle]: "
4785                         + "subscription service unavailable");
4786             }
4787         } catch (RemoteException ex) {
4788             ex.rethrowAsRuntimeException();
4789         }
4790     }
4791 
4792     /**
4793      * Get UserHandle of this subscription.
4794      *
4795      * Used to get user handle associated with this subscription.
4796      *
4797      * @param subscriptionId the subId of the subscription.
4798      * @return userHandle associated with this subscription
4799      * or {@code null} if subscription is not associated with any user.
4800      *
4801      * @throws IllegalArgumentException if subscription is invalid.
4802      * @throws SecurityException if the caller doesn't have permissions required.
4803      *
4804      * @hide
4805      */
4806     @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION)
getSubscriptionUserHandle(int subscriptionId)4807     public @Nullable UserHandle getSubscriptionUserHandle(int subscriptionId) {
4808         if (!isValidSubscriptionId(subscriptionId)) {
4809             throw new IllegalArgumentException("[getSubscriptionUserHandle]: "
4810                     + "Invalid subscriptionId: " + subscriptionId);
4811         }
4812 
4813         try {
4814             ISub iSub = TelephonyManager.getSubscriptionService();
4815             if (iSub != null) {
4816                 return iSub.getSubscriptionUserHandle(subscriptionId);
4817             } else {
4818                 Log.e(LOG_TAG, "[getSubscriptionUserHandle]: subscription service unavailable");
4819             }
4820         } catch (RemoteException ex) {
4821             ex.rethrowAsRuntimeException();
4822         }
4823         return null;
4824     }
4825 
4826     /**
4827      * Check if subscription and user are associated with each other.
4828      *
4829      * @param subscriptionId the subId of the subscription
4830      * @param userHandle user handle of the user
4831      * @return {@code true} if subscription is associated with user
4832      * else {@code false} if subscription is not associated with user.
4833      *
4834      * @throws IllegalArgumentException if subscription doesn't exist.
4835      * @throws SecurityException if the caller doesn't have permissions required.
4836      *
4837      * @hide
4838      */
4839     @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION)
isSubscriptionAssociatedWithUser(int subscriptionId, @NonNull UserHandle userHandle)4840     public boolean isSubscriptionAssociatedWithUser(int subscriptionId,
4841             @NonNull UserHandle userHandle) {
4842         if (!isValidSubscriptionId(subscriptionId)) {
4843             throw new IllegalArgumentException("[isSubscriptionAssociatedWithUser]: "
4844                     + "Invalid subscriptionId: " + subscriptionId);
4845         }
4846 
4847         try {
4848             ISub iSub = TelephonyManager.getSubscriptionService();
4849             if (iSub != null) {
4850                 return iSub.isSubscriptionAssociatedWithUser(subscriptionId, userHandle);
4851             } else {
4852                 Log.e(LOG_TAG, "[isSubscriptionAssociatedWithUser]: subscription service "
4853                         + "unavailable");
4854             }
4855         } catch (RemoteException ex) {
4856             ex.rethrowAsRuntimeException();
4857         }
4858         return false;
4859     }
4860 
4861     /**
4862      * Returns whether the given subscription is associated with the calling user.
4863      *
4864      * @param subscriptionId the subscription ID of the subscription
4865      * @return {@code true} if the subscription is associated with the user that the current process
4866      *         is running in; {@code false} otherwise.
4867      *
4868      * @throws IllegalArgumentException if subscription doesn't exist.
4869      * @throws SecurityException if the caller doesn't have permissions required.
4870      */
4871     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
4872     @FlaggedApi(Flags.FLAG_SUBSCRIPTION_USER_ASSOCIATION_QUERY)
isSubscriptionAssociatedWithUser(int subscriptionId)4873     public boolean isSubscriptionAssociatedWithUser(int subscriptionId) {
4874         if (!isValidSubscriptionId(subscriptionId)) {
4875             throw new IllegalArgumentException("[isSubscriptionAssociatedWithCallingUser]: "
4876                     + "Invalid subscriptionId: " + subscriptionId);
4877         }
4878 
4879         String contextPkg = mContext != null ? mContext.getOpPackageName() : "<unknown>";
4880         String contextAttributionTag = mContext != null ? mContext.getAttributionTag() : null;
4881 
4882         try {
4883             ISub iSub = TelephonyManager.getSubscriptionService();
4884             if (iSub != null) {
4885                 return iSub.isSubscriptionAssociatedWithCallingUser(subscriptionId, contextPkg,
4886                         contextAttributionTag);
4887             } else {
4888                 throw new IllegalStateException("subscription service unavailable.");
4889             }
4890         } catch (RemoteException ex) {
4891             ex.rethrowAsRuntimeException();
4892         }
4893         return false;
4894     }
4895 
4896     /**
4897      * Get list of subscriptions associated with user.
4898      *
4899      * @param userHandle user handle of the user
4900      * @return list of subscriptionInfo associated with the user.
4901      *
4902      * @throws SecurityException if the caller doesn't have permissions required.
4903      * @throws IllegalStateException if subscription service is not available.
4904      *
4905      * @hide
4906      */
4907     @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION)
getSubscriptionInfoListAssociatedWithUser( @onNull UserHandle userHandle)4908     public @NonNull List<SubscriptionInfo> getSubscriptionInfoListAssociatedWithUser(
4909             @NonNull UserHandle userHandle) {
4910         try {
4911             ISub iSub = TelephonyManager.getSubscriptionService();
4912             if (iSub != null) {
4913                 return iSub.getSubscriptionInfoListAssociatedWithUser(userHandle);
4914             } else {
4915                 Log.e(LOG_TAG, "[getSubscriptionInfoListAssociatedWithUser]: "
4916                         + "subscription service unavailable");
4917             }
4918         } catch (RemoteException ex) {
4919             ex.rethrowAsRuntimeException();
4920         }
4921         return new ArrayList<>();
4922     }
4923 
4924     /**
4925      * @return the bitmasks combination of all service capabilities.
4926      * @hide
4927      */
getAllServiceCapabilityBitmasks()4928     public static int getAllServiceCapabilityBitmasks() {
4929         return SERVICE_CAPABILITY_VOICE_BITMASK | SERVICE_CAPABILITY_SMS_BITMASK
4930                 | SERVICE_CAPABILITY_DATA_BITMASK;
4931     }
4932 
4933     /**
4934      * @return The set of service capability from a bitmask combined one.
4935      * @hide
4936      */
4937     @NonNull
4938     @ServiceCapability
getServiceCapabilitiesSet(int combinedServiceCapabilities)4939     public static Set<Integer> getServiceCapabilitiesSet(int combinedServiceCapabilities) {
4940         Set<Integer> capabilities = new HashSet<>();
4941         for (int i = SERVICE_CAPABILITY_VOICE; i <= SERVICE_CAPABILITY_MAX; i++) {
4942             final int capabilityBitmask = serviceCapabilityToBitmask(i);
4943             if ((combinedServiceCapabilities & capabilityBitmask) == capabilityBitmask) {
4944                 capabilities.add(i);
4945             }
4946         }
4947         return Collections.unmodifiableSet(capabilities);
4948     }
4949 
4950     /**
4951      * @return The service capability bitmask from a {@link ServiceCapability} value.
4952      * @hide
4953      */
serviceCapabilityToBitmask(@erviceCapability int capability)4954     public static int serviceCapabilityToBitmask(@ServiceCapability int capability) {
4955         return 1 << (capability - 1);
4956     }
4957 
4958     /**
4959      * Set the transfer status of the subscriptionInfo of the subId.
4960      * @param subscriptionId The unique SubscriptionInfo key in database.
4961      * @param status The transfer status to change.
4962      *
4963      *
4964      * @hide
4965      */
4966     @FlaggedApi(Flags.FLAG_SUPPORT_PSIM_TO_ESIM_CONVERSION)
4967     @SystemApi
4968     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
setTransferStatus(int subscriptionId, @TransferStatus int status)4969     public void setTransferStatus(int subscriptionId, @TransferStatus int status) {
4970         try {
4971             ISub iSub = TelephonyManager.getSubscriptionService();
4972             if (iSub != null) {
4973                 iSub.setTransferStatus(subscriptionId, status);
4974             }
4975         } catch (RemoteException ex) {
4976             logd("setTransferStatus for subId = " + subscriptionId + " failed.");
4977             throw ex.rethrowFromSystemServer();
4978         }
4979     }
4980 }
4981