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