blob: 080800b38855992191df85156228e34ed4d42cff [file] [log] [blame]
Wink Savillefb40dd42014-06-12 17:02:31 -07001/*
Wink Savillef5bca082014-09-03 15:13:33 -07002 * 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 */
Wink Savillefb40dd42014-06-12 17:02:31 -070016
17package android.telephony;
18
Aaron Huang79f52ea2019-12-30 20:11:36 +080019import static android.net.NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_CONGESTED;
20import static android.net.NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED;
Jeff Sharkey9252b342018-01-19 07:58:35 +090021
Malcolm Chenbe9240b2018-12-03 20:29:33 -080022import android.Manifest;
Malcolm Chen27829e22018-09-04 22:12:31 -070023import android.annotation.CallbackExecutor;
changbetty23eee52e2019-12-18 18:09:56 +080024import android.annotation.ColorInt;
Jeff Sharkey9252b342018-01-19 07:58:35 +090025import android.annotation.DurationMillisLong;
Grace Chen5be6e9c2018-12-20 22:50:18 -080026import android.annotation.IntDef;
Jeff Sharkey32566012014-12-02 18:30:14 -080027import android.annotation.NonNull;
Jeff Sharkey717f52f2018-01-04 16:04:11 -070028import android.annotation.Nullable;
Hui Wangc47df7f2021-12-14 20:37:47 +000029import android.annotation.RequiresFeature;
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -070030import android.annotation.RequiresPermission;
Wink Savillec650e0b2014-09-02 22:37:08 -070031import android.annotation.SdkConstant;
32import android.annotation.SdkConstant.SdkConstantType;
Jeff Davidson3c0415a2018-02-23 15:27:46 -080033import android.annotation.SuppressAutoDoc;
Jeff Sharkey717f52f2018-01-04 16:04:11 -070034import android.annotation.SystemApi;
Jeff Sharkey17bebd22017-07-19 21:00:38 -060035import android.annotation.SystemService;
Malcolm Chen0ac24ef2018-08-07 15:03:32 -070036import android.app.PendingIntent;
Collin Fijalkovich4ffdedf2019-12-10 09:52:14 -080037import android.app.PropertyInvalidatedCache;
Artur Satayev54af4fc2019-12-10 17:47:56 +000038import android.compat.annotation.UnsupportedAppUsage;
Wink Savillea374c3d2014-11-11 11:48:04 -080039import android.content.Context;
Wink Savillefb40dd42014-06-12 17:02:31 -070040import android.content.Intent;
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -080041import android.content.pm.PackageInfo;
Jeff Sharkey717f52f2018-01-04 16:04:11 -070042import android.content.pm.PackageManager;
Sanket Padawedc493092015-07-14 14:21:43 -070043import android.content.res.Configuration;
44import android.content.res.Resources;
chen xua0007492018-10-02 19:34:10 -070045import android.database.ContentObserver;
Jeff Sharkey9252b342018-01-19 07:58:35 +090046import android.net.NetworkCapabilities;
Aaron Huang21089442020-01-16 23:31:02 +080047import android.net.NetworkPolicyManager;
Wink Savillefb40dd42014-06-12 17:02:31 -070048import android.net.Uri;
Malcolm Chenb2129eb2018-10-16 18:18:51 -070049import android.os.Binder;
Mathew Inwood45d2c252018-09-14 12:35:36 +010050import android.os.Build;
Jack Nudelmane2ea4282021-01-13 18:46:57 -080051import android.os.Bundle;
Wink Savilled09c4ca2014-11-22 10:08:16 -080052import android.os.Handler;
Jack He9fc75742017-11-16 15:54:14 -080053import android.os.Looper;
Malcolm Chen4674a792019-03-20 20:32:27 -070054import android.os.ParcelUuid;
55import android.os.Process;
Wink Savillefb40dd42014-06-12 17:02:31 -070056import android.os.RemoteException;
changbetty239b6ce2019-12-02 15:04:49 +080057import android.provider.Telephony.SimInfo;
Malcolm Chen0ac24ef2018-08-07 15:03:32 -070058import android.telephony.euicc.EuiccManager;
chen xubf38b062018-11-01 00:08:37 -070059import android.telephony.ims.ImsMmTelManager;
Grace Jia2bd23cf2021-03-18 14:47:31 -070060import android.util.Base64;
Malcolm Chen27829e22018-09-04 22:12:31 -070061import android.util.Log;
Torbjorn Eklundf8899f02019-11-20 10:59:59 +010062import android.util.Pair;
Jeff Sharkey717f52f2018-01-04 16:04:11 -070063
Malcolm Chenfd11df22019-02-05 17:19:48 -080064import com.android.internal.telephony.ISetOpportunisticDataCallback;
Jeff Davidsond02731f2017-04-09 14:31:09 -070065import com.android.internal.telephony.ISub;
Wink Savillefb40dd42014-06-12 17:02:31 -070066import com.android.internal.telephony.PhoneConstants;
Sooraj Sasindran041a6d32019-12-02 13:08:23 -080067import com.android.internal.telephony.util.HandlerExecutor;
Hall Liu29b1874f2020-04-07 18:23:09 -070068import com.android.internal.util.FunctionalUtils;
Malcolm Chen80e1e5c2019-02-27 15:16:05 -080069import com.android.internal.util.Preconditions;
Meng Wange3387ef92020-01-30 12:38:32 -080070import com.android.telephony.Rlog;
Jeff Sharkey717f52f2018-01-04 16:04:11 -070071
Grace Jia2bd23cf2021-03-18 14:47:31 -070072import java.io.ByteArrayInputStream;
73import java.io.ByteArrayOutputStream;
74import java.io.IOException;
75import java.io.ObjectInputStream;
76import java.io.ObjectOutputStream;
Grace Chen5be6e9c2018-12-20 22:50:18 -080077import java.lang.annotation.Retention;
78import java.lang.annotation.RetentionPolicy;
Wink Saville905bb542014-09-04 17:10:23 -070079import java.util.ArrayList;
Jeff Sharkey53313d72017-07-13 16:47:32 -060080import java.util.Arrays;
Rajeev Kumarc8ac4f3b2017-07-26 15:59:08 -070081import java.util.Collections;
Malcolm Chenb82864c2019-02-26 16:48:40 -080082import java.util.HashMap;
Wink Savillefb40dd42014-06-12 17:02:31 -070083import java.util.List;
Torbjorn Eklund99c11d82018-08-21 16:06:47 +020084import java.util.Locale;
Malcolm Chenb82864c2019-02-26 16:48:40 -080085import java.util.Map;
Torbjorn Eklundf8899f02019-11-20 10:59:59 +010086import java.util.concurrent.ConcurrentHashMap;
Malcolm Chen27829e22018-09-04 22:12:31 -070087import java.util.concurrent.Executor;
Malcolm Chenfd11df22019-02-05 17:19:48 -080088import java.util.function.Consumer;
Malcolm Chen0db9aa12018-12-06 11:19:03 -080089import java.util.stream.Collectors;
Wink Savillefb40dd42014-06-12 17:02:31 -070090
91/**
Wink Savillef5bca082014-09-03 15:13:33 -070092 * SubscriptionManager is the application interface to SubscriptionController
93 * and provides information about the current Telephony Subscriptions.
Wink Savillefb40dd42014-06-12 17:02:31 -070094 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060095@SystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)
Hui Wangc47df7f2021-12-14 20:37:47 +000096@RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
Wink Savilled09c4ca2014-11-22 10:08:16 -080097public class SubscriptionManager {
98 private static final String LOG_TAG = "SubscriptionManager";
99 private static final boolean DBG = false;
Wink Savillefb40dd42014-06-12 17:02:31 -0700100 private static final boolean VDBG = false;
101
Wink Savillea374c3d2014-11-11 11:48:04 -0800102 /** An invalid subscription identifier */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800103 public static final int INVALID_SUBSCRIPTION_ID = -1;
104
Tyler Gunn460360d2020-07-29 10:21:45 -0700105 /** Base value for placeholder SUBSCRIPTION_ID's. */
106 /** @hide */
107 public static final int PLACEHOLDER_SUBSCRIPTION_ID_BASE = INVALID_SUBSCRIPTION_ID - 1;
Wink Savillefb40dd42014-06-12 17:02:31 -0700108
Wink Savillea374c3d2014-11-11 11:48:04 -0800109 /** An invalid phone identifier */
110 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800111 public static final int INVALID_PHONE_INDEX = -1;
Wink Savillec650e0b2014-09-02 22:37:08 -0700112
sqian996a3182018-10-12 18:41:19 -0700113 /** Indicates invalid sim slot. This can be returned by {@link #getSlotIndex(int)}. */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800114 public static final int INVALID_SIM_SLOT_INDEX = -1;
Wink Savillea374c3d2014-11-11 11:48:04 -0800115
sqian798da562018-09-12 16:31:17 -0700116 /** Indicates the default subscription ID in Telephony. */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800117 public static final int DEFAULT_SUBSCRIPTION_ID = Integer.MAX_VALUE;
Wink Savillea374c3d2014-11-11 11:48:04 -0800118
Wink Savilled09c4ca2014-11-22 10:08:16 -0800119 /**
120 * Indicates the caller wants the default phone id.
Jack Yu67140302015-12-10 12:27:58 -0800121 * Used in SubscriptionController and Phone but do we really need it???
Wink Savilled09c4ca2014-11-22 10:08:16 -0800122 * @hide
123 */
124 public static final int DEFAULT_PHONE_INDEX = Integer.MAX_VALUE;
Wink Saville2d1ee982014-11-20 20:29:51 +0000125
Wink Savilled09c4ca2014-11-22 10:08:16 -0800126 /** Indicates the caller wants the default slot id. NOT used remove? */
Wink Saville2d1ee982014-11-20 20:29:51 +0000127 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800128 public static final int DEFAULT_SIM_SLOT_INDEX = Integer.MAX_VALUE;
Wink Savillec650e0b2014-09-02 22:37:08 -0700129
Wink Saville8eab2b62014-09-23 14:20:58 -0700130 /** Minimum possible subid that represents a subscription */
131 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800132 public static final int MIN_SUBSCRIPTION_ID_VALUE = 0;
Wink Saville8eab2b62014-09-23 14:20:58 -0700133
134 /** Maximum possible subid that represents a subscription */
135 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800136 public static final int MAX_SUBSCRIPTION_ID_VALUE = DEFAULT_SUBSCRIPTION_ID - 1;
Wink Saville8eab2b62014-09-23 14:20:58 -0700137
Wink Savillef5bca082014-09-03 15:13:33 -0700138 /** @hide */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +0000139 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
changbetty239b6ce2019-12-02 15:04:49 +0800140 public static final Uri CONTENT_URI = SimInfo.CONTENT_URI;
Wink Savillefb40dd42014-06-12 17:02:31 -0700141
Collin Fijalkovich4ffdedf2019-12-10 09:52:14 -0800142 /** @hide */
143 public static final String CACHE_KEY_DEFAULT_SUB_ID_PROPERTY =
144 "cache_key.telephony.get_default_sub_id";
145
Collin Fijalkovichce43a592020-03-25 14:30:21 -0700146 /** @hide */
147 public static final String CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY =
148 "cache_key.telephony.get_default_data_sub_id";
149
Collin Fijalkovich7d7ce512020-04-02 13:32:32 -0700150 /** @hide */
Collin Fijalkovich02e5c592020-04-06 10:54:28 -0700151 public static final String CACHE_KEY_DEFAULT_SMS_SUB_ID_PROPERTY =
152 "cache_key.telephony.get_default_sms_sub_id";
153
154 /** @hide */
Collin Fijalkovich7d7ce512020-04-02 13:32:32 -0700155 public static final String CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY =
156 "cache_key.telephony.get_active_data_sub_id";
157
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700158 /** @hide */
159 public static final String CACHE_KEY_SLOT_INDEX_PROPERTY =
160 "cache_key.telephony.get_slot_index";
161
Jack Nudelmane2ea4282021-01-13 18:46:57 -0800162 /** @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
Collin Fijalkovichce43a592020-03-25 14:30:21 -0700178 private static final int MAX_CACHE_SIZE = 4;
Collin Fijalkovich4ffdedf2019-12-10 09:52:14 -0800179
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700180 private static class VoidPropertyInvalidatedCache<T>
Hall Liu29b1874f2020-04-07 18:23:09 -0700181 extends PropertyInvalidatedCache<Void, T> {
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700182 private final FunctionalUtils.ThrowingFunction<ISub, T> mInterfaceMethod;
Hall Liu29b1874f2020-04-07 18:23:09 -0700183 private final String mCacheKeyProperty;
184 private final T mDefaultValue;
Collin Fijalkovich4ffdedf2019-12-10 09:52:14 -0800185
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700186 VoidPropertyInvalidatedCache(
Hall Liu29b1874f2020-04-07 18:23:09 -0700187 FunctionalUtils.ThrowingFunction<ISub, T> subscriptionInterfaceMethod,
188 String cacheKeyProperty,
189 T defaultValue) {
190 super(MAX_CACHE_SIZE, cacheKeyProperty);
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700191 mInterfaceMethod = subscriptionInterfaceMethod;
Hall Liu29b1874f2020-04-07 18:23:09 -0700192 mCacheKeyProperty = cacheKeyProperty;
193 mDefaultValue = defaultValue;
194 }
195
196 @Override
Lee Shombert0cece382022-01-04 08:10:15 -0800197 public T recompute(Void aVoid) {
Hall Liu29b1874f2020-04-07 18:23:09 -0700198 T result = mDefaultValue;
199
200 try {
201 ISub iSub = TelephonyManager.getSubscriptionService();
202 if (iSub != null) {
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700203 result = mInterfaceMethod.applyOrThrow(iSub);
Hall Liu29b1874f2020-04-07 18:23:09 -0700204 }
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
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700214 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
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
Lee Shombert0cece382022-01-04 08:10:15 -0800231 public T recompute(Integer query) {
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700232 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,
Hall Liu29b1874f2020-04-07 18:23:09 -0700250 CACHE_KEY_DEFAULT_SUB_ID_PROPERTY,
251 INVALID_SUBSCRIPTION_ID);
252
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700253 private static VoidPropertyInvalidatedCache<Integer> sDefaultDataSubIdCache =
254 new VoidPropertyInvalidatedCache<>(ISub::getDefaultDataSubId,
Hall Liu29b1874f2020-04-07 18:23:09 -0700255 CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY,
256 INVALID_SUBSCRIPTION_ID);
Collin Fijalkovich4ffdedf2019-12-10 09:52:14 -0800257
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700258 private static VoidPropertyInvalidatedCache<Integer> sDefaultSmsSubIdCache =
259 new VoidPropertyInvalidatedCache<>(ISub::getDefaultSmsSubId,
Collin Fijalkovich02e5c592020-04-06 10:54:28 -0700260 CACHE_KEY_DEFAULT_SMS_SUB_ID_PROPERTY,
261 INVALID_SUBSCRIPTION_ID);
262
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700263 private static VoidPropertyInvalidatedCache<Integer> sActiveDataSubIdCache =
264 new VoidPropertyInvalidatedCache<>(ISub::getActiveDataSubscriptionId,
Collin Fijalkovich02e5c592020-04-06 10:54:28 -0700265 CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY,
266 INVALID_SUBSCRIPTION_ID);
Collin Fijalkovich7d7ce512020-04-02 13:32:32 -0700267
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700268 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
chen xua0007492018-10-02 19:34:10 -0700279 /**
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 */
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
chen xubf38b062018-11-01 00:08:37 -0700294 * subscription wfc enabled {@link ImsMmTelManager#isVoWiFiSettingEnabled()}
Makoto Onuki2da26292019-08-07 08:59:39 -0700295 * while your app is running. You can also use a {@link android.app.job.JobService}
296 * to ensure your app
chen xua0007492018-10-02 19:34:10 -0700297 * is notified of changes to the {@link Uri} even when it is not running.
Makoto Onuki2da26292019-08-07 08:59:39 -0700298 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
299 * delivery of updates to the {@link Uri}.
chen xua0007492018-10-02 19:34:10 -0700300 * To be notified of changes to a specific subId, append subId to the URI
301 * {@link Uri#withAppendedPath(Uri, String)}.
302 * @hide
303 */
chen xu81653862019-02-28 10:44:54 -0800304 @NonNull
chen xua0007492018-10-02 19:34:10 -0700305 @SystemApi
306 public static final Uri WFC_ENABLED_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc");
307
308 /**
chen xu83a8fb52018-11-27 23:00:50 -0800309 * A content {@link Uri} used to receive updates on advanced calling user setting
310 * @see ImsMmTelManager#isAdvancedCallingSettingEnabled().
chen xua0007492018-10-02 19:34:10 -0700311 * <p>
312 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
chen xubf38b062018-11-01 00:08:37 -0700313 * subscription advanced calling enabled
314 * {@link ImsMmTelManager#isAdvancedCallingSettingEnabled()} while your app is running.
Makoto Onuki2da26292019-08-07 08:59:39 -0700315 * 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}.
chen xubf38b062018-11-01 00:08:37 -0700319 * To be notified of changes to a specific subId, append subId to the URI
320 * {@link Uri#withAppendedPath(Uri, String)}.
321 * @hide
322 */
chen xu81653862019-02-28 10:44:54 -0800323 @NonNull
chen xubf38b062018-11-01 00:08:37 -0700324 @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()}
Makoto Onuki2da26292019-08-07 08:59:39 -0700333 * 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}.
chen xua0007492018-10-02 19:34:10 -0700337 * To be notified of changes to a specific subId, append subId to the URI
338 * {@link Uri#withAppendedPath(Uri, String)}.
339 * @hide
340 */
chen xu81653862019-02-28 10:44:54 -0800341 @NonNull
chen xua0007492018-10-02 19:34:10 -0700342 @SystemApi
chen xubf38b062018-11-01 00:08:37 -0700343 public static final Uri WFC_MODE_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc_mode");
chen xua0007492018-10-02 19:34:10 -0700344
chen xubf38b062018-11-01 00:08:37 -0700345 /**
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()}
Makoto Onuki2da26292019-08-07 08:59:39 -0700350 * 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}.
chen xubf38b062018-11-01 00:08:37 -0700354 * To be notified of changes to a specific subId, append subId to the URI
355 * {@link Uri#withAppendedPath(Uri, String)}.
356 * @hide
357 */
chen xu81653862019-02-28 10:44:54 -0800358 @NonNull
chen xubf38b062018-11-01 00:08:37 -0700359 @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()}
Makoto Onuki2da26292019-08-07 08:59:39 -0700369 * 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}.
chen xubf38b062018-11-01 00:08:37 -0700373 * To be notified of changes to a specific subId, append subId to the URI
374 * {@link Uri#withAppendedPath(Uri, String)}.
375 * @hide
376 */
chen xu81653862019-02-28 10:44:54 -0800377 @NonNull
chen xubf38b062018-11-01 00:08:37 -0700378 @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()}
Makoto Onuki2da26292019-08-07 08:59:39 -0700387 * 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}.
chen xubf38b062018-11-01 00:08:37 -0700391 * To be notified of changes to a specific subId, append subId to the URI
392 * {@link Uri#withAppendedPath(Uri, String)}.
393 * @hide
394 */
chen xu81653862019-02-28 10:44:54 -0800395 @NonNull
chen xubf38b062018-11-01 00:08:37 -0700396 @SystemApi
397 public static final Uri WFC_ROAMING_ENABLED_CONTENT_URI = Uri.withAppendedPath(
398 CONTENT_URI, "wfc_roaming_enabled");
chen xua0007492018-10-02 19:34:10 -0700399
Jack Nudelmane2ea4282021-01-13 18:46:57 -0800400
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
Wink Savillefb40dd42014-06-12 17:02:31 -0700422 /**
Sooraj Sasindrand1610872020-11-23 19:33:52 -0800423 * 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
Sooraj Sasindran1bf22692021-03-10 16:45:27 -0800427 * {@link ImsMmTelManager#isCrossSimCallingEnabled()}
Sooraj Sasindrand1610872020-11-23 19:33:52 -0800428 * 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 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -0800443 * TelephonyProvider unique key column name is the subscription id.
444 * <P>Type: TEXT (String)</P>
445 */
446 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800447 public static final String UNIQUE_KEY_SUBSCRIPTION_ID =
448 SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800449
450 /**
Vasu Noriaea03912018-09-04 11:19:59 -0700451 * 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.
Wink Savillefb40dd42014-06-12 17:02:31 -0700454 * <P>Type: TEXT (String)</P>
455 */
Wink Savillef5bca082014-09-03 15:13:33 -0700456 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800457 public static final String ICC_ID = SimInfo.COLUMN_ICC_ID;
Wink Savillefb40dd42014-06-12 17:02:31 -0700458
459 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -0800460 * TelephonyProvider column name for user SIM_SlOT_INDEX
Wink Savillefb40dd42014-06-12 17:02:31 -0700461 * <P>Type: INTEGER (int)</P>
462 */
Wink Savillef5bca082014-09-03 15:13:33 -0700463 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800464 public static final String SIM_SLOT_INDEX = SimInfo.COLUMN_SIM_SLOT_INDEX;
Wink Saville905bb542014-09-04 17:10:23 -0700465
466 /** SIM is not inserted */
Wink Savillea374c3d2014-11-11 11:48:04 -0800467 /** @hide */
Peter Wang78af57d2019-11-25 16:50:50 -0800468 public static final int SIM_NOT_INSERTED = SimInfo.SIM_NOT_INSERTED;
Wink Savillefb40dd42014-06-12 17:02:31 -0700469
470 /**
Vasu Noriaea03912018-09-04 11:19:59 -0700471 * 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 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800483 public static final String SUBSCRIPTION_TYPE = SimInfo.COLUMN_SUBSCRIPTION_TYPE;
Malcolm Chen7611d692019-04-09 19:27:57 -0700484
485 /**
Jack Yua726a482019-05-23 16:37:35 -0700486 * 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 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800496 public static final String DATA_ENABLED_OVERRIDE_RULES =
497 SimInfo.COLUMN_DATA_ENABLED_OVERRIDE_RULES;
Peter Wang78af57d2019-11-25 16:50:50 -0800498
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 {}
Jack Yua726a482019-05-23 16:37:35 -0700506
507 /**
Vasu Noriaea03912018-09-04 11:19:59 -0700508 * 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 */
Peter Wang78af57d2019-11-25 16:50:50 -0800513 public static final int SUBSCRIPTION_TYPE_LOCAL_SIM = SimInfo.SUBSCRIPTION_TYPE_LOCAL_SIM;
Vasu Noriaea03912018-09-04 11:19:59 -0700514
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 */
Peter Wang78af57d2019-11-25 16:50:50 -0800539 public static final int SUBSCRIPTION_TYPE_REMOTE_SIM = SimInfo.SUBSCRIPTION_TYPE_REMOTE_SIM;
Vasu Noriaea03912018-09-04 11:19:59 -0700540
541 /**
Wink Saville905bb542014-09-04 17:10:23 -0700542 * TelephonyProvider column name for user displayed name.
Wink Savillefb40dd42014-06-12 17:02:31 -0700543 * <P>Type: TEXT (String)</P>
544 */
Wink Savillef5bca082014-09-03 15:13:33 -0700545 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800546 public static final String DISPLAY_NAME = SimInfo.COLUMN_DISPLAY_NAME;
Wink Savillefb40dd42014-06-12 17:02:31 -0700547
Wink Saville905bb542014-09-04 17:10:23 -0700548 /**
Sanket Padawee1013f92014-11-07 11:37:29 -0800549 * TelephonyProvider column name for the service provider name for the SIM.
550 * <P>Type: TEXT (String)</P>
551 */
552 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800553 public static final String CARRIER_NAME = SimInfo.COLUMN_CARRIER_NAME;
Sanket Padawee1013f92014-11-07 11:37:29 -0800554
555 /**
Wink Saville905bb542014-09-04 17:10:23 -0700556 * Default name resource
557 * @hide
558 */
Wink Savillefb40dd42014-06-12 17:02:31 -0700559 public static final int DEFAULT_NAME_RES = com.android.internal.R.string.unknownName;
560
561 /**
Wink Saville905bb542014-09-04 17:10:23 -0700562 * 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
Wink Savillefb40dd42014-06-12 17:02:31 -0700566 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800567 public static final String NAME_SOURCE = SimInfo.COLUMN_NAME_SOURCE;
Wink Savillefb40dd42014-06-12 17:02:31 -0700568
Wink Saville905bb542014-09-04 17:10:23 -0700569 /**
Peter Wang0ddf4402020-01-31 18:46:26 -0800570 * The name_source is from the carrier id.
Wink Saville905bb542014-09-04 17:10:23 -0700571 * @hide
572 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800573 public static final int NAME_SOURCE_CARRIER_ID = SimInfo.NAME_SOURCE_CARRIER_ID;
Wink Savillefb40dd42014-06-12 17:02:31 -0700574
Wink Saville905bb542014-09-04 17:10:23 -0700575 /**
Jack Yu5c6eb0e2019-10-16 09:16:54 -0700576 * The name_source is from SIM EF_SPN.
Wink Saville905bb542014-09-04 17:10:23 -0700577 * @hide
578 */
Peter Wang78af57d2019-11-25 16:50:50 -0800579 public static final int NAME_SOURCE_SIM_SPN = SimInfo.NAME_SOURCE_SIM_SPN;
Wink Savillec650e0b2014-09-02 22:37:08 -0700580
Wink Saville905bb542014-09-04 17:10:23 -0700581 /**
Jack Yu5c6eb0e2019-10-16 09:16:54 -0700582 * The name_source is from user input
Wink Saville905bb542014-09-04 17:10:23 -0700583 * @hide
584 */
Mathew Inwood45d2c252018-09-14 12:35:36 +0100585 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Peter Wang78af57d2019-11-25 16:50:50 -0800586 public static final int NAME_SOURCE_USER_INPUT = SimInfo.NAME_SOURCE_USER_INPUT;
Wink Savillefb40dd42014-06-12 17:02:31 -0700587
588 /**
Amit Mahajanecdf8c52019-05-14 10:36:15 -0700589 * The name_source is carrier (carrier app, carrier config, etc.)
590 * @hide
591 */
Peter Wang78af57d2019-11-25 16:50:50 -0800592 public static final int NAME_SOURCE_CARRIER = SimInfo.NAME_SOURCE_CARRIER;
Amit Mahajanecdf8c52019-05-14 10:36:15 -0700593
594 /**
Jack Yu5c6eb0e2019-10-16 09:16:54 -0700595 * The name_source is from SIM EF_PNN.
596 * @hide
597 */
Peter Wang78af57d2019-11-25 16:50:50 -0800598 public static final int NAME_SOURCE_SIM_PNN = SimInfo.NAME_SOURCE_SIM_PNN;
Jack Yu5c6eb0e2019-10-16 09:16:54 -0700599
600 /** @hide */
601 @Retention(RetentionPolicy.SOURCE)
602 @IntDef(prefix = {"NAME_SOURCE_"},
603 value = {
Peter Wang0ddf4402020-01-31 18:46:26 -0800604 NAME_SOURCE_CARRIER_ID,
Jack Yu5c6eb0e2019-10-16 09:16:54 -0700605 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 /**
Grace Jiab53cb662021-02-12 15:29:29 -0800613 * 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 /**
Grace Jia2bd23cf2021-03-18 14:47:31 -0700623 * Device status is shared with all selected contacts.
Grace Jiab53cb662021-02-12 15:29:29 -0800624 */
Grace Jia2bd23cf2021-03-18 14:47:31 -0700625 public static final int D2D_SHARING_SELECTED_CONTACTS = 2;
Grace Jiab53cb662021-02-12 15:29:29 -0800626
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,
Grace Jia2bd23cf2021-03-18 14:47:31 -0700638 D2D_SHARING_SELECTED_CONTACTS,
Grace Jiab53cb662021-02-12 15:29:29 -0800639 D2D_SHARING_ALL
640 })
Grace Jiaaeea4ec2021-03-10 14:00:43 -0800641 public @interface DeviceToDeviceStatusSharingPreference {}
Grace Jiab53cb662021-02-12 15:29:29 -0800642
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 /**
Grace Jia2bd23cf2021-03-18 14:47:31 -0700650 * 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 /**
Wink Saville905bb542014-09-04 17:10:23 -0700657 * TelephonyProvider column name for the color of a SIM.
Wink Savillefb40dd42014-06-12 17:02:31 -0700658 * <P>Type: INTEGER (int)</P>
659 */
Wink Savillef5bca082014-09-03 15:13:33 -0700660 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800661 public static final String HUE = SimInfo.COLUMN_COLOR;
Wink Savillefb40dd42014-06-12 17:02:31 -0700662
663 /**
Wink Saville905bb542014-09-04 17:10:23 -0700664 * TelephonyProvider column name for the phone number of a SIM.
Wink Savillefb40dd42014-06-12 17:02:31 -0700665 * <P>Type: TEXT (String)</P>
666 */
Wink Savillef5bca082014-09-03 15:13:33 -0700667 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800668 public static final String NUMBER = SimInfo.COLUMN_NUMBER;
Wink Savillefb40dd42014-06-12 17:02:31 -0700669
670 /**
Peter Wang78af57d2019-11-25 16:50:50 -0800671 * TelephonyProvider column name for whether data roaming is enabled.
Wink Savillefb40dd42014-06-12 17:02:31 -0700672 * <P>Type: INTEGER (int)</P>
673 */
Wink Savillef5bca082014-09-03 15:13:33 -0700674 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800675 public static final String DATA_ROAMING = SimInfo.COLUMN_DATA_ROAMING;
Wink Savillefb40dd42014-06-12 17:02:31 -0700676
Stuart Scott400a3f62015-01-14 10:49:49 -0800677 /** Indicates that data roaming is enabled for a subscription */
Peter Wang78af57d2019-11-25 16:50:50 -0800678 public static final int DATA_ROAMING_ENABLE = SimInfo.DATA_ROAMING_ENABLE;
Wink Savillefb40dd42014-06-12 17:02:31 -0700679
Stuart Scott400a3f62015-01-14 10:49:49 -0800680 /** Indicates that data roaming is disabled for a subscription */
Peter Wang78af57d2019-11-25 16:50:50 -0800681 public static final int DATA_ROAMING_DISABLE = SimInfo.DATA_ROAMING_DISABLE;
Wink Savillefb40dd42014-06-12 17:02:31 -0700682
Tom Taylor7a962072014-09-04 14:05:20 -0700683 /**
chen xu64e81db2018-12-14 00:14:06 -0800684 * TelephonyProvider column name for subscription carrier id.
685 * @see TelephonyManager#getSimCarrierId()
686 * <p>Type: INTEGER (int) </p>
687 * @hide
688 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800689 public static final String CARRIER_ID = SimInfo.COLUMN_CARRIER_ID;
chen xu64e81db2018-12-14 00:14:06 -0800690
691 /**
Hall Liue0ac1f72019-04-11 15:28:20 -0700692 * @hide A comma-separated list of EHPLMNs associated with the subscription
693 * <P>Type: TEXT (String)</P>
694 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800695 public static final String EHPLMNS = SimInfo.COLUMN_EHPLMNS;
Hall Liue0ac1f72019-04-11 15:28:20 -0700696
697 /**
698 * @hide A comma-separated list of HPLMNs associated with the subscription
699 * <P>Type: TEXT (String)</P>
700 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800701 public static final String HPLMNS = SimInfo.COLUMN_HPLMNS;
Hall Liue0ac1f72019-04-11 15:28:20 -0700702
703 /**
Hall Liu0c149bd2018-06-08 18:14:21 -0700704 * TelephonyProvider column name for the MCC associated with a SIM, stored as a string.
705 * <P>Type: TEXT (String)</P>
706 * @hide
707 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800708 public static final String MCC_STRING = SimInfo.COLUMN_MCC_STRING;
Hall Liu0c149bd2018-06-08 18:14:21 -0700709
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 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800715 public static final String MNC_STRING = SimInfo.COLUMN_MNC_STRING;
Hall Liu0c149bd2018-06-08 18:14:21 -0700716
717 /**
Wink Saville905bb542014-09-04 17:10:23 -0700718 * TelephonyProvider column name for the MCC associated with a SIM.
Tom Taylor7a962072014-09-04 14:05:20 -0700719 * <P>Type: INTEGER (int)</P>
Wink Savillea374c3d2014-11-11 11:48:04 -0800720 * @hide
Tom Taylor7a962072014-09-04 14:05:20 -0700721 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800722 public static final String MCC = SimInfo.COLUMN_MCC;
Tom Taylor7a962072014-09-04 14:05:20 -0700723
724 /**
Wink Saville905bb542014-09-04 17:10:23 -0700725 * TelephonyProvider column name for the MNC associated with a SIM.
Tom Taylor7a962072014-09-04 14:05:20 -0700726 * <P>Type: INTEGER (int)</P>
Wink Savillea374c3d2014-11-11 11:48:04 -0800727 * @hide
Tom Taylor7a962072014-09-04 14:05:20 -0700728 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800729 public static final String MNC = SimInfo.COLUMN_MNC;
Tom Taylor7a962072014-09-04 14:05:20 -0700730
Wink Savillec650e0b2014-09-02 22:37:08 -0700731 /**
chen xua2618622018-12-02 14:14:15 -0800732 * TelephonyProvider column name for the iso country code associated with a SIM.
733 * <P>Type: TEXT (String)</P>
734 * @hide
735 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800736 public static final String ISO_COUNTRY_CODE = SimInfo.COLUMN_ISO_COUNTRY_CODE;
chen xua2618622018-12-02 14:14:15 -0800737
738 /**
Jeff Davidsond02731f2017-04-09 14:31:09 -0700739 * 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 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800744 public static final String IS_EMBEDDED = SimInfo.COLUMN_IS_EMBEDDED;
Jeff Davidsond02731f2017-04-09 14:31:09 -0700745
746 /**
yinxu921daf92018-01-05 11:15:24 -0800747 * 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 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800752 public static final String CARD_ID = SimInfo.COLUMN_CARD_ID;
yinxu921daf92018-01-05 11:15:24 -0800753
754 /**
Jeff Davidsond02731f2017-04-09 14:31:09 -0700755 * 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 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800760 public static final String ACCESS_RULES = SimInfo.COLUMN_ACCESS_RULES;
Jeff Davidsond02731f2017-04-09 14:31:09 -0700761
762 /**
Nazanin Bakhshi693cec22019-08-02 16:43:44 -0700763 * 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 =
Peter Wang0ddf4402020-01-31 18:46:26 -0800770 SimInfo.COLUMN_ACCESS_RULES_FROM_CARRIER_CONFIGS;
Nazanin Bakhshi693cec22019-08-02 16:43:44 -0700771
772 /**
Jeff Davidsond02731f2017-04-09 14:31:09 -0700773 * 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 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800780 public static final String IS_REMOVABLE = SimInfo.COLUMN_IS_REMOVABLE;
Jeff Davidsond02731f2017-04-09 14:31:09 -0700781
782 /**
Sanket Padawedc493092015-07-14 14:21:43 -0700783 * TelephonyProvider column name for extreme threat in CB settings
784 * @hide
785 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800786 public static final String CB_EXTREME_THREAT_ALERT =
787 SimInfo.COLUMN_CB_EXTREME_THREAT_ALERT;
Sanket Padawedc493092015-07-14 14:21:43 -0700788
789 /**
790 * TelephonyProvider column name for severe threat in CB settings
791 *@hide
792 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800793 public static final String CB_SEVERE_THREAT_ALERT = SimInfo.COLUMN_CB_SEVERE_THREAT_ALERT;
Sanket Padawedc493092015-07-14 14:21:43 -0700794
795 /**
796 * TelephonyProvider column name for amber alert in CB settings
797 *@hide
798 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800799 public static final String CB_AMBER_ALERT = SimInfo.COLUMN_CB_AMBER_ALERT;
Sanket Padawedc493092015-07-14 14:21:43 -0700800
801 /**
802 * TelephonyProvider column name for emergency alert in CB settings
803 *@hide
804 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800805 public static final String CB_EMERGENCY_ALERT = SimInfo.COLUMN_CB_EMERGENCY_ALERT;
Sanket Padawedc493092015-07-14 14:21:43 -0700806
807 /**
808 * TelephonyProvider column name for alert sound duration in CB settings
809 *@hide
810 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800811 public static final String CB_ALERT_SOUND_DURATION =
812 SimInfo.COLUMN_CB_ALERT_SOUND_DURATION;
Sanket Padawedc493092015-07-14 14:21:43 -0700813
814 /**
815 * TelephonyProvider column name for alert reminder interval in CB settings
816 *@hide
817 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800818 public static final String CB_ALERT_REMINDER_INTERVAL =
819 SimInfo.COLUMN_CB_ALERT_REMINDER_INTERVAL;
Sanket Padawedc493092015-07-14 14:21:43 -0700820
821 /**
822 * TelephonyProvider column name for enabling vibrate in CB settings
823 *@hide
824 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800825 public static final String CB_ALERT_VIBRATE = SimInfo.COLUMN_CB_ALERT_VIBRATE;
Sanket Padawedc493092015-07-14 14:21:43 -0700826
827 /**
828 * TelephonyProvider column name for enabling alert speech in CB settings
829 *@hide
830 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800831 public static final String CB_ALERT_SPEECH = SimInfo.COLUMN_CB_ALERT_SPEECH;
Sanket Padawedc493092015-07-14 14:21:43 -0700832
833 /**
834 * TelephonyProvider column name for ETWS test alert in CB settings
835 *@hide
836 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800837 public static final String CB_ETWS_TEST_ALERT = SimInfo.COLUMN_CB_ETWS_TEST_ALERT;
Sanket Padawedc493092015-07-14 14:21:43 -0700838
839 /**
840 * TelephonyProvider column name for enable channel50 alert in CB settings
841 *@hide
842 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800843 public static final String CB_CHANNEL_50_ALERT = SimInfo.COLUMN_CB_CHANNEL_50_ALERT;
Sanket Padawedc493092015-07-14 14:21:43 -0700844
845 /**
846 * TelephonyProvider column name for CMAS test alert in CB settings
847 *@hide
848 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800849 public static final String CB_CMAS_TEST_ALERT = SimInfo.COLUMN_CB_CMAS_TEST_ALERT;
Sanket Padawedc493092015-07-14 14:21:43 -0700850
851 /**
852 * TelephonyProvider column name for Opt out dialog in CB settings
853 *@hide
854 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800855 public static final String CB_OPT_OUT_DIALOG = SimInfo.COLUMN_CB_OPT_OUT_DIALOG;
Sanket Padawedc493092015-07-14 14:21:43 -0700856
857 /**
Malcolm Chenc66dee92017-09-26 14:45:40 -0700858 * TelephonyProvider column name for enable Volte.
Jordan Liud6350112017-11-14 13:45:19 -0800859 *
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}.
Malcolm Chenc66dee92017-09-26 14:45:40 -0700862 *@hide
863 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800864 public static final String ENHANCED_4G_MODE_ENABLED =
865 SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED;
Malcolm Chenc66dee92017-09-26 14:45:40 -0700866
867 /**
868 * TelephonyProvider column name for enable VT (Video Telephony over IMS)
869 *@hide
870 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800871 public static final String VT_IMS_ENABLED = SimInfo.COLUMN_VT_IMS_ENABLED;
Malcolm Chenc66dee92017-09-26 14:45:40 -0700872
873 /**
874 * TelephonyProvider column name for enable Wifi calling
875 *@hide
876 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800877 public static final String WFC_IMS_ENABLED = SimInfo.COLUMN_WFC_IMS_ENABLED;
Malcolm Chenc66dee92017-09-26 14:45:40 -0700878
879 /**
880 * TelephonyProvider column name for Wifi calling mode
881 *@hide
882 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800883 public static final String WFC_IMS_MODE = SimInfo.COLUMN_WFC_IMS_MODE;
Malcolm Chenc66dee92017-09-26 14:45:40 -0700884
885 /**
886 * TelephonyProvider column name for Wifi calling mode in roaming
887 *@hide
888 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800889 public static final String WFC_IMS_ROAMING_MODE = SimInfo.COLUMN_WFC_IMS_ROAMING_MODE;
Malcolm Chenc66dee92017-09-26 14:45:40 -0700890
891 /**
892 * TelephonyProvider column name for enable Wifi calling in roaming
893 *@hide
894 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800895 public static final String WFC_IMS_ROAMING_ENABLED = SimInfo.COLUMN_WFC_IMS_ROAMING_ENABLED;
Malcolm Chenc66dee92017-09-26 14:45:40 -0700896
897 /**
Brad Ebinger41c232c2020-01-22 16:09:57 -0800898 * Determines if the user has enabled IMS RCS User Capability Exchange (UCE) for this
899 * subscription.
900 * @hide
901 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800902 public static final String IMS_RCS_UCE_ENABLED = SimInfo.COLUMN_IMS_RCS_UCE_ENABLED;
Brad Ebinger41c232c2020-01-22 16:09:57 -0800903
904 /**
Jack Yuea905072020-11-17 19:48:31 -0800905 * 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 /**
Malcolm Chen0ac24ef2018-08-07 15:03:32 -0700912 * 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.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -0700915 * <p>Type: INTEGER (int), 1 for opportunistic or 0 for non-opportunistic.
916 * @hide
917 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800918 public static final String IS_OPPORTUNISTIC = SimInfo.COLUMN_IS_OPPORTUNISTIC;
Malcolm Chen52f6dff2018-11-28 11:15:57 -0800919
Malcolm Chen0ac24ef2018-08-07 15:03:32 -0700920 /**
Malcolm Chenaea9b022018-10-31 20:18:02 -0700921 * 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 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800927 public static final String GROUP_UUID = SimInfo.COLUMN_GROUP_UUID;
Malcolm Chen52f6dff2018-11-28 11:15:57 -0800928
Nazanin Bakhshib9b87be2018-11-21 16:32:05 -0800929 /**
Malcolm Chen0b9b81b2019-03-29 17:13:08 -0700930 * TelephonyProvider column name for group owner. It's the package name who created
931 * the subscription group.
932 *
933 * @hide
934 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800935 public static final String GROUP_OWNER = SimInfo.COLUMN_GROUP_OWNER;
Malcolm Chen52f6dff2018-11-28 11:15:57 -0800936
Malcolm Chenaea9b022018-10-31 20:18:02 -0700937 /**
Grace Chen5be6e9c2018-12-20 22:50:18 -0800938 * 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 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800943 public static final String PROFILE_CLASS = SimInfo.COLUMN_PROFILE_CLASS;
Grace Chen5be6e9c2018-12-20 22:50:18 -0800944
945 /**
Muralidhar Reddy090a67a2021-12-10 21:11:28 +0000946 * 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 /**
Jayachandran Chinnakkannu2cdad9f2021-02-18 20:55:44 +0800953 * 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 /**
Gary Jian204ec2a2021-10-13 13:09:54 +0800961 * 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 /**
Grace Chen5be6e9c2018-12-20 22:50:18 -0800970 * Profile class of the subscription
971 * @hide
972 */
973 @Retention(RetentionPolicy.SOURCE)
974 @IntDef(prefix = { "PROFILE_CLASS_" }, value = {
Peter Wang78af57d2019-11-25 16:50:50 -0800975 SimInfo.PROFILE_CLASS_TESTING,
976 SimInfo.PROFILE_CLASS_PROVISIONING,
977 SimInfo.PROFILE_CLASS_OPERATIONAL,
978 SimInfo.PROFILE_CLASS_UNSET,
Grace Chen5be6e9c2018-12-20 22:50:18 -0800979 })
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
Peter Wang78af57d2019-11-25 16:50:50 -0800990 public static final int PROFILE_CLASS_TESTING = SimInfo.PROFILE_CLASS_TESTING;
Grace Chen5be6e9c2018-12-20 22:50:18 -0800991
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
Peter Wang78af57d2019-11-25 16:50:50 -0800999 public static final int PROFILE_CLASS_PROVISIONING = SimInfo.PROFILE_CLASS_PROVISIONING;
Grace Chen5be6e9c2018-12-20 22:50:18 -08001000
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
Peter Wang78af57d2019-11-25 16:50:50 -08001008 public static final int PROFILE_CLASS_OPERATIONAL = SimInfo.PROFILE_CLASS_OPERATIONAL;
Grace Chen5be6e9c2018-12-20 22:50:18 -08001009
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
Peter Wang78af57d2019-11-25 16:50:50 -08001017 public static final int PROFILE_CLASS_UNSET = SimInfo.PROFILE_CLASS_UNSET;
Grace Chen5be6e9c2018-12-20 22:50:18 -08001018
1019 /**
1020 * Default profile class
1021 * @hide
1022 */
1023 @SystemApi
Peter Wang0ddf4402020-01-31 18:46:26 -08001024 @Deprecated
1025 public static final int PROFILE_CLASS_DEFAULT = SimInfo.PROFILE_CLASS_UNSET;
Grace Chen5be6e9c2018-12-20 22:50:18 -08001026
1027 /**
Nazanin Bakhshi1eaf7a82019-05-31 16:34:10 -07001028 * IMSI (International Mobile Subscriber Identity).
1029 * <P>Type: TEXT </P>
1030 * @hide
1031 */
1032 //TODO: add @SystemApi
Peter Wang0ddf4402020-01-31 18:46:26 -08001033 public static final String IMSI = SimInfo.COLUMN_IMSI;
Nazanin Bakhshi1eaf7a82019-05-31 16:34:10 -07001034
1035 /**
Malcolm Chenb7c6ee382019-12-04 19:07:56 -08001036 * Whether uicc applications is set to be enabled or disabled. By default it's enabled.
1037 * @hide
1038 */
Peter Wang0ddf4402020-01-31 18:46:26 -08001039 public static final String UICC_APPLICATIONS_ENABLED = SimInfo.COLUMN_UICC_APPLICATIONS_ENABLED;
Malcolm Chenb7c6ee382019-12-04 19:07:56 -08001040
1041 /**
Nathan Haroldbd5f0d92021-11-02 19:20:56 -07001042 * Indicate which network type is allowed.
calvinpand77e0bd2020-01-14 20:37:31 +08001043 * @hide
1044 */
SongFerngWang7d951852020-12-21 16:24:25 +08001045 public static final String ALLOWED_NETWORK_TYPES =
1046 SimInfo.COLUMN_ALLOWED_NETWORK_TYPES_FOR_REASONS;
calvinpand77e0bd2020-01-14 20:37:31 +08001047
Nathan Harold7e2d58a2021-11-02 16:32:06 -07001048 /** @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.
Nathan Harold7e2d58a2021-11-02 16:32:06 -07001066 */
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}
Nathan Harold7e2d58a2021-11-02 16:32:06 -07001079 */
1080 public static final int USAGE_SETTING_DEFAULT = 0;
1081
1082 /**
1083 * This subscription is forced to voice-centric mode
1084 *
Nathan Harolddff34b32021-12-15 16:38:25 -08001085 * <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.
Nathan Harold7e2d58a2021-11-02 16:32:06 -07001088 */
1089 public static final int USAGE_SETTING_VOICE_CENTRIC = 1;
1090
1091 /**
1092 * This subscription is forced to data-centric mode
1093 *
Nathan Harolddff34b32021-12-15 16:38:25 -08001094 * <p>Refer to data-centric mode in 3gpp 24.301 sec 4.3 and 3gpp 24.501 sec 4.3.
1095 * Also refer to "UE's usage setting" as defined in 3gpp 24.301 section 3.1 and 3gpp 23.221
1096 * Annex A.
Nathan Harold7e2d58a2021-11-02 16:32:06 -07001097 */
1098 public static final int USAGE_SETTING_DATA_CENTRIC = 2;
1099
calvinpand77e0bd2020-01-14 20:37:31 +08001100 /**
Nathan Haroldbd5f0d92021-11-02 19:20:56 -07001101 * Indicate the preferred usage setting for the subscription.
1102 *
1103 * 0 - Default - If the value has not been explicitly set, it will be "default"
1104 * 1 - Voice-centric
1105 * 2 - Data-centric
1106 *
1107 * @hide
1108 */
1109 public static final String USAGE_SETTING = SimInfo.COLUMN_USAGE_SETTING;
1110
1111 /**
Wink Savillec650e0b2014-09-02 22:37:08 -07001112 * Broadcast Action: The user has changed one of the default subs related to
1113 * data, phone calls, or sms</p>
Wink Savilled09c4ca2014-11-22 10:08:16 -08001114 *
1115 * TODO: Change to a listener
Wink Savillef5bca082014-09-03 15:13:33 -07001116 * @hide
Wink Savillec650e0b2014-09-02 22:37:08 -07001117 */
1118 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1119 public static final String SUB_DEFAULT_CHANGED_ACTION =
Rajeev Kumarc8ac4f3b2017-07-26 15:59:08 -07001120 "android.intent.action.SUB_DEFAULT_CHANGED";
Wink Savillefb40dd42014-06-12 17:02:31 -07001121
Malcolm Chen598d24c2017-04-24 18:37:29 -07001122 /**
1123 * Broadcast Action: The default subscription has changed. This has the following
1124 * extra values:</p>
1125 * The {@link #EXTRA_SUBSCRIPTION_INDEX} extra indicates the current default subscription index
1126 */
1127 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1128 public static final String ACTION_DEFAULT_SUBSCRIPTION_CHANGED
1129 = "android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED";
1130
1131 /**
1132 * Broadcast Action: The default sms subscription has changed. This has the following
1133 * extra values:</p>
1134 * {@link #EXTRA_SUBSCRIPTION_INDEX} extra indicates the current default sms
1135 * subscription index
1136 */
1137 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1138 public static final String ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED
1139 = "android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED";
1140
1141 /**
Jeff Sharkey717f52f2018-01-04 16:04:11 -07001142 * Activity Action: Display UI for managing the billing relationship plans
1143 * between a carrier and a specific subscriber.
1144 * <p>
1145 * Carrier apps are encouraged to implement this activity, and the OS will
1146 * provide an affordance to quickly enter this activity, typically via
1147 * Settings. This affordance will only be shown when the carrier app is
1148 * actively providing subscription plan information via
1149 * {@link #setSubscriptionPlans(int, List)}.
1150 * <p>
1151 * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
1152 * the user is interested in.
Jeff Sharkey717f52f2018-01-04 16:04:11 -07001153 */
1154 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
Jeff Sharkey717f52f2018-01-04 16:04:11 -07001155 public static final String ACTION_MANAGE_SUBSCRIPTION_PLANS
1156 = "android.telephony.action.MANAGE_SUBSCRIPTION_PLANS";
1157
1158 /**
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07001159 * Broadcast Action: Request a refresh of the billing relationship plans
1160 * between a carrier and a specific subscriber.
1161 * <p>
1162 * Carrier apps are encouraged to implement this receiver, and the OS will
1163 * provide an affordance to request a refresh. This affordance will only be
1164 * shown when the carrier app is actively providing subscription plan
1165 * information via {@link #setSubscriptionPlans(int, List)}.
1166 * <p>
1167 * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
1168 * the user is interested in.
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06001169 * <p>
1170 * Receivers should protect themselves by checking that the sender holds the
1171 * {@code android.permission.MANAGE_SUBSCRIPTION_PLANS} permission.
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07001172 */
1173 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07001174 public static final String ACTION_REFRESH_SUBSCRIPTION_PLANS
1175 = "android.telephony.action.REFRESH_SUBSCRIPTION_PLANS";
1176
1177 /**
1178 * Broadcast Action: The billing relationship plans between a carrier and a
1179 * specific subscriber has changed.
1180 * <p>
1181 * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
1182 * changed.
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07001183 * @hide
1184 */
Daniel Bright10aa8e72019-12-17 16:52:03 -08001185 @SystemApi
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07001186 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1187 @RequiresPermission(android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS)
1188 public static final String ACTION_SUBSCRIPTION_PLANS_CHANGED
1189 = "android.telephony.action.SUBSCRIPTION_PLANS_CHANGED";
1190
1191 /**
Malcolm Chen598d24c2017-04-24 18:37:29 -07001192 * Integer extra used with {@link #ACTION_DEFAULT_SUBSCRIPTION_CHANGED} and
1193 * {@link #ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED} to indicate the subscription
1194 * which has changed.
1195 */
1196 public static final String EXTRA_SUBSCRIPTION_INDEX = "android.telephony.extra.SUBSCRIPTION_INDEX";
1197
Jack Yud8104ec2019-09-18 09:31:28 -07001198 /**
1199 * Integer extra to specify SIM slot index.
1200 */
1201 public static final String EXTRA_SLOT_INDEX = "android.telephony.extra.SLOT_INDEX";
1202
Meng Wang0594b4f2021-10-26 13:12:47 -07001203 /**
1204 * A source of phone number: the EF-MSISDN (see 3GPP TS 31.102),
1205 * or EF-MDN for CDMA (see 3GPP2 C.P0065-B), from UICC application.
1206 *
1207 * <p>The availability and a of the number depends on the carrier.
1208 * The number may be updated by over-the-air update to UICC applications
1209 * from the carrier, or by other means with physical access to the SIM.
1210 */
1211 public static final int PHONE_NUMBER_SOURCE_UICC = 1;
1212
1213 /**
1214 * A source of phone number: provided by an app that has carrier privilege.
1215 *
1216 * <p>The number is intended to be set by a carrier app knowing the correct number
1217 * which is, for example, different from the number in {@link #PHONE_NUMBER_SOURCE_UICC UICC}
1218 * for some reason.
1219 * The number is not available until a carrier app sets one via
1220 * {@link #setCarrierPhoneNumber(int, String)}.
1221 * The app can update the number with the same API should the number change.
1222 */
1223 public static final int PHONE_NUMBER_SOURCE_CARRIER = 2;
1224
1225 /**
1226 * A source of phone number: provided by IMS (IP Multimedia Subsystem) implementation.
1227 * When IMS service is registered (as indicated by
1228 * {@link android.telephony.ims.RegistrationManager.RegistrationCallback#onRegistered(int)})
1229 * the IMS implementation may return P-Associated-Uri SIP headers (RFC 3455). The URIs
1230 * are the user’s public user identities known to the network (see 3GPP TS 24.229 5.4.1.2),
1231 * and the phone number is typically one of them (see “global number” in 3GPP TS 23.003 13.4).
1232 *
1233 * <p>This source provides the phone number from the last IMS registration.
1234 * IMS registration may happen on every device reboot or other network condition changes.
1235 * The number will be updated should the associated URI change after an IMS registration.
1236 */
1237 public static final int PHONE_NUMBER_SOURCE_IMS = 3;
1238
1239 /** @hide */
1240 @Retention(RetentionPolicy.SOURCE)
1241 @IntDef(prefix = {"PHONE_NUMBER_SOURCE"},
1242 value = {
1243 PHONE_NUMBER_SOURCE_UICC,
1244 PHONE_NUMBER_SOURCE_CARRIER,
1245 PHONE_NUMBER_SOURCE_IMS,
1246 })
1247 public @interface PhoneNumberSource {}
1248
Wink Savilled09c4ca2014-11-22 10:08:16 -08001249 private final Context mContext;
1250
Torbjorn Eklundf8899f02019-11-20 10:59:59 +01001251 // Cache of Resource that has been created in getResourcesForSubId. Key is a Pair containing
1252 // the Context and subId.
1253 private static final Map<Pair<Context, Integer>, Resources> sResourcesCache =
1254 new ConcurrentHashMap<>();
1255
Wink Savilled09c4ca2014-11-22 10:08:16 -08001256 /**
1257 * A listener class for monitoring changes to {@link SubscriptionInfo} records.
1258 * <p>
1259 * Override the onSubscriptionsChanged method in the object that extends this
Wink Saville071743f2015-01-12 17:11:04 -08001260 * class and pass it to {@link #addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener)}
Wink Savilled09c4ca2014-11-22 10:08:16 -08001261 * to register your listener and to unregister invoke
Wink Saville071743f2015-01-12 17:11:04 -08001262 * {@link #removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener)}
Wink Savilled09c4ca2014-11-22 10:08:16 -08001263 * <p>
1264 * Permissions android.Manifest.permission.READ_PHONE_STATE is required
1265 * for #onSubscriptionsChanged to be invoked.
1266 */
1267 public static class OnSubscriptionsChangedListener {
Jack He9fc75742017-11-16 15:54:14 -08001268 private class OnSubscriptionsChangedListenerHandler extends Handler {
1269 OnSubscriptionsChangedListenerHandler() {
1270 super();
1271 }
1272
1273 OnSubscriptionsChangedListenerHandler(Looper looper) {
1274 super(looper);
1275 }
Jack He9fc75742017-11-16 15:54:14 -08001276 }
1277
Chen Xu8eb62f92019-10-13 17:30:32 -07001278 /**
1279 * Posted executor callback on the handler associated with a given looper.
1280 * The looper can be the calling thread's looper or the looper passed from the
1281 * constructor {@link #OnSubscriptionsChangedListener(Looper)}.
1282 */
1283 private final HandlerExecutor mExecutor;
1284
1285 /**
1286 * @hide
1287 */
1288 public HandlerExecutor getHandlerExecutor() {
1289 return mExecutor;
1290 }
Jack He9fc75742017-11-16 15:54:14 -08001291
1292 public OnSubscriptionsChangedListener() {
Chen Xu8eb62f92019-10-13 17:30:32 -07001293 mExecutor = new HandlerExecutor(new OnSubscriptionsChangedListenerHandler());
Jack He9fc75742017-11-16 15:54:14 -08001294 }
1295
1296 /**
1297 * Allow a listener to be created with a custom looper
1298 * @param looper the looper that the underlining handler should run on
1299 * @hide
1300 */
1301 public OnSubscriptionsChangedListener(Looper looper) {
Chen Xu8eb62f92019-10-13 17:30:32 -07001302 mExecutor = new HandlerExecutor(new OnSubscriptionsChangedListenerHandler(looper));
Jack He9fc75742017-11-16 15:54:14 -08001303 }
Wink Savilled09c4ca2014-11-22 10:08:16 -08001304
1305 /**
Jordan Liu45da5052019-02-12 10:29:24 -08001306 * Callback invoked when there is any change to any SubscriptionInfo, as well as once on
1307 * registering for changes with {@link #addOnSubscriptionsChangedListener}. Typically
Wink Savilled09c4ca2014-11-22 10:08:16 -08001308 * this method would invoke {@link #getActiveSubscriptionInfoList}
1309 */
1310 public void onSubscriptionsChanged() {
1311 if (DBG) log("onSubscriptionsChanged: NOT OVERRIDDEN");
1312 }
1313
Tyler Gunn76ab5fb2020-03-25 17:49:35 -07001314 /**
1315 * Callback invoked when {@link SubscriptionManager#addOnSubscriptionsChangedListener(
1316 * Executor, OnSubscriptionsChangedListener)} or
1317 * {@link SubscriptionManager#addOnSubscriptionsChangedListener(
1318 * OnSubscriptionsChangedListener)} fails to complete due to the
1319 * {@link Context#TELEPHONY_REGISTRY_SERVICE} being unavailable.
1320 * @hide
1321 */
1322 public void onAddListenerFailed() {
1323 Rlog.w(LOG_TAG, "onAddListenerFailed not overridden");
1324 }
1325
Wink Savilled09c4ca2014-11-22 10:08:16 -08001326 private void log(String s) {
1327 Rlog.d(LOG_TAG, s);
1328 }
1329 }
1330
Wink Savillef5bca082014-09-03 15:13:33 -07001331 /** @hide */
Mathew Inwooda8382062018-08-16 17:01:12 +01001332 @UnsupportedAppUsage
Robin Leeeaf46802018-01-18 14:34:20 +01001333 public SubscriptionManager(Context context) {
Wink Savillefb40dd42014-06-12 17:02:31 -07001334 if (DBG) logd("SubscriptionManager created");
Wink Savilled09c4ca2014-11-22 10:08:16 -08001335 mContext = context;
Wink Savillefb40dd42014-06-12 17:02:31 -07001336 }
1337
Aaron Huang21089442020-01-16 23:31:02 +08001338 private NetworkPolicyManager getNetworkPolicyManager() {
1339 return (NetworkPolicyManager) mContext
1340 .getSystemService(Context.NETWORK_POLICY_SERVICE);
1341 }
1342
Wink Savillefb40dd42014-06-12 17:02:31 -07001343 /**
Jeff Sharkey717f52f2018-01-04 16:04:11 -07001344 * @deprecated developers should always obtain references directly from
1345 * {@link Context#getSystemService(Class)}.
Wink Savillefb40dd42014-06-12 17:02:31 -07001346 */
Jeff Sharkey717f52f2018-01-04 16:04:11 -07001347 @Deprecated
Wink Savilled09c4ca2014-11-22 10:08:16 -08001348 public static SubscriptionManager from(Context context) {
Jeff Sharkeyddf21642018-01-08 13:38:43 -07001349 return (SubscriptionManager) context
1350 .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Wink Savilled09c4ca2014-11-22 10:08:16 -08001351 }
1352
1353 /**
1354 * Register for changes to the list of active {@link SubscriptionInfo} records or to the
1355 * individual records themselves. When a change occurs the onSubscriptionsChanged method of
Jordan Liu45da5052019-02-12 10:29:24 -08001356 * the listener will be invoked immediately if there has been a notification. The
1357 * onSubscriptionChanged method will also be triggered once initially when calling this
Zongheng Wangeb56d062020-02-20 18:19:10 -08001358 * function. The callback will be invoked on the looper specified in the listener's constructor.
Wink Savilled09c4ca2014-11-22 10:08:16 -08001359 *
1360 * @param listener an instance of {@link OnSubscriptionsChangedListener} with
1361 * onSubscriptionsChanged overridden.
Zongheng Wangeb56d062020-02-20 18:19:10 -08001362 *
1363 * @deprecated Will get exception if the parameter listener is not initialized with a Looper.
1364 * Use {@link #addOnSubscriptionsChangedListener(Executor, OnSubscriptionsChangedListener)}.
Wink Savilled09c4ca2014-11-22 10:08:16 -08001365 */
Zongheng Wangeb56d062020-02-20 18:19:10 -08001366 @Deprecated
Wink Saville071743f2015-01-12 17:11:04 -08001367 public void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
Chen Xu8eb62f92019-10-13 17:30:32 -07001368 if (listener == null) return;
Zongheng Wang5d39bd12020-01-07 13:46:13 +08001369 addOnSubscriptionsChangedListener(listener.mExecutor, listener);
1370 }
1371
1372 /**
1373 * Register for changes to the list of active {@link SubscriptionInfo} records or to the
1374 * individual records themselves. When a change occurs the onSubscriptionsChanged method of
1375 * the listener will be invoked immediately if there has been a notification. The
1376 * onSubscriptionChanged method will also be triggered once initially when calling this
1377 * function.
1378 *
1379 * @param listener an instance of {@link OnSubscriptionsChangedListener} with
1380 * onSubscriptionsChanged overridden.
1381 * @param executor the executor that will execute callbacks.
1382 */
1383 public void addOnSubscriptionsChangedListener(
1384 @NonNull @CallbackExecutor Executor executor,
1385 @NonNull OnSubscriptionsChangedListener listener) {
Hall Liu5fb337f2017-11-22 17:38:15 -08001386 String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>";
Wink Savillea374c3d2014-11-11 11:48:04 -08001387 if (DBG) {
Hall Liu5fb337f2017-11-22 17:38:15 -08001388 logd("register OnSubscriptionsChangedListener pkgName=" + pkgName
Wink Savilled09c4ca2014-11-22 10:08:16 -08001389 + " listener=" + listener);
Wink Savillea374c3d2014-11-11 11:48:04 -08001390 }
Chen Xu8eb62f92019-10-13 17:30:32 -07001391 // We use the TelephonyRegistry as it runs in the system and thus is always
1392 // available. Where as SubscriptionController could crash and not be available
1393 TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
1394 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
1395 if (telephonyRegistryManager != null) {
1396 telephonyRegistryManager.addOnSubscriptionsChangedListener(listener,
Zongheng Wang5d39bd12020-01-07 13:46:13 +08001397 executor);
Tyler Gunn76ab5fb2020-03-25 17:49:35 -07001398 } else {
1399 // If the telephony registry isn't available, we will inform the caller on their
1400 // listener that it failed so they can try to re-register.
1401 loge("addOnSubscriptionsChangedListener: pkgname=" + pkgName + " failed to be added "
1402 + " due to TELEPHONY_REGISTRY_SERVICE being unavailable.");
1403 executor.execute(() -> listener.onAddListenerFailed());
Wink Savillea374c3d2014-11-11 11:48:04 -08001404 }
1405 }
1406
1407 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -08001408 * Unregister the {@link OnSubscriptionsChangedListener}. This is not strictly necessary
1409 * as the listener will automatically be unregistered if an attempt to invoke the listener
1410 * fails.
Wink Savillea374c3d2014-11-11 11:48:04 -08001411 *
Wink Savilled09c4ca2014-11-22 10:08:16 -08001412 * @param listener that is to be unregistered.
Wink Savillea374c3d2014-11-11 11:48:04 -08001413 */
Wink Saville071743f2015-01-12 17:11:04 -08001414 public void removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
Chen Xu8eb62f92019-10-13 17:30:32 -07001415 if (listener == null) return;
Robert Greenwalt278b8f92015-07-01 14:34:17 -07001416 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
Wink Savillea374c3d2014-11-11 11:48:04 -08001417 if (DBG) {
Wink Savilled09c4ca2014-11-22 10:08:16 -08001418 logd("unregister OnSubscriptionsChangedListener pkgForDebug=" + pkgForDebug
Wink Savillea374c3d2014-11-11 11:48:04 -08001419 + " listener=" + listener);
1420 }
Chen Xu8eb62f92019-10-13 17:30:32 -07001421 // We use the TelephonyRegistry as it runs in the system and thus is always
1422 // available where as SubscriptionController could crash and not be available
1423 TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
1424 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
1425 if (telephonyRegistryManager != null) {
1426 telephonyRegistryManager.removeOnSubscriptionsChangedListener(listener);
Malcolm Chen27829e22018-09-04 22:12:31 -07001427 }
1428 }
1429
1430 /**
1431 * A listener class for monitoring changes to {@link SubscriptionInfo} records of opportunistic
1432 * subscriptions.
1433 * <p>
1434 * Override the onOpportunisticSubscriptionsChanged method in the object that extends this
1435 * or {@link #addOnOpportunisticSubscriptionsChangedListener(
1436 * Executor, OnOpportunisticSubscriptionsChangedListener)}
1437 * to register your listener and to unregister invoke
1438 * {@link #removeOnOpportunisticSubscriptionsChangedListener(
1439 * OnOpportunisticSubscriptionsChangedListener)}
1440 * <p>
1441 * Permissions android.Manifest.permission.READ_PHONE_STATE is required
1442 * for #onOpportunisticSubscriptionsChanged to be invoked.
1443 */
1444 public static class OnOpportunisticSubscriptionsChangedListener {
Malcolm Chen27829e22018-09-04 22:12:31 -07001445 /**
1446 * Callback invoked when there is any change to any SubscriptionInfo. Typically
1447 * this method would invoke {@link #getActiveSubscriptionInfoList}
1448 */
1449 public void onOpportunisticSubscriptionsChanged() {
1450 if (DBG) log("onOpportunisticSubscriptionsChanged: NOT OVERRIDDEN");
1451 }
1452
Malcolm Chen27829e22018-09-04 22:12:31 -07001453 private void log(String s) {
1454 Rlog.d(LOG_TAG, s);
1455 }
1456 }
1457
1458 /**
1459 * Register for changes to the list of opportunistic subscription records or to the
1460 * individual records themselves. When a change occurs the onOpportunisticSubscriptionsChanged
1461 * method of the listener will be invoked immediately if there has been a notification.
1462 *
1463 * @param listener an instance of {@link OnOpportunisticSubscriptionsChangedListener} with
1464 * onOpportunisticSubscriptionsChanged overridden.
1465 */
1466 public void addOnOpportunisticSubscriptionsChangedListener(
1467 @NonNull @CallbackExecutor Executor executor,
1468 @NonNull OnOpportunisticSubscriptionsChangedListener listener) {
1469 if (executor == null || listener == null) {
1470 return;
1471 }
1472
1473 String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>";
1474 if (DBG) {
1475 logd("register addOnOpportunisticSubscriptionsChangedListener pkgName=" + pkgName
1476 + " listener=" + listener);
1477 }
1478
Chen Xu8eb62f92019-10-13 17:30:32 -07001479 // We use the TelephonyRegistry as it runs in the system and thus is always
1480 // available where as SubscriptionController could crash and not be available
1481 TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
1482 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
1483 if (telephonyRegistryManager != null) {
1484 telephonyRegistryManager.addOnOpportunisticSubscriptionsChangedListener(
1485 listener, executor);
Malcolm Chen27829e22018-09-04 22:12:31 -07001486 }
1487 }
1488
1489 /**
1490 * Unregister the {@link OnOpportunisticSubscriptionsChangedListener} that is currently
1491 * listening opportunistic subscriptions change. This is not strictly necessary
1492 * as the listener will automatically be unregistered if an attempt to invoke the listener
1493 * fails.
1494 *
1495 * @param listener that is to be unregistered.
1496 */
1497 public void removeOnOpportunisticSubscriptionsChangedListener(
Malcolm Chen80e1e5c2019-02-27 15:16:05 -08001498 @NonNull OnOpportunisticSubscriptionsChangedListener listener) {
1499 Preconditions.checkNotNull(listener, "listener cannot be null");
Malcolm Chen27829e22018-09-04 22:12:31 -07001500 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
1501 if (DBG) {
1502 logd("unregister OnOpportunisticSubscriptionsChangedListener pkgForDebug="
1503 + pkgForDebug + " listener=" + listener);
1504 }
Chen Xu8eb62f92019-10-13 17:30:32 -07001505 TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
1506 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
1507 if (telephonyRegistryManager != null) {
1508 telephonyRegistryManager.removeOnOpportunisticSubscriptionsChangedListener(listener);
Wink Savillea374c3d2014-11-11 11:48:04 -08001509 }
1510 }
1511
1512 /**
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001513 * Get the active SubscriptionInfo with the input subId.
1514 *
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001515 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1516 * or that the calling app has carrier privileges (see
1517 * {@link TelephonyManager#hasCarrierPrivileges}).
1518 *
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001519 * @param subId The unique SubscriptionInfo key in database.
Wink Savilled09c4ca2014-11-22 10:08:16 -08001520 * @return SubscriptionInfo, maybe null if its not active.
Wink Savillea374c3d2014-11-11 11:48:04 -08001521 */
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001522 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
1523 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
Wink Savilled09c4ca2014-11-22 10:08:16 -08001524 public SubscriptionInfo getActiveSubscriptionInfo(int subId) {
1525 if (VDBG) logd("[getActiveSubscriptionInfo]+ subId=" + subId);
Wink Savillea54bf652014-12-11 13:37:50 -08001526 if (!isValidSubscriptionId(subId)) {
Sanket Padawe28964eb2015-06-05 16:13:51 -07001527 if (DBG) {
1528 logd("[getActiveSubscriptionInfo]- invalid subId");
1529 }
Wink Savillefb40dd42014-06-12 17:02:31 -07001530 return null;
1531 }
1532
Wink Savillea374c3d2014-11-11 11:48:04 -08001533 SubscriptionInfo subInfo = null;
Wink Savillefb40dd42014-06-12 17:02:31 -07001534
1535 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001536 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07001537 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08001538 subInfo = iSub.getActiveSubscriptionInfo(subId, mContext.getOpPackageName(),
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08001539 mContext.getAttributionTag());
Wink Savillefb40dd42014-06-12 17:02:31 -07001540 }
1541 } catch (RemoteException ex) {
1542 // ignore it
1543 }
1544
1545 return subInfo;
Wink Savillefb40dd42014-06-12 17:02:31 -07001546 }
1547
1548 /**
sqianff8dfe72020-01-07 13:45:07 -08001549 * Gets an active SubscriptionInfo {@link SubscriptionInfo} associated with the Sim IccId.
1550 *
Wink Savillefb40dd42014-06-12 17:02:31 -07001551 * @param iccId the IccId of SIM card
Wink Savilled09c4ca2014-11-22 10:08:16 -08001552 * @return SubscriptionInfo, maybe null if its not active
sqianff8dfe72020-01-07 13:45:07 -08001553 *
Wink Savillef5bca082014-09-03 15:13:33 -07001554 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07001555 */
sqianff8dfe72020-01-07 13:45:07 -08001556 @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
1557 @Nullable
1558 @SystemApi
1559 public SubscriptionInfo getActiveSubscriptionInfoForIcc(@NonNull String iccId) {
Wink Savilled09c4ca2014-11-22 10:08:16 -08001560 if (VDBG) logd("[getActiveSubscriptionInfoForIccIndex]+ iccId=" + iccId);
Wink Savillefb40dd42014-06-12 17:02:31 -07001561 if (iccId == null) {
Wink Savilled09c4ca2014-11-22 10:08:16 -08001562 logd("[getActiveSubscriptionInfoForIccIndex]- null iccid");
Wink Savillefb40dd42014-06-12 17:02:31 -07001563 return null;
1564 }
1565
Wink Savilled09c4ca2014-11-22 10:08:16 -08001566 SubscriptionInfo result = null;
Wink Savillefb40dd42014-06-12 17:02:31 -07001567
1568 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001569 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07001570 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08001571 result = iSub.getActiveSubscriptionInfoForIccId(iccId, mContext.getOpPackageName(),
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08001572 mContext.getAttributionTag());
Wink Savillefb40dd42014-06-12 17:02:31 -07001573 }
1574 } catch (RemoteException ex) {
1575 // ignore it
1576 }
1577
1578 return result;
1579 }
1580
1581 /**
Sanket Padawe7e460252017-03-10 16:18:20 -08001582 * Get the active SubscriptionInfo associated with the slotIndex
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001583 *
1584 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1585 * or that the calling app has carrier privileges (see
1586 * {@link TelephonyManager#hasCarrierPrivileges}).
1587 *
Sanket Padawe7e460252017-03-10 16:18:20 -08001588 * @param slotIndex the slot which the subscription is inserted
Wink Savilled09c4ca2014-11-22 10:08:16 -08001589 * @return SubscriptionInfo, maybe null if its not active
Wink Savillefb40dd42014-06-12 17:02:31 -07001590 */
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001591 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
1592 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
Sanket Padawe7e460252017-03-10 16:18:20 -08001593 public SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex) {
1594 if (VDBG) logd("[getActiveSubscriptionInfoForSimSlotIndex]+ slotIndex=" + slotIndex);
1595 if (!isValidSlotIndex(slotIndex)) {
1596 logd("[getActiveSubscriptionInfoForSimSlotIndex]- invalid slotIndex");
Wink Savillefb40dd42014-06-12 17:02:31 -07001597 return null;
1598 }
1599
Wink Savilled09c4ca2014-11-22 10:08:16 -08001600 SubscriptionInfo result = null;
Wink Savillefb40dd42014-06-12 17:02:31 -07001601
1602 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001603 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07001604 if (iSub != null) {
Sanket Padawe7e460252017-03-10 16:18:20 -08001605 result = iSub.getActiveSubscriptionInfoForSimSlotIndex(slotIndex,
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08001606 mContext.getOpPackageName(), mContext.getAttributionTag());
Wink Savillefb40dd42014-06-12 17:02:31 -07001607 }
1608 } catch (RemoteException ex) {
1609 // ignore it
1610 }
1611
1612 return result;
1613 }
1614
1615 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -08001616 * @return List of all SubscriptionInfo records in database,
1617 * include those that were inserted before, maybe empty but not null.
Wink Savillef5bca082014-09-03 15:13:33 -07001618 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07001619 */
Benedict Wong061b2f72020-11-02 17:52:06 -08001620 @NonNull
Mathew Inwooda8382062018-08-16 17:01:12 +01001621 @UnsupportedAppUsage
Wink Savilled09c4ca2014-11-22 10:08:16 -08001622 public List<SubscriptionInfo> getAllSubscriptionInfoList() {
Wink Savillea374c3d2014-11-11 11:48:04 -08001623 if (VDBG) logd("[getAllSubscriptionInfoList]+");
Wink Savillefb40dd42014-06-12 17:02:31 -07001624
Wink Savillea374c3d2014-11-11 11:48:04 -08001625 List<SubscriptionInfo> result = null;
Wink Savillefb40dd42014-06-12 17:02:31 -07001626
1627 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001628 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07001629 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08001630 result = iSub.getAllSubInfoList(mContext.getOpPackageName(),
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08001631 mContext.getAttributionTag());
Wink Savillefb40dd42014-06-12 17:02:31 -07001632 }
1633 } catch (RemoteException ex) {
1634 // ignore it
1635 }
1636
Wink Saville905bb542014-09-04 17:10:23 -07001637 if (result == null) {
Benedict Wong061b2f72020-11-02 17:52:06 -08001638 result = Collections.emptyList();
Wink Saville905bb542014-09-04 17:10:23 -07001639 }
Wink Savillefb40dd42014-06-12 17:02:31 -07001640 return result;
1641 }
1642
1643 /**
Vasu Noriaea03912018-09-04 11:19:59 -07001644 * Get the SubscriptionInfo(s) of the currently active SIM(s). The records will be sorted
Wink Savilled09c4ca2014-11-22 10:08:16 -08001645 * by {@link SubscriptionInfo#getSimSlotIndex} then by {@link SubscriptionInfo#getSubscriptionId}.
1646 *
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001647 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1648 * or that the calling app has carrier privileges (see
1649 * {@link TelephonyManager#hasCarrierPrivileges}). In the latter case, only records accessible
1650 * to the calling app are returned.
1651 *
Wink Savilled09c4ca2014-11-22 10:08:16 -08001652 * @return Sorted list of the currently {@link SubscriptionInfo} records available on the device.
1653 * <ul>
1654 * <li>
1655 * If null is returned the current state is unknown but if a {@link OnSubscriptionsChangedListener}
1656 * has been registered {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be
1657 * invoked in the future.
1658 * </li>
1659 * <li>
1660 * If the list is empty then there are no {@link SubscriptionInfo} records currently available.
1661 * </li>
1662 * <li>
1663 * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
1664 * then by {@link SubscriptionInfo#getSubscriptionId}.
1665 * </li>
1666 * </ul>
Wink Savillefb40dd42014-06-12 17:02:31 -07001667 */
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001668 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
1669 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
Wink Savilled09c4ca2014-11-22 10:08:16 -08001670 public List<SubscriptionInfo> getActiveSubscriptionInfoList() {
Malcolm Chen31071852019-02-12 17:29:59 -08001671 return getActiveSubscriptionInfoList(/* userVisibleonly */true);
Malcolm Chenc3d7de02018-12-21 17:00:30 -08001672 }
1673
1674 /**
Sooraj Sasindrane5ac4da2019-11-07 18:32:37 -08001675 * Get both hidden and visible SubscriptionInfo(s) of the currently active SIM(s).
1676 * The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex}
1677 * then by {@link SubscriptionInfo#getSubscriptionId}.
Malcolm Chenc3d7de02018-12-21 17:00:30 -08001678 *
Peter Wang01d128c2019-12-17 19:11:23 -08001679 * Hidden subscriptions refer to those are not meant visible to the users.
1680 * For example, an opportunistic subscription that is grouped with other
1681 * subscriptions should remain invisible to users as they are only functionally
1682 * supplementary to primary ones.
1683 *
Sooraj Sasindrane5ac4da2019-11-07 18:32:37 -08001684 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1685 * or that the calling app has carrier privileges (see
1686 * {@link TelephonyManager#hasCarrierPrivileges}). In the latter case, only records accessible
1687 * to the calling app are returned.
1688 *
1689 * @return Sorted list of the currently available {@link SubscriptionInfo}
1690 * records on the device.
1691 * This is similar to {@link #getActiveSubscriptionInfoList} except that it will return
1692 * both active and hidden SubscriptionInfos.
1693 *
Malcolm Chenc3d7de02018-12-21 17:00:30 -08001694 */
Sooraj Sasindran40468062020-01-06 19:10:50 -08001695 public @NonNull List<SubscriptionInfo> getCompleteActiveSubscriptionInfoList() {
1696 List<SubscriptionInfo> completeList = getActiveSubscriptionInfoList(
1697 /* userVisibleonly */false);
1698 if (completeList == null) {
1699 completeList = new ArrayList<>();
1700 }
1701 return completeList;
Sooraj Sasindrane5ac4da2019-11-07 18:32:37 -08001702 }
1703
1704 /**
1705 * This is similar to {@link #getActiveSubscriptionInfoList()}, but if userVisibleOnly
1706 * is true, it will filter out the hidden subscriptions.
1707 *
1708 * @hide
1709 */
1710 public @Nullable List<SubscriptionInfo> getActiveSubscriptionInfoList(boolean userVisibleOnly) {
Malcolm Chenc3d7de02018-12-21 17:00:30 -08001711 List<SubscriptionInfo> activeList = null;
Wink Savillefb40dd42014-06-12 17:02:31 -07001712
1713 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001714 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07001715 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08001716 activeList = iSub.getActiveSubscriptionInfoList(mContext.getOpPackageName(),
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08001717 mContext.getAttributionTag());
Wink Savillefb40dd42014-06-12 17:02:31 -07001718 }
1719 } catch (RemoteException ex) {
1720 // ignore it
1721 }
Malcolm Chenc3d7de02018-12-21 17:00:30 -08001722
1723 if (!userVisibleOnly || activeList == null) {
1724 return activeList;
1725 } else {
Malcolm Chend1b4a812019-02-28 14:07:59 -08001726 return activeList.stream().filter(subInfo -> isSubscriptionVisible(subInfo))
Malcolm Chenc3d7de02018-12-21 17:00:30 -08001727 .collect(Collectors.toList());
1728 }
Wink Savillefb40dd42014-06-12 17:02:31 -07001729 }
1730
1731 /**
Jeff Davidsond02731f2017-04-09 14:31:09 -07001732 * Gets the SubscriptionInfo(s) of all available subscriptions, if any.
1733 *
1734 * <p>Available subscriptions include active ones (those with a non-negative
1735 * {@link SubscriptionInfo#getSimSlotIndex()}) as well as inactive but installed embedded
1736 * subscriptions.
1737 *
1738 * <p>The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by
1739 * {@link SubscriptionInfo#getSubscriptionId}.
1740 *
1741 * @return Sorted list of the current {@link SubscriptionInfo} records available on the
1742 * device.
1743 * <ul>
1744 * <li>
1745 * If null is returned the current state is unknown but if a
1746 * {@link OnSubscriptionsChangedListener} has been registered
1747 * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be invoked in the future.
1748 * <li>
1749 * If the list is empty then there are no {@link SubscriptionInfo} records currently available.
1750 * <li>
1751 * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
1752 * then by {@link SubscriptionInfo#getSubscriptionId}.
1753 * </ul>
Jiuyu Sund3bb4ae2018-02-08 16:38:26 +00001754 *
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08001755 * <p>
1756 * Permissions android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE is required
1757 * for #getAvailableSubscriptionInfoList to be invoked.
1758 * @hide
Jeff Davidsond02731f2017-04-09 14:31:09 -07001759 */
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08001760 @SystemApi
Jeff Davidsond02731f2017-04-09 14:31:09 -07001761 public List<SubscriptionInfo> getAvailableSubscriptionInfoList() {
1762 List<SubscriptionInfo> result = null;
1763
1764 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001765 ISub iSub = TelephonyManager.getSubscriptionService();
Jeff Davidsond02731f2017-04-09 14:31:09 -07001766 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08001767 result = iSub.getAvailableSubscriptionInfoList(mContext.getOpPackageName(),
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08001768 mContext.getAttributionTag());
Jeff Davidsond02731f2017-04-09 14:31:09 -07001769 }
1770 } catch (RemoteException ex) {
1771 // ignore it
1772 }
1773 return result;
1774 }
1775
1776 /**
1777 * Gets the SubscriptionInfo(s) of all embedded subscriptions accessible to the calling app, if
1778 * any.
1779 *
1780 * <p>Only those subscriptions for which the calling app has carrier privileges per the
1781 * subscription metadata, if any, will be included in the returned list.
1782 *
1783 * <p>The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by
1784 * {@link SubscriptionInfo#getSubscriptionId}.
1785 *
1786 * @return Sorted list of the current embedded {@link SubscriptionInfo} records available on the
1787 * device which are accessible to the caller.
1788 * <ul>
1789 * <li>
1790 * If null is returned the current state is unknown but if a
1791 * {@link OnSubscriptionsChangedListener} has been registered
1792 * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be invoked in the future.
1793 * <li>
1794 * If the list is empty then there are no {@link SubscriptionInfo} records currently available.
1795 * <li>
1796 * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
1797 * then by {@link SubscriptionInfo#getSubscriptionId}.
1798 * </ul>
Jeff Davidsond02731f2017-04-09 14:31:09 -07001799 */
1800 public List<SubscriptionInfo> getAccessibleSubscriptionInfoList() {
1801 List<SubscriptionInfo> result = null;
1802
1803 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001804 ISub iSub = TelephonyManager.getSubscriptionService();
Jeff Davidsond02731f2017-04-09 14:31:09 -07001805 if (iSub != null) {
1806 result = iSub.getAccessibleSubscriptionInfoList(mContext.getOpPackageName());
1807 }
1808 } catch (RemoteException ex) {
1809 // ignore it
1810 }
1811 return result;
1812 }
1813
1814 /**
Pengquan Mengeb7ac732018-11-29 18:33:17 -08001815 * Request a refresh of the platform cache of profile information for the eUICC which
1816 * corresponds to the card ID returned by {@link TelephonyManager#getCardIdForDefaultEuicc()}.
Jeff Davidsond02731f2017-04-09 14:31:09 -07001817 *
1818 * <p>Should be called by the EuiccService implementation whenever this information changes due
1819 * to an operation done outside the scope of a request initiated by the platform to the
1820 * EuiccService. There is no need to refresh for downloads, deletes, or other operations that
1821 * were made through the EuiccService.
1822 *
1823 * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
Pengquan Mengeb7ac732018-11-29 18:33:17 -08001824 *
1825 * @see {@link TelephonyManager#getCardIdForDefaultEuicc()} for more information on the card ID.
1826 *
Jeff Davidsond02731f2017-04-09 14:31:09 -07001827 * @hide
Jeff Davidsond02731f2017-04-09 14:31:09 -07001828 */
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08001829 @SystemApi
Jeff Davidsond02731f2017-04-09 14:31:09 -07001830 public void requestEmbeddedSubscriptionInfoListRefresh() {
Pengquan Mengeb7ac732018-11-29 18:33:17 -08001831 int cardId = TelephonyManager.from(mContext).getCardIdForDefaultEuicc();
Jeff Davidsond02731f2017-04-09 14:31:09 -07001832 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001833 ISub iSub = TelephonyManager.getSubscriptionService();
Jeff Davidsond02731f2017-04-09 14:31:09 -07001834 if (iSub != null) {
Pengquan Mengeb7ac732018-11-29 18:33:17 -08001835 iSub.requestEmbeddedSubscriptionInfoListRefresh(cardId);
Jeff Davidsond02731f2017-04-09 14:31:09 -07001836 }
1837 } catch (RemoteException ex) {
Pengquan Mengeb7ac732018-11-29 18:33:17 -08001838 logd("requestEmbeddedSubscriptionInfoListFresh for card = " + cardId + " failed.");
1839 }
1840 }
1841
1842 /**
1843 * Request a refresh of the platform cache of profile information for the eUICC with the given
1844 * {@code cardId}.
1845 *
1846 * <p>Should be called by the EuiccService implementation whenever this information changes due
1847 * to an operation done outside the scope of a request initiated by the platform to the
1848 * EuiccService. There is no need to refresh for downloads, deletes, or other operations that
1849 * were made through the EuiccService.
1850 *
1851 * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
1852 *
1853 * @param cardId the card ID of the eUICC.
1854 *
1855 * @see {@link TelephonyManager#getCardIdForDefaultEuicc()} for more information on the card ID.
1856 *
1857 * @hide
1858 */
1859 @SystemApi
1860 public void requestEmbeddedSubscriptionInfoListRefresh(int cardId) {
1861 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001862 ISub iSub = TelephonyManager.getSubscriptionService();
Pengquan Mengeb7ac732018-11-29 18:33:17 -08001863 if (iSub != null) {
1864 iSub.requestEmbeddedSubscriptionInfoListRefresh(cardId);
1865 }
1866 } catch (RemoteException ex) {
1867 logd("requestEmbeddedSubscriptionInfoListFresh for card = " + cardId + " failed.");
Jeff Davidsond02731f2017-04-09 14:31:09 -07001868 }
1869 }
1870
1871 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -08001872 * @return the count of all subscriptions in the database, this includes
1873 * all subscriptions that have been seen.
Wink Savillef5bca082014-09-03 15:13:33 -07001874 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07001875 */
Mathew Inwooda8382062018-08-16 17:01:12 +01001876 @UnsupportedAppUsage
Wink Savilled09c4ca2014-11-22 10:08:16 -08001877 public int getAllSubscriptionInfoCount() {
Wink Savillea374c3d2014-11-11 11:48:04 -08001878 if (VDBG) logd("[getAllSubscriptionInfoCount]+");
Wink Savillefb40dd42014-06-12 17:02:31 -07001879
1880 int result = 0;
1881
1882 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001883 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07001884 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08001885 result = iSub.getAllSubInfoCount(mContext.getOpPackageName(),
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08001886 mContext.getAttributionTag());
Wink Savillefb40dd42014-06-12 17:02:31 -07001887 }
1888 } catch (RemoteException ex) {
1889 // ignore it
1890 }
1891
1892 return result;
1893 }
1894
1895 /**
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001896 *
1897 * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1898 * or that the calling app has carrier privileges (see
1899 * {@link TelephonyManager#hasCarrierPrivileges}). In the latter case, the count will include
1900 * only those subscriptions accessible to the caller.
1901 *
Wink Savilled09c4ca2014-11-22 10:08:16 -08001902 * @return the current number of active subscriptions. There is no guarantee the value
1903 * returned by this method will be the same as the length of the list returned by
1904 * {@link #getActiveSubscriptionInfoList}.
Wink Savillec650e0b2014-09-02 22:37:08 -07001905 */
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001906 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
1907 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
Wink Savilled09c4ca2014-11-22 10:08:16 -08001908 public int getActiveSubscriptionInfoCount() {
Wink Savillec650e0b2014-09-02 22:37:08 -07001909 int result = 0;
1910
1911 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001912 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillec650e0b2014-09-02 22:37:08 -07001913 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08001914 result = iSub.getActiveSubInfoCount(mContext.getOpPackageName(),
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08001915 mContext.getAttributionTag());
Wink Savillec650e0b2014-09-02 22:37:08 -07001916 }
1917 } catch (RemoteException ex) {
1918 // ignore it
1919 }
1920
1921 return result;
1922 }
1923
1924 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -08001925 * @return the maximum number of active subscriptions that will be returned by
1926 * {@link #getActiveSubscriptionInfoList} and the value returned by
1927 * {@link #getActiveSubscriptionInfoCount}.
1928 */
1929 public int getActiveSubscriptionInfoCountMax() {
1930 int result = 0;
1931
1932 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001933 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savilled09c4ca2014-11-22 10:08:16 -08001934 if (iSub != null) {
1935 result = iSub.getActiveSubInfoCountMax();
1936 }
1937 } catch (RemoteException ex) {
1938 // ignore it
1939 }
1940
1941 return result;
1942 }
1943
1944 /**
1945 * Add a new SubscriptionInfo to SubscriptionInfo database if needed
Wink Savillefb40dd42014-06-12 17:02:31 -07001946 * @param iccId the IccId of the SIM card
Sanket Padawe7e460252017-03-10 16:18:20 -08001947 * @param slotIndex the slot which the SIM is inserted
Wink Savillefb40dd42014-06-12 17:02:31 -07001948 * @return the URL of the newly created row or the updated row
Wink Savillef5bca082014-09-03 15:13:33 -07001949 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07001950 */
Sanket Padawe7e460252017-03-10 16:18:20 -08001951 public Uri addSubscriptionInfoRecord(String iccId, int slotIndex) {
1952 if (VDBG) logd("[addSubscriptionInfoRecord]+ iccId:" + iccId + " slotIndex:" + slotIndex);
Wink Savillefb40dd42014-06-12 17:02:31 -07001953 if (iccId == null) {
Wink Savillea374c3d2014-11-11 11:48:04 -08001954 logd("[addSubscriptionInfoRecord]- null iccId");
Wink Savillefb40dd42014-06-12 17:02:31 -07001955 }
Sanket Padawe7e460252017-03-10 16:18:20 -08001956 if (!isValidSlotIndex(slotIndex)) {
1957 logd("[addSubscriptionInfoRecord]- invalid slotIndex");
Wink Savillec650e0b2014-09-02 22:37:08 -07001958 }
Wink Savillefb40dd42014-06-12 17:02:31 -07001959
Vasu Noriaea03912018-09-04 11:19:59 -07001960 addSubscriptionInfoRecord(iccId, null, slotIndex, SUBSCRIPTION_TYPE_LOCAL_SIM);
Wink Savillefb40dd42014-06-12 17:02:31 -07001961
1962 // FIXME: Always returns null?
1963 return null;
1964
1965 }
1966
1967 /**
Vasu Noriaea03912018-09-04 11:19:59 -07001968 * Add a new SubscriptionInfo to SubscriptionInfo database if needed
1969 * @param uniqueId This is the unique identifier for the subscription within the
1970 * specific subscription type.
1971 * @param displayName human-readable name of the device the subscription corresponds to.
1972 * @param slotIndex the slot assigned to this subscription. It is ignored for subscriptionType
1973 * of {@link #SUBSCRIPTION_TYPE_REMOTE_SIM}.
1974 * @param subscriptionType the {@link #SUBSCRIPTION_TYPE}
1975 * @hide
1976 */
Etienne Ruffieux6a646db2021-07-27 10:06:27 +00001977 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
1978 public void addSubscriptionInfoRecord(@NonNull String uniqueId, @Nullable String displayName,
Etienne Ruffieux036f3012022-02-24 10:33:04 +00001979 int slotIndex, @SubscriptionType int subscriptionType) {
Vasu Noriaea03912018-09-04 11:19:59 -07001980 if (VDBG) {
1981 logd("[addSubscriptionInfoRecord]+ uniqueId:" + uniqueId
1982 + ", displayName:" + displayName + ", slotIndex:" + slotIndex
1983 + ", subscriptionType: " + subscriptionType);
1984 }
1985 if (uniqueId == null) {
1986 Log.e(LOG_TAG, "[addSubscriptionInfoRecord]- uniqueId is null");
1987 return;
1988 }
1989
1990 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001991 ISub iSub = TelephonyManager.getSubscriptionService();
Vasu Noriaea03912018-09-04 11:19:59 -07001992 if (iSub == null) {
1993 Log.e(LOG_TAG, "[addSubscriptionInfoRecord]- ISub service is null");
1994 return;
1995 }
1996 int result = iSub.addSubInfo(uniqueId, displayName, slotIndex, subscriptionType);
1997 if (result < 0) {
1998 Log.e(LOG_TAG, "Adding of subscription didn't succeed: error = " + result);
1999 } else {
2000 logd("successfully added new subscription");
2001 }
2002 } catch (RemoteException ex) {
2003 // ignore it
2004 }
2005 }
2006
2007 /**
2008 * Remove SubscriptionInfo record from the SubscriptionInfo database
2009 * @param uniqueId This is the unique identifier for the subscription within the specific
2010 * subscription type.
2011 * @param subscriptionType the {@link #SUBSCRIPTION_TYPE}
2012 * @hide
2013 */
Etienne Ruffieux6a646db2021-07-27 10:06:27 +00002014 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
Etienne Ruffieux036f3012022-02-24 10:33:04 +00002015 public void removeSubscriptionInfoRecord(@NonNull String uniqueId,
2016 @SubscriptionType int subscriptionType) {
Vasu Noriaea03912018-09-04 11:19:59 -07002017 if (VDBG) {
2018 logd("[removeSubscriptionInfoRecord]+ uniqueId:" + uniqueId
2019 + ", subscriptionType: " + subscriptionType);
2020 }
2021 if (uniqueId == null) {
2022 Log.e(LOG_TAG, "[addSubscriptionInfoRecord]- uniqueId is null");
2023 return;
2024 }
2025
2026 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002027 ISub iSub = TelephonyManager.getSubscriptionService();
Vasu Noriaea03912018-09-04 11:19:59 -07002028 if (iSub == null) {
2029 Log.e(LOG_TAG, "[removeSubscriptionInfoRecord]- ISub service is null");
2030 return;
2031 }
2032 int result = iSub.removeSubInfo(uniqueId, subscriptionType);
2033 if (result < 0) {
2034 Log.e(LOG_TAG, "Removal of subscription didn't succeed: error = " + result);
2035 } else {
2036 logd("successfully removed subscription");
2037 }
2038 } catch (RemoteException ex) {
2039 // ignore it
2040 }
2041 }
2042
2043 /**
changbetty23eee52e2019-12-18 18:09:56 +08002044 * Set SIM icon tint color for subscription ID
Wink Savilled09c4ca2014-11-22 10:08:16 -08002045 * @param tint the RGB value of icon tint color of the SIM
changbetty23eee52e2019-12-18 18:09:56 +08002046 * @param subId the unique Subscritpion ID in database
Wink Savillefb40dd42014-06-12 17:02:31 -07002047 * @return the number of records updated
Wink Savillef5bca082014-09-03 15:13:33 -07002048 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07002049 */
changbetty23eee52e2019-12-18 18:09:56 +08002050 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
2051 public int setIconTint(@ColorInt int tint, int subId) {
Stuart Scottab45ec12014-10-28 09:29:01 -07002052 if (VDBG) logd("[setIconTint]+ tint:" + tint + " subId:" + subId);
Malcolm Chenbd4ae762018-08-03 17:24:07 -07002053 return setSubscriptionPropertyHelper(subId, "setIconTint",
2054 (iSub)-> iSub.setIconTint(tint, subId)
2055 );
Wink Savillefb40dd42014-06-12 17:02:31 -07002056 }
2057
2058 /**
changbetty23eee52e2019-12-18 18:09:56 +08002059 * Set the display name for a subscription ID
Wink Savillefb40dd42014-06-12 17:02:31 -07002060 * @param displayName the display name of SIM card
changbetty23eee52e2019-12-18 18:09:56 +08002061 * @param subId the unique Subscritpion ID in database
Jack Yu5c6eb0e2019-10-16 09:16:54 -07002062 * @param nameSource SIM display name source
Wink Saville98513d72014-12-08 12:44:16 -08002063 * @return the number of records updated or < 0 if invalid subId
Wink Savillef5bca082014-09-03 15:13:33 -07002064 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07002065 */
changbetty23eee52e2019-12-18 18:09:56 +08002066 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
2067 public int setDisplayName(@Nullable String displayName, int subId,
2068 @SimDisplayNameSource int nameSource) {
Wink Savillec650e0b2014-09-02 22:37:08 -07002069 if (VDBG) {
2070 logd("[setDisplayName]+ displayName:" + displayName + " subId:" + subId
2071 + " nameSource:" + nameSource);
2072 }
Malcolm Chenbd4ae762018-08-03 17:24:07 -07002073 return setSubscriptionPropertyHelper(subId, "setDisplayName",
2074 (iSub)-> iSub.setDisplayNameUsingSrc(displayName, subId, nameSource)
2075 );
Wink Savillefb40dd42014-06-12 17:02:31 -07002076 }
2077
2078 /**
2079 * Set phone number by subId
Wink Savillefb40dd42014-06-12 17:02:31 -07002080 * @param number the phone number of the SIM
Wink Savillea374c3d2014-11-11 11:48:04 -08002081 * @param subId the unique SubscriptionInfo index in database
Wink Savillefb40dd42014-06-12 17:02:31 -07002082 * @return the number of records updated
Wink Savillef5bca082014-09-03 15:13:33 -07002083 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07002084 */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +00002085 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Wink Savilled09c4ca2014-11-22 10:08:16 -08002086 public int setDisplayNumber(String number, int subId) {
Malcolm Chenbd4ae762018-08-03 17:24:07 -07002087 if (number == null) {
Wink Savillec650e0b2014-09-02 22:37:08 -07002088 logd("[setDisplayNumber]- fail");
Wink Savillefb40dd42014-06-12 17:02:31 -07002089 return -1;
2090 }
Malcolm Chenbd4ae762018-08-03 17:24:07 -07002091 return setSubscriptionPropertyHelper(subId, "setDisplayNumber",
2092 (iSub)-> iSub.setDisplayNumber(number, subId)
2093 );
Wink Savillefb40dd42014-06-12 17:02:31 -07002094 }
2095
2096 /**
Wink Savillefb40dd42014-06-12 17:02:31 -07002097 * Set data roaming by simInfo index
Wink Savillefb40dd42014-06-12 17:02:31 -07002098 * @param roaming 0:Don't allow data when roaming, 1:Allow data when roaming
Wink Savillea374c3d2014-11-11 11:48:04 -08002099 * @param subId the unique SubscriptionInfo index in database
Wink Savillefb40dd42014-06-12 17:02:31 -07002100 * @return the number of records updated
Wink Savillef5bca082014-09-03 15:13:33 -07002101 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07002102 */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +00002103 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Wink Savilled09c4ca2014-11-22 10:08:16 -08002104 public int setDataRoaming(int roaming, int subId) {
Wink Savillefb40dd42014-06-12 17:02:31 -07002105 if (VDBG) logd("[setDataRoaming]+ roaming:" + roaming + " subId:" + subId);
Malcolm Chenbd4ae762018-08-03 17:24:07 -07002106 return setSubscriptionPropertyHelper(subId, "setDataRoaming",
2107 (iSub)->iSub.setDataRoaming(roaming, subId)
2108 );
Wink Savillefb40dd42014-06-12 17:02:31 -07002109 }
2110
Wink Saville905bb542014-09-04 17:10:23 -07002111 /**
Sanket Padawe7e460252017-03-10 16:18:20 -08002112 * Get slotIndex associated with the subscription.
sqian996a3182018-10-12 18:41:19 -07002113 *
2114 * @param subscriptionId the unique SubscriptionInfo index in database
2115 * @return slotIndex as a positive integer or {@link #INVALID_SIM_SLOT_INDEX} if the supplied
2116 * subscriptionId doesn't have an associated slot index.
Wink Saville905bb542014-09-04 17:10:23 -07002117 */
sqian996a3182018-10-12 18:41:19 -07002118 public static int getSlotIndex(int subscriptionId) {
Collin Fijalkovich41f94622020-04-10 14:01:42 -07002119 return sSlotIndexCache.query(subscriptionId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002120 }
2121
sqiancd4dafb2018-08-29 13:58:49 -07002122 /**
2123 * Get an array of Subscription Ids for specified slot Index.
sqian91412858b2018-11-09 14:52:25 -08002124 * @param slotIndex the slot index.
2125 * @return subscription Ids or null if the given slot Index is not valid or there are no active
2126 * subscriptions in the slot.
sqiancd4dafb2018-08-29 13:58:49 -07002127 */
sqianf8ace212018-10-19 19:01:42 -07002128 @Nullable
sqiand8c30b92018-10-30 16:58:20 -07002129 public int[] getSubscriptionIds(int slotIndex) {
sqiancd4dafb2018-08-29 13:58:49 -07002130 return getSubId(slotIndex);
2131 }
2132
Wink Savillef5bca082014-09-03 15:13:33 -07002133 /** @hide */
Mathew Inwooda8382062018-08-16 17:01:12 +01002134 @UnsupportedAppUsage
Sanket Padawe7e460252017-03-10 16:18:20 -08002135 public static int[] getSubId(int slotIndex) {
2136 if (!isValidSlotIndex(slotIndex)) {
Wink Savillec650e0b2014-09-02 22:37:08 -07002137 logd("[getSubId]- fail");
2138 return null;
2139 }
Wink Savillefb40dd42014-06-12 17:02:31 -07002140
Wink Saville63f03dd2014-10-23 10:44:45 -07002141 int[] subId = null;
Wink Savillefb40dd42014-06-12 17:02:31 -07002142
2143 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002144 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07002145 if (iSub != null) {
Sanket Padawe7e460252017-03-10 16:18:20 -08002146 subId = iSub.getSubId(slotIndex);
Wink Savillefb40dd42014-06-12 17:02:31 -07002147 }
2148 } catch (RemoteException ex) {
2149 // ignore it
2150 }
2151
2152 return subId;
2153 }
2154
Wink Savillef5bca082014-09-03 15:13:33 -07002155 /** @hide */
Chen Xu4c0b06d2018-10-22 16:54:39 +00002156 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
Wink Saville63f03dd2014-10-23 10:44:45 -07002157 public static int getPhoneId(int subId) {
Collin Fijalkovich41f94622020-04-10 14:01:42 -07002158 return sPhoneIdCache.query(subId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002159 }
2160
Wink Savillefb40dd42014-06-12 17:02:31 -07002161 private static void logd(String msg) {
Wink Savilled09c4ca2014-11-22 10:08:16 -08002162 Rlog.d(LOG_TAG, msg);
Wink Savillefb40dd42014-06-12 17:02:31 -07002163 }
2164
Malcolm Chen4674a792019-03-20 20:32:27 -07002165 private static void loge(String msg) {
2166 Rlog.e(LOG_TAG, msg);
2167 }
2168
Wink Savillefb40dd42014-06-12 17:02:31 -07002169 /**
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002170 * Returns the system's default subscription id.
2171 *
2172 * For a voice capable device, it will return getDefaultVoiceSubscriptionId.
2173 * For a data only device, it will return the getDefaultDataSubscriptionId.
2174 * May return an INVALID_SUBSCRIPTION_ID on error.
2175 *
2176 * @return the "system" default subscription id.
Wink Savillefb40dd42014-06-12 17:02:31 -07002177 */
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002178 public static int getDefaultSubscriptionId() {
Collin Fijalkovich4ffdedf2019-12-10 09:52:14 -08002179 return sDefaultSubIdCache.query(null);
Wink Savillefb40dd42014-06-12 17:02:31 -07002180 }
2181
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002182 /**
2183 * Returns the system's default voice subscription id.
2184 *
2185 * On a data only device or on error, will return INVALID_SUBSCRIPTION_ID.
2186 *
2187 * @return the default voice subscription Id.
2188 */
2189 public static int getDefaultVoiceSubscriptionId() {
Wink Savilled09c4ca2014-11-22 10:08:16 -08002190 int subId = INVALID_SUBSCRIPTION_ID;
Wink Savillefb40dd42014-06-12 17:02:31 -07002191
2192 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002193 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07002194 if (iSub != null) {
2195 subId = iSub.getDefaultVoiceSubId();
2196 }
2197 } catch (RemoteException ex) {
2198 // ignore it
2199 }
2200
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002201 if (VDBG) logd("getDefaultVoiceSubscriptionId, sub id = " + subId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002202 return subId;
2203 }
2204
Hall Liud2f962a2019-10-31 15:17:58 -07002205 /**
2206 * Sets the system's default voice subscription id.
2207 *
2208 * On a data-only device, this is a no-op.
2209 *
2210 * May throw a {@link RuntimeException} if the provided subscription id is equal to
2211 * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}
2212 *
2213 * @param subscriptionId A valid subscription ID to set as the system default, or
2214 * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}
2215 * @hide
2216 */
2217 @SystemApi
Hall Liud2f962a2019-10-31 15:17:58 -07002218 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
2219 public void setDefaultVoiceSubscriptionId(int subscriptionId) {
2220 if (VDBG) logd("setDefaultVoiceSubId sub id = " + subscriptionId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002221 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002222 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07002223 if (iSub != null) {
Hall Liud2f962a2019-10-31 15:17:58 -07002224 iSub.setDefaultVoiceSubId(subscriptionId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002225 }
2226 } catch (RemoteException ex) {
Wink Savillec650e0b2014-09-02 22:37:08 -07002227 // ignore it
Wink Savillefb40dd42014-06-12 17:02:31 -07002228 }
2229 }
2230
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002231 /**
Hall Liud2f962a2019-10-31 15:17:58 -07002232 * Same as {@link #setDefaultVoiceSubscriptionId(int)}, but preserved for backwards
2233 * compatibility.
2234 * @hide
2235 */
2236 public void setDefaultVoiceSubId(int subId) {
2237 setDefaultVoiceSubscriptionId(subId);
2238 }
2239
2240 /**
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002241 * Return the SubscriptionInfo for default voice subscription.
2242 *
2243 * Will return null on data only devices, or on error.
2244 *
2245 * @return the SubscriptionInfo for the default voice subscription.
2246 * @hide
2247 */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +00002248 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Wink Savilled09c4ca2014-11-22 10:08:16 -08002249 public SubscriptionInfo getDefaultVoiceSubscriptionInfo() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002250 return getActiveSubscriptionInfo(getDefaultVoiceSubscriptionId());
Wink Savillefb40dd42014-06-12 17:02:31 -07002251 }
2252
Wink Savillef5bca082014-09-03 15:13:33 -07002253 /** @hide */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +00002254 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Wink Savillec650e0b2014-09-02 22:37:08 -07002255 public static int getDefaultVoicePhoneId() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002256 return getPhoneId(getDefaultVoiceSubscriptionId());
Wink Savillefb40dd42014-06-12 17:02:31 -07002257 }
2258
Wink Saville905bb542014-09-04 17:10:23 -07002259 /**
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002260 * Returns the system's default SMS subscription id.
Wink Savilled09c4ca2014-11-22 10:08:16 -08002261 *
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002262 * On a data only device or on error, will return INVALID_SUBSCRIPTION_ID.
2263 *
2264 * @return the default SMS subscription Id.
Wink Saville905bb542014-09-04 17:10:23 -07002265 */
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002266 public static int getDefaultSmsSubscriptionId() {
Collin Fijalkovich02e5c592020-04-06 10:54:28 -07002267 return sDefaultSmsSubIdCache.query(null);
Wink Savillec650e0b2014-09-02 22:37:08 -07002268 }
2269
sqiandb496412018-11-12 18:14:18 -08002270 /**
2271 * Set the subscription which will be used by default for SMS, with the subscription which
2272 * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied
2273 * subscription ID is not usable (check with {@link #isUsableSubscriptionId(int)}).
2274 *
2275 * @param subscriptionId the supplied subscription ID
2276 *
2277 * @hide
2278 */
2279 @SystemApi
2280 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
2281 public void setDefaultSmsSubId(int subscriptionId) {
2282 if (VDBG) logd("setDefaultSmsSubId sub id = " + subscriptionId);
Wink Savillec650e0b2014-09-02 22:37:08 -07002283 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002284 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillec650e0b2014-09-02 22:37:08 -07002285 if (iSub != null) {
sqiandb496412018-11-12 18:14:18 -08002286 iSub.setDefaultSmsSubId(subscriptionId);
Wink Savillec650e0b2014-09-02 22:37:08 -07002287 }
2288 } catch (RemoteException ex) {
sqiana31ef442019-02-13 14:41:44 -08002289 ex.rethrowFromSystemServer();
Wink Savillec650e0b2014-09-02 22:37:08 -07002290 }
2291 }
2292
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002293 /**
2294 * Return the SubscriptionInfo for default voice subscription.
2295 *
2296 * Will return null on data only devices, or on error.
2297 *
2298 * @return the SubscriptionInfo for the default SMS subscription.
2299 * @hide
2300 */
Wink Savilled09c4ca2014-11-22 10:08:16 -08002301 public SubscriptionInfo getDefaultSmsSubscriptionInfo() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002302 return getActiveSubscriptionInfo(getDefaultSmsSubscriptionId());
Wink Savillec650e0b2014-09-02 22:37:08 -07002303 }
2304
Wink Savillef5bca082014-09-03 15:13:33 -07002305 /** @hide */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +00002306 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Wink Savilled09c4ca2014-11-22 10:08:16 -08002307 public int getDefaultSmsPhoneId() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002308 return getPhoneId(getDefaultSmsSubscriptionId());
Wink Savillec650e0b2014-09-02 22:37:08 -07002309 }
2310
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002311 /**
2312 * Returns the system's default data subscription id.
2313 *
2314 * On a voice only device or on error, will return INVALID_SUBSCRIPTION_ID.
2315 *
2316 * @return the default data subscription Id.
2317 */
2318 public static int getDefaultDataSubscriptionId() {
Collin Fijalkovichce43a592020-03-25 14:30:21 -07002319 return sDefaultDataSubIdCache.query(null);
Wink Savillefb40dd42014-06-12 17:02:31 -07002320 }
2321
sqiandb496412018-11-12 18:14:18 -08002322 /**
2323 * Set the subscription which will be used by default for data, with the subscription which
2324 * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied
2325 * subscription ID is not usable (check with {@link #isUsableSubscriptionId(int)}).
2326 *
2327 * @param subscriptionId the supplied subscription ID
2328 *
2329 * @hide
2330 */
2331 @SystemApi
2332 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
2333 public void setDefaultDataSubId(int subscriptionId) {
2334 if (VDBG) logd("setDataSubscription sub id = " + subscriptionId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002335 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002336 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07002337 if (iSub != null) {
sqiandb496412018-11-12 18:14:18 -08002338 iSub.setDefaultDataSubId(subscriptionId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002339 }
2340 } catch (RemoteException ex) {
Wink Savillec650e0b2014-09-02 22:37:08 -07002341 // ignore it
Wink Savillefb40dd42014-06-12 17:02:31 -07002342 }
2343 }
2344
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002345 /**
2346 * Return the SubscriptionInfo for default data subscription.
2347 *
2348 * Will return null on voice only devices, or on error.
2349 *
2350 * @return the SubscriptionInfo for the default data subscription.
2351 * @hide
2352 */
Mathew Inwooda8382062018-08-16 17:01:12 +01002353 @UnsupportedAppUsage
Wink Savilled09c4ca2014-11-22 10:08:16 -08002354 public SubscriptionInfo getDefaultDataSubscriptionInfo() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002355 return getActiveSubscriptionInfo(getDefaultDataSubscriptionId());
Wink Savillec650e0b2014-09-02 22:37:08 -07002356 }
Wink Savillefb40dd42014-06-12 17:02:31 -07002357
Wink Savillef5bca082014-09-03 15:13:33 -07002358 /** @hide */
Mathew Inwooda8382062018-08-16 17:01:12 +01002359 @UnsupportedAppUsage
Wink Savilled09c4ca2014-11-22 10:08:16 -08002360 public int getDefaultDataPhoneId() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002361 return getPhoneId(getDefaultDataSubscriptionId());
Wink Savillec650e0b2014-09-02 22:37:08 -07002362 }
2363
Wink Savillef5bca082014-09-03 15:13:33 -07002364 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -08002365 public void clearSubscriptionInfo() {
Wink Savillefb40dd42014-06-12 17:02:31 -07002366 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002367 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07002368 if (iSub != null) {
Robert Greenwalt278b8f92015-07-01 14:34:17 -07002369 iSub.clearSubInfo();
Wink Savillefb40dd42014-06-12 17:02:31 -07002370 }
2371 } catch (RemoteException ex) {
2372 // ignore it
2373 }
2374
2375 return;
2376 }
2377
Wink Savillec650e0b2014-09-02 22:37:08 -07002378 //FIXME this is vulnerable to race conditions
Wink Savillef5bca082014-09-03 15:13:33 -07002379 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -08002380 public boolean allDefaultsSelected() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002381 if (!isValidSubscriptionId(getDefaultDataSubscriptionId())) {
Wink Savillec650e0b2014-09-02 22:37:08 -07002382 return false;
2383 }
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002384 if (!isValidSubscriptionId(getDefaultSmsSubscriptionId())) {
Wink Savillec650e0b2014-09-02 22:37:08 -07002385 return false;
2386 }
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002387 if (!isValidSubscriptionId(getDefaultVoiceSubscriptionId())) {
Wink Savillec650e0b2014-09-02 22:37:08 -07002388 return false;
2389 }
2390 return true;
2391 }
2392
2393 /**
sqian0bcdd6c2018-10-30 13:55:23 -07002394 * Check if the supplied subscription ID is valid.
2395 *
2396 * <p>A valid subscription ID is not necessarily an active subscription ID
2397 * (see {@link #isActiveSubscriptionId(int)}) or an usable subscription ID
2398 * (see {@link #isUsableSubscriptionId(int)}). Unless specifically noted, subscription
2399 * APIs work with a valid subscription ID.
sqian00dae7e02018-08-30 11:53:14 -07002400 *
2401 * @param subscriptionId The subscription ID.
sqian0bcdd6c2018-10-30 13:55:23 -07002402 * @return {@code true} if the supplied subscriptionId is valid; {@code false} otherwise.
Wink Saville905bb542014-09-04 17:10:23 -07002403 */
sqian00dae7e02018-08-30 11:53:14 -07002404 public static boolean isValidSubscriptionId(int subscriptionId) {
2405 return subscriptionId > INVALID_SUBSCRIPTION_ID;
Wink Savillec650e0b2014-09-02 22:37:08 -07002406 }
2407
Wink Saville8eab2b62014-09-23 14:20:58 -07002408 /**
sqian0bcdd6c2018-10-30 13:55:23 -07002409 * Check if the supplied subscription ID is usable.
sqian798da562018-09-12 16:31:17 -07002410 *
sqian0bcdd6c2018-10-30 13:55:23 -07002411 * <p>A usable subscription ID is a valid subscription ID, but not necessarily an active
2412 * subscription ID (see {@link #isActiveSubscriptionId(int)}). Some subscription APIs
2413 * require a usable subscription ID, and this is noted in their documentation; otherwise, a
2414 * subscription ID does not need to be usable for subscription functions, only valid.
sqian798da562018-09-12 16:31:17 -07002415 *
2416 * @param subscriptionId the subscription ID
2417 * @return {@code true} if the subscription ID is usable; {@code false} otherwise.
2418 */
2419 public static boolean isUsableSubscriptionId(int subscriptionId) {
2420 return isUsableSubIdValue(subscriptionId);
2421 }
2422
2423 /**
Wink Saville8eab2b62014-09-23 14:20:58 -07002424 * @return true if subId is an usable subId value else false. A
Wink Saville98513d72014-12-08 12:44:16 -08002425 * usable subId means its neither a INVALID_SUBSCRIPTION_ID nor a DEFAULT_SUB_ID.
Wink Saville8eab2b62014-09-23 14:20:58 -07002426 * @hide
2427 */
Chen Xu4c0b06d2018-10-22 16:54:39 +00002428 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
Wink Saville63f03dd2014-10-23 10:44:45 -07002429 public static boolean isUsableSubIdValue(int subId) {
Wink Savilled09c4ca2014-11-22 10:08:16 -08002430 return subId >= MIN_SUBSCRIPTION_ID_VALUE && subId <= MAX_SUBSCRIPTION_ID_VALUE;
Wink Saville8eab2b62014-09-23 14:20:58 -07002431 }
2432
Wink Savillef5bca082014-09-03 15:13:33 -07002433 /** @hide */
Mathew Inwood45d2c252018-09-14 12:35:36 +01002434 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Sanket Padawe7e460252017-03-10 16:18:20 -08002435 public static boolean isValidSlotIndex(int slotIndex) {
Malcolm Chena43e23f2019-10-21 14:22:18 -07002436 return slotIndex >= 0 && slotIndex < TelephonyManager.getDefault().getActiveModemCount();
Wink Savillec650e0b2014-09-02 22:37:08 -07002437 }
2438
Wink Savillef5bca082014-09-03 15:13:33 -07002439 /** @hide */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +00002440 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Wink Savillec650e0b2014-09-02 22:37:08 -07002441 public static boolean isValidPhoneId(int phoneId) {
Malcolm Chena43e23f2019-10-21 14:22:18 -07002442 return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getActiveModemCount();
Malcolm Chenf87292f2019-09-23 14:06:19 -07002443 }
2444
Wink Savillef5bca082014-09-03 15:13:33 -07002445 /** @hide */
Chen Xu4c0b06d2018-10-22 16:54:39 +00002446 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
Wink Savillefb40dd42014-06-12 17:02:31 -07002447 public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId) {
Wink Saville63f03dd2014-10-23 10:44:45 -07002448 int[] subIds = SubscriptionManager.getSubId(phoneId);
Wink Savillec650e0b2014-09-02 22:37:08 -07002449 if (subIds != null && subIds.length > 0) {
2450 putPhoneIdAndSubIdExtra(intent, phoneId, subIds[0]);
Wink Savillefb40dd42014-06-12 17:02:31 -07002451 } else {
2452 logd("putPhoneIdAndSubIdExtra: no valid subs");
Amit Mahajanba71c5f2019-02-07 12:29:55 -08002453 intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
Daniel Bright71d3dac2020-01-15 12:10:53 -08002454 intent.putExtra(EXTRA_SLOT_INDEX, phoneId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002455 }
2456 }
Wink Savilleeeacf932014-06-18 01:07:10 -07002457
Wink Savillef5bca082014-09-03 15:13:33 -07002458 /** @hide */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +00002459 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Wink Saville63f03dd2014-10-23 10:44:45 -07002460 public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId, int subId) {
Wink Savilleeeacf932014-06-18 01:07:10 -07002461 if (VDBG) logd("putPhoneIdAndSubIdExtra: phoneId=" + phoneId + " subId=" + subId);
Jack Yud8104ec2019-09-18 09:31:28 -07002462 intent.putExtra(EXTRA_SLOT_INDEX, phoneId);
Wink Savillec650e0b2014-09-02 22:37:08 -07002463 intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
Daniel Bright0b5d2852020-01-09 21:58:16 -08002464 putSubscriptionIdExtra(intent, subId);
Wink Savillec650e0b2014-09-02 22:37:08 -07002465 }
2466
2467 /**
Peter Wang01d128c2019-12-17 19:11:23 -08002468 * Get visible subscription Id(s) of the currently active SIM(s).
Hunter Knepshieldb26cbbd2019-07-03 14:22:32 -07002469 *
Wink Saville8a38a202014-09-03 12:22:54 -07002470 * @return the list of subId's that are active,
Peter Wang01d128c2019-12-17 19:11:23 -08002471 * is never null but the length may be 0.
Wink Savillef5bca082014-09-03 15:13:33 -07002472 * @hide
Wink Savillec650e0b2014-09-02 22:37:08 -07002473 */
Peter Wang01d128c2019-12-17 19:11:23 -08002474 @SystemApi
Peter Wangc061cdf2020-03-16 04:45:23 -07002475 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
Jeff Sharkey32566012014-12-02 18:30:14 -08002476 public @NonNull int[] getActiveSubscriptionIdList() {
Hunter Knepshieldb26cbbd2019-07-03 14:22:32 -07002477 return getActiveSubscriptionIdList(/* visibleOnly */ true);
2478 }
Wink Savillec650e0b2014-09-02 22:37:08 -07002479
Hunter Knepshieldb26cbbd2019-07-03 14:22:32 -07002480 /**
Peter Wang01d128c2019-12-17 19:11:23 -08002481 * Get both hidden and visible subscription Id(s) of the currently active SIM(s).
Hunter Knepshieldb26cbbd2019-07-03 14:22:32 -07002482 *
Peter Wang01d128c2019-12-17 19:11:23 -08002483 * Hidden subscriptions refer to those are not meant visible to the users.
2484 * For example, an opportunistic subscription that is grouped with other
2485 * subscriptions should remain invisible to users as they are only functionally
2486 * supplementary to primary ones.
2487 *
2488 * @return the list of subId's that are active,
2489 * is never null but the length may be 0.
2490 * @hide
2491 */
2492 @SystemApi
Peter Wangc061cdf2020-03-16 04:45:23 -07002493 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
2494 public @NonNull int[] getCompleteActiveSubscriptionIdList() {
Peter Wang01d128c2019-12-17 19:11:23 -08002495 return getActiveSubscriptionIdList(/* visibleOnly */false);
2496 }
2497
2498 /**
Hunter Knepshieldb26cbbd2019-07-03 14:22:32 -07002499 * @return a non-null list of subId's that are active.
2500 *
2501 * @hide
2502 */
2503 public @NonNull int[] getActiveSubscriptionIdList(boolean visibleOnly) {
Wink Savillec650e0b2014-09-02 22:37:08 -07002504 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002505 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillec650e0b2014-09-02 22:37:08 -07002506 if (iSub != null) {
Hunter Knepshieldb26cbbd2019-07-03 14:22:32 -07002507 int[] subId = iSub.getActiveSubIdList(visibleOnly);
2508 if (subId != null) return subId;
Wink Savillec650e0b2014-09-02 22:37:08 -07002509 }
2510 } catch (RemoteException ex) {
2511 // ignore it
2512 }
2513
Hunter Knepshieldb26cbbd2019-07-03 14:22:32 -07002514 return new int[0];
Wink Savilleeeacf932014-06-18 01:07:10 -07002515 }
Wink Savilled09c4ca2014-11-22 10:08:16 -08002516
2517 /**
2518 * Returns true if the device is considered roaming on the current
2519 * network for a subscription.
2520 * <p>
2521 * Availability: Only when user registered to a network.
2522 *
2523 * @param subId The subscription ID
2524 * @return true if the network for the subscription is roaming, false otherwise
2525 */
2526 public boolean isNetworkRoaming(int subId) {
2527 final int phoneId = getPhoneId(subId);
2528 if (phoneId < 0) {
2529 // What else can we do?
2530 return false;
2531 }
Legler Wu85973dc2015-01-29 15:07:39 +08002532 return TelephonyManager.getDefault().isNetworkRoaming(subId);
Wink Savilled09c4ca2014-11-22 10:08:16 -08002533 }
Wink Saville47920fa2014-12-02 17:08:14 -08002534
2535 /**
Sanket Padawe7e460252017-03-10 16:18:20 -08002536 * Returns a constant indicating the state of sim for the slot index.
Wink Saville47920fa2014-12-02 17:08:14 -08002537 *
Sanket Padawe7e460252017-03-10 16:18:20 -08002538 * @param slotIndex
Wink Saville47920fa2014-12-02 17:08:14 -08002539 *
2540 * {@See TelephonyManager#SIM_STATE_UNKNOWN}
2541 * {@See TelephonyManager#SIM_STATE_ABSENT}
2542 * {@See TelephonyManager#SIM_STATE_PIN_REQUIRED}
2543 * {@See TelephonyManager#SIM_STATE_PUK_REQUIRED}
2544 * {@See TelephonyManager#SIM_STATE_NETWORK_LOCKED}
2545 * {@See TelephonyManager#SIM_STATE_READY}
2546 * {@See TelephonyManager#SIM_STATE_NOT_READY}
2547 * {@See TelephonyManager#SIM_STATE_PERM_DISABLED}
2548 * {@See TelephonyManager#SIM_STATE_CARD_IO_ERROR}
2549 *
2550 * {@hide}
2551 */
Sanket Padawe7e460252017-03-10 16:18:20 -08002552 public static int getSimStateForSlotIndex(int slotIndex) {
Sanket Padawe330dcac2015-06-18 12:08:01 -07002553 int simState = TelephonyManager.SIM_STATE_UNKNOWN;
Wink Saville47920fa2014-12-02 17:08:14 -08002554
2555 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002556 ISub iSub = TelephonyManager.getSubscriptionService();
Sanket Padawe330dcac2015-06-18 12:08:01 -07002557 if (iSub != null) {
Sanket Padawe7e460252017-03-10 16:18:20 -08002558 simState = iSub.getSimStateForSlotIndex(slotIndex);
Sanket Padawe330dcac2015-06-18 12:08:01 -07002559 }
Wink Saville47920fa2014-12-02 17:08:14 -08002560 } catch (RemoteException ex) {
Wink Saville47920fa2014-12-02 17:08:14 -08002561 }
Jack Yud2cf0ce2015-12-30 12:06:01 -08002562
Wink Saville47920fa2014-12-02 17:08:14 -08002563 return simState;
2564 }
Shishir Agrawal0ced7922014-12-10 10:20:39 -08002565
2566 /**
Sanket Padawedc493092015-07-14 14:21:43 -07002567 * Store properties associated with SubscriptionInfo in database
2568 * @param subId Subscription Id of Subscription
2569 * @param propKey Column name in database associated with SubscriptionInfo
2570 * @param propValue Value to store in DB for particular subId & column name
2571 * @hide
2572 */
2573 public static void setSubscriptionProperty(int subId, String propKey, String propValue) {
2574 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002575 ISub iSub = TelephonyManager.getSubscriptionService();
Sanket Padawedc493092015-07-14 14:21:43 -07002576 if (iSub != null) {
2577 iSub.setSubscriptionProperty(subId, propKey, propValue);
2578 }
2579 } catch (RemoteException ex) {
2580 // ignore it
2581 }
2582 }
2583
2584 /**
Grace Jia2bd23cf2021-03-18 14:47:31 -07002585 * Serialize list of contacts uri to string
2586 * @hide
2587 */
2588 public static String serializeUriLists(List<Uri> uris) {
2589 List<String> contacts = new ArrayList<>();
2590 for (Uri uri : uris) {
2591 contacts.add(uri.toString());
2592 }
2593 try {
2594 ByteArrayOutputStream bos = new ByteArrayOutputStream();
2595 ObjectOutputStream oos = new ObjectOutputStream(bos);
2596 oos.writeObject(contacts);
2597 oos.flush();
2598 return Base64.encodeToString(bos.toByteArray(), Base64.DEFAULT);
2599 } catch (IOException e) {
2600 logd("serializeUriLists IO exception");
2601 }
2602 return "";
2603 }
2604
2605 /**
2606 * Return list of contacts uri corresponding to query result.
2607 * @param subId Subscription Id of Subscription
2608 * @param propKey Column name in SubscriptionInfo database
2609 * @return list of contacts uri to be returned
2610 * @hide
2611 */
2612 private static List<Uri> getContactsFromSubscriptionProperty(int subId, String propKey,
2613 Context context) {
2614 String result = getSubscriptionProperty(subId, propKey, context);
2615 if (result != null) {
2616 try {
2617 byte[] b = Base64.decode(result, Base64.DEFAULT);
2618 ByteArrayInputStream bis = new ByteArrayInputStream(b);
2619 ObjectInputStream ois = new ObjectInputStream(bis);
2620 List<String> contacts = ArrayList.class.cast(ois.readObject());
2621 List<Uri> uris = new ArrayList<>();
2622 for (String contact : contacts) {
2623 uris.add(Uri.parse(contact));
2624 }
2625 return uris;
2626 } catch (IOException e) {
2627 logd("getContactsFromSubscriptionProperty IO exception");
2628 } catch (ClassNotFoundException e) {
2629 logd("getContactsFromSubscriptionProperty ClassNotFound exception");
2630 }
2631 }
2632 return new ArrayList<>();
2633 }
2634
2635 /**
Sanket Padawedc493092015-07-14 14:21:43 -07002636 * Store properties associated with SubscriptionInfo in database
2637 * @param subId Subscription Id of Subscription
2638 * @param propKey Column name in SubscriptionInfo database
2639 * @return Value associated with subId and propKey column in database
2640 * @hide
2641 */
2642 private static String getSubscriptionProperty(int subId, String propKey,
2643 Context context) {
2644 String resultValue = null;
2645 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002646 ISub iSub = TelephonyManager.getSubscriptionService();
Sanket Padawedc493092015-07-14 14:21:43 -07002647 if (iSub != null) {
Rajeev Kumarc8ac4f3b2017-07-26 15:59:08 -07002648 resultValue = iSub.getSubscriptionProperty(subId, propKey,
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08002649 context.getOpPackageName(), context.getAttributionTag());
Sanket Padawedc493092015-07-14 14:21:43 -07002650 }
2651 } catch (RemoteException ex) {
2652 // ignore it
2653 }
2654 return resultValue;
2655 }
2656
2657 /**
2658 * Returns boolean value corresponding to query result.
2659 * @param subId Subscription Id of Subscription
2660 * @param propKey Column name in SubscriptionInfo database
2661 * @param defValue Default boolean value to be returned
2662 * @return boolean result value to be returned
2663 * @hide
2664 */
2665 public static boolean getBooleanSubscriptionProperty(int subId, String propKey,
2666 boolean defValue, Context context) {
2667 String result = getSubscriptionProperty(subId, propKey, context);
2668 if (result != null) {
2669 try {
2670 return Integer.parseInt(result) == 1;
2671 } catch (NumberFormatException err) {
2672 logd("getBooleanSubscriptionProperty NumberFormat exception");
2673 }
2674 }
2675 return defValue;
2676 }
2677
2678 /**
2679 * Returns integer value corresponding to query result.
2680 * @param subId Subscription Id of Subscription
2681 * @param propKey Column name in SubscriptionInfo database
2682 * @param defValue Default integer value to be returned
2683 * @return integer result value to be returned
2684 * @hide
2685 */
2686 public static int getIntegerSubscriptionProperty(int subId, String propKey, int defValue,
2687 Context context) {
2688 String result = getSubscriptionProperty(subId, propKey, context);
2689 if (result != null) {
2690 try {
2691 return Integer.parseInt(result);
2692 } catch (NumberFormatException err) {
calvinpand77e0bd2020-01-14 20:37:31 +08002693 logd("getIntegerSubscriptionProperty NumberFormat exception");
2694 }
2695 }
2696 return defValue;
2697 }
2698
2699 /**
2700 * Returns long value corresponding to query result.
2701 * @param subId Subscription Id of Subscription
2702 * @param propKey Column name in SubscriptionInfo database
2703 * @param defValue Default long value to be returned
2704 * @return long result value to be returned
2705 * @hide
2706 */
2707 public static long getLongSubscriptionProperty(int subId, String propKey, long defValue,
2708 Context context) {
2709 String result = getSubscriptionProperty(subId, propKey, context);
2710 if (result != null) {
2711 try {
2712 return Long.parseLong(result);
2713 } catch (NumberFormatException err) {
2714 logd("getLongSubscriptionProperty NumberFormat exception");
Sanket Padawedc493092015-07-14 14:21:43 -07002715 }
2716 }
2717 return defValue;
2718 }
2719
2720 /**
Jordan Liue4141f02019-08-16 14:07:03 -07002721 * Returns the {@link Resources} from the given {@link Context} for the MCC/MNC associated with
2722 * the subscription. If the subscription ID is invalid, the base resources are returned instead.
2723 *
2724 * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
2725 *
Sanket Padawedc493092015-07-14 14:21:43 -07002726 * @param context Context object
Jordan Liue4141f02019-08-16 14:07:03 -07002727 * @param subId Subscription Id of Subscription whose resources are required
Sanket Padawedc493092015-07-14 14:21:43 -07002728 * @return Resources associated with Subscription.
2729 * @hide
2730 */
Jordan Liue4141f02019-08-16 14:07:03 -07002731 @NonNull
2732 @SystemApi
2733 public static Resources getResourcesForSubId(@NonNull Context context, int subId) {
Torbjorn Eklund99c11d82018-08-21 16:06:47 +02002734 return getResourcesForSubId(context, subId, false);
2735 }
2736
2737 /**
2738 * Returns the resources associated with Subscription.
2739 * @param context Context object
2740 * @param subId Subscription Id of Subscription who's resources are required
2741 * @param useRootLocale if root locale should be used. Localized locale is used if false.
2742 * @return Resources associated with Subscription.
2743 * @hide
2744 */
Torbjorn Eklundf8899f02019-11-20 10:59:59 +01002745 @NonNull
Torbjorn Eklund99c11d82018-08-21 16:06:47 +02002746 public static Resources getResourcesForSubId(Context context, int subId,
2747 boolean useRootLocale) {
Torbjorn Eklundf8899f02019-11-20 10:59:59 +01002748 // Check if resources for this context and subId already exist in the resource cache.
2749 // Resources that use the root locale are not cached.
2750 Pair<Context, Integer> cacheKey = null;
2751 if (isValidSubscriptionId(subId) && !useRootLocale) {
2752 cacheKey = Pair.create(context, subId);
2753 if (sResourcesCache.containsKey(cacheKey)) {
2754 // Cache hit. Use cached Resources.
2755 return sResourcesCache.get(cacheKey);
2756 }
2757 }
2758
Sanket Padawedc493092015-07-14 14:21:43 -07002759 final SubscriptionInfo subInfo =
2760 SubscriptionManager.from(context).getActiveSubscriptionInfo(subId);
2761
Jordan Liu0e161082020-01-21 10:55:08 -08002762 Configuration overrideConfig = new Configuration();
Sanket Padawedc493092015-07-14 14:21:43 -07002763 if (subInfo != null) {
Jordan Liu0e161082020-01-21 10:55:08 -08002764 overrideConfig.mcc = subInfo.getMcc();
2765 overrideConfig.mnc = subInfo.getMnc();
Willy Hu138b89d2021-03-22 11:36:54 +08002766 if (overrideConfig.mnc == 0) {
2767 overrideConfig.mnc = Configuration.MNC_ZERO;
2768 cacheKey = null;
2769 }
Sanket Padawedc493092015-07-14 14:21:43 -07002770 }
Torbjorn Eklund99c11d82018-08-21 16:06:47 +02002771
2772 if (useRootLocale) {
Jordan Liu0e161082020-01-21 10:55:08 -08002773 overrideConfig.setLocale(Locale.ROOT);
Torbjorn Eklund99c11d82018-08-21 16:06:47 +02002774 }
2775
Jordan Liu0e161082020-01-21 10:55:08 -08002776 // Create new context with new configuration so that we can avoid modifying the passed in
2777 // context.
2778 // Note that if the original context configuration changes, the resources here will also
2779 // change for all values except those overridden by newConfig (e.g. if the device has an
2780 // orientation change).
2781 Context newContext = context.createConfigurationContext(overrideConfig);
2782 Resources res = newContext.getResources();
Torbjorn Eklundf8899f02019-11-20 10:59:59 +01002783
2784 if (cacheKey != null) {
2785 // Save the newly created Resources in the resource cache.
2786 sResourcesCache.put(cacheKey, res);
2787 }
2788 return res;
Sanket Padawedc493092015-07-14 14:21:43 -07002789 }
2790
2791 /**
sqian0bcdd6c2018-10-30 13:55:23 -07002792 * Checks if the supplied subscription ID corresponds to a subscription which is actively in
2793 * use on the device. An active subscription ID is a valid and usable subscription ID.
sqianec149462018-09-10 19:05:51 -07002794 *
2795 * @param subscriptionId the subscription ID.
2796 * @return {@code true} if the supplied subscription ID corresponds to an active subscription;
2797 * {@code false} if it does not correspond to an active subscription; or throw a
2798 * SecurityException if the caller hasn't got the right permission.
2799 */
2800 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
2801 public boolean isActiveSubscriptionId(int subscriptionId) {
2802 return isActiveSubId(subscriptionId);
2803 }
2804
2805 /**
Shishir Agrawal0ced7922014-12-10 10:20:39 -08002806 * @return true if the sub ID is active. i.e. The sub ID corresponds to a known subscription
2807 * and the SIM providing the subscription is present in a slot and in "LOADED" state.
2808 * @hide
2809 */
Mathew Inwooda8382062018-08-16 17:01:12 +01002810 @UnsupportedAppUsage
Shishir Agrawal0ced7922014-12-10 10:20:39 -08002811 public boolean isActiveSubId(int subId) {
2812 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002813 ISub iSub = TelephonyManager.getSubscriptionService();
Sanket Padawe330dcac2015-06-18 12:08:01 -07002814 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08002815 return iSub.isActiveSubId(subId, mContext.getOpPackageName(),
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08002816 mContext.getAttributionTag());
Sanket Padawe330dcac2015-06-18 12:08:01 -07002817 }
Shishir Agrawal0ced7922014-12-10 10:20:39 -08002818 } catch (RemoteException ex) {
2819 }
2820 return false;
2821 }
Jeff Sharkey53313d72017-07-13 16:47:32 -06002822
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002823 /**
2824 * Get the description of the billing relationship plan between a carrier
2825 * and a specific subscriber.
2826 * <p>
2827 * This method is only accessible to the following narrow set of apps:
2828 * <ul>
2829 * <li>The carrier app for this subscriberId, as determined by
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07002830 * {@link TelephonyManager#hasCarrierPrivileges()}.
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002831 * <li>The carrier app explicitly delegated access through
2832 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2833 * </ul>
2834 *
2835 * @param subId the subscriber this relationship applies to
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06002836 * @throws SecurityException if the caller doesn't meet the requirements
2837 * outlined above.
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002838 */
Jeff Sharkey53313d72017-07-13 16:47:32 -06002839 public @NonNull List<SubscriptionPlan> getSubscriptionPlans(int subId) {
Aaron Huang21089442020-01-16 23:31:02 +08002840 SubscriptionPlan[] subscriptionPlans =
2841 getNetworkPolicyManager().getSubscriptionPlans(subId, mContext.getOpPackageName());
2842 return subscriptionPlans == null
2843 ? Collections.emptyList() : Arrays.asList(subscriptionPlans);
Jeff Sharkey53313d72017-07-13 16:47:32 -06002844 }
2845
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002846 /**
2847 * Set the description of the billing relationship plan between a carrier
2848 * and a specific subscriber.
2849 * <p>
2850 * This method is only accessible to the following narrow set of apps:
2851 * <ul>
2852 * <li>The carrier app for this subscriberId, as determined by
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07002853 * {@link TelephonyManager#hasCarrierPrivileges()}.
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002854 * <li>The carrier app explicitly delegated access through
2855 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2856 * </ul>
2857 *
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06002858 * @param subId the subscriber this relationship applies to. An empty list
2859 * may be sent to clear any existing plans.
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002860 * @param plans the list of plans. The first plan is always the primary and
2861 * most important plan. Any additional plans are secondary and
2862 * may not be displayed or used by decision making logic.
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06002863 * @throws SecurityException if the caller doesn't meet the requirements
2864 * outlined above.
Sarah Chin80b73b92019-09-26 11:37:13 -07002865 * @throws IllegalArgumentException if plans don't meet the requirements
Sarah Chinc9e48d92019-10-29 15:30:24 -07002866 * defined in {@link SubscriptionPlan}.
Sarah Chine6f17fe2022-01-31 19:10:14 -08002867 * @deprecated use {@link #setSubscriptionPlans(int, List, long)} instead.
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002868 */
Sarah Chine6f17fe2022-01-31 19:10:14 -08002869 @Deprecated
Jeff Sharkey53313d72017-07-13 16:47:32 -06002870 public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans) {
Sarah Chine6f17fe2022-01-31 19:10:14 -08002871 setSubscriptionPlans(subId, plans, 0);
2872 }
2873
2874 /**
2875 * Set the description of the billing relationship plan between a carrier
2876 * and a specific subscriber.
2877 * <p>
2878 * This method is only accessible to the following narrow set of apps:
2879 * <ul>
2880 * <li>The carrier app for this subscriberId, as determined by
2881 * {@link TelephonyManager#hasCarrierPrivileges()}.
2882 * <li>The carrier app explicitly delegated access through
2883 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2884 * </ul>
2885 *
2886 * @param subId the subscriber this relationship applies to. An empty list
2887 * may be sent to clear any existing plans.
2888 * @param plans the list of plans. The first plan is always the primary and
2889 * most important plan. Any additional plans are secondary and
2890 * may not be displayed or used by decision making logic.
2891 * @param expirationDurationMillis the duration after which the subscription plans
2892 * will be automatically cleared, or {@code 0} to leave the plans until
2893 * explicitly cleared, or the next reboot, whichever happens first.
2894 * @throws SecurityException if the caller doesn't meet the requirements
2895 * outlined above.
2896 * @throws IllegalArgumentException if plans don't meet the requirements
2897 * defined in {@link SubscriptionPlan}.
2898 */
2899 public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans,
2900 @DurationMillisLong long expirationDurationMillis) {
Aaron Huang21089442020-01-16 23:31:02 +08002901 getNetworkPolicyManager().setSubscriptionPlans(subId,
Sarah Chine6f17fe2022-01-31 19:10:14 -08002902 plans.toArray(new SubscriptionPlan[0]), expirationDurationMillis,
2903 mContext.getOpPackageName());
Jeff Sharkey53313d72017-07-13 16:47:32 -06002904 }
Jeff Sharkey717f52f2018-01-04 16:04:11 -07002905
Jeff Sharkey717f52f2018-01-04 16:04:11 -07002906 /**
Jeff Sharkey9252b342018-01-19 07:58:35 +09002907 * Temporarily override the billing relationship plan between a carrier and
2908 * a specific subscriber to be considered unmetered. This will be reflected
2909 * to apps via {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED}.
2910 * <p>
2911 * This method is only accessible to the following narrow set of apps:
2912 * <ul>
2913 * <li>The carrier app for this subscriberId, as determined by
2914 * {@link TelephonyManager#hasCarrierPrivileges()}.
2915 * <li>The carrier app explicitly delegated access through
2916 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2917 * </ul>
2918 *
2919 * @param subId the subscriber this override applies to.
2920 * @param overrideUnmetered set if the billing relationship should be
2921 * considered unmetered.
Sarah Chine6f17fe2022-01-31 19:10:14 -08002922 * @param expirationDurationMillis the duration after which the requested override
2923 * will be automatically cleared, or {@code 0} to leave in the
Jeff Sharkey9252b342018-01-19 07:58:35 +09002924 * requested state until explicitly cleared, or the next reboot,
2925 * whichever happens first.
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06002926 * @throws SecurityException if the caller doesn't meet the requirements
Sarah Chinb321fb52021-01-07 16:40:16 -08002927 * outlined above.
Jeff Sharkey9252b342018-01-19 07:58:35 +09002928 */
Jeff Sharkey9252b342018-01-19 07:58:35 +09002929 public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered,
Sarah Chine6f17fe2022-01-31 19:10:14 -08002930 @DurationMillisLong long expirationDurationMillis) {
Sarah Chinb321fb52021-01-07 16:40:16 -08002931 setSubscriptionOverrideUnmetered(subId, overrideUnmetered,
Sarah Chine6f17fe2022-01-31 19:10:14 -08002932 TelephonyManager.getAllNetworkTypes(), expirationDurationMillis);
Sarah Chinb321fb52021-01-07 16:40:16 -08002933 }
Aaron Huang21089442020-01-16 23:31:02 +08002934
Sarah Chinb321fb52021-01-07 16:40:16 -08002935 /**
2936 * Temporarily override the billing relationship plan between a carrier and
2937 * a specific subscriber to be considered unmetered. This will be reflected
2938 * to apps via {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED}.
2939 * <p>
2940 * This method is only accessible to the following narrow set of apps:
2941 * <ul>
2942 * <li>The carrier app for this subscriberId, as determined by
2943 * {@link TelephonyManager#hasCarrierPrivileges()}.
2944 * <li>The carrier app explicitly delegated access through
2945 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2946 * </ul>
2947 *
2948 * @param subId the subscriber this override applies to.
2949 * @param overrideUnmetered set if the billing relationship should be
2950 * considered unmetered.
Sarah Chinf7e9c832021-04-15 19:40:25 -07002951 * @param networkTypes the network types this override applies to. If no
2952 * network types are specified, override values will be ignored.
Sarah Chinb321fb52021-01-07 16:40:16 -08002953 * {@see TelephonyManager#getAllNetworkTypes()}
Sarah Chine6f17fe2022-01-31 19:10:14 -08002954 * @param expirationDurationMillis the duration after which the requested override
2955 * will be automatically cleared, or {@code 0} to leave in the
Sarah Chinb321fb52021-01-07 16:40:16 -08002956 * requested state until explicitly cleared, or the next reboot,
2957 * whichever happens first.
2958 * @throws SecurityException if the caller doesn't meet the requirements
2959 * outlined above.
2960 */
2961 public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered,
2962 @NonNull @Annotation.NetworkType int[] networkTypes,
Sarah Chine6f17fe2022-01-31 19:10:14 -08002963 @DurationMillisLong long expirationDurationMillis) {
Aaron Huang21089442020-01-16 23:31:02 +08002964 final int overrideValue = overrideUnmetered ? SUBSCRIPTION_OVERRIDE_UNMETERED : 0;
2965 getNetworkPolicyManager().setSubscriptionOverride(subId, SUBSCRIPTION_OVERRIDE_UNMETERED,
Sarah Chine6f17fe2022-01-31 19:10:14 -08002966 overrideValue, networkTypes, expirationDurationMillis, mContext.getOpPackageName());
Jeff Sharkey9252b342018-01-19 07:58:35 +09002967 }
2968
2969 /**
2970 * Temporarily override the billing relationship plan between a carrier and
2971 * a specific subscriber to be considered congested. This will cause the
2972 * device to delay certain network requests when possible, such as developer
2973 * jobs that are willing to run in a flexible time window.
2974 * <p>
2975 * This method is only accessible to the following narrow set of apps:
2976 * <ul>
2977 * <li>The carrier app for this subscriberId, as determined by
2978 * {@link TelephonyManager#hasCarrierPrivileges()}.
2979 * <li>The carrier app explicitly delegated access through
2980 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2981 * </ul>
2982 *
2983 * @param subId the subscriber this override applies to.
2984 * @param overrideCongested set if the subscription should be considered
2985 * congested.
Sarah Chine6f17fe2022-01-31 19:10:14 -08002986 * @param expirationDurationMillis the duration after which the requested override
2987 * will be automatically cleared, or {@code 0} to leave in the
Jeff Sharkey9252b342018-01-19 07:58:35 +09002988 * requested state until explicitly cleared, or the next reboot,
2989 * whichever happens first.
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06002990 * @throws SecurityException if the caller doesn't meet the requirements
Sarah Chinb321fb52021-01-07 16:40:16 -08002991 * outlined above.
Jeff Sharkey9252b342018-01-19 07:58:35 +09002992 */
Jeff Sharkey9252b342018-01-19 07:58:35 +09002993 public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested,
Sarah Chine6f17fe2022-01-31 19:10:14 -08002994 @DurationMillisLong long expirationDurationMillis) {
Sarah Chinb321fb52021-01-07 16:40:16 -08002995 setSubscriptionOverrideCongested(subId, overrideCongested,
Sarah Chine6f17fe2022-01-31 19:10:14 -08002996 TelephonyManager.getAllNetworkTypes(), expirationDurationMillis);
Sarah Chinb321fb52021-01-07 16:40:16 -08002997 }
2998
2999 /**
3000 * Temporarily override the billing relationship plan between a carrier and
3001 * a specific subscriber to be considered congested. This will cause the
3002 * device to delay certain network requests when possible, such as developer
3003 * jobs that are willing to run in a flexible time window.
3004 * <p>
3005 * This method is only accessible to the following narrow set of apps:
3006 * <ul>
3007 * <li>The carrier app for this subscriberId, as determined by
3008 * {@link TelephonyManager#hasCarrierPrivileges()}.
3009 * <li>The carrier app explicitly delegated access through
3010 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
3011 * </ul>
3012 *
3013 * @param subId the subscriber this override applies to.
3014 * @param overrideCongested set if the subscription should be considered
3015 * congested.
Sarah Chinf7e9c832021-04-15 19:40:25 -07003016 * @param networkTypes the network types this override applies to. If no
3017 * network types are specified, override values will be ignored.
Sarah Chinb321fb52021-01-07 16:40:16 -08003018 * {@see TelephonyManager#getAllNetworkTypes()}
Sarah Chine6f17fe2022-01-31 19:10:14 -08003019 * @param expirationDurationMillis the duration after which the requested override
3020 * will be automatically cleared, or {@code 0} to leave in the
Sarah Chinb321fb52021-01-07 16:40:16 -08003021 * requested state until explicitly cleared, or the next reboot,
3022 * whichever happens first.
3023 * @throws SecurityException if the caller doesn't meet the requirements
3024 * outlined above.
3025 */
3026 public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested,
3027 @NonNull @Annotation.NetworkType int[] networkTypes,
Sarah Chine6f17fe2022-01-31 19:10:14 -08003028 @DurationMillisLong long expirationDurationMillis) {
Aaron Huang21089442020-01-16 23:31:02 +08003029 final int overrideValue = overrideCongested ? SUBSCRIPTION_OVERRIDE_CONGESTED : 0;
3030 getNetworkPolicyManager().setSubscriptionOverride(subId, SUBSCRIPTION_OVERRIDE_CONGESTED,
Sarah Chine6f17fe2022-01-31 19:10:14 -08003031 overrideValue, networkTypes, expirationDurationMillis, mContext.getOpPackageName());
Jeff Sharkey9252b342018-01-19 07:58:35 +09003032 }
3033
3034 /**
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003035 * Checks whether the app with the given context is authorized to manage the given subscription
Malcolm Chen2619a9b2019-12-26 13:17:34 -08003036 * according to its metadata.
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003037 *
Sarah Chin172f15e2021-02-23 12:21:24 -08003038 * Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded} returns
3039 * true). To check for permissions for non-embedded subscription as well,
3040 * {@see android.telephony.TelephonyManager#hasCarrierPrivileges}.
3041 *
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003042 * @param info The subscription to check.
3043 * @return whether the app is authorized to manage this subscription per its metadata.
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003044 */
3045 public boolean canManageSubscription(SubscriptionInfo info) {
3046 return canManageSubscription(info, mContext.getPackageName());
3047 }
3048
3049 /**
Holly Jiuyu Sun59159c42018-03-15 18:06:42 -07003050 * Checks whether the given app is authorized to manage the given subscription. An app can only
3051 * be authorized if it is included in the {@link android.telephony.UiccAccessRule} of the
3052 * {@link android.telephony.SubscriptionInfo} with the access status.
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003053 *
Sarah Chin172f15e2021-02-23 12:21:24 -08003054 * Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded} returns
3055 * true). To check for permissions for non-embedded subscription as well,
3056 * {@see android.telephony.TelephonyManager#hasCarrierPrivileges}.
3057 *
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003058 * @param info The subscription to check.
3059 * @param packageName Package name of the app to check.
Holly Jiuyu Sun59159c42018-03-15 18:06:42 -07003060 * @return whether the app is authorized to manage this subscription per its access rules.
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003061 * @hide
3062 */
Malcolm Chen2619a9b2019-12-26 13:17:34 -08003063 @SystemApi
Malcolm Chen05d1ed12020-02-25 17:50:05 -08003064 public boolean canManageSubscription(@NonNull SubscriptionInfo info,
3065 @NonNull String packageName) {
Malcolm Chen2619a9b2019-12-26 13:17:34 -08003066 if (info == null || info.getAllAccessRules() == null || packageName == null) {
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003067 return false;
3068 }
3069 PackageManager packageManager = mContext.getPackageManager();
3070 PackageInfo packageInfo;
3071 try {
Cheonho Park51586d52019-07-31 14:19:41 +09003072 packageInfo = packageManager.getPackageInfo(packageName,
3073 PackageManager.GET_SIGNING_CERTIFICATES);
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003074 } catch (PackageManager.NameNotFoundException e) {
Nazanin Bakhshi293ecad2019-08-29 16:19:12 -07003075 logd("Unknown package: " + packageName);
3076 return false;
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003077 }
Nazanin Bakhshi693cec22019-08-02 16:43:44 -07003078 for (UiccAccessRule rule : info.getAllAccessRules()) {
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003079 if (rule.getCarrierPrivilegeStatus(packageInfo)
3080 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
3081 return true;
3082 }
3083 }
3084 return false;
3085 }
Malcolm Chenbd4ae762018-08-03 17:24:07 -07003086
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003087 /**
Malcolm Chen009f0a92018-10-22 20:03:46 -07003088 * Set which subscription is preferred for cellular data.
3089 * It's also usually the subscription we set up internet connection on.
Malcolm Chen8cf1b782018-09-24 20:00:08 -07003090 *
3091 * PreferredData overwrites user setting of default data subscription. And it's used
Malcolm Chen009f0a92018-10-22 20:03:46 -07003092 * by AlternativeNetworkService or carrier apps to switch primary and CBRS
Malcolm Chenc1873af2018-09-24 20:01:32 -07003093 * subscription dynamically in multi-SIM devices.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003094 *
Malcolm Chen009f0a92018-10-22 20:03:46 -07003095 * @param subId which subscription is preferred to for cellular data. If it's
Malcolm Chen003c8e52018-11-12 20:13:29 -08003096 * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}, it means
Malcolm Chen009f0a92018-10-22 20:03:46 -07003097 * it's unset and {@link SubscriptionManager#getDefaultDataSubscriptionId()}
3098 * is used to determine which modem is preferred.
Malcolm Chenfe577d32019-03-18 17:26:43 -07003099 * @param needValidation whether Telephony will wait until the network is validated by
3100 * connectivity service before switching data to it. More details see
3101 * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED}.
Malcolm Chenfd11df22019-02-05 17:19:48 -08003102 * @param executor The executor of where the callback will execute.
3103 * @param callback Callback will be triggered once it succeeds or failed.
Malcolm Chen9ee14732019-03-29 18:30:23 -07003104 * Pass null if don't care about the result.
Malcolm Chenfd11df22019-02-05 17:19:48 -08003105 *
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003106 * @hide
3107 *
3108 */
Malcolm Chenfd11df22019-02-05 17:19:48 -08003109 @SystemApi
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003110 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
Malcolm Chenfd11df22019-02-05 17:19:48 -08003111 public void setPreferredDataSubscriptionId(int subId, boolean needValidation,
Malcolm Chen9ee14732019-03-29 18:30:23 -07003112 @Nullable @CallbackExecutor Executor executor, @Nullable
3113 @TelephonyManager.SetOpportunisticSubscriptionResult Consumer<Integer> callback) {
Nazanin Bakhshie0215a72019-01-04 17:38:36 -08003114 if (VDBG) logd("[setPreferredDataSubscriptionId]+ subId:" + subId);
Malcolm Chend78dac02019-01-24 16:33:51 -08003115 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003116 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chenfd11df22019-02-05 17:19:48 -08003117 if (iSub == null) return;
3118
3119 ISetOpportunisticDataCallback callbackStub = new ISetOpportunisticDataCallback.Stub() {
3120 @Override
3121 public void onComplete(int result) {
Sooraj Sasindran3b09d712019-02-28 14:46:14 -08003122 if (executor == null || callback == null) {
3123 return;
3124 }
Sooraj Sasindrane6a2c0a2019-11-26 13:56:49 -08003125 final long identity = Binder.clearCallingIdentity();
3126 try {
3127 executor.execute(() -> {
3128 callback.accept(result);
3129 });
3130 } finally {
3131 Binder.restoreCallingIdentity(identity);
3132 }
Malcolm Chenfd11df22019-02-05 17:19:48 -08003133 }
3134 };
3135 iSub.setPreferredDataSubscriptionId(subId, needValidation, callbackStub);
Malcolm Chend78dac02019-01-24 16:33:51 -08003136 } catch (RemoteException ex) {
3137 // ignore it
3138 }
Nazanin Bakhshie0215a72019-01-04 17:38:36 -08003139 }
3140
3141 /**
3142 * Get which subscription is preferred for cellular data.
3143 * It's also usually the subscription we set up internet connection on.
3144 *
3145 * PreferredData overwrites user setting of default data subscription. And it's used
3146 * by AlternativeNetworkService or carrier apps to switch primary and CBRS
3147 * subscription dynamically in multi-SIM devices.
3148 *
3149 * @return preferred subscription id for cellular data. {@link DEFAULT_SUBSCRIPTION_ID} if
3150 * there's no prefered subscription.
3151 *
3152 * @hide
3153 *
3154 */
3155 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
3156 public int getPreferredDataSubscriptionId() {
3157 int preferredSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
3158 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003159 ISub iSub = TelephonyManager.getSubscriptionService();
Nazanin Bakhshie0215a72019-01-04 17:38:36 -08003160 if (iSub != null) {
3161 preferredSubId = iSub.getPreferredDataSubscriptionId();
3162 }
3163 } catch (RemoteException ex) {
3164 // ignore it
3165 }
3166
3167 return preferredSubId;
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003168 }
3169
3170 /**
Malcolm Chen44137862018-10-23 18:44:03 -07003171 * Return opportunistic subscriptions that can be visible to the caller.
3172 * Opportunistic subscriptions are for opportunistic networks, which are cellular
3173 * networks with limited capabilities and coverage, for example, CBRS.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003174 *
Malcolm Chen44137862018-10-23 18:44:03 -07003175 * <p>Requires Permission:
3176 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
3177 * or that the calling app has carrier privileges (see
3178 * {@link TelephonyManager#hasCarrierPrivileges}).
3179 *
3180 * @return the list of opportunistic subscription info. If none exists, an empty list.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003181 */
Malcolm Chen44137862018-10-23 18:44:03 -07003182 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003183 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
Malcolm Chen44137862018-10-23 18:44:03 -07003184 public @NonNull List<SubscriptionInfo> getOpportunisticSubscriptions() {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08003185 String contextPkg = mContext != null ? mContext.getOpPackageName() : "<unknown>";
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08003186 String contextAttributionTag = mContext != null ? mContext.getAttributionTag() : null;
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003187 List<SubscriptionInfo> subInfoList = null;
3188
3189 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003190 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003191 if (iSub != null) {
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08003192 subInfoList = iSub.getOpportunisticSubscriptions(contextPkg,
3193 contextAttributionTag);
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003194 }
3195 } catch (RemoteException ex) {
3196 // ignore it
3197 }
3198
3199 if (subInfoList == null) {
3200 subInfoList = new ArrayList<>();
3201 }
3202
3203 return subInfoList;
3204 }
3205
3206 /**
3207 * Switch to a certain subscription
3208 *
3209 * @param subId sub id
3210 * @param callbackIntent pending intent that will be sent after operation is done.
sandeepjsb061a762022-03-24 10:30:59 +00003211 *
3212 * to-be-deprecated this API is a duplicate of {@link EuiccManager#switchToSubscription(int,
3213 * PendingIntent)} and does not support Multiple Enabled Profile(MEP). Apps should use
3214 * {@link EuiccManager#switchToSubscription(int, PendingIntent)} or
3215 * {@link EuiccManager#switchToSubscription(int, int, PendingIntent)} instead.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003216 */
3217 @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
Malcolm Chen80e1e5c2019-02-27 15:16:05 -08003218 public void switchToSubscription(int subId, @NonNull PendingIntent callbackIntent) {
3219 Preconditions.checkNotNull(callbackIntent, "callbackIntent cannot be null");
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003220 EuiccManager euiccManager = new EuiccManager(mContext);
3221 euiccManager.switchToSubscription(subId, callbackIntent);
3222 }
3223
3224 /**
Malcolm Chend4dc4ee2018-12-11 13:56:53 -08003225 * Set whether a subscription is opportunistic, that is, whether the network it connects
3226 * to has limited coverage. For example, CBRS. Setting a subscription opportunistic has
3227 * following impacts:
3228 * 1) Even if it's active, it will be dormant most of the time. The modem will not try
3229 * to scan or camp until it knows an available network is nearby to save power.
3230 * 2) Telephony relies on system app or carrier input to notify nearby available networks.
danielwbhuanga3358802019-03-11 11:52:10 +08003231 * See {@link TelephonyManager#updateAvailableNetworks(List, Executor, Consumer)}
3232 * for more information.
Malcolm Chend4dc4ee2018-12-11 13:56:53 -08003233 * 3) In multi-SIM devices, when the network is nearby and camped, system may automatically
3234 * switch internet data between it and default data subscription, based on carrier
3235 * recommendation and its signal strength and metered-ness, etc.
3236 *
3237 *
3238 * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE} or carrier
3239 * privilege permission of the subscription.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003240 *
3241 * @param opportunistic whether it’s opportunistic subscription.
3242 * @param subId the unique SubscriptionInfo index in database
Malcolm Chend4dc4ee2018-12-11 13:56:53 -08003243 * @return {@code true} if the operation is succeed, {@code false} otherwise.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003244 */
Malcolm Chend4dc4ee2018-12-11 13:56:53 -08003245 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003246 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
Malcolm Chend4dc4ee2018-12-11 13:56:53 -08003247 public boolean setOpportunistic(boolean opportunistic, int subId) {
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003248 if (VDBG) logd("[setOpportunistic]+ opportunistic:" + opportunistic + " subId:" + subId);
3249 return setSubscriptionPropertyHelper(subId, "setOpportunistic",
Malcolm Chend4dc4ee2018-12-11 13:56:53 -08003250 (iSub)-> iSub.setOpportunistic(
3251 opportunistic, subId, mContext.getOpPackageName())) == 1;
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003252 }
3253
3254 /**
Malcolm Chenaea9b022018-10-31 20:18:02 -07003255 * Inform SubscriptionManager that subscriptions in the list are bundled
Malcolm Chen4674a792019-03-20 20:32:27 -07003256 * as a group. It can be multiple primary (non-opportunistic) subscriptions,
3257 * or one or more primary plus one or more opportunistic subscriptions.
3258 *
3259 * This API will always create a new immutable group and assign group UUID to all the
3260 * subscriptions, regardless whether they are in a group already or not.
3261 *
3262 * Grouped subscriptions will have below behaviors:
3263 * 1) They will share the same user settings.
3264 * 2) The opportunistic subscriptions in the group is considered invisible and will not
3265 * return from {@link #getActiveSubscriptionInfoList()}, unless caller has carrier
3266 * privilege permission of the subscriptions.
3267 * 3) The opportunistic subscriptions in the group can't be active by itself. If all other
3268 * non-opportunistic ones are deactivated (unplugged or disabled in Settings),
3269 * the opportunistic ones will be deactivated automatically.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003270 *
John Reckc877f582018-11-16 15:46:02 -08003271 * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003272 * permission or had carrier privilege permission on the subscriptions:
Malcolm Chen18350e42018-12-12 10:29:16 -08003273 * {@link TelephonyManager#hasCarrierPrivileges()} or
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003274 * {@link #canManageSubscription(SubscriptionInfo)}
3275 *
3276 * @throws SecurityException if the caller doesn't meet the requirements
3277 * outlined above.
Malcolm Chen3c976932019-04-03 18:39:21 -07003278 * @throws IllegalArgumentException if any of the subscriptions in the list doesn't exist.
3279 * @throws IllegalStateException if Telephony service is in bad state.
Malcolm Chenaea9b022018-10-31 20:18:02 -07003280 *
3281 * @param subIdList list of subId that will be in the same group
Malcolm Chen4674a792019-03-20 20:32:27 -07003282 * @return groupUUID a UUID assigned to the subscription group.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003283 *
3284 */
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003285 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003286 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
Malcolm Chen4674a792019-03-20 20:32:27 -07003287 public @NonNull ParcelUuid createSubscriptionGroup(@NonNull List<Integer> subIdList) {
3288 Preconditions.checkNotNull(subIdList, "can't create group for null subId list");
Malcolm Chenaea9b022018-10-31 20:18:02 -07003289 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
3290 if (VDBG) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003291 logd("[createSubscriptionGroup]");
Malcolm Chenaea9b022018-10-31 20:18:02 -07003292 }
3293
Malcolm Chen4674a792019-03-20 20:32:27 -07003294 ParcelUuid groupUuid = null;
3295 int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray();
Malcolm Chenaea9b022018-10-31 20:18:02 -07003296 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003297 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chenaea9b022018-10-31 20:18:02 -07003298 if (iSub != null) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003299 groupUuid = iSub.createSubscriptionGroup(subIdArray, pkgForDebug);
3300 } else {
3301 if (!isSystemProcess()) {
3302 throw new IllegalStateException("telephony service is null.");
3303 }
Malcolm Chenaea9b022018-10-31 20:18:02 -07003304 }
3305 } catch (RemoteException ex) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003306 loge("createSubscriptionGroup RemoteException " + ex);
3307 if (!isSystemProcess()) {
3308 ex.rethrowAsRuntimeException();
3309 }
Malcolm Chenaea9b022018-10-31 20:18:02 -07003310 }
3311
Malcolm Chen4674a792019-03-20 20:32:27 -07003312 return groupUuid;
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003313 }
3314
Nazanin Bakhshib9b87be2018-11-21 16:32:05 -08003315 /**
Malcolm Chen4674a792019-03-20 20:32:27 -07003316 * Add a list of subscriptions into a group.
3317 * See {@link #createSubscriptionGroup(List)} for more details.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003318 *
3319 * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
3320 * permission or had carrier privilege permission on the subscriptions:
Malcolm Chen18350e42018-12-12 10:29:16 -08003321 * {@link TelephonyManager#hasCarrierPrivileges()} or
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003322 * {@link #canManageSubscription(SubscriptionInfo)}
3323 *
3324 * @throws SecurityException if the caller doesn't meet the requirements
3325 * outlined above.
Malcolm Chen710a09a2019-08-22 13:07:30 -07003326 * @throws IllegalArgumentException if the some subscriptions in the list doesn't exist.
Malcolm Chen3c976932019-04-03 18:39:21 -07003327 * @throws IllegalStateException if Telephony service is in bad state.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003328 *
Malcolm Chen4674a792019-03-20 20:32:27 -07003329 * @param subIdList list of subId that need adding into the group
3330 * @param groupUuid the groupUuid the subscriptions are being added to.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003331 *
3332 */
3333 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
3334 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
Malcolm Chen4674a792019-03-20 20:32:27 -07003335 public void addSubscriptionsIntoGroup(@NonNull List<Integer> subIdList,
3336 @NonNull ParcelUuid groupUuid) {
3337 Preconditions.checkNotNull(subIdList, "subIdList can't be null.");
3338 Preconditions.checkNotNull(groupUuid, "groupUuid can't be null.");
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003339 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
3340 if (VDBG) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003341 logd("[addSubscriptionsIntoGroup]");
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003342 }
3343
Malcolm Chen4674a792019-03-20 20:32:27 -07003344 int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray();
3345
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003346 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003347 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003348 if (iSub != null) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003349 iSub.addSubscriptionsIntoGroup(subIdArray, groupUuid, pkgForDebug);
3350 } else {
3351 if (!isSystemProcess()) {
3352 throw new IllegalStateException("telephony service is null.");
3353 }
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003354 }
3355 } catch (RemoteException ex) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003356 loge("addSubscriptionsIntoGroup RemoteException " + ex);
3357 if (!isSystemProcess()) {
3358 ex.rethrowAsRuntimeException();
3359 }
3360 }
3361 }
3362
3363 private boolean isSystemProcess() {
3364 return Process.myUid() == Process.SYSTEM_UID;
3365 }
3366
3367 /**
3368 * Remove a list of subscriptions from their subscription group.
3369 * See {@link #createSubscriptionGroup(List)} for more details.
3370 *
3371 * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
3372 * permission or had carrier privilege permission on the subscriptions:
3373 * {@link TelephonyManager#hasCarrierPrivileges()} or
3374 * {@link #canManageSubscription(SubscriptionInfo)}
3375 *
3376 * @throws SecurityException if the caller doesn't meet the requirements
3377 * outlined above.
3378 * @throws IllegalArgumentException if the some subscriptions in the list doesn't belong
3379 * the specified group.
Malcolm Chen3c976932019-04-03 18:39:21 -07003380 * @throws IllegalStateException if Telephony service is in bad state.
Malcolm Chen4674a792019-03-20 20:32:27 -07003381 *
3382 * @param subIdList list of subId that need removing from their groups.
3383 *
3384 */
3385 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
3386 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
3387 public void removeSubscriptionsFromGroup(@NonNull List<Integer> subIdList,
3388 @NonNull ParcelUuid groupUuid) {
3389 Preconditions.checkNotNull(subIdList, "subIdList can't be null.");
3390 Preconditions.checkNotNull(groupUuid, "groupUuid can't be null.");
3391 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
3392 if (VDBG) {
3393 logd("[removeSubscriptionsFromGroup]");
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003394 }
3395
Malcolm Chen4674a792019-03-20 20:32:27 -07003396 int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray();
3397
3398 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003399 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chen4674a792019-03-20 20:32:27 -07003400 if (iSub != null) {
3401 iSub.removeSubscriptionsFromGroup(subIdArray, groupUuid, pkgForDebug);
3402 } else {
3403 if (!isSystemProcess()) {
3404 throw new IllegalStateException("telephony service is null.");
3405 }
3406 }
3407 } catch (RemoteException ex) {
3408 loge("removeSubscriptionsFromGroup RemoteException " + ex);
3409 if (!isSystemProcess()) {
3410 ex.rethrowAsRuntimeException();
3411 }
3412 }
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003413 }
3414
3415 /**
3416 * Get subscriptionInfo list of subscriptions that are in the same group of given subId.
Malcolm Chen4674a792019-03-20 20:32:27 -07003417 * See {@link #createSubscriptionGroup(List)} for more details.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003418 *
3419 * Caller will either have {@link android.Manifest.permission#READ_PHONE_STATE}
3420 * permission or had carrier privilege permission on the subscription.
Malcolm Chen18350e42018-12-12 10:29:16 -08003421 * {@link TelephonyManager#hasCarrierPrivileges()}
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003422 *
Malcolm Chen4f609c72019-11-06 14:02:46 -08003423 * @throws IllegalStateException if Telephony service is in bad state.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003424 * @throws SecurityException if the caller doesn't meet the requirements
3425 * outlined above.
3426 *
Malcolm Chen4674a792019-03-20 20:32:27 -07003427 * @param groupUuid of which list of subInfo will be returned.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003428 * @return list of subscriptionInfo that belong to the same group, including the given
Malcolm Chen4674a792019-03-20 20:32:27 -07003429 * subscription itself. It will return an empty list if no subscription belongs to the group.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003430 *
3431 */
3432 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
3433 @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
Malcolm Chen4674a792019-03-20 20:32:27 -07003434 public @NonNull List<SubscriptionInfo> getSubscriptionsInGroup(@NonNull ParcelUuid groupUuid) {
3435 Preconditions.checkNotNull(groupUuid, "groupUuid can't be null");
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08003436 String contextPkg = mContext != null ? mContext.getOpPackageName() : "<unknown>";
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08003437 String contextAttributionTag = mContext != null ? mContext.getAttributionTag() : null;
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003438 if (VDBG) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003439 logd("[getSubscriptionsInGroup]+ groupUuid:" + groupUuid);
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003440 }
3441
3442 List<SubscriptionInfo> result = null;
3443 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003444 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003445 if (iSub != null) {
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08003446 result = iSub.getSubscriptionsInGroup(groupUuid, contextPkg,
3447 contextAttributionTag);
Malcolm Chen4674a792019-03-20 20:32:27 -07003448 } else {
3449 if (!isSystemProcess()) {
3450 throw new IllegalStateException("telephony service is null.");
3451 }
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003452 }
3453 } catch (RemoteException ex) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003454 loge("removeSubscriptionsFromGroup RemoteException " + ex);
3455 if (!isSystemProcess()) {
3456 ex.rethrowAsRuntimeException();
3457 }
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003458 }
3459
3460 return result;
3461 }
3462
3463 /**
Malcolm Chend1b4a812019-02-28 14:07:59 -08003464 * Whether a subscription is visible to API caller. If it's a bundled opportunistic
3465 * subscription, it should be hidden anywhere in Settings, dialer, status bar etc.
3466 * Exception is if caller owns carrier privilege, in which case they will
Malcolm Chen31071852019-02-12 17:29:59 -08003467 * want to see their own hidden subscriptions.
Malcolm Chen0db9aa12018-12-06 11:19:03 -08003468 *
3469 * @param info the subscriptionInfo to check against.
Malcolm Chend1b4a812019-02-28 14:07:59 -08003470 * @return true if this subscription should be visible to the API caller.
Malcolm Chen0db9aa12018-12-06 11:19:03 -08003471 *
Qingxi Lie0662472019-05-17 15:16:21 -07003472 * @hide
Malcolm Chen0db9aa12018-12-06 11:19:03 -08003473 */
Qingxi Lie0662472019-05-17 15:16:21 -07003474 public boolean isSubscriptionVisible(SubscriptionInfo info) {
Malcolm Chen31071852019-02-12 17:29:59 -08003475 if (info == null) return false;
Malcolm Chend1b4a812019-02-28 14:07:59 -08003476 // If subscription is NOT grouped opportunistic subscription, it's visible.
Malcolm Chen4674a792019-03-20 20:32:27 -07003477 if (info.getGroupUuid() == null || !info.isOpportunistic()) return true;
Malcolm Chen31071852019-02-12 17:29:59 -08003478
Malcolm Chend1b4a812019-02-28 14:07:59 -08003479 // If the caller is the carrier app and owns the subscription, it should be visible
3480 // to the caller.
3481 boolean hasCarrierPrivilegePermission = TelephonyManager.from(mContext)
3482 .hasCarrierPrivileges(info.getSubscriptionId())
Nazanin Bakhshi65371b22019-08-19 16:36:07 -07003483 || canManageSubscription(info);
Malcolm Chend1b4a812019-02-28 14:07:59 -08003484 return hasCarrierPrivilegePermission;
Malcolm Chen0db9aa12018-12-06 11:19:03 -08003485 }
3486
3487 /**
3488 * Return a list of subscriptions that are available and visible to the user.
3489 * Used by Settings app to show a list of subscriptions for user to pick.
3490 *
3491 * <p>
3492 * Permissions android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE is required
3493 * for getSelectableSubscriptionInfoList to be invoked.
3494 * @return list of user selectable subscriptions.
3495 *
3496 * @hide
3497 */
3498 public @Nullable List<SubscriptionInfo> getSelectableSubscriptionInfoList() {
3499 List<SubscriptionInfo> availableList = getAvailableSubscriptionInfoList();
3500 if (availableList == null) {
3501 return null;
3502 } else {
Malcolm Chenb82864c2019-02-26 16:48:40 -08003503 // Multiple subscriptions in a group should only have one representative.
3504 // It should be the current active primary subscription if any, or any
3505 // primary subscription.
3506 List<SubscriptionInfo> selectableList = new ArrayList<>();
Malcolm Chen4674a792019-03-20 20:32:27 -07003507 Map<ParcelUuid, SubscriptionInfo> groupMap = new HashMap<>();
Malcolm Chenb82864c2019-02-26 16:48:40 -08003508
3509 for (SubscriptionInfo info : availableList) {
3510 // Opportunistic subscriptions are considered invisible
3511 // to users so they should never be returned.
Malcolm Chend1b4a812019-02-28 14:07:59 -08003512 if (!isSubscriptionVisible(info)) continue;
Malcolm Chenb82864c2019-02-26 16:48:40 -08003513
Malcolm Chen4674a792019-03-20 20:32:27 -07003514 ParcelUuid groupUuid = info.getGroupUuid();
Malcolm Chenb82864c2019-02-26 16:48:40 -08003515 if (groupUuid == null) {
3516 // Doesn't belong to any group. Add in the list.
3517 selectableList.add(info);
3518 } else if (!groupMap.containsKey(groupUuid)
3519 || (groupMap.get(groupUuid).getSimSlotIndex() == INVALID_SIM_SLOT_INDEX
3520 && info.getSimSlotIndex() != INVALID_SIM_SLOT_INDEX)) {
3521 // If it belongs to a group that has never been recorded or it's the current
3522 // active subscription, add it in the list.
3523 selectableList.remove(groupMap.get(groupUuid));
3524 selectableList.add(info);
3525 groupMap.put(groupUuid, info);
3526 }
3527
3528 }
3529 return selectableList;
Malcolm Chen0db9aa12018-12-06 11:19:03 -08003530 }
3531 }
3532
Malcolm Chen77b2b552018-12-13 19:24:03 -08003533 /**
Malcolm Chen4c7c1b22019-11-19 15:27:55 -08003534 * Enables or disables a subscription. This is currently used in the settings page. It will
3535 * fail and return false if operation is not supported or failed.
3536 *
3537 * To disable an active subscription on a physical (non-Euicc) SIM,
3538 * {@link #canDisablePhysicalSubscription} needs to be true.
Malcolm Chen77b2b552018-12-13 19:24:03 -08003539 *
3540 * <p>
3541 * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
3542 *
3543 * @param enable whether user is turning it on or off.
3544 * @param subscriptionId Subscription to be enabled or disabled.
3545 * It could be a eSIM or pSIM subscription.
3546 *
3547 * @return whether the operation is successful.
3548 *
3549 * @hide
3550 */
3551 @SystemApi
3552 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
3553 public boolean setSubscriptionEnabled(int subscriptionId, boolean enable) {
3554 if (VDBG) {
3555 logd("setSubscriptionActivated subId= " + subscriptionId + " enable " + enable);
3556 }
3557 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003558 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chen77b2b552018-12-13 19:24:03 -08003559 if (iSub != null) {
3560 return iSub.setSubscriptionEnabled(enable, subscriptionId);
3561 }
3562 } catch (RemoteException ex) {
3563 // ignore it
3564 }
3565
3566 return false;
3567 }
3568
3569 /**
Malcolm Chen4ece3db2019-12-16 14:01:50 -08003570 * Set uicc applications being enabled or disabled.
3571 * The value will be remembered on the subscription and will be applied whenever it's present.
3572 * If the subscription in currently present, it will also apply the setting to modem
Jordan Liu02939242021-04-27 13:34:31 -07003573 * immediately (the setting in the modem will not change until the modem receives and responds
3574 * to the request, but typically this should only take a few seconds. The user visible setting
3575 * available from SubscriptionInfo.areUiccApplicationsEnabled() will be updated
3576 * immediately.)
Malcolm Chen4ece3db2019-12-16 14:01:50 -08003577 *
3578 * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
3579 *
Malcolm Chen4ece3db2019-12-16 14:01:50 -08003580 * @param subscriptionId which subscription to operate on.
Malcolm Chen91056a42020-02-21 17:11:57 -08003581 * @param enabled whether uicc applications are enabled or disabled.
Malcolm Chen4ece3db2019-12-16 14:01:50 -08003582 * @hide
3583 */
3584 @SystemApi
3585 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
Malcolm Chen91056a42020-02-21 17:11:57 -08003586 public void setUiccApplicationsEnabled(int subscriptionId, boolean enabled) {
Malcolm Chen4ece3db2019-12-16 14:01:50 -08003587 if (VDBG) {
3588 logd("setUiccApplicationsEnabled subId= " + subscriptionId + " enable " + enabled);
3589 }
3590 try {
Peter Wangd9eebca2019-12-30 16:14:01 -08003591 ISub iSub = ISub.Stub.asInterface(
3592 TelephonyFrameworkInitializer
3593 .getTelephonyServiceManager()
3594 .getSubscriptionServiceRegisterer()
3595 .get());
Malcolm Chen4ece3db2019-12-16 14:01:50 -08003596 if (iSub != null) {
3597 iSub.setUiccApplicationsEnabled(enabled, subscriptionId);
3598 }
3599 } catch (RemoteException ex) {
3600 // ignore it
3601 }
3602 }
3603
3604 /**
Malcolm Chen4c7c1b22019-11-19 15:27:55 -08003605 * Whether it's supported to disable / re-enable a subscription on a physical (non-euicc) SIM.
3606 *
3607 * Physical SIM refers non-euicc, or aka non-programmable SIM.
3608 *
3609 * It provides whether a physical SIM card can be disabled without taking it out, which is done
3610 * via {@link #setSubscriptionEnabled(int, boolean)} API.
3611 *
3612 * Requires Permission: READ_PRIVILEGED_PHONE_STATE.
3613 *
3614 * @return whether can disable subscriptions on physical SIMs.
3615 *
3616 * @hide
3617 */
3618 @SystemApi
3619 @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
3620 public boolean canDisablePhysicalSubscription() {
3621 if (VDBG) {
3622 logd("canDisablePhysicalSubscription");
3623 }
3624 try {
Peter Wangd9eebca2019-12-30 16:14:01 -08003625 ISub iSub = ISub.Stub.asInterface(
3626 TelephonyFrameworkInitializer
3627 .getTelephonyServiceManager()
3628 .getSubscriptionServiceRegisterer()
3629 .get());
Malcolm Chen4c7c1b22019-11-19 15:27:55 -08003630 if (iSub != null) {
3631 return iSub.canDisablePhysicalSubscription();
3632 }
3633 } catch (RemoteException ex) {
3634 // ignore it
3635 }
3636
3637 return false;
3638 }
3639
3640 /**
Malcolm Chendcc97e12019-06-18 13:57:03 -07003641 * DO NOT USE.
3642 * This API is designed for features that are not finished at this point. Do not call this API.
Malcolm Chen77b2b552018-12-13 19:24:03 -08003643 * @hide
Malcolm Chendcc97e12019-06-18 13:57:03 -07003644 * TODO b/135547512: further clean up
Malcolm Chen77b2b552018-12-13 19:24:03 -08003645 */
3646 @SystemApi
3647 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
3648 public boolean isSubscriptionEnabled(int subscriptionId) {
3649 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003650 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chen77b2b552018-12-13 19:24:03 -08003651 if (iSub != null) {
3652 return iSub.isSubscriptionEnabled(subscriptionId);
3653 }
3654 } catch (RemoteException ex) {
3655 // ignore it
3656 }
3657
3658 return false;
3659 }
3660
3661 /**
Grace Jiab53cb662021-02-12 15:29:29 -08003662 * Set the device to device status sharing user preference for a subscription ID. The setting
3663 * app uses this method to indicate with whom they wish to share device to device status
3664 * information.
3665 * @param sharing the status sharing preference
Grace Jiaaeea4ec2021-03-10 14:00:43 -08003666 * @param subscriptionId the unique Subscription ID in database
Grace Jiab53cb662021-02-12 15:29:29 -08003667 */
3668 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
Grace Jia25a8bdb2021-03-29 22:56:57 -07003669 public void setDeviceToDeviceStatusSharingPreference(int subscriptionId,
3670 @DeviceToDeviceStatusSharingPreference int sharing) {
Grace Jiab53cb662021-02-12 15:29:29 -08003671 if (VDBG) {
Grace Jiaaeea4ec2021-03-10 14:00:43 -08003672 logd("[setDeviceToDeviceStatusSharing] + sharing: " + sharing + " subId: "
3673 + subscriptionId);
Grace Jiab53cb662021-02-12 15:29:29 -08003674 }
Grace Jiaaeea4ec2021-03-10 14:00:43 -08003675 setSubscriptionPropertyHelper(subscriptionId, "setDeviceToDeviceSharingStatus",
3676 (iSub)->iSub.setDeviceToDeviceStatusSharing(sharing, subscriptionId));
Grace Jiab53cb662021-02-12 15:29:29 -08003677 }
3678
3679 /**
3680 * Returns the user-chosen device to device status sharing preference
Grace Jiaaeea4ec2021-03-10 14:00:43 -08003681 * @param subscriptionId Subscription id of subscription
Grace Jiab53cb662021-02-12 15:29:29 -08003682 * @return The device to device status sharing preference
3683 */
Grace Jiaaeea4ec2021-03-10 14:00:43 -08003684 public @DeviceToDeviceStatusSharingPreference int getDeviceToDeviceStatusSharingPreference(
3685 int subscriptionId) {
Grace Jiab53cb662021-02-12 15:29:29 -08003686 if (VDBG) {
Grace Jiaaeea4ec2021-03-10 14:00:43 -08003687 logd("[getDeviceToDeviceStatusSharing] + subId: " + subscriptionId);
Grace Jiab53cb662021-02-12 15:29:29 -08003688 }
Grace Jiaaeea4ec2021-03-10 14:00:43 -08003689 return getIntegerSubscriptionProperty(subscriptionId, D2D_STATUS_SHARING,
3690 D2D_SHARING_DISABLED, mContext);
Grace Jiab53cb662021-02-12 15:29:29 -08003691 }
3692
3693 /**
Grace Jia2bd23cf2021-03-18 14:47:31 -07003694 * Set the list of contacts that allow device to device status sharing for a subscription ID.
3695 * The setting app uses this method to indicate with whom they wish to share device to device
3696 * status information.
3697 * @param contacts The list of contacts that allow device to device status sharing
3698 * @param subscriptionId The unique Subscription ID in database
3699 */
3700 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
Grace Jia25a8bdb2021-03-29 22:56:57 -07003701 public void setDeviceToDeviceStatusSharingContacts(int subscriptionId,
3702 @NonNull List<Uri> contacts) {
Grace Jia2bd23cf2021-03-18 14:47:31 -07003703 String contactString = serializeUriLists(contacts);
3704 if (VDBG) {
3705 logd("[setDeviceToDeviceStatusSharingContacts] + contacts: " + contactString
3706 + " subId: " + subscriptionId);
3707 }
3708 setSubscriptionPropertyHelper(subscriptionId, "setDeviceToDeviceSharingStatus",
3709 (iSub)->iSub.setDeviceToDeviceStatusSharingContacts(serializeUriLists(contacts),
3710 subscriptionId));
3711 }
3712
3713 /**
3714 * Returns the list of contacts that allow device to device status sharing.
3715 * @param subscriptionId Subscription id of subscription
3716 * @return The list of contacts that allow device to device status sharing
3717 */
3718 public @NonNull List<Uri> getDeviceToDeviceStatusSharingContacts(
3719 int subscriptionId) {
3720 if (VDBG) {
3721 logd("[getDeviceToDeviceStatusSharingContacts] + subId: " + subscriptionId);
3722 }
3723 return getContactsFromSubscriptionProperty(subscriptionId,
3724 D2D_STATUS_SHARING_SELECTED_CONTACTS, mContext);
3725 }
3726
3727 /**
Malcolm Chendcc97e12019-06-18 13:57:03 -07003728 * DO NOT USE.
3729 * This API is designed for features that are not finished at this point. Do not call this API.
Malcolm Chen77b2b552018-12-13 19:24:03 -08003730 * @hide
Malcolm Chendcc97e12019-06-18 13:57:03 -07003731 * TODO b/135547512: further clean up
Malcolm Chen77b2b552018-12-13 19:24:03 -08003732 */
3733 @SystemApi
3734 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
3735 public int getEnabledSubscriptionId(int slotIndex) {
3736 int subId = INVALID_SUBSCRIPTION_ID;
3737
3738 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003739 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chen77b2b552018-12-13 19:24:03 -08003740 if (iSub != null) {
3741 subId = iSub.getEnabledSubscriptionId(slotIndex);
3742 }
3743 } catch (RemoteException ex) {
3744 // ignore it
3745 }
3746
3747 if (VDBG) logd("getEnabledSubscriptionId, subId = " + subId);
3748 return subId;
3749 }
3750
Malcolm Chenbd4ae762018-08-03 17:24:07 -07003751 private interface CallISubMethodHelper {
3752 int callMethod(ISub iSub) throws RemoteException;
3753 }
3754
3755 private int setSubscriptionPropertyHelper(int subId, String methodName,
3756 CallISubMethodHelper helper) {
3757 if (!isValidSubscriptionId(subId)) {
3758 logd("[" + methodName + "]" + "- fail");
3759 return -1;
3760 }
3761
3762 int result = 0;
3763
3764 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003765 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chenbd4ae762018-08-03 17:24:07 -07003766 if (iSub != null) {
3767 result = helper.callMethod(iSub);
3768 }
3769 } catch (RemoteException ex) {
3770 // ignore it
3771 }
3772
3773 return result;
3774 }
Jack Yu807a82b2019-06-06 17:13:06 -07003775
3776 /**
Jayachandran C9ecb50e2019-11-08 00:47:34 -08003777 * Get active data subscription id. Active data subscription refers to the subscription
3778 * currently chosen to provide cellular internet connection to the user. This may be
3779 * different from getDefaultDataSubscriptionId(). Eg. Opportunistics data
3780 *
Jack Yu807a82b2019-06-06 17:13:06 -07003781 * See {@link PhoneStateListener#onActiveDataSubscriptionIdChanged(int)} for the details.
3782 *
Jayachandran C9ecb50e2019-11-08 00:47:34 -08003783 * @return Active data subscription id if any is chosen, or
3784 * SubscriptionManager.INVALID_SUBSCRIPTION_ID if not.
Jack Yu807a82b2019-06-06 17:13:06 -07003785 */
3786 public static int getActiveDataSubscriptionId() {
Collin Fijalkovich7d7ce512020-04-02 13:32:32 -07003787 return sActiveDataSubIdCache.query(null);
Jack Yu807a82b2019-06-06 17:13:06 -07003788 }
Daniel Bright0b5d2852020-01-09 21:58:16 -08003789
3790 /**
3791 * Helper method that puts a subscription id on an intent with the constants:
3792 * PhoneConstant.SUBSCRIPTION_KEY and SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX.
3793 * Both constants are used to support backwards compatibility. Once we know we got all places,
3794 * we can remove PhoneConstants.SUBSCRIPTION_KEY.
3795 * @param intent Intent to put sub id on.
3796 * @param subId SubscriptionId to put on intent.
3797 *
3798 * @hide
3799 */
3800 public static void putSubscriptionIdExtra(Intent intent, int subId) {
3801 intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
3802 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
3803 }
Collin Fijalkovich4ffdedf2019-12-10 09:52:14 -08003804
3805 /** @hide */
3806 public static void invalidateDefaultSubIdCaches() {
3807 PropertyInvalidatedCache.invalidateCache(CACHE_KEY_DEFAULT_SUB_ID_PROPERTY);
3808 }
3809
Collin Fijalkovichce43a592020-03-25 14:30:21 -07003810 /** @hide */
3811 public static void invalidateDefaultDataSubIdCaches() {
3812 PropertyInvalidatedCache.invalidateCache(CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY);
3813 }
3814
Collin Fijalkovich7d7ce512020-04-02 13:32:32 -07003815 /** @hide */
Collin Fijalkovich02e5c592020-04-06 10:54:28 -07003816 public static void invalidateDefaultSmsSubIdCaches() {
3817 PropertyInvalidatedCache.invalidateCache(CACHE_KEY_DEFAULT_SMS_SUB_ID_PROPERTY);
3818 }
3819
3820 /** @hide */
Collin Fijalkovich7d7ce512020-04-02 13:32:32 -07003821 public static void invalidateActiveDataSubIdCaches() {
3822 PropertyInvalidatedCache.invalidateCache(CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY);
3823 }
3824
Collin Fijalkovich41f94622020-04-10 14:01:42 -07003825 /** @hide */
3826 public static void invalidateSlotIndexCaches() {
3827 PropertyInvalidatedCache.invalidateCache(CACHE_KEY_SLOT_INDEX_PROPERTY);
Collin Fijalkovich7d7ce512020-04-02 13:32:32 -07003828 }
3829
3830 /**
3831 * Allows a test process to disable client-side caching operations.
3832 *
3833 * @hide
3834 */
3835 public static void disableCaching() {
3836 sDefaultSubIdCache.disableLocal();
3837 sDefaultDataSubIdCache.disableLocal();
3838 sActiveDataSubIdCache.disableLocal();
Collin Fijalkovich02e5c592020-04-06 10:54:28 -07003839 sDefaultSmsSubIdCache.disableLocal();
Collin Fijalkovich41f94622020-04-10 14:01:42 -07003840 sSlotIndexCache.disableLocal();
3841 sPhoneIdCache.disableLocal();
3842 }
3843
3844 /**
3845 * Clears all process-local binder caches.
3846 *
3847 * @hide */
3848 public static void clearCaches() {
3849 sDefaultSubIdCache.clear();
3850 sDefaultDataSubIdCache.clear();
3851 sActiveDataSubIdCache.clear();
3852 sDefaultSmsSubIdCache.clear();
3853 sSlotIndexCache.clear();
3854 sPhoneIdCache.clear();
Collin Fijalkovich4ffdedf2019-12-10 09:52:14 -08003855 }
Jack Nudelmane2ea4282021-01-13 18:46:57 -08003856
3857 /**
3858 * Called to retrieve SIM-specific settings data to be backed up.
3859 *
3860 * @return data in byte[] to be backed up.
3861 *
3862 * @hide
3863 */
3864 @NonNull
3865 @SystemApi
3866 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
3867 public byte[] getAllSimSpecificSettingsForBackup() {
3868 Bundle bundle = mContext.getContentResolver().call(
3869 SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
3870 GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME, null, null);
3871 return bundle.getByteArray(SubscriptionManager.KEY_SIM_SPECIFIC_SETTINGS_DATA);
3872 }
3873
3874 /**
3875 * Called to attempt to restore the backed up sim-specific configs to device for specific sim.
3876 * This will try to restore the data that was stored internally when {@link
3877 * #restoreAllSimSpecificSettingsFromBackup(byte[] data)} was called during setup wizard.
3878 * End result is SimInfoDB is modified to match any backed up configs for the requested
3879 * inserted sim.
3880 *
3881 * <p>
3882 * The {@link Uri} {@link #SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI} is notified if any SimInfoDB
3883 * entry is updated as the result of this method call.
3884 *
3885 * @param iccId of the sim that a restore is requested for.
3886 *
3887 * @hide
3888 */
3889 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
3890 public void restoreSimSpecificSettingsForIccIdFromBackup(@NonNull String iccId) {
3891 mContext.getContentResolver().call(
3892 SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
3893 RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME,
3894 iccId, null);
3895 }
3896
3897 /**
3898 * Called during setup wizard restore flow to attempt to restore the backed up sim-specific
3899 * configs to device for all existing SIMs in SimInfoDB. Internally, it will store the backup
3900 * data in an internal file. This file will persist on device for device's lifetime and will be
3901 * used later on when a SIM is inserted to restore that specific SIM's settings by calling
3902 * {@link #restoreSimSpecificSettingsForIccIdFromBackup(String iccId)}. End result is
3903 * SimInfoDB is modified to match any backed up configs for the appropriate inserted SIMs.
3904 *
3905 * <p>
3906 * The {@link Uri} {@link #SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI} is notified if any SimInfoDB
3907 * entry is updated as the result of this method call.
3908 *
3909 * @param data with the sim specific configs to be backed up.
3910 *
3911 * @hide
3912 */
3913 @SystemApi
3914 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
3915 public void restoreAllSimSpecificSettingsFromBackup(@NonNull byte[] data) {
3916 Bundle bundle = new Bundle();
3917 bundle.putByteArray(KEY_SIM_SPECIFIC_SETTINGS_DATA, data);
3918 mContext.getContentResolver().call(
3919 SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
3920 RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME,
3921 null, bundle);
3922 }
Meng Wang0594b4f2021-10-26 13:12:47 -07003923
3924 /**
Meng Wangbbb01fc2021-11-17 13:43:02 -08003925 * Returns the phone number for the given {@code subscriptionId} and {@code source},
Meng Wang0594b4f2021-10-26 13:12:47 -07003926 * or an empty string if not available.
3927 *
Meng Wangbbb01fc2021-11-17 13:43:02 -08003928 * <p>General apps that need to know the phone number should use {@link #getPhoneNumber(int)}
3929 * instead. This API may be suitable specific apps that needs to know the phone number from
3930 * a specific source. For example, a carrier app needs to know exactly what's on
3931 * {@link #PHONE_NUMBER_SOURCE_UICC UICC} and decide if the previously set phone number
3932 * of source {@link #PHONE_NUMBER_SOURCE_CARRIER carrier} should be updated.
3933 *
Meng Wang355b2542022-01-13 22:36:59 +00003934 * <p>The API provides no guarantees of what format the number is in: the format can vary
3935 * depending on the {@code source} and the network etc. Programmatic parsing should be done
3936 * cautiously, for example, after formatting the number to a consistent format with
3937 * {@link android.telephony.PhoneNumberUtils#formatNumberToE164(String, String)}.
3938 *
Meng Wangbbb01fc2021-11-17 13:43:02 -08003939 * <p>Note the assumption is that one subscription (which usually means one SIM) has
3940 * only one phone number. The multiple sources backup each other so hopefully at least one
3941 * is availavle. For example, for a carrier that doesn't typically set phone numbers
3942 * on {@link #PHONE_NUMBER_SOURCE_UICC UICC}, the source {@link #PHONE_NUMBER_SOURCE_IMS IMS}
3943 * may provide one. Or, a carrier may decide to provide the phone number via source
3944 * {@link #PHONE_NUMBER_SOURCE_CARRIER carrier} if neither source UICC nor IMS is available.
Meng Wang0594b4f2021-10-26 13:12:47 -07003945 *
3946 * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID}
3947 * for the default one.
3948 * @param source the source of the phone number, one of the PHONE_NUMBER_SOURCE_* constants.
3949 * @return the phone number, or an empty string if not available.
3950 * @throws IllegalArgumentException if {@code source} is invalid.
3951 * @throws IllegalStateException if the telephony process is not currently available.
3952 * @throws SecurityException if the caller doesn't have permissions required.
3953 * @see #PHONE_NUMBER_SOURCE_UICC
3954 * @see #PHONE_NUMBER_SOURCE_CARRIER
3955 * @see #PHONE_NUMBER_SOURCE_IMS
3956 */
Meng Wang0594b4f2021-10-26 13:12:47 -07003957 @RequiresPermission(anyOf = {
3958 android.Manifest.permission.READ_PHONE_NUMBERS,
3959 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
Meng Wangbbb01fc2021-11-17 13:43:02 -08003960 "carrier privileges",
Meng Wang0594b4f2021-10-26 13:12:47 -07003961 })
3962 @NonNull
3963 public String getPhoneNumber(int subscriptionId, @PhoneNumberSource int source) {
3964 if (subscriptionId == DEFAULT_SUBSCRIPTION_ID) {
3965 subscriptionId = getDefaultSubscriptionId();
3966 }
3967 if (source != PHONE_NUMBER_SOURCE_UICC
3968 && source != PHONE_NUMBER_SOURCE_CARRIER
3969 && source != PHONE_NUMBER_SOURCE_IMS) {
3970 throw new IllegalArgumentException("invalid source " + source);
3971 }
3972 try {
3973 ISub iSub = TelephonyManager.getSubscriptionService();
3974 if (iSub != null) {
3975 return iSub.getPhoneNumber(subscriptionId, source,
3976 mContext.getOpPackageName(), mContext.getAttributionTag());
3977 } else {
3978 throw new IllegalStateException("subscription service unavailable.");
3979 }
3980 } catch (RemoteException ex) {
3981 throw ex.rethrowAsRuntimeException();
3982 }
3983 }
3984
3985 /**
3986 * Returns the phone number for the given {@code subId}, or an empty string if
3987 * not available.
3988 *
Meng Wangbbb01fc2021-11-17 13:43:02 -08003989 * <p>This API is suitable for general apps that needs to know the phone number.
3990 * For specific apps that needs to know the phone number provided by a specific source,
3991 * {@link #getPhoneNumber(int, int)} may be suitable.
3992 *
Meng Wang0594b4f2021-10-26 13:12:47 -07003993 * <p>This API is built up on {@link #getPhoneNumber(int, int)}, but picks
3994 * from available sources in the following order: {@link #PHONE_NUMBER_SOURCE_CARRIER}
3995 * > {@link #PHONE_NUMBER_SOURCE_UICC} > {@link #PHONE_NUMBER_SOURCE_IMS}.
3996 *
Meng Wang355b2542022-01-13 22:36:59 +00003997 * <p>The API provides no guarantees of what format the number is in: the format can vary
3998 * depending on the underlying source and the network etc. Programmatic parsing should be done
3999 * cautiously, for example, after formatting the number to a consistent format with
4000 * {@link android.telephony.PhoneNumberUtils#formatNumberToE164(String, String)}.
4001 *
Meng Wang0594b4f2021-10-26 13:12:47 -07004002 * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID}
4003 * for the default one.
4004 * @return the phone number, or an empty string if not available.
4005 * @throws IllegalStateException if the telephony process is not currently available.
4006 * @throws SecurityException if the caller doesn't have permissions required.
4007 * @see #getPhoneNumber(int, int)
4008 */
Meng Wang0594b4f2021-10-26 13:12:47 -07004009 @RequiresPermission(anyOf = {
4010 android.Manifest.permission.READ_PHONE_NUMBERS,
4011 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
Meng Wangbbb01fc2021-11-17 13:43:02 -08004012 "carrier privileges",
Meng Wang0594b4f2021-10-26 13:12:47 -07004013 })
4014 @NonNull
4015 public String getPhoneNumber(int subscriptionId) {
4016 if (subscriptionId == DEFAULT_SUBSCRIPTION_ID) {
4017 subscriptionId = getDefaultSubscriptionId();
4018 }
4019 try {
4020 ISub iSub = TelephonyManager.getSubscriptionService();
4021 if (iSub != null) {
4022 return iSub.getPhoneNumberFromFirstAvailableSource(subscriptionId,
4023 mContext.getOpPackageName(), mContext.getAttributionTag());
4024 } else {
4025 throw new IllegalStateException("subscription service unavailable.");
4026 }
4027 } catch (RemoteException ex) {
4028 throw ex.rethrowAsRuntimeException();
4029 }
4030 }
4031
4032 /**
4033 * Sets the phone number for the given {@code subId} for source
4034 * {@link #PHONE_NUMBER_SOURCE_CARRIER carrier}.
4035 * Sets an empty string to remove the previously set phone number.
4036 *
Meng Wangbbb01fc2021-11-17 13:43:02 -08004037 * <p>The API is suitable for carrier apps to provide a phone number, for example when
4038 * it's not possible to update {@link #PHONE_NUMBER_SOURCE_UICC UICC} directly.
Meng Wang0594b4f2021-10-26 13:12:47 -07004039 *
Meng Wang355b2542022-01-13 22:36:59 +00004040 * <p>It's recommended that the phone number is formatted to well-known formats,
4041 * for example, by {@link PhoneNumberUtils} {@code formatNumber*} methods.
4042 *
Meng Wang0594b4f2021-10-26 13:12:47 -07004043 * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID}
4044 * for the default one.
4045 * @param number the phone number, or an empty string to remove the previously set number.
4046 * @throws IllegalStateException if the telephony process is not currently available.
4047 * @throws NullPointerException if {@code number} is {@code null}.
4048 * @throws SecurityException if the caller doesn't have permissions required.
4049 */
Meng Wangbbb01fc2021-11-17 13:43:02 -08004050 @RequiresPermission("carrier privileges")
Meng Wang0594b4f2021-10-26 13:12:47 -07004051 public void setCarrierPhoneNumber(int subscriptionId, @NonNull String number) {
4052 if (subscriptionId == DEFAULT_SUBSCRIPTION_ID) {
4053 subscriptionId = getDefaultSubscriptionId();
4054 }
4055 if (number == null) {
4056 throw new NullPointerException("invalid number null");
4057 }
4058 try {
4059 ISub iSub = TelephonyManager.getSubscriptionService();
4060 if (iSub != null) {
4061 iSub.setPhoneNumber(subscriptionId, PHONE_NUMBER_SOURCE_CARRIER, number,
4062 mContext.getOpPackageName(), mContext.getAttributionTag());
4063 } else {
4064 throw new IllegalStateException("subscription service unavailable.");
4065 }
4066 } catch (RemoteException ex) {
4067 throw ex.rethrowAsRuntimeException();
4068 }
4069 }
Nathan Harolde93321c2021-11-03 15:56:27 -07004070
4071 /**
4072 * Set the preferred usage setting.
4073 *
4074 * The cellular usage setting is a switch which controls the mode of operation for the cellular
4075 * radio to either require or not require voice service. It is not managed via Android’s
4076 * Settings.
4077 *
4078 * @param subscriptionId the subId of the subscription.
4079 * @param usageSetting the requested usage setting.
4080 *
4081 * @throws IllegalStateException if a specific mode or setting the mode is not supported on a
4082 * particular device.
4083 *
4084 * <p>Requires {@link android.Manifest.permission#MODIFY_PHONE_STATE}
4085 * or that the calling app has CarrierPrivileges for the given subscription.
4086 *
4087 * Note: This method will not allow the setting of USAGE_SETTING_UNKNOWN.
4088 *
4089 * @hide
4090 */
4091 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
4092 void setUsageSetting(int subscriptionId, @UsageSetting int usageSetting) {
4093 if (VDBG) logd("[setUsageSetting]+ setting:" + usageSetting + " subId:" + subscriptionId);
4094 setSubscriptionPropertyHelper(subscriptionId, "setUsageSetting",
4095 (iSub)-> iSub.setUsageSetting(
4096 usageSetting, subscriptionId, mContext.getOpPackageName()));
4097 }
Wink Savillefb40dd42014-06-12 17:02:31 -07004098}
Nathan Harolde93321c2021-11-03 15:56:27 -07004099