blob: 76b4e0052792799b8ecbef7ff0ee8e47aa137456 [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;
Ling Ma9a53a422023-11-13 14:11:09 -080026import android.annotation.FlaggedApi;
Grace Chen5be6e9c2018-12-20 22:50:18 -080027import android.annotation.IntDef;
Jeff Sharkey32566012014-12-02 18:30:14 -080028import android.annotation.NonNull;
Jeff Sharkey717f52f2018-01-04 16:04:11 -070029import android.annotation.Nullable;
Hui Wangc47df7f2021-12-14 20:37:47 +000030import android.annotation.RequiresFeature;
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -070031import android.annotation.RequiresPermission;
Wink Savillec650e0b2014-09-02 22:37:08 -070032import android.annotation.SdkConstant;
33import android.annotation.SdkConstant.SdkConstantType;
Jeff Davidson3c0415a2018-02-23 15:27:46 -080034import android.annotation.SuppressAutoDoc;
Jeff Sharkey717f52f2018-01-04 16:04:11 -070035import android.annotation.SystemApi;
Jeff Sharkey17bebd22017-07-19 21:00:38 -060036import android.annotation.SystemService;
Malcolm Chen0ac24ef2018-08-07 15:03:32 -070037import android.app.PendingIntent;
Collin Fijalkovich4ffdedf2019-12-10 09:52:14 -080038import android.app.PropertyInvalidatedCache;
Nathan Harold958f2002023-06-21 11:51:16 -070039import android.compat.Compatibility;
40import android.compat.annotation.ChangeId;
41import android.compat.annotation.EnabledAfter;
Artur Satayev54af4fc2019-12-10 17:47:56 +000042import android.compat.annotation.UnsupportedAppUsage;
Wink Savillea374c3d2014-11-11 11:48:04 -080043import android.content.Context;
Wink Savillefb40dd42014-06-12 17:02:31 -070044import android.content.Intent;
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -080045import android.content.pm.PackageInfo;
Jeff Sharkey717f52f2018-01-04 16:04:11 -070046import android.content.pm.PackageManager;
Sanket Padawedc493092015-07-14 14:21:43 -070047import android.content.res.Configuration;
48import android.content.res.Resources;
chen xua0007492018-10-02 19:34:10 -070049import android.database.ContentObserver;
Jeff Sharkey9252b342018-01-19 07:58:35 +090050import android.net.NetworkCapabilities;
Aaron Huang21089442020-01-16 23:31:02 +080051import android.net.NetworkPolicyManager;
Wink Savillefb40dd42014-06-12 17:02:31 -070052import android.net.Uri;
Malcolm Chenb2129eb2018-10-16 18:18:51 -070053import android.os.Binder;
Mathew Inwood45d2c252018-09-14 12:35:36 +010054import android.os.Build;
Jack Nudelmane2ea4282021-01-13 18:46:57 -080055import android.os.Bundle;
Wink Savilled09c4ca2014-11-22 10:08:16 -080056import android.os.Handler;
Jack He9fc75742017-11-16 15:54:14 -080057import android.os.Looper;
Malcolm Chen4674a792019-03-20 20:32:27 -070058import android.os.ParcelUuid;
59import android.os.Process;
Wink Savillefb40dd42014-06-12 17:02:31 -070060import android.os.RemoteException;
Aishwarya Mallampati4f838952022-09-22 22:21:41 +000061import android.os.UserHandle;
changbetty239b6ce2019-12-02 15:04:49 +080062import android.provider.Telephony.SimInfo;
Malcolm Chen0ac24ef2018-08-07 15:03:32 -070063import android.telephony.euicc.EuiccManager;
chen xubf38b062018-11-01 00:08:37 -070064import android.telephony.ims.ImsMmTelManager;
Jack Yub0f281b2022-12-10 02:11:18 -080065import android.text.TextUtils;
Grace Jia2bd23cf2021-03-18 14:47:31 -070066import android.util.Base64;
Malcolm Chen27829e22018-09-04 22:12:31 -070067import android.util.Log;
sangyunfbcde602023-08-23 10:40:55 +090068import android.util.LruCache;
Torbjorn Eklundf8899f02019-11-20 10:59:59 +010069import android.util.Pair;
Jeff Sharkey717f52f2018-01-04 16:04:11 -070070
Malcolm Chenfd11df22019-02-05 17:19:48 -080071import com.android.internal.telephony.ISetOpportunisticDataCallback;
Jeff Davidsond02731f2017-04-09 14:31:09 -070072import com.android.internal.telephony.ISub;
Wink Savillefb40dd42014-06-12 17:02:31 -070073import com.android.internal.telephony.PhoneConstants;
Ling Ma9a53a422023-11-13 14:11:09 -080074import com.android.internal.telephony.flags.Flags;
Sooraj Sasindran041a6d32019-12-02 13:08:23 -080075import com.android.internal.telephony.util.HandlerExecutor;
Hall Liu29b1874f2020-04-07 18:23:09 -070076import com.android.internal.util.FunctionalUtils;
Malcolm Chen80e1e5c2019-02-27 15:16:05 -080077import com.android.internal.util.Preconditions;
Meng Wange3387ef92020-01-30 12:38:32 -080078import com.android.telephony.Rlog;
Jeff Sharkey717f52f2018-01-04 16:04:11 -070079
Grace Jia2bd23cf2021-03-18 14:47:31 -070080import java.io.ByteArrayInputStream;
81import java.io.ByteArrayOutputStream;
82import java.io.IOException;
83import java.io.ObjectInputStream;
84import java.io.ObjectOutputStream;
Grace Chen5be6e9c2018-12-20 22:50:18 -080085import java.lang.annotation.Retention;
86import java.lang.annotation.RetentionPolicy;
Wink Saville905bb542014-09-04 17:10:23 -070087import java.util.ArrayList;
Jeff Sharkey53313d72017-07-13 16:47:32 -060088import java.util.Arrays;
Rajeev Kumarc8ac4f3b2017-07-26 15:59:08 -070089import java.util.Collections;
Malcolm Chenb82864c2019-02-26 16:48:40 -080090import java.util.HashMap;
rambowang558016e2023-12-04 10:22:13 -060091import java.util.HashSet;
Wink Savillefb40dd42014-06-12 17:02:31 -070092import java.util.List;
Torbjorn Eklund99c11d82018-08-21 16:06:47 +020093import java.util.Locale;
Malcolm Chenb82864c2019-02-26 16:48:40 -080094import java.util.Map;
Nathan Harold958f2002023-06-21 11:51:16 -070095import java.util.Objects;
rambowang558016e2023-12-04 10:22:13 -060096import java.util.Set;
Malcolm Chen27829e22018-09-04 22:12:31 -070097import java.util.concurrent.Executor;
Malcolm Chenfd11df22019-02-05 17:19:48 -080098import java.util.function.Consumer;
Malcolm Chen0db9aa12018-12-06 11:19:03 -080099import java.util.stream.Collectors;
Wink Savillefb40dd42014-06-12 17:02:31 -0700100
101/**
Ling Ma34891072024-05-15 17:57:21 -0700102 * Subscription manager provides the mobile subscription information.
Wink Savillefb40dd42014-06-12 17:02:31 -0700103 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -0600104@SystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)
Hui Wangc47df7f2021-12-14 20:37:47 +0000105@RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
Wink Savilled09c4ca2014-11-22 10:08:16 -0800106public class SubscriptionManager {
107 private static final String LOG_TAG = "SubscriptionManager";
108 private static final boolean DBG = false;
Wink Savillefb40dd42014-06-12 17:02:31 -0700109 private static final boolean VDBG = false;
110
Wink Savillea374c3d2014-11-11 11:48:04 -0800111 /** An invalid subscription identifier */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800112 public static final int INVALID_SUBSCRIPTION_ID = -1;
113
Tyler Gunn460360d2020-07-29 10:21:45 -0700114 /** Base value for placeholder SUBSCRIPTION_ID's. */
115 /** @hide */
116 public static final int PLACEHOLDER_SUBSCRIPTION_ID_BASE = INVALID_SUBSCRIPTION_ID - 1;
Wink Savillefb40dd42014-06-12 17:02:31 -0700117
Wink Savillea374c3d2014-11-11 11:48:04 -0800118 /** An invalid phone identifier */
119 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800120 public static final int INVALID_PHONE_INDEX = -1;
Wink Savillec650e0b2014-09-02 22:37:08 -0700121
sqian996a3182018-10-12 18:41:19 -0700122 /** Indicates invalid sim slot. This can be returned by {@link #getSlotIndex(int)}. */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800123 public static final int INVALID_SIM_SLOT_INDEX = -1;
Wink Savillea374c3d2014-11-11 11:48:04 -0800124
sqian798da562018-09-12 16:31:17 -0700125 /** Indicates the default subscription ID in Telephony. */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800126 public static final int DEFAULT_SUBSCRIPTION_ID = Integer.MAX_VALUE;
Wink Savillea374c3d2014-11-11 11:48:04 -0800127
Wink Savilled09c4ca2014-11-22 10:08:16 -0800128 /**
Jack Yu4a922da2023-04-14 09:17:36 -0700129 * Indicates the default phone id.
Wink Savilled09c4ca2014-11-22 10:08:16 -0800130 * @hide
131 */
132 public static final int DEFAULT_PHONE_INDEX = Integer.MAX_VALUE;
Wink Saville2d1ee982014-11-20 20:29:51 +0000133
Jack Yu4a922da2023-04-14 09:17:36 -0700134 /** Indicates the default slot index. */
Wink Saville2d1ee982014-11-20 20:29:51 +0000135 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800136 public static final int DEFAULT_SIM_SLOT_INDEX = Integer.MAX_VALUE;
Wink Savillec650e0b2014-09-02 22:37:08 -0700137
Wink Saville8eab2b62014-09-23 14:20:58 -0700138 /** Minimum possible subid that represents a subscription */
139 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800140 public static final int MIN_SUBSCRIPTION_ID_VALUE = 0;
Wink Saville8eab2b62014-09-23 14:20:58 -0700141
142 /** Maximum possible subid that represents a subscription */
143 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800144 public static final int MAX_SUBSCRIPTION_ID_VALUE = DEFAULT_SUBSCRIPTION_ID - 1;
Wink Saville8eab2b62014-09-23 14:20:58 -0700145
Wink Savillef5bca082014-09-03 15:13:33 -0700146 /** @hide */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +0000147 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
changbetty239b6ce2019-12-02 15:04:49 +0800148 public static final Uri CONTENT_URI = SimInfo.CONTENT_URI;
Wink Savillefb40dd42014-06-12 17:02:31 -0700149
Jack Yu50de0612022-11-26 01:19:17 -0800150 /** The IPC cache key shared by all subscription manager service cacheable properties. */
151 private static final String CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY =
152 "cache_key.telephony.subscription_manager_service";
153
Jack Nudelmane2ea4282021-01-13 18:46:57 -0800154 /** @hide */
155 public static final String GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME = "getSimSpecificSettings";
156
157 /** @hide */
158 public static final String RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME =
159 "restoreSimSpecificSettings";
160
161 /**
Jack Yu7542cfc2023-07-18 19:33:58 -0700162 * The key of the boolean flag indicating whether restoring subscriptions actually changes
163 * the subscription database or not.
164 *
165 * @hide
166 */
167 public static final String RESTORE_SIM_SPECIFIC_SETTINGS_DATABASE_UPDATED =
168 "restoreSimSpecificSettingsDatabaseUpdated";
169
170 /**
Jack Nudelmane2ea4282021-01-13 18:46:57 -0800171 * Key to the backup & restore data byte array in the Bundle that is returned by {@link
172 * #getAllSimSpecificSettingsForBackup()} or to be pass in to {@link
Jack Yu66b2b6c2023-02-12 23:35:26 -0800173 * #restoreAllSimSpecificSettingsFromBackup(byte[])}.
Jack Nudelmane2ea4282021-01-13 18:46:57 -0800174 *
175 * @hide
176 */
177 public static final String KEY_SIM_SPECIFIC_SETTINGS_DATA = "KEY_SIM_SPECIFIC_SETTINGS_DATA";
178
Collin Fijalkovichce43a592020-03-25 14:30:21 -0700179 private static final int MAX_CACHE_SIZE = 4;
Collin Fijalkovich4ffdedf2019-12-10 09:52:14 -0800180
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700181 private static class VoidPropertyInvalidatedCache<T>
Hall Liu29b1874f2020-04-07 18:23:09 -0700182 extends PropertyInvalidatedCache<Void, T> {
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700183 private final FunctionalUtils.ThrowingFunction<ISub, T> mInterfaceMethod;
Hall Liu29b1874f2020-04-07 18:23:09 -0700184 private final String mCacheKeyProperty;
185 private final T mDefaultValue;
Collin Fijalkovich4ffdedf2019-12-10 09:52:14 -0800186
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700187 VoidPropertyInvalidatedCache(
Hall Liu29b1874f2020-04-07 18:23:09 -0700188 FunctionalUtils.ThrowingFunction<ISub, T> subscriptionInterfaceMethod,
189 String cacheKeyProperty,
190 T defaultValue) {
191 super(MAX_CACHE_SIZE, cacheKeyProperty);
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700192 mInterfaceMethod = subscriptionInterfaceMethod;
Hall Liu29b1874f2020-04-07 18:23:09 -0700193 mCacheKeyProperty = cacheKeyProperty;
194 mDefaultValue = defaultValue;
195 }
196
197 @Override
Lee Shombert0d9ec2f2022-07-29 07:39:36 -0700198 public T recompute(Void query) {
199 // This always throws on any error. The exceptions must be handled outside
200 // the cache.
201 try {
202 return mInterfaceMethod.applyOrThrow(TelephonyManager.getSubscriptionService());
203 } catch (Exception re) {
204 throw new RuntimeException(re);
205 }
206 }
207
208 @Override
209 public T query(Void query) {
Hall Liu29b1874f2020-04-07 18:23:09 -0700210 T result = mDefaultValue;
211
212 try {
213 ISub iSub = TelephonyManager.getSubscriptionService();
214 if (iSub != null) {
Lee Shombert0d9ec2f2022-07-29 07:39:36 -0700215 result = super.query(query);
Hall Liu29b1874f2020-04-07 18:23:09 -0700216 }
217 } catch (Exception ex) {
218 Rlog.w(LOG_TAG, "Failed to recompute cache key for " + mCacheKeyProperty);
219 }
220
221 if (VDBG) logd("recomputing " + mCacheKeyProperty + ", result = " + result);
222 return result;
223 }
224 }
225
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700226 private static class IntegerPropertyInvalidatedCache<T>
227 extends PropertyInvalidatedCache<Integer, T> {
228 private final FunctionalUtils.ThrowingBiFunction<ISub, Integer, T> mInterfaceMethod;
229 private final String mCacheKeyProperty;
230 private final T mDefaultValue;
231
232 IntegerPropertyInvalidatedCache(
233 FunctionalUtils.ThrowingBiFunction<ISub, Integer, T> subscriptionInterfaceMethod,
234 String cacheKeyProperty,
235 T defaultValue) {
236 super(MAX_CACHE_SIZE, cacheKeyProperty);
237 mInterfaceMethod = subscriptionInterfaceMethod;
238 mCacheKeyProperty = cacheKeyProperty;
239 mDefaultValue = defaultValue;
240 }
241
242 @Override
Lee Shombert0cece382022-01-04 08:10:15 -0800243 public T recompute(Integer query) {
Lee Shombert0d9ec2f2022-07-29 07:39:36 -0700244 // This always throws on any error. The exceptions must be handled outside
245 // the cache.
246 try {
247 return mInterfaceMethod.applyOrThrow(
248 TelephonyManager.getSubscriptionService(), query);
249 } catch (Exception re) {
250 throw new RuntimeException(re);
251 }
252 }
253
254 @Override
255 public T query(Integer query) {
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700256 T result = mDefaultValue;
257
258 try {
259 ISub iSub = TelephonyManager.getSubscriptionService();
260 if (iSub != null) {
Lee Shombert0d9ec2f2022-07-29 07:39:36 -0700261 result = super.query(query);
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700262 }
263 } catch (Exception ex) {
264 Rlog.w(LOG_TAG, "Failed to recompute cache key for " + mCacheKeyProperty);
265 }
266
267 if (VDBG) logd("recomputing " + mCacheKeyProperty + ", result = " + result);
268 return result;
269 }
270 }
271
Ling Ma19cfc632023-10-31 06:27:35 +0000272 private static IntegerPropertyInvalidatedCache<Integer> sGetDefaultSubIdCacheAsUser =
273 new IntegerPropertyInvalidatedCache<>(ISub::getDefaultSubIdAsUser,
Jack Yu50de0612022-11-26 01:19:17 -0800274 CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
275 INVALID_SUBSCRIPTION_ID);
276
Jack Yu50de0612022-11-26 01:19:17 -0800277 private static VoidPropertyInvalidatedCache<Integer> sGetDefaultDataSubIdCache =
278 new VoidPropertyInvalidatedCache<>(ISub::getDefaultDataSubId,
279 CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
280 INVALID_SUBSCRIPTION_ID);
281
Ling Ma19cfc632023-10-31 06:27:35 +0000282 private static IntegerPropertyInvalidatedCache<Integer> sGetDefaultSmsSubIdCacheAsUser =
283 new IntegerPropertyInvalidatedCache<>(ISub::getDefaultSmsSubIdAsUser,
Jack Yu50de0612022-11-26 01:19:17 -0800284 CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
285 INVALID_SUBSCRIPTION_ID);
286
Jack Yu50de0612022-11-26 01:19:17 -0800287 private static VoidPropertyInvalidatedCache<Integer> sGetActiveDataSubscriptionIdCache =
288 new VoidPropertyInvalidatedCache<>(ISub::getActiveDataSubscriptionId,
289 CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
290 INVALID_SUBSCRIPTION_ID);
291
Jack Yu50de0612022-11-26 01:19:17 -0800292 private static IntegerPropertyInvalidatedCache<Integer> sGetSlotIndexCache =
293 new IntegerPropertyInvalidatedCache<>(ISub::getSlotIndex,
294 CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
295 INVALID_SIM_SLOT_INDEX);
296
Jack Yu50de0612022-11-26 01:19:17 -0800297 private static IntegerPropertyInvalidatedCache<Integer> sGetSubIdCache =
298 new IntegerPropertyInvalidatedCache<>(ISub::getSubId,
299 CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
300 INVALID_SUBSCRIPTION_ID);
301
Jack Yu50de0612022-11-26 01:19:17 -0800302 private static IntegerPropertyInvalidatedCache<Integer> sGetPhoneIdCache =
303 new IntegerPropertyInvalidatedCache<>(ISub::getPhoneId,
304 CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
305 INVALID_PHONE_INDEX);
306
chen xua0007492018-10-02 19:34:10 -0700307 /**
308 * Generates a content {@link Uri} used to receive updates on simInfo change
309 * on the given subscriptionId
310 * @param subscriptionId the subscriptionId to receive updates on
311 * @return the Uri used to observe carrier identity changes
312 * @hide
313 */
314 public static Uri getUriForSubscriptionId(int subscriptionId) {
315 return Uri.withAppendedPath(CONTENT_URI, String.valueOf(subscriptionId));
316 }
317
318 /**
319 * A content {@link Uri} used to receive updates on wfc enabled user setting.
320 * <p>
321 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
chen xubf38b062018-11-01 00:08:37 -0700322 * subscription wfc enabled {@link ImsMmTelManager#isVoWiFiSettingEnabled()}
Makoto Onuki2da26292019-08-07 08:59:39 -0700323 * while your app is running. You can also use a {@link android.app.job.JobService}
324 * to ensure your app
chen xua0007492018-10-02 19:34:10 -0700325 * is notified of changes to the {@link Uri} even when it is not running.
Makoto Onuki2da26292019-08-07 08:59:39 -0700326 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
327 * delivery of updates to the {@link Uri}.
chen xua0007492018-10-02 19:34:10 -0700328 * To be notified of changes to a specific subId, append subId to the URI
329 * {@link Uri#withAppendedPath(Uri, String)}.
330 * @hide
331 */
chen xu81653862019-02-28 10:44:54 -0800332 @NonNull
chen xua0007492018-10-02 19:34:10 -0700333 @SystemApi
334 public static final Uri WFC_ENABLED_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc");
335
336 /**
chen xu83a8fb52018-11-27 23:00:50 -0800337 * A content {@link Uri} used to receive updates on advanced calling user setting
Jack Yu647bbb92022-12-12 21:45:26 -0800338 *
chen xua0007492018-10-02 19:34:10 -0700339 * <p>
340 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
chen xubf38b062018-11-01 00:08:37 -0700341 * subscription advanced calling enabled
342 * {@link ImsMmTelManager#isAdvancedCallingSettingEnabled()} while your app is running.
Makoto Onuki2da26292019-08-07 08:59:39 -0700343 * You can also use a {@link android.app.job.JobService} to ensure your app is notified of
344 * changes to the {@link Uri} even when it is not running.
345 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
346 * delivery of updates to the {@link Uri}.
chen xubf38b062018-11-01 00:08:37 -0700347 * To be notified of changes to a specific subId, append subId to the URI
348 * {@link Uri#withAppendedPath(Uri, String)}.
Jack Yu647bbb92022-12-12 21:45:26 -0800349 *
350 * @see ImsMmTelManager#isAdvancedCallingSettingEnabled()
351 *
chen xubf38b062018-11-01 00:08:37 -0700352 * @hide
353 */
chen xu81653862019-02-28 10:44:54 -0800354 @NonNull
chen xubf38b062018-11-01 00:08:37 -0700355 @SystemApi
356 public static final Uri ADVANCED_CALLING_ENABLED_CONTENT_URI = Uri.withAppendedPath(
357 CONTENT_URI, "advanced_calling");
358
359 /**
360 * A content {@link Uri} used to receive updates on wfc mode setting.
361 * <p>
362 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
363 * subscription wfc mode {@link ImsMmTelManager#getVoWiFiModeSetting()}
Makoto Onuki2da26292019-08-07 08:59:39 -0700364 * while your app is running. You can also use a {@link android.app.job.JobService} to ensure
365 * your app is notified of changes to the {@link Uri} even when it is not running.
366 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
367 * delivery of updates to the {@link Uri}.
chen xua0007492018-10-02 19:34:10 -0700368 * To be notified of changes to a specific subId, append subId to the URI
369 * {@link Uri#withAppendedPath(Uri, String)}.
370 * @hide
371 */
chen xu81653862019-02-28 10:44:54 -0800372 @NonNull
chen xua0007492018-10-02 19:34:10 -0700373 @SystemApi
chen xubf38b062018-11-01 00:08:37 -0700374 public static final Uri WFC_MODE_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc_mode");
chen xua0007492018-10-02 19:34:10 -0700375
chen xubf38b062018-11-01 00:08:37 -0700376 /**
377 * A content {@link Uri} used to receive updates on wfc roaming mode setting.
378 * <p>
379 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
380 * subscription wfc roaming mode {@link ImsMmTelManager#getVoWiFiRoamingModeSetting()}
Makoto Onuki2da26292019-08-07 08:59:39 -0700381 * while your app is running. You can also use a {@link android.app.job.JobService}
382 * to ensure your app is notified of changes to the {@link Uri} even when it is not running.
383 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
384 * delivery of updates to the {@link Uri}.
chen xubf38b062018-11-01 00:08:37 -0700385 * To be notified of changes to a specific subId, append subId to the URI
386 * {@link Uri#withAppendedPath(Uri, String)}.
387 * @hide
388 */
chen xu81653862019-02-28 10:44:54 -0800389 @NonNull
chen xubf38b062018-11-01 00:08:37 -0700390 @SystemApi
391 public static final Uri WFC_ROAMING_MODE_CONTENT_URI = Uri.withAppendedPath(
392 CONTENT_URI, "wfc_roaming_mode");
393
394 /**
395 * A content {@link Uri} used to receive updates on vt(video telephony over IMS) enabled
396 * setting.
397 * <p>
398 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
399 * subscription vt enabled {@link ImsMmTelManager#isVtSettingEnabled()}
Makoto Onuki2da26292019-08-07 08:59:39 -0700400 * while your app is running. You can also use a {@link android.app.job.JobService} to ensure
401 * your app is notified of changes to the {@link Uri} even when it is not running.
402 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
403 * delivery of updates to the {@link Uri}.
chen xubf38b062018-11-01 00:08:37 -0700404 * To be notified of changes to a specific subId, append subId to the URI
405 * {@link Uri#withAppendedPath(Uri, String)}.
406 * @hide
407 */
chen xu81653862019-02-28 10:44:54 -0800408 @NonNull
chen xubf38b062018-11-01 00:08:37 -0700409 @SystemApi
410 public static final Uri VT_ENABLED_CONTENT_URI = Uri.withAppendedPath(
411 CONTENT_URI, "vt_enabled");
412
413 /**
414 * A content {@link Uri} used to receive updates on wfc roaming enabled setting.
415 * <p>
416 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
417 * subscription wfc roaming enabled {@link ImsMmTelManager#isVoWiFiRoamingSettingEnabled()}
Makoto Onuki2da26292019-08-07 08:59:39 -0700418 * while your app is running. You can also use a {@link android.app.job.JobService} to ensure
419 * your app is notified of changes to the {@link Uri} even when it is not running.
420 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
421 * delivery of updates to the {@link Uri}.
chen xubf38b062018-11-01 00:08:37 -0700422 * To be notified of changes to a specific subId, append subId to the URI
423 * {@link Uri#withAppendedPath(Uri, String)}.
424 * @hide
425 */
chen xu81653862019-02-28 10:44:54 -0800426 @NonNull
chen xubf38b062018-11-01 00:08:37 -0700427 @SystemApi
428 public static final Uri WFC_ROAMING_ENABLED_CONTENT_URI = Uri.withAppendedPath(
429 CONTENT_URI, "wfc_roaming_enabled");
chen xua0007492018-10-02 19:34:10 -0700430
Jack Nudelmane2ea4282021-01-13 18:46:57 -0800431
432 /**
433 * A content {@link uri} used to call the appropriate backup or restore method for sim-specific
434 * settings
435 * <p>
436 * See {@link #GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME} and {@link
437 * #RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME} for information on what method to call.
438 * @hide
439 */
440 @NonNull
441 public static final Uri SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI = Uri.withAppendedPath(
442 CONTENT_URI, "backup_and_restore");
443
444 /**
445 * A content {@link uri} used to notify contentobservers listening to siminfo restore during
446 * SuW.
447 * @hide
448 */
449 @NonNull
450 public static final Uri SIM_INFO_SUW_RESTORE_CONTENT_URI = Uri.withAppendedPath(
451 SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI, "suw_restore");
452
Wink Savillefb40dd42014-06-12 17:02:31 -0700453 /**
Sooraj Sasindrand1610872020-11-23 19:33:52 -0800454 * A content {@link Uri} used to receive updates on cross sim enabled user setting.
455 * <p>
456 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
457 * subscription cross sim calling enabled
Sooraj Sasindran1bf22692021-03-10 16:45:27 -0800458 * {@link ImsMmTelManager#isCrossSimCallingEnabled()}
Sooraj Sasindrand1610872020-11-23 19:33:52 -0800459 * while your app is running. You can also use a {@link android.app.job.JobService}
460 * to ensure your app
461 * is notified of changes to the {@link Uri} even when it is not running.
462 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
463 * delivery of updates to the {@link Uri}.
464 * To be notified of changes to a specific subId, append subId to the URI
465 * {@link Uri#withAppendedPath(Uri, String)}.
466 * @hide
467 */
468 @NonNull
469 @SystemApi
470 public static final Uri CROSS_SIM_ENABLED_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI,
471 SimInfo.COLUMN_CROSS_SIM_CALLING_ENABLED);
472
473 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -0800474 * TelephonyProvider unique key column name is the subscription id.
475 * <P>Type: TEXT (String)</P>
476 */
477 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800478 public static final String UNIQUE_KEY_SUBSCRIPTION_ID =
479 SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800480
481 /**
Vasu Noriaea03912018-09-04 11:19:59 -0700482 * TelephonyProvider column name for a unique identifier for the subscription within the
483 * specific subscription type. For example, it contains SIM ICC Identifier subscriptions
484 * on Local SIMs. and Mac-address for Remote-SIM Subscriptions for Bluetooth devices.
Wink Savillefb40dd42014-06-12 17:02:31 -0700485 * <P>Type: TEXT (String)</P>
486 */
Wink Savillef5bca082014-09-03 15:13:33 -0700487 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800488 public static final String ICC_ID = SimInfo.COLUMN_ICC_ID;
Wink Savillefb40dd42014-06-12 17:02:31 -0700489
490 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -0800491 * TelephonyProvider column name for user SIM_SlOT_INDEX
Wink Savillefb40dd42014-06-12 17:02:31 -0700492 * <P>Type: INTEGER (int)</P>
493 */
Wink Savillef5bca082014-09-03 15:13:33 -0700494 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800495 public static final String SIM_SLOT_INDEX = SimInfo.COLUMN_SIM_SLOT_INDEX;
Wink Saville905bb542014-09-04 17:10:23 -0700496
497 /** SIM is not inserted */
Wink Savillea374c3d2014-11-11 11:48:04 -0800498 /** @hide */
Peter Wang78af57d2019-11-25 16:50:50 -0800499 public static final int SIM_NOT_INSERTED = SimInfo.SIM_NOT_INSERTED;
Wink Savillefb40dd42014-06-12 17:02:31 -0700500
501 /**
Vasu Noriaea03912018-09-04 11:19:59 -0700502 * The slot-index for Bluetooth Remote-SIM subscriptions
503 * @hide
504 */
505 public static final int SLOT_INDEX_FOR_REMOTE_SIM_SUB = INVALID_SIM_SLOT_INDEX;
506
507 /**
508 * TelephonyProvider column name Subscription-type.
509 * <P>Type: INTEGER (int)</P> {@link #SUBSCRIPTION_TYPE_LOCAL_SIM} for Local-SIM Subscriptions,
510 * {@link #SUBSCRIPTION_TYPE_REMOTE_SIM} for Remote-SIM Subscriptions.
511 * Default value is 0.
512 */
513 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800514 public static final String SUBSCRIPTION_TYPE = SimInfo.COLUMN_SUBSCRIPTION_TYPE;
Malcolm Chen7611d692019-04-09 19:27:57 -0700515
516 /**
Ramya Manoharane88f8482022-04-21 05:02:14 +0000517 * TelephonyProvider column name for last used TP - message Reference
518 * <P>Type: INTEGER (int)</P> with -1 as default value
519 * TP - Message Reference valid range [0 - 255]
520 * @hide
521 */
522 public static final String TP_MESSAGE_REF = SimInfo.COLUMN_TP_MESSAGE_REF;
523
524 /**
Ling Ma640da902022-09-16 14:03:52 -0700525 * TelephonyProvider column name enabled_mobile_data_policies.
526 * A list of mobile data policies, each of which represented by an integer and joint by ",".
Jack Yua726a482019-05-23 16:37:35 -0700527 *
528 * Default value is empty string.
Jack Yua726a482019-05-23 16:37:35 -0700529 * @hide
530 */
Ling Ma640da902022-09-16 14:03:52 -0700531 public static final String ENABLED_MOBILE_DATA_POLICIES =
532 SimInfo.COLUMN_ENABLED_MOBILE_DATA_POLICIES;
Peter Wang78af57d2019-11-25 16:50:50 -0800533
534 /** @hide */
535 @Retention(RetentionPolicy.SOURCE)
536 @IntDef(prefix = {"SUBSCRIPTION_TYPE_"},
537 value = {
538 SUBSCRIPTION_TYPE_LOCAL_SIM,
539 SUBSCRIPTION_TYPE_REMOTE_SIM})
540 public @interface SubscriptionType {}
Jack Yua726a482019-05-23 16:37:35 -0700541
542 /**
Vasu Noriaea03912018-09-04 11:19:59 -0700543 * This constant is to designate a subscription as a Local-SIM Subscription.
544 * <p> A Local-SIM can be a physical SIM inserted into a sim-slot in the device, or eSIM on the
545 * device.
546 * </p>
547 */
Peter Wang78af57d2019-11-25 16:50:50 -0800548 public static final int SUBSCRIPTION_TYPE_LOCAL_SIM = SimInfo.SUBSCRIPTION_TYPE_LOCAL_SIM;
Vasu Noriaea03912018-09-04 11:19:59 -0700549
550 /**
551 * This constant is to designate a subscription as a Remote-SIM Subscription.
552 * <p>
553 * A Remote-SIM subscription is for a SIM on a phone connected to this device via some
554 * connectivity mechanism, for example bluetooth. Similar to Local SIM, this subscription can
555 * be used for SMS, Voice and data by proxying data through the connected device.
556 * Certain data of the SIM, such as IMEI, are not accessible for Remote SIMs.
557 * </p>
558 *
559 * <p>
560 * A Remote-SIM is available only as long the phone stays connected to this device.
561 * When the phone disconnects, Remote-SIM subscription is removed from this device and is
562 * no longer known. All data associated with the subscription, such as stored SMS, call logs,
563 * contacts etc, are removed from this device.
564 * </p>
565 *
566 * <p>
567 * If the phone re-connects to this device, a new Remote-SIM subscription is created for
568 * the phone. The Subscription Id associated with the new subscription is different from
569 * the Subscription Id of the previous Remote-SIM subscription created (and removed) for the
570 * phone; i.e., new Remote-SIM subscription treats the reconnected phone as a Remote-SIM that
571 * was never seen before.
572 * </p>
573 */
Peter Wang78af57d2019-11-25 16:50:50 -0800574 public static final int SUBSCRIPTION_TYPE_REMOTE_SIM = SimInfo.SUBSCRIPTION_TYPE_REMOTE_SIM;
Vasu Noriaea03912018-09-04 11:19:59 -0700575
576 /**
Wink Saville905bb542014-09-04 17:10:23 -0700577 * TelephonyProvider column name for user displayed name.
Wink Savillefb40dd42014-06-12 17:02:31 -0700578 * <P>Type: TEXT (String)</P>
579 */
Wink Savillef5bca082014-09-03 15:13:33 -0700580 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800581 public static final String DISPLAY_NAME = SimInfo.COLUMN_DISPLAY_NAME;
Wink Savillefb40dd42014-06-12 17:02:31 -0700582
Wink Saville905bb542014-09-04 17:10:23 -0700583 /**
Sanket Padawee1013f92014-11-07 11:37:29 -0800584 * TelephonyProvider column name for the service provider name for the SIM.
585 * <P>Type: TEXT (String)</P>
586 */
587 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800588 public static final String CARRIER_NAME = SimInfo.COLUMN_CARRIER_NAME;
Sanket Padawee1013f92014-11-07 11:37:29 -0800589
590 /**
Wink Saville905bb542014-09-04 17:10:23 -0700591 * Default name resource
592 * @hide
593 */
Wink Savillefb40dd42014-06-12 17:02:31 -0700594 public static final int DEFAULT_NAME_RES = com.android.internal.R.string.unknownName;
595
596 /**
Wink Saville905bb542014-09-04 17:10:23 -0700597 * TelephonyProvider column name for source of the user displayed name.
598 * <P>Type: INT (int)</P> with one of the NAME_SOURCE_XXXX values below
599 *
600 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -0700601 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800602 public static final String NAME_SOURCE = SimInfo.COLUMN_NAME_SOURCE;
Wink Savillefb40dd42014-06-12 17:02:31 -0700603
Wink Saville905bb542014-09-04 17:10:23 -0700604 /**
Jack Yu59ca6fc2022-10-07 23:06:20 -0700605 * The name_source is unknown. (for initialization)
606 * @hide
607 */
608 public static final int NAME_SOURCE_UNKNOWN = SimInfo.NAME_SOURCE_UNKNOWN;
609
610 /**
Peter Wang0ddf4402020-01-31 18:46:26 -0800611 * The name_source is from the carrier id.
Wink Saville905bb542014-09-04 17:10:23 -0700612 * @hide
613 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800614 public static final int NAME_SOURCE_CARRIER_ID = SimInfo.NAME_SOURCE_CARRIER_ID;
Wink Savillefb40dd42014-06-12 17:02:31 -0700615
Wink Saville905bb542014-09-04 17:10:23 -0700616 /**
Jack Yu5c6eb0e2019-10-16 09:16:54 -0700617 * The name_source is from SIM EF_SPN.
Wink Saville905bb542014-09-04 17:10:23 -0700618 * @hide
619 */
Peter Wang78af57d2019-11-25 16:50:50 -0800620 public static final int NAME_SOURCE_SIM_SPN = SimInfo.NAME_SOURCE_SIM_SPN;
Wink Savillec650e0b2014-09-02 22:37:08 -0700621
Wink Saville905bb542014-09-04 17:10:23 -0700622 /**
Jack Yu5c6eb0e2019-10-16 09:16:54 -0700623 * The name_source is from user input
Wink Saville905bb542014-09-04 17:10:23 -0700624 * @hide
625 */
Mathew Inwood45d2c252018-09-14 12:35:36 +0100626 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Peter Wang78af57d2019-11-25 16:50:50 -0800627 public static final int NAME_SOURCE_USER_INPUT = SimInfo.NAME_SOURCE_USER_INPUT;
Wink Savillefb40dd42014-06-12 17:02:31 -0700628
629 /**
Amit Mahajanecdf8c52019-05-14 10:36:15 -0700630 * The name_source is carrier (carrier app, carrier config, etc.)
631 * @hide
632 */
Peter Wang78af57d2019-11-25 16:50:50 -0800633 public static final int NAME_SOURCE_CARRIER = SimInfo.NAME_SOURCE_CARRIER;
Amit Mahajanecdf8c52019-05-14 10:36:15 -0700634
635 /**
Jack Yu5c6eb0e2019-10-16 09:16:54 -0700636 * The name_source is from SIM EF_PNN.
637 * @hide
638 */
Peter Wang78af57d2019-11-25 16:50:50 -0800639 public static final int NAME_SOURCE_SIM_PNN = SimInfo.NAME_SOURCE_SIM_PNN;
Jack Yu5c6eb0e2019-10-16 09:16:54 -0700640
641 /** @hide */
642 @Retention(RetentionPolicy.SOURCE)
643 @IntDef(prefix = {"NAME_SOURCE_"},
644 value = {
Jack Yu59ca6fc2022-10-07 23:06:20 -0700645 NAME_SOURCE_UNKNOWN,
Peter Wang0ddf4402020-01-31 18:46:26 -0800646 NAME_SOURCE_CARRIER_ID,
Jack Yu5c6eb0e2019-10-16 09:16:54 -0700647 NAME_SOURCE_SIM_SPN,
648 NAME_SOURCE_USER_INPUT,
649 NAME_SOURCE_CARRIER,
650 NAME_SOURCE_SIM_PNN
651 })
652 public @interface SimDisplayNameSource {}
653
654 /**
Grace Jiab53cb662021-02-12 15:29:29 -0800655 * Device status is not shared to a remote party.
656 */
657 public static final int D2D_SHARING_DISABLED = 0;
658
659 /**
660 * Device status is shared with all numbers in the user's contacts.
661 */
662 public static final int D2D_SHARING_ALL_CONTACTS = 1;
663
664 /**
Grace Jia2bd23cf2021-03-18 14:47:31 -0700665 * Device status is shared with all selected contacts.
Grace Jiab53cb662021-02-12 15:29:29 -0800666 */
Grace Jia2bd23cf2021-03-18 14:47:31 -0700667 public static final int D2D_SHARING_SELECTED_CONTACTS = 2;
Grace Jiab53cb662021-02-12 15:29:29 -0800668
669 /**
670 * Device status is shared whenever possible.
671 */
672 public static final int D2D_SHARING_ALL = 3;
673
674 /** @hide */
675 @Retention(RetentionPolicy.SOURCE)
676 @IntDef(prefix = {"D2D_SHARING_"},
677 value = {
678 D2D_SHARING_DISABLED,
679 D2D_SHARING_ALL_CONTACTS,
Grace Jia2bd23cf2021-03-18 14:47:31 -0700680 D2D_SHARING_SELECTED_CONTACTS,
Grace Jiab53cb662021-02-12 15:29:29 -0800681 D2D_SHARING_ALL
682 })
Grace Jiaaeea4ec2021-03-10 14:00:43 -0800683 public @interface DeviceToDeviceStatusSharingPreference {}
Grace Jiab53cb662021-02-12 15:29:29 -0800684
685 /**
686 * TelephonyProvider column name for device to device sharing status.
687 * <P>Type: INTEGER (int)</P>
688 */
689 public static final String D2D_STATUS_SHARING = SimInfo.COLUMN_D2D_STATUS_SHARING;
690
691 /**
Grace Jia2bd23cf2021-03-18 14:47:31 -0700692 * TelephonyProvider column name for contacts information that allow device to device sharing.
693 * <P>Type: TEXT (String)</P>
694 */
695 public static final String D2D_STATUS_SHARING_SELECTED_CONTACTS =
696 SimInfo.COLUMN_D2D_STATUS_SHARING_SELECTED_CONTACTS;
697
698 /**
Wink Saville905bb542014-09-04 17:10:23 -0700699 * TelephonyProvider column name for the color of a SIM.
Wink Savillefb40dd42014-06-12 17:02:31 -0700700 * <P>Type: INTEGER (int)</P>
701 */
Wink Savillef5bca082014-09-03 15:13:33 -0700702 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800703 public static final String HUE = SimInfo.COLUMN_COLOR;
Wink Savillefb40dd42014-06-12 17:02:31 -0700704
705 /**
Wink Saville905bb542014-09-04 17:10:23 -0700706 * TelephonyProvider column name for the phone number of a SIM.
Wink Savillefb40dd42014-06-12 17:02:31 -0700707 * <P>Type: TEXT (String)</P>
708 */
Wink Savillef5bca082014-09-03 15:13:33 -0700709 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800710 public static final String NUMBER = SimInfo.COLUMN_NUMBER;
Wink Savillefb40dd42014-06-12 17:02:31 -0700711
712 /**
Peter Wang78af57d2019-11-25 16:50:50 -0800713 * TelephonyProvider column name for whether data roaming is enabled.
Wink Savillefb40dd42014-06-12 17:02:31 -0700714 * <P>Type: INTEGER (int)</P>
715 */
Wink Savillef5bca082014-09-03 15:13:33 -0700716 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800717 public static final String DATA_ROAMING = SimInfo.COLUMN_DATA_ROAMING;
Wink Savillefb40dd42014-06-12 17:02:31 -0700718
Stuart Scott400a3f62015-01-14 10:49:49 -0800719 /** Indicates that data roaming is enabled for a subscription */
Peter Wang78af57d2019-11-25 16:50:50 -0800720 public static final int DATA_ROAMING_ENABLE = SimInfo.DATA_ROAMING_ENABLE;
Wink Savillefb40dd42014-06-12 17:02:31 -0700721
Stuart Scott400a3f62015-01-14 10:49:49 -0800722 /** Indicates that data roaming is disabled for a subscription */
Peter Wang78af57d2019-11-25 16:50:50 -0800723 public static final int DATA_ROAMING_DISABLE = SimInfo.DATA_ROAMING_DISABLE;
Wink Savillefb40dd42014-06-12 17:02:31 -0700724
Jack Yu37742192022-12-09 02:20:59 -0800725 /** @hide */
726 @Retention(RetentionPolicy.SOURCE)
727 @IntDef(prefix = {"DATA_ROAMING_"},
728 value = {
729 DATA_ROAMING_ENABLE,
730 DATA_ROAMING_DISABLE
731 })
732 public @interface DataRoamingMode {}
733
Tom Taylor7a962072014-09-04 14:05:20 -0700734 /**
chen xu64e81db2018-12-14 00:14:06 -0800735 * TelephonyProvider column name for subscription carrier id.
736 * @see TelephonyManager#getSimCarrierId()
737 * <p>Type: INTEGER (int) </p>
738 * @hide
739 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800740 public static final String CARRIER_ID = SimInfo.COLUMN_CARRIER_ID;
chen xu64e81db2018-12-14 00:14:06 -0800741
742 /**
Hall Liue0ac1f72019-04-11 15:28:20 -0700743 * @hide A comma-separated list of EHPLMNs associated with the subscription
744 * <P>Type: TEXT (String)</P>
745 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800746 public static final String EHPLMNS = SimInfo.COLUMN_EHPLMNS;
Hall Liue0ac1f72019-04-11 15:28:20 -0700747
748 /**
749 * @hide A comma-separated list of HPLMNs associated with the subscription
750 * <P>Type: TEXT (String)</P>
751 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800752 public static final String HPLMNS = SimInfo.COLUMN_HPLMNS;
Hall Liue0ac1f72019-04-11 15:28:20 -0700753
754 /**
Hall Liu0c149bd2018-06-08 18:14:21 -0700755 * TelephonyProvider column name for the MCC associated with a SIM, stored as a string.
756 * <P>Type: TEXT (String)</P>
757 * @hide
758 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800759 public static final String MCC_STRING = SimInfo.COLUMN_MCC_STRING;
Hall Liu0c149bd2018-06-08 18:14:21 -0700760
761 /**
762 * TelephonyProvider column name for the MNC associated with a SIM, stored as a string.
763 * <P>Type: TEXT (String)</P>
764 * @hide
765 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800766 public static final String MNC_STRING = SimInfo.COLUMN_MNC_STRING;
Hall Liu0c149bd2018-06-08 18:14:21 -0700767
768 /**
Wink Saville905bb542014-09-04 17:10:23 -0700769 * TelephonyProvider column name for the MCC associated with a SIM.
Tom Taylor7a962072014-09-04 14:05:20 -0700770 * <P>Type: INTEGER (int)</P>
Wink Savillea374c3d2014-11-11 11:48:04 -0800771 * @hide
Tom Taylor7a962072014-09-04 14:05:20 -0700772 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800773 public static final String MCC = SimInfo.COLUMN_MCC;
Tom Taylor7a962072014-09-04 14:05:20 -0700774
775 /**
Wink Saville905bb542014-09-04 17:10:23 -0700776 * TelephonyProvider column name for the MNC associated with a SIM.
Tom Taylor7a962072014-09-04 14:05:20 -0700777 * <P>Type: INTEGER (int)</P>
Wink Savillea374c3d2014-11-11 11:48:04 -0800778 * @hide
Tom Taylor7a962072014-09-04 14:05:20 -0700779 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800780 public static final String MNC = SimInfo.COLUMN_MNC;
Tom Taylor7a962072014-09-04 14:05:20 -0700781
Wink Savillec650e0b2014-09-02 22:37:08 -0700782 /**
chen xua2618622018-12-02 14:14:15 -0800783 * TelephonyProvider column name for the iso country code associated with a SIM.
784 * <P>Type: TEXT (String)</P>
785 * @hide
786 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800787 public static final String ISO_COUNTRY_CODE = SimInfo.COLUMN_ISO_COUNTRY_CODE;
chen xua2618622018-12-02 14:14:15 -0800788
789 /**
Jeff Davidsond02731f2017-04-09 14:31:09 -0700790 * TelephonyProvider column name for whether a subscription is embedded (that is, present on an
791 * eSIM).
792 * <p>Type: INTEGER (int), 1 for embedded or 0 for non-embedded.
793 * @hide
794 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800795 public static final String IS_EMBEDDED = SimInfo.COLUMN_IS_EMBEDDED;
Jeff Davidsond02731f2017-04-09 14:31:09 -0700796
797 /**
yinxu921daf92018-01-05 11:15:24 -0800798 * TelephonyProvider column name for SIM card identifier. For UICC card it is the ICCID of the
799 * current enabled profile on the card, while for eUICC card it is the EID of the card.
800 * <P>Type: TEXT (String)</P>
801 * @hide
802 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800803 public static final String CARD_ID = SimInfo.COLUMN_CARD_ID;
yinxu921daf92018-01-05 11:15:24 -0800804
805 /**
Jeff Davidsond02731f2017-04-09 14:31:09 -0700806 * TelephonyProvider column name for the encoded {@link UiccAccessRule}s from
807 * {@link UiccAccessRule#encodeRules}. Only present if {@link #IS_EMBEDDED} is 1.
808 * <p>TYPE: BLOB
809 * @hide
810 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800811 public static final String ACCESS_RULES = SimInfo.COLUMN_ACCESS_RULES;
Jeff Davidsond02731f2017-04-09 14:31:09 -0700812
813 /**
Nazanin Bakhshi693cec22019-08-02 16:43:44 -0700814 * TelephonyProvider column name for the encoded {@link UiccAccessRule}s from
815 * {@link UiccAccessRule#encodeRules} but for the rules that come from CarrierConfigs.
816 * Only present if there are access rules in CarrierConfigs
817 * <p>TYPE: BLOB
818 * @hide
819 */
820 public static final String ACCESS_RULES_FROM_CARRIER_CONFIGS =
Peter Wang0ddf4402020-01-31 18:46:26 -0800821 SimInfo.COLUMN_ACCESS_RULES_FROM_CARRIER_CONFIGS;
Nazanin Bakhshi693cec22019-08-02 16:43:44 -0700822
823 /**
Jeff Davidsond02731f2017-04-09 14:31:09 -0700824 * TelephonyProvider column name identifying whether an embedded subscription is on a removable
825 * card. Such subscriptions are marked inaccessible as soon as the current card is removed.
826 * Otherwise, they will remain accessible unless explicitly deleted. Only present if
827 * {@link #IS_EMBEDDED} is 1.
828 * <p>TYPE: INTEGER (int), 1 for removable or 0 for non-removable.
829 * @hide
830 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800831 public static final String IS_REMOVABLE = SimInfo.COLUMN_IS_REMOVABLE;
Jeff Davidsond02731f2017-04-09 14:31:09 -0700832
833 /**
Sanket Padawedc493092015-07-14 14:21:43 -0700834 * TelephonyProvider column name for extreme threat in CB settings
835 * @hide
836 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800837 public static final String CB_EXTREME_THREAT_ALERT =
838 SimInfo.COLUMN_CB_EXTREME_THREAT_ALERT;
Sanket Padawedc493092015-07-14 14:21:43 -0700839
840 /**
841 * TelephonyProvider column name for severe threat in CB settings
842 *@hide
843 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800844 public static final String CB_SEVERE_THREAT_ALERT = SimInfo.COLUMN_CB_SEVERE_THREAT_ALERT;
Sanket Padawedc493092015-07-14 14:21:43 -0700845
846 /**
847 * TelephonyProvider column name for amber alert in CB settings
848 *@hide
849 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800850 public static final String CB_AMBER_ALERT = SimInfo.COLUMN_CB_AMBER_ALERT;
Sanket Padawedc493092015-07-14 14:21:43 -0700851
852 /**
853 * TelephonyProvider column name for emergency alert in CB settings
854 *@hide
855 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800856 public static final String CB_EMERGENCY_ALERT = SimInfo.COLUMN_CB_EMERGENCY_ALERT;
Sanket Padawedc493092015-07-14 14:21:43 -0700857
858 /**
859 * TelephonyProvider column name for alert sound duration in CB settings
860 *@hide
861 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800862 public static final String CB_ALERT_SOUND_DURATION =
863 SimInfo.COLUMN_CB_ALERT_SOUND_DURATION;
Sanket Padawedc493092015-07-14 14:21:43 -0700864
865 /**
866 * TelephonyProvider column name for alert reminder interval in CB settings
867 *@hide
868 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800869 public static final String CB_ALERT_REMINDER_INTERVAL =
870 SimInfo.COLUMN_CB_ALERT_REMINDER_INTERVAL;
Sanket Padawedc493092015-07-14 14:21:43 -0700871
872 /**
873 * TelephonyProvider column name for enabling vibrate in CB settings
874 *@hide
875 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800876 public static final String CB_ALERT_VIBRATE = SimInfo.COLUMN_CB_ALERT_VIBRATE;
Sanket Padawedc493092015-07-14 14:21:43 -0700877
878 /**
879 * TelephonyProvider column name for enabling alert speech in CB settings
880 *@hide
881 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800882 public static final String CB_ALERT_SPEECH = SimInfo.COLUMN_CB_ALERT_SPEECH;
Sanket Padawedc493092015-07-14 14:21:43 -0700883
884 /**
885 * TelephonyProvider column name for ETWS test alert in CB settings
886 *@hide
887 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800888 public static final String CB_ETWS_TEST_ALERT = SimInfo.COLUMN_CB_ETWS_TEST_ALERT;
Sanket Padawedc493092015-07-14 14:21:43 -0700889
890 /**
891 * TelephonyProvider column name for enable channel50 alert in CB settings
892 *@hide
893 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800894 public static final String CB_CHANNEL_50_ALERT = SimInfo.COLUMN_CB_CHANNEL_50_ALERT;
Sanket Padawedc493092015-07-14 14:21:43 -0700895
896 /**
897 * TelephonyProvider column name for CMAS test alert in CB settings
898 *@hide
899 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800900 public static final String CB_CMAS_TEST_ALERT = SimInfo.COLUMN_CB_CMAS_TEST_ALERT;
Sanket Padawedc493092015-07-14 14:21:43 -0700901
902 /**
903 * TelephonyProvider column name for Opt out dialog in CB settings
904 *@hide
905 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800906 public static final String CB_OPT_OUT_DIALOG = SimInfo.COLUMN_CB_OPT_OUT_DIALOG;
Sanket Padawedc493092015-07-14 14:21:43 -0700907
908 /**
Malcolm Chenc66dee92017-09-26 14:45:40 -0700909 * TelephonyProvider column name for enable Volte.
Jordan Liud6350112017-11-14 13:45:19 -0800910 *
911 * If this setting is not initialized (set to -1) then we use the Carrier Config value
912 * {@link CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL}.
Malcolm Chenc66dee92017-09-26 14:45:40 -0700913 *@hide
914 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800915 public static final String ENHANCED_4G_MODE_ENABLED =
916 SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED;
Malcolm Chenc66dee92017-09-26 14:45:40 -0700917
918 /**
919 * TelephonyProvider column name for enable VT (Video Telephony over IMS)
920 *@hide
921 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800922 public static final String VT_IMS_ENABLED = SimInfo.COLUMN_VT_IMS_ENABLED;
Malcolm Chenc66dee92017-09-26 14:45:40 -0700923
924 /**
925 * TelephonyProvider column name for enable Wifi calling
926 *@hide
927 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800928 public static final String WFC_IMS_ENABLED = SimInfo.COLUMN_WFC_IMS_ENABLED;
Malcolm Chenc66dee92017-09-26 14:45:40 -0700929
930 /**
931 * TelephonyProvider column name for Wifi calling mode
932 *@hide
933 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800934 public static final String WFC_IMS_MODE = SimInfo.COLUMN_WFC_IMS_MODE;
Malcolm Chenc66dee92017-09-26 14:45:40 -0700935
936 /**
937 * TelephonyProvider column name for Wifi calling mode in roaming
938 *@hide
939 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800940 public static final String WFC_IMS_ROAMING_MODE = SimInfo.COLUMN_WFC_IMS_ROAMING_MODE;
Malcolm Chenc66dee92017-09-26 14:45:40 -0700941
942 /**
943 * TelephonyProvider column name for enable Wifi calling in roaming
944 *@hide
945 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800946 public static final String WFC_IMS_ROAMING_ENABLED = SimInfo.COLUMN_WFC_IMS_ROAMING_ENABLED;
Malcolm Chenc66dee92017-09-26 14:45:40 -0700947
948 /**
Brad Ebinger41c232c2020-01-22 16:09:57 -0800949 * Determines if the user has enabled IMS RCS User Capability Exchange (UCE) for this
950 * subscription.
951 * @hide
952 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800953 public static final String IMS_RCS_UCE_ENABLED = SimInfo.COLUMN_IMS_RCS_UCE_ENABLED;
Brad Ebinger41c232c2020-01-22 16:09:57 -0800954
955 /**
Jack Yuea905072020-11-17 19:48:31 -0800956 * Determines if the user has enabled cross SIM calling for this subscription.
957 *
958 * @hide
959 */
960 public static final String CROSS_SIM_CALLING_ENABLED = SimInfo.COLUMN_CROSS_SIM_CALLING_ENABLED;
961
962 /**
Malcolm Chen0ac24ef2018-08-07 15:03:32 -0700963 * TelephonyProvider column name for whether a subscription is opportunistic, that is,
964 * whether the network it connects to is limited in functionality or coverage.
965 * For example, CBRS.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -0700966 * <p>Type: INTEGER (int), 1 for opportunistic or 0 for non-opportunistic.
967 * @hide
968 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800969 public static final String IS_OPPORTUNISTIC = SimInfo.COLUMN_IS_OPPORTUNISTIC;
Malcolm Chen52f6dff2018-11-28 11:15:57 -0800970
Malcolm Chen0ac24ef2018-08-07 15:03:32 -0700971 /**
Malcolm Chenaea9b022018-10-31 20:18:02 -0700972 * TelephonyProvider column name for group ID. Subscriptions with same group ID
973 * are considered bundled together, and should behave as a single subscription at
974 * certain scenarios.
975 *
976 * @hide
977 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800978 public static final String GROUP_UUID = SimInfo.COLUMN_GROUP_UUID;
Malcolm Chen52f6dff2018-11-28 11:15:57 -0800979
Nazanin Bakhshib9b87be2018-11-21 16:32:05 -0800980 /**
Malcolm Chen0b9b81b2019-03-29 17:13:08 -0700981 * TelephonyProvider column name for group owner. It's the package name who created
982 * the subscription group.
983 *
984 * @hide
985 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800986 public static final String GROUP_OWNER = SimInfo.COLUMN_GROUP_OWNER;
Malcolm Chen52f6dff2018-11-28 11:15:57 -0800987
Malcolm Chenaea9b022018-10-31 20:18:02 -0700988 /**
Grace Chen5be6e9c2018-12-20 22:50:18 -0800989 * TelephonyProvider column name for the profile class of a subscription
990 * Only present if {@link #IS_EMBEDDED} is 1.
991 * <P>Type: INTEGER (int)</P>
992 * @hide
993 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800994 public static final String PROFILE_CLASS = SimInfo.COLUMN_PROFILE_CLASS;
Grace Chen5be6e9c2018-12-20 22:50:18 -0800995
996 /**
Muralidhar Reddy090a67a2021-12-10 21:11:28 +0000997 * TelephonyProvider column name for the port index of the active UICC port.
998 * <P>Type: INTEGER (int)</P>
999 * @hide
1000 */
1001 public static final String PORT_INDEX = SimInfo.COLUMN_PORT_INDEX;
1002
1003 /**
Jayachandran Chinnakkannu2cdad9f2021-02-18 20:55:44 +08001004 * TelephonyProvider column name for VoIMS opt-in status.
1005 *
1006 * <P>Type: INTEGER (int)</P>
1007 * @hide
1008 */
1009 public static final String VOIMS_OPT_IN_STATUS = SimInfo.COLUMN_VOIMS_OPT_IN_STATUS;
1010
1011 /**
Gary Jian204ec2a2021-10-13 13:09:54 +08001012 * TelephonyProvider column name for NR Advanced calling
1013 * Determines if the user has enabled VoNR settings for this subscription.
1014 *
1015 * @hide
1016 */
1017 public static final String NR_ADVANCED_CALLING_ENABLED =
1018 SimInfo.COLUMN_NR_ADVANCED_CALLING_ENABLED;
1019
1020 /**
Grace Chen5be6e9c2018-12-20 22:50:18 -08001021 * Profile class of the subscription
1022 * @hide
1023 */
1024 @Retention(RetentionPolicy.SOURCE)
1025 @IntDef(prefix = { "PROFILE_CLASS_" }, value = {
Peter Wang78af57d2019-11-25 16:50:50 -08001026 SimInfo.PROFILE_CLASS_TESTING,
1027 SimInfo.PROFILE_CLASS_PROVISIONING,
1028 SimInfo.PROFILE_CLASS_OPERATIONAL,
1029 SimInfo.PROFILE_CLASS_UNSET,
Grace Chen5be6e9c2018-12-20 22:50:18 -08001030 })
1031 public @interface ProfileClass {}
1032
1033 /**
1034 * A testing profile can be pre-loaded or downloaded onto
1035 * the eUICC and provides connectivity to test equipment
1036 * for the purpose of testing the device and the eUICC. It
1037 * is not intended to store any operator credentials.
1038 * @hide
1039 */
1040 @SystemApi
Peter Wang78af57d2019-11-25 16:50:50 -08001041 public static final int PROFILE_CLASS_TESTING = SimInfo.PROFILE_CLASS_TESTING;
Grace Chen5be6e9c2018-12-20 22:50:18 -08001042
1043 /**
1044 * A provisioning profile is pre-loaded onto the eUICC and
1045 * provides connectivity to a mobile network solely for the
1046 * purpose of provisioning profiles.
1047 * @hide
1048 */
1049 @SystemApi
Peter Wang78af57d2019-11-25 16:50:50 -08001050 public static final int PROFILE_CLASS_PROVISIONING = SimInfo.PROFILE_CLASS_PROVISIONING;
Grace Chen5be6e9c2018-12-20 22:50:18 -08001051
1052 /**
1053 * An operational profile can be pre-loaded or downloaded
1054 * onto the eUICC and provides services provided by the
1055 * operator.
1056 * @hide
1057 */
1058 @SystemApi
Peter Wang78af57d2019-11-25 16:50:50 -08001059 public static final int PROFILE_CLASS_OPERATIONAL = SimInfo.PROFILE_CLASS_OPERATIONAL;
Grace Chen5be6e9c2018-12-20 22:50:18 -08001060
1061 /**
1062 * The profile class is unset. This occurs when profile class
1063 * info is not available. The subscription either has no profile
1064 * metadata or the profile metadata did not encode profile class.
1065 * @hide
1066 */
1067 @SystemApi
Peter Wang78af57d2019-11-25 16:50:50 -08001068 public static final int PROFILE_CLASS_UNSET = SimInfo.PROFILE_CLASS_UNSET;
Grace Chen5be6e9c2018-12-20 22:50:18 -08001069
1070 /**
1071 * Default profile class
1072 * @hide
1073 */
1074 @SystemApi
Peter Wang0ddf4402020-01-31 18:46:26 -08001075 @Deprecated
1076 public static final int PROFILE_CLASS_DEFAULT = SimInfo.PROFILE_CLASS_UNSET;
Grace Chen5be6e9c2018-12-20 22:50:18 -08001077
1078 /**
Nazanin Bakhshi1eaf7a82019-05-31 16:34:10 -07001079 * IMSI (International Mobile Subscriber Identity).
1080 * <P>Type: TEXT </P>
1081 * @hide
1082 */
1083 //TODO: add @SystemApi
Peter Wang0ddf4402020-01-31 18:46:26 -08001084 public static final String IMSI = SimInfo.COLUMN_IMSI;
Nazanin Bakhshi1eaf7a82019-05-31 16:34:10 -07001085
1086 /**
Malcolm Chenb7c6ee382019-12-04 19:07:56 -08001087 * Whether uicc applications is set to be enabled or disabled. By default it's enabled.
1088 * @hide
1089 */
Peter Wang0ddf4402020-01-31 18:46:26 -08001090 public static final String UICC_APPLICATIONS_ENABLED = SimInfo.COLUMN_UICC_APPLICATIONS_ENABLED;
Malcolm Chenb7c6ee382019-12-04 19:07:56 -08001091
1092 /**
Nathan Haroldbd5f0d92021-11-02 19:20:56 -07001093 * Indicate which network type is allowed.
calvinpand77e0bd2020-01-14 20:37:31 +08001094 * @hide
1095 */
SongFerngWang7d951852020-12-21 16:24:25 +08001096 public static final String ALLOWED_NETWORK_TYPES =
1097 SimInfo.COLUMN_ALLOWED_NETWORK_TYPES_FOR_REASONS;
calvinpand77e0bd2020-01-14 20:37:31 +08001098
Aishwarya Mallampati747cef72022-09-20 22:51:48 +00001099 /**
1100 * TelephonyProvider column name for user handle associated with a sim.
1101 * <P>Type: INTEGER (int)</P>
1102 * @hide
1103 */
1104 public static final String USER_HANDLE = SimInfo.COLUMN_USER_HANDLE;
1105
Aishwarya Mallampatidc116102022-12-22 19:20:11 +00001106 /**
1107 * TelephonyProvider column name for satellite enabled.
1108 * By default, it's disabled.
1109 * <P>Type: INTEGER (int)</P>
1110 * @hide
1111 */
1112 public static final String SATELLITE_ENABLED = SimInfo.COLUMN_SATELLITE_ENABLED;
1113
Hakjun Choi7303de32023-08-04 04:46:47 +00001114 /**
1115 * TelephonyProvider column name for satellite attach enabled for carrier. The value of this
1116 * column is set based on user settings.
Hyosun Kim44046672024-01-25 14:02:27 +00001117 * By default, it's enabled.
Hakjun Choi7303de32023-08-04 04:46:47 +00001118 * <P>Type: INTEGER (int)</P>
1119 * @hide
1120 */
1121 public static final String SATELLITE_ATTACH_ENABLED_FOR_CARRIER =
1122 SimInfo.COLUMN_SATELLITE_ATTACH_ENABLED_FOR_CARRIER;
1123
Hakjun Choi70e69c02023-09-06 07:31:32 +00001124 /**
1125 * TelephonyProvider column name to identify eSIM profile of a non-terrestrial network.
1126 * By default, it's disabled.
1127 * <P>Type: INTEGER (int)</P>
1128 * @hide
1129 */
1130 public static final String IS_NTN = SimInfo.COLUMN_IS_NTN;
1131
rambowang558016e2023-12-04 10:22:13 -06001132 /**
1133 * TelephonyProvider column name to identify service capabilities.
1134 * Disabled by default.
1135 * <P>Type: INTEGER (int)</P>
1136 * @hide
1137 */
1138 public static final String SERVICE_CAPABILITIES = SimInfo.COLUMN_SERVICE_CAPABILITIES;
1139
Hyunhoaeba1f22024-01-11 08:52:29 +00001140 /**
1141 * TelephonyProvider column name to identify eSIM's transfer status.
1142 * By default, it's disabled.
1143 * <P>Type: INTEGER (int)</P>
1144 * @hide
1145 */
1146 public static final String TRANSFER_STATUS = SimInfo.COLUMN_TRANSFER_STATUS;
1147
Hyosun Kim8dfd5692024-01-30 10:02:38 +00001148 /**
1149 * TelephonyProvider column name for satellite entitlement status. The value of this column is
1150 * set based on entitlement query result for satellite configuration.
1151 * By default, it's disabled.
1152 * <P>Type: INTEGER (int)</P>
1153 *
1154 * @hide
1155 */
1156 public static final String SATELLITE_ENTITLEMENT_STATUS =
1157 SimInfo.COLUMN_SATELLITE_ENTITLEMENT_STATUS;
1158
1159 /**
1160 * TelephonyProvider column name for satellite entitlement plmns. The value of this column is
1161 * set based on entitlement query result for satellite configuration.
1162 * By default, it's empty.
1163 * <P>Type: TEXT </P>
1164 *
1165 * @hide
1166 */
1167 public static final String SATELLITE_ENTITLEMENT_PLMNS =
1168 SimInfo.COLUMN_SATELLITE_ENTITLEMENT_PLMNS;
1169
Nathan Harold7e2d58a2021-11-02 16:32:06 -07001170 /** @hide */
1171 @Retention(RetentionPolicy.SOURCE)
1172 @IntDef(prefix = {"USAGE_SETTING_"},
1173 value = {
1174 USAGE_SETTING_UNKNOWN,
1175 USAGE_SETTING_DEFAULT,
1176 USAGE_SETTING_VOICE_CENTRIC,
1177 USAGE_SETTING_DATA_CENTRIC})
1178 public @interface UsageSetting {}
1179
1180 /**
1181 * The usage setting is unknown.
1182 *
1183 * This will be the usage setting returned on devices that do not support querying the
1184 * or setting the usage setting.
1185 *
1186 * It may also be provided by a carrier that wishes to provide a value to avoid making any
1187 * settings changes.
Nathan Harold7e2d58a2021-11-02 16:32:06 -07001188 */
1189 public static final int USAGE_SETTING_UNKNOWN = -1;
1190
1191 /**
1192 * Subscription uses the default setting.
1193 *
1194 * The value is based upon device capability and the other properties of the subscription.
1195 *
1196 * Most subscriptions will default to voice-centric when in a phone.
1197 *
1198 * An opportunistic subscription will default to data-centric.
1199 *
Jack Yu647bbb92022-12-12 21:45:26 -08001200 * @see SubscriptionInfo#isOpportunistic
Nathan Harold7e2d58a2021-11-02 16:32:06 -07001201 */
1202 public static final int USAGE_SETTING_DEFAULT = 0;
1203
1204 /**
1205 * This subscription is forced to voice-centric mode
1206 *
Nathan Harolddff34b32021-12-15 16:38:25 -08001207 * <p>Refer to voice-centric mode in 3gpp 24.301 sec 4.3 and 3gpp 24.501 sec 4.3.
1208 * Also refer to "UE's usage setting" as defined in 3gpp 24.301 section 3.1 and 3gpp 23.221
1209 * Annex A.
Nathan Haroldb36dcb02022-03-25 13:51:55 -07001210 *
1211 * <p>Devices that support {@link PackageManager#FEATURE_TELEPHONY_CALLING} and support usage
1212 * setting configuration must support setting this value via
1213 * {@link CarrierConfigManager#KEY_CELLULAR_USAGE_SETTING_INT}.
Nathan Harold7e2d58a2021-11-02 16:32:06 -07001214 */
1215 public static final int USAGE_SETTING_VOICE_CENTRIC = 1;
1216
1217 /**
1218 * This subscription is forced to data-centric mode
1219 *
Nathan Harolddff34b32021-12-15 16:38:25 -08001220 * <p>Refer to data-centric mode in 3gpp 24.301 sec 4.3 and 3gpp 24.501 sec 4.3.
1221 * Also refer to "UE's usage setting" as defined in 3gpp 24.301 section 3.1 and 3gpp 23.221
1222 * Annex A.
Nathan Haroldb36dcb02022-03-25 13:51:55 -07001223 *
1224 * <p>Devices that support {@link PackageManager#FEATURE_TELEPHONY_DATA} and support usage
1225 * setting configuration must support setting this value via.
1226 * {@link CarrierConfigManager#KEY_CELLULAR_USAGE_SETTING_INT}.
Nathan Harold7e2d58a2021-11-02 16:32:06 -07001227 */
1228 public static final int USAGE_SETTING_DATA_CENTRIC = 2;
1229
calvinpand77e0bd2020-01-14 20:37:31 +08001230 /**
Nathan Haroldbd5f0d92021-11-02 19:20:56 -07001231 * Indicate the preferred usage setting for the subscription.
1232 *
1233 * 0 - Default - If the value has not been explicitly set, it will be "default"
1234 * 1 - Voice-centric
1235 * 2 - Data-centric
1236 *
1237 * @hide
1238 */
1239 public static final String USAGE_SETTING = SimInfo.COLUMN_USAGE_SETTING;
1240
1241 /**
Wink Savillec650e0b2014-09-02 22:37:08 -07001242 * Broadcast Action: The user has changed one of the default subs related to
1243 * data, phone calls, or sms</p>
Wink Savilled09c4ca2014-11-22 10:08:16 -08001244 *
1245 * TODO: Change to a listener
Wink Savillef5bca082014-09-03 15:13:33 -07001246 * @hide
Wink Savillec650e0b2014-09-02 22:37:08 -07001247 */
1248 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1249 public static final String SUB_DEFAULT_CHANGED_ACTION =
Rajeev Kumarc8ac4f3b2017-07-26 15:59:08 -07001250 "android.intent.action.SUB_DEFAULT_CHANGED";
Wink Savillefb40dd42014-06-12 17:02:31 -07001251
Malcolm Chen598d24c2017-04-24 18:37:29 -07001252 /**
1253 * Broadcast Action: The default subscription has changed. This has the following
1254 * extra values:</p>
1255 * The {@link #EXTRA_SUBSCRIPTION_INDEX} extra indicates the current default subscription index
1256 */
1257 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1258 public static final String ACTION_DEFAULT_SUBSCRIPTION_CHANGED
1259 = "android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED";
1260
1261 /**
1262 * Broadcast Action: The default sms subscription has changed. This has the following
1263 * extra values:</p>
1264 * {@link #EXTRA_SUBSCRIPTION_INDEX} extra indicates the current default sms
1265 * subscription index
1266 */
1267 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1268 public static final String ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED
1269 = "android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED";
1270
1271 /**
Jeff Sharkey717f52f2018-01-04 16:04:11 -07001272 * Activity Action: Display UI for managing the billing relationship plans
1273 * between a carrier and a specific subscriber.
1274 * <p>
1275 * Carrier apps are encouraged to implement this activity, and the OS will
1276 * provide an affordance to quickly enter this activity, typically via
1277 * Settings. This affordance will only be shown when the carrier app is
1278 * actively providing subscription plan information via
1279 * {@link #setSubscriptionPlans(int, List)}.
1280 * <p>
1281 * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
1282 * the user is interested in.
Jeff Sharkey717f52f2018-01-04 16:04:11 -07001283 */
1284 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
Jeff Sharkey717f52f2018-01-04 16:04:11 -07001285 public static final String ACTION_MANAGE_SUBSCRIPTION_PLANS
1286 = "android.telephony.action.MANAGE_SUBSCRIPTION_PLANS";
1287
1288 /**
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07001289 * Broadcast Action: Request a refresh of the billing relationship plans
1290 * between a carrier and a specific subscriber.
1291 * <p>
1292 * Carrier apps are encouraged to implement this receiver, and the OS will
1293 * provide an affordance to request a refresh. This affordance will only be
1294 * shown when the carrier app is actively providing subscription plan
1295 * information via {@link #setSubscriptionPlans(int, List)}.
1296 * <p>
1297 * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
1298 * the user is interested in.
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06001299 * <p>
1300 * Receivers should protect themselves by checking that the sender holds the
1301 * {@code android.permission.MANAGE_SUBSCRIPTION_PLANS} permission.
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07001302 */
1303 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07001304 public static final String ACTION_REFRESH_SUBSCRIPTION_PLANS
1305 = "android.telephony.action.REFRESH_SUBSCRIPTION_PLANS";
1306
1307 /**
1308 * Broadcast Action: The billing relationship plans between a carrier and a
1309 * specific subscriber has changed.
1310 * <p>
1311 * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
1312 * changed.
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07001313 * @hide
1314 */
Daniel Bright10aa8e72019-12-17 16:52:03 -08001315 @SystemApi
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07001316 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1317 @RequiresPermission(android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS)
1318 public static final String ACTION_SUBSCRIPTION_PLANS_CHANGED
1319 = "android.telephony.action.SUBSCRIPTION_PLANS_CHANGED";
1320
1321 /**
Malcolm Chen598d24c2017-04-24 18:37:29 -07001322 * Integer extra used with {@link #ACTION_DEFAULT_SUBSCRIPTION_CHANGED} and
1323 * {@link #ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED} to indicate the subscription
1324 * which has changed.
1325 */
1326 public static final String EXTRA_SUBSCRIPTION_INDEX = "android.telephony.extra.SUBSCRIPTION_INDEX";
1327
Jack Yud8104ec2019-09-18 09:31:28 -07001328 /**
1329 * Integer extra to specify SIM slot index.
1330 */
1331 public static final String EXTRA_SLOT_INDEX = "android.telephony.extra.SLOT_INDEX";
1332
Meng Wang0594b4f2021-10-26 13:12:47 -07001333 /**
1334 * A source of phone number: the EF-MSISDN (see 3GPP TS 31.102),
1335 * or EF-MDN for CDMA (see 3GPP2 C.P0065-B), from UICC application.
1336 *
Dave McCloskey6f56f532023-12-27 23:18:38 +00001337 * <p>The availability and accuracy of the number depends on the carrier.
Meng Wang0594b4f2021-10-26 13:12:47 -07001338 * The number may be updated by over-the-air update to UICC applications
1339 * from the carrier, or by other means with physical access to the SIM.
1340 */
1341 public static final int PHONE_NUMBER_SOURCE_UICC = 1;
1342
1343 /**
1344 * A source of phone number: provided by an app that has carrier privilege.
1345 *
1346 * <p>The number is intended to be set by a carrier app knowing the correct number
1347 * which is, for example, different from the number in {@link #PHONE_NUMBER_SOURCE_UICC UICC}
1348 * for some reason.
1349 * The number is not available until a carrier app sets one via
1350 * {@link #setCarrierPhoneNumber(int, String)}.
1351 * The app can update the number with the same API should the number change.
1352 */
1353 public static final int PHONE_NUMBER_SOURCE_CARRIER = 2;
1354
1355 /**
1356 * A source of phone number: provided by IMS (IP Multimedia Subsystem) implementation.
1357 * When IMS service is registered (as indicated by
1358 * {@link android.telephony.ims.RegistrationManager.RegistrationCallback#onRegistered(int)})
1359 * the IMS implementation may return P-Associated-Uri SIP headers (RFC 3455). The URIs
1360 * are the user’s public user identities known to the network (see 3GPP TS 24.229 5.4.1.2),
1361 * and the phone number is typically one of them (see “global number” in 3GPP TS 23.003 13.4).
1362 *
1363 * <p>This source provides the phone number from the last IMS registration.
1364 * IMS registration may happen on every device reboot or other network condition changes.
1365 * The number will be updated should the associated URI change after an IMS registration.
1366 */
1367 public static final int PHONE_NUMBER_SOURCE_IMS = 3;
1368
1369 /** @hide */
1370 @Retention(RetentionPolicy.SOURCE)
1371 @IntDef(prefix = {"PHONE_NUMBER_SOURCE"},
1372 value = {
1373 PHONE_NUMBER_SOURCE_UICC,
1374 PHONE_NUMBER_SOURCE_CARRIER,
1375 PHONE_NUMBER_SOURCE_IMS,
1376 })
1377 public @interface PhoneNumberSource {}
1378
rambowang558016e2023-12-04 10:22:13 -06001379 /** @hide */
1380 @Retention(RetentionPolicy.SOURCE)
1381 @IntDef(prefix = {"SERVICE_CAPABILITY"},
1382 value = {
1383 SERVICE_CAPABILITY_VOICE,
1384 SERVICE_CAPABILITY_SMS,
1385 SERVICE_CAPABILITY_DATA,
1386 })
1387 public @interface ServiceCapability {
1388 }
1389
1390 /**
1391 * Represents a value indicating the voice calling capabilities of a subscription.
1392 *
1393 * <p>This value identifies whether the subscription supports various voice calling services.
1394 * These services can include circuit-switched (CS) calling, packet-switched (PS) IMS (IP
1395 * Multimedia Subsystem) calling, and over-the-top (OTT) calling options.
1396 *
1397 * <p>Note: The availability of emergency calling services is not solely dependent on this
1398 * voice capability. Emergency services may be accessible even if the subscription lacks
1399 * standard voice capabilities. However, the device's ability to support emergency calls
1400 * can be influenced by its inherent voice capabilities, as determined by
1401 * {@link TelephonyManager#isDeviceVoiceCapable()}.
1402 *
1403 * @see TelephonyManager#isDeviceVoiceCapable()
1404 */
1405 @FlaggedApi(Flags.FLAG_DATA_ONLY_CELLULAR_SERVICE)
1406 public static final int SERVICE_CAPABILITY_VOICE = 1;
1407
1408 /**
1409 * Represents a value indicating the SMS capabilities of a subscription.
1410 *
1411 * <p>This value identifies whether the subscription supports various sms services.
1412 * These services can include circuit-switched (CS) SMS, packet-switched (PS) IMS (IP
1413 * Multimedia Subsystem) SMS, and over-the-top (OTT) SMS options.
1414 *
1415 * <p>Note: The availability of emergency SMS services is not solely dependent on this
1416 * sms capability. Emergency services may be accessible even if the subscription lacks
1417 * standard sms capabilities. However, the device's ability to support emergency sms
1418 * can be influenced by its inherent sms capabilities, as determined by
1419 * {@link TelephonyManager#isDeviceSmsCapable()}.
1420 *
1421 * @see TelephonyManager#isDeviceSmsCapable()
1422 */
1423 @FlaggedApi(Flags.FLAG_DATA_ONLY_CELLULAR_SERVICE)
1424 public static final int SERVICE_CAPABILITY_SMS = 2;
1425
1426 /**
1427 * Represents a value indicating the data calling capabilities of a subscription.
1428 */
1429 @FlaggedApi(Flags.FLAG_DATA_ONLY_CELLULAR_SERVICE)
1430 public static final int SERVICE_CAPABILITY_DATA = 3;
1431
1432 /**
1433 * Maximum value of service capabilities supported so far.
1434 * @hide
1435 */
1436 public static final int SERVICE_CAPABILITY_MAX = SERVICE_CAPABILITY_DATA;
1437
1438 /**
1439 * Bitmask for {@code SERVICE_CAPABILITY_VOICE}.
1440 * @hide
1441 */
1442 public static final int SERVICE_CAPABILITY_VOICE_BITMASK =
1443 serviceCapabilityToBitmask(SERVICE_CAPABILITY_VOICE);
1444
1445 /**
1446 * Bitmask for {@code SERVICE_CAPABILITY_SMS}.
1447 * @hide
1448 */
1449 public static final int SERVICE_CAPABILITY_SMS_BITMASK =
1450 serviceCapabilityToBitmask(SERVICE_CAPABILITY_SMS);
1451
1452 /**
1453 * Bitmask for {@code SERVICE_CAPABILITY_DATA}.
1454 * @hide
1455 */
1456 public static final int SERVICE_CAPABILITY_DATA_BITMASK =
1457 serviceCapabilityToBitmask(SERVICE_CAPABILITY_DATA);
1458
Wink Savilled09c4ca2014-11-22 10:08:16 -08001459 private final Context mContext;
1460
sangyun62c0da52023-08-07 15:31:24 +09001461 /**
1462 * In order to prevent the overflow of the heap size due to an indiscriminate increase in the
1463 * cache, the heap size of the resource cache is set sufficiently large.
1464 */
sangyunfbcde602023-08-23 10:40:55 +09001465 private static final int MAX_RESOURCE_CACHE_ENTRY_COUNT = 1_000;
sangyun62c0da52023-08-07 15:31:24 +09001466
1467 /**
1468 * Cache of Resources that has been created in getResourcesForSubId. Key contains package name,
1469 * and Configuration of Resources. If more than the maximum number of resources are stored in
1470 * this cache, the least recently used Resources will be removed to maintain the maximum size.
1471 */
sangyunfbcde602023-08-23 10:40:55 +09001472 private static final LruCache<Pair<String, Configuration>, Resources> sResourcesCache =
1473 new LruCache<>(MAX_RESOURCE_CACHE_ENTRY_COUNT);
Torbjorn Eklundf8899f02019-11-20 10:59:59 +01001474
Hyunhoaeba1f22024-01-11 08:52:29 +00001475
1476 /**
1477 * The profile has not been transferred or converted to an eSIM.
1478 * @hide
1479 */
1480 @FlaggedApi(Flags.FLAG_SUPPORT_PSIM_TO_ESIM_CONVERSION)
1481 @SystemApi
1482 public static final int TRANSFER_STATUS_NONE = 0;
1483
1484 /**
1485 * The existing profile of the old device has been transferred to an eSIM of the new device.
1486 * @hide
1487 */
1488 @FlaggedApi(Flags.FLAG_SUPPORT_PSIM_TO_ESIM_CONVERSION)
1489 @SystemApi
1490 public static final int TRANSFER_STATUS_TRANSFERRED_OUT = 1;
1491
1492 /**
1493 * The existing profile of the same device has been converted to an eSIM of the same device
1494 * @hide
1495 */
1496 @FlaggedApi(Flags.FLAG_SUPPORT_PSIM_TO_ESIM_CONVERSION)
1497 @SystemApi
1498 public static final int TRANSFER_STATUS_CONVERTED = 2;
1499 /** @hide */
1500 @Retention(RetentionPolicy.SOURCE)
1501 @IntDef(prefix = {"TRANSFER_STATUS"},
1502 value = {
1503 TRANSFER_STATUS_NONE,
1504 TRANSFER_STATUS_TRANSFERRED_OUT,
1505 TRANSFER_STATUS_CONVERTED,
1506 })
1507 public @interface TransferStatus {}
1508
1509
Wink Savilled09c4ca2014-11-22 10:08:16 -08001510 /**
1511 * A listener class for monitoring changes to {@link SubscriptionInfo} records.
1512 * <p>
1513 * Override the onSubscriptionsChanged method in the object that extends this
Wink Saville071743f2015-01-12 17:11:04 -08001514 * class and pass it to {@link #addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener)}
Wink Savilled09c4ca2014-11-22 10:08:16 -08001515 * to register your listener and to unregister invoke
Wink Saville071743f2015-01-12 17:11:04 -08001516 * {@link #removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener)}
Wink Savilled09c4ca2014-11-22 10:08:16 -08001517 * <p>
1518 * Permissions android.Manifest.permission.READ_PHONE_STATE is required
1519 * for #onSubscriptionsChanged to be invoked.
1520 */
1521 public static class OnSubscriptionsChangedListener {
Jack He9fc75742017-11-16 15:54:14 -08001522
Chen Xu8eb62f92019-10-13 17:30:32 -07001523 /**
Anton Hansson84d6d752023-10-05 09:46:37 +00001524 * After {@link Build.VERSION_CODES#Q}, it is no longer necessary to instantiate a
Nathan Harold958f2002023-06-21 11:51:16 -07001525 * Handler inside of the OnSubscriptionsChangedListener in all cases, so it will only
1526 * be done for callers that do not supply an Executor.
Chen Xu8eb62f92019-10-13 17:30:32 -07001527 */
Nathan Harold958f2002023-06-21 11:51:16 -07001528 @ChangeId
1529 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
1530 private static final long LAZY_INITIALIZE_SUBSCRIPTIONS_CHANGED_HANDLER = 278814050L;
1531
1532 /**
1533 * For backwards compatibility reasons, stashes the Looper associated with the thread
1534 * context in which this listener was created.
1535 */
1536 private final Looper mCreatorLooper;
Chen Xu8eb62f92019-10-13 17:30:32 -07001537
1538 /**
1539 * @hide
1540 */
Nathan Harold958f2002023-06-21 11:51:16 -07001541 public Looper getCreatorLooper() {
1542 return mCreatorLooper;
Chen Xu8eb62f92019-10-13 17:30:32 -07001543 }
Jack He9fc75742017-11-16 15:54:14 -08001544
Nathan Harold958f2002023-06-21 11:51:16 -07001545 /**
1546 * Create an OnSubscriptionsChangedListener.
1547 *
Anton Hansson84d6d752023-10-05 09:46:37 +00001548 * For callers targeting {@link Build.VERSION_CODES#P} or earlier, this can only be called
Nathan Harold958f2002023-06-21 11:51:16 -07001549 * on a thread that already has a prepared Looper. Callers targeting Q or later should
1550 * subsequently use {@link SubscriptionManager#addOnSubscriptionsChangedListener(
1551 * Executor, OnSubscriptionsChangedListener)}.
1552 *
Anton Hansson84d6d752023-10-05 09:46:37 +00001553 * On OS versions prior to {@link Build.VERSION_CODES#VANILLA_ICE_CREAM} callers should
1554 * assume that this call will fail if invoked on a thread that does not already have a
1555 * prepared looper.
Nathan Harold958f2002023-06-21 11:51:16 -07001556 */
Jack He9fc75742017-11-16 15:54:14 -08001557 public OnSubscriptionsChangedListener() {
Nathan Harold958f2002023-06-21 11:51:16 -07001558 mCreatorLooper = Looper.myLooper();
1559 if (mCreatorLooper == null
1560 && !Compatibility.isChangeEnabled(
1561 LAZY_INITIALIZE_SUBSCRIPTIONS_CHANGED_HANDLER)) {
1562 // matches the implementation of Handler
1563 throw new RuntimeException(
1564 "Can't create handler inside thread "
1565 + Thread.currentThread()
1566 + " that has not called Looper.prepare()");
1567 }
Jack He9fc75742017-11-16 15:54:14 -08001568 }
1569
1570 /**
1571 * Allow a listener to be created with a custom looper
Nathan Harold958f2002023-06-21 11:51:16 -07001572 * @param looper the non-null Looper that the underlining handler should run on
Jack He9fc75742017-11-16 15:54:14 -08001573 * @hide
1574 */
Nathan Harold958f2002023-06-21 11:51:16 -07001575 public OnSubscriptionsChangedListener(@NonNull Looper looper) {
1576 Objects.requireNonNull(looper);
1577 mCreatorLooper = looper;
Jack He9fc75742017-11-16 15:54:14 -08001578 }
Wink Savilled09c4ca2014-11-22 10:08:16 -08001579
1580 /**
Jordan Liu45da5052019-02-12 10:29:24 -08001581 * Callback invoked when there is any change to any SubscriptionInfo, as well as once on
1582 * registering for changes with {@link #addOnSubscriptionsChangedListener}. Typically
Wink Savilled09c4ca2014-11-22 10:08:16 -08001583 * this method would invoke {@link #getActiveSubscriptionInfoList}
1584 */
1585 public void onSubscriptionsChanged() {
1586 if (DBG) log("onSubscriptionsChanged: NOT OVERRIDDEN");
1587 }
1588
Tyler Gunn76ab5fb2020-03-25 17:49:35 -07001589 /**
1590 * Callback invoked when {@link SubscriptionManager#addOnSubscriptionsChangedListener(
1591 * Executor, OnSubscriptionsChangedListener)} or
1592 * {@link SubscriptionManager#addOnSubscriptionsChangedListener(
1593 * OnSubscriptionsChangedListener)} fails to complete due to the
1594 * {@link Context#TELEPHONY_REGISTRY_SERVICE} being unavailable.
1595 * @hide
1596 */
1597 public void onAddListenerFailed() {
1598 Rlog.w(LOG_TAG, "onAddListenerFailed not overridden");
1599 }
1600
Wink Savilled09c4ca2014-11-22 10:08:16 -08001601 private void log(String s) {
1602 Rlog.d(LOG_TAG, s);
1603 }
1604 }
1605
Ling Ma9a53a422023-11-13 14:11:09 -08001606 /**
1607 * {@code true} if the SubscriptionManager instance should see all subscriptions regardless its
1608 * association with particular user profile.
1609 *
1610 * <p> It only applies to Android SDK 35(V) and above. For Android SDK 34(U) and below, the
1611 * caller can see all subscription across user profiles as it does today today even if it's
1612 * {@code false}.
1613 */
Ling Ma87862082024-01-11 00:25:16 +00001614 private final boolean mIsForAllUserProfiles;
Ling Ma9a53a422023-11-13 14:11:09 -08001615
Wink Savillef5bca082014-09-03 15:13:33 -07001616 /** @hide */
Mathew Inwooda8382062018-08-16 17:01:12 +01001617 @UnsupportedAppUsage
Robin Leeeaf46802018-01-18 14:34:20 +01001618 public SubscriptionManager(Context context) {
Ling Ma87862082024-01-11 00:25:16 +00001619 this(context, false /*isForAllUserProfiles*/);
1620 }
1621
1622 /** Constructor */
1623 private SubscriptionManager(Context context, boolean isForAllUserProfiles) {
1624 if (DBG) {
1625 logd("SubscriptionManager created "
1626 + (isForAllUserProfiles ? "for all user profile" : ""));
1627 }
1628 mIsForAllUserProfiles = isForAllUserProfiles;
Wink Savilled09c4ca2014-11-22 10:08:16 -08001629 mContext = context;
Jack Yu50de0612022-11-26 01:19:17 -08001630 }
1631
Aaron Huang21089442020-01-16 23:31:02 +08001632 private NetworkPolicyManager getNetworkPolicyManager() {
1633 return (NetworkPolicyManager) mContext
1634 .getSystemService(Context.NETWORK_POLICY_SERVICE);
1635 }
1636
Wink Savillefb40dd42014-06-12 17:02:31 -07001637 /**
Jeff Sharkey717f52f2018-01-04 16:04:11 -07001638 * @deprecated developers should always obtain references directly from
1639 * {@link Context#getSystemService(Class)}.
Wink Savillefb40dd42014-06-12 17:02:31 -07001640 */
Jeff Sharkey717f52f2018-01-04 16:04:11 -07001641 @Deprecated
Wink Savilled09c4ca2014-11-22 10:08:16 -08001642 public static SubscriptionManager from(Context context) {
Jeff Sharkeyddf21642018-01-08 13:38:43 -07001643 return (SubscriptionManager) context
1644 .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Wink Savilled09c4ca2014-11-22 10:08:16 -08001645 }
1646
1647 /**
1648 * Register for changes to the list of active {@link SubscriptionInfo} records or to the
1649 * individual records themselves. When a change occurs the onSubscriptionsChanged method of
Jordan Liu45da5052019-02-12 10:29:24 -08001650 * the listener will be invoked immediately if there has been a notification. The
1651 * onSubscriptionChanged method will also be triggered once initially when calling this
Zongheng Wangeb56d062020-02-20 18:19:10 -08001652 * function. The callback will be invoked on the looper specified in the listener's constructor.
Wink Savilled09c4ca2014-11-22 10:08:16 -08001653 *
1654 * @param listener an instance of {@link OnSubscriptionsChangedListener} with
1655 * onSubscriptionsChanged overridden.
Zongheng Wangeb56d062020-02-20 18:19:10 -08001656 *
1657 * @deprecated Will get exception if the parameter listener is not initialized with a Looper.
1658 * Use {@link #addOnSubscriptionsChangedListener(Executor, OnSubscriptionsChangedListener)}.
Wink Savilled09c4ca2014-11-22 10:08:16 -08001659 */
Zongheng Wangeb56d062020-02-20 18:19:10 -08001660 @Deprecated
Wink Saville071743f2015-01-12 17:11:04 -08001661 public void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
Chen Xu8eb62f92019-10-13 17:30:32 -07001662 if (listener == null) return;
Nathan Harold958f2002023-06-21 11:51:16 -07001663
sangyun9ccc9142023-12-06 13:36:07 +09001664 Looper looper = listener.getCreatorLooper();
1665 if (looper == null) {
1666 throw new RuntimeException(
1667 "Can't create handler inside thread " + Thread.currentThread()
1668 + " that has not called Looper.prepare()");
1669 }
1670
1671 addOnSubscriptionsChangedListener(new HandlerExecutor(new Handler(looper)), listener);
Zongheng Wang5d39bd12020-01-07 13:46:13 +08001672 }
1673
1674 /**
Jack Yue44aa7e2024-01-19 17:05:53 -08001675 * Register for changes to the list of {@link SubscriptionInfo} records or to the
1676 * individual records (active or inactive) themselves. When a change occurs, the
1677 * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged()} method of
1678 * the listener will be invoked immediately. The
1679 * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged()} method will also be invoked
1680 * once initially when calling this method.
Zongheng Wang5d39bd12020-01-07 13:46:13 +08001681 *
1682 * @param listener an instance of {@link OnSubscriptionsChangedListener} with
Jack Yue44aa7e2024-01-19 17:05:53 -08001683 * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged()} overridden.
Zongheng Wang5d39bd12020-01-07 13:46:13 +08001684 * @param executor the executor that will execute callbacks.
1685 */
1686 public void addOnSubscriptionsChangedListener(
1687 @NonNull @CallbackExecutor Executor executor,
1688 @NonNull OnSubscriptionsChangedListener listener) {
Hall Liu5fb337f2017-11-22 17:38:15 -08001689 String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>";
Wink Savillea374c3d2014-11-11 11:48:04 -08001690 if (DBG) {
Hall Liu5fb337f2017-11-22 17:38:15 -08001691 logd("register OnSubscriptionsChangedListener pkgName=" + pkgName
Wink Savilled09c4ca2014-11-22 10:08:16 -08001692 + " listener=" + listener);
Wink Savillea374c3d2014-11-11 11:48:04 -08001693 }
Chen Xu8eb62f92019-10-13 17:30:32 -07001694 // We use the TelephonyRegistry as it runs in the system and thus is always
Jack Yu4a922da2023-04-14 09:17:36 -07001695 // available.
Chen Xu8eb62f92019-10-13 17:30:32 -07001696 TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
1697 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
1698 if (telephonyRegistryManager != null) {
1699 telephonyRegistryManager.addOnSubscriptionsChangedListener(listener,
Zongheng Wang5d39bd12020-01-07 13:46:13 +08001700 executor);
Tyler Gunn76ab5fb2020-03-25 17:49:35 -07001701 } else {
1702 // If the telephony registry isn't available, we will inform the caller on their
1703 // listener that it failed so they can try to re-register.
1704 loge("addOnSubscriptionsChangedListener: pkgname=" + pkgName + " failed to be added "
1705 + " due to TELEPHONY_REGISTRY_SERVICE being unavailable.");
1706 executor.execute(() -> listener.onAddListenerFailed());
Wink Savillea374c3d2014-11-11 11:48:04 -08001707 }
1708 }
1709
1710 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -08001711 * Unregister the {@link OnSubscriptionsChangedListener}. This is not strictly necessary
1712 * as the listener will automatically be unregistered if an attempt to invoke the listener
1713 * fails.
Wink Savillea374c3d2014-11-11 11:48:04 -08001714 *
Wink Savilled09c4ca2014-11-22 10:08:16 -08001715 * @param listener that is to be unregistered.
Wink Savillea374c3d2014-11-11 11:48:04 -08001716 */
Wink Saville071743f2015-01-12 17:11:04 -08001717 public void removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
Chen Xu8eb62f92019-10-13 17:30:32 -07001718 if (listener == null) return;
Robert Greenwalt278b8f92015-07-01 14:34:17 -07001719 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
Wink Savillea374c3d2014-11-11 11:48:04 -08001720 if (DBG) {
Wink Savilled09c4ca2014-11-22 10:08:16 -08001721 logd("unregister OnSubscriptionsChangedListener pkgForDebug=" + pkgForDebug
Wink Savillea374c3d2014-11-11 11:48:04 -08001722 + " listener=" + listener);
1723 }
Chen Xu8eb62f92019-10-13 17:30:32 -07001724 // We use the TelephonyRegistry as it runs in the system and thus is always
Jack Yu4a922da2023-04-14 09:17:36 -07001725 // available.
Chen Xu8eb62f92019-10-13 17:30:32 -07001726 TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
1727 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
1728 if (telephonyRegistryManager != null) {
1729 telephonyRegistryManager.removeOnSubscriptionsChangedListener(listener);
Malcolm Chen27829e22018-09-04 22:12:31 -07001730 }
1731 }
1732
1733 /**
1734 * A listener class for monitoring changes to {@link SubscriptionInfo} records of opportunistic
1735 * subscriptions.
1736 * <p>
1737 * Override the onOpportunisticSubscriptionsChanged method in the object that extends this
1738 * or {@link #addOnOpportunisticSubscriptionsChangedListener(
1739 * Executor, OnOpportunisticSubscriptionsChangedListener)}
1740 * to register your listener and to unregister invoke
1741 * {@link #removeOnOpportunisticSubscriptionsChangedListener(
1742 * OnOpportunisticSubscriptionsChangedListener)}
1743 * <p>
1744 * Permissions android.Manifest.permission.READ_PHONE_STATE is required
1745 * for #onOpportunisticSubscriptionsChanged to be invoked.
1746 */
1747 public static class OnOpportunisticSubscriptionsChangedListener {
Malcolm Chen27829e22018-09-04 22:12:31 -07001748 /**
1749 * Callback invoked when there is any change to any SubscriptionInfo. Typically
1750 * this method would invoke {@link #getActiveSubscriptionInfoList}
1751 */
1752 public void onOpportunisticSubscriptionsChanged() {
1753 if (DBG) log("onOpportunisticSubscriptionsChanged: NOT OVERRIDDEN");
1754 }
1755
Malcolm Chen27829e22018-09-04 22:12:31 -07001756 private void log(String s) {
1757 Rlog.d(LOG_TAG, s);
1758 }
1759 }
1760
1761 /**
1762 * Register for changes to the list of opportunistic subscription records or to the
1763 * individual records themselves. When a change occurs the onOpportunisticSubscriptionsChanged
1764 * method of the listener will be invoked immediately if there has been a notification.
1765 *
1766 * @param listener an instance of {@link OnOpportunisticSubscriptionsChangedListener} with
1767 * onOpportunisticSubscriptionsChanged overridden.
1768 */
1769 public void addOnOpportunisticSubscriptionsChangedListener(
1770 @NonNull @CallbackExecutor Executor executor,
1771 @NonNull OnOpportunisticSubscriptionsChangedListener listener) {
1772 if (executor == null || listener == null) {
1773 return;
1774 }
1775
1776 String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>";
1777 if (DBG) {
1778 logd("register addOnOpportunisticSubscriptionsChangedListener pkgName=" + pkgName
1779 + " listener=" + listener);
1780 }
1781
Chen Xu8eb62f92019-10-13 17:30:32 -07001782 // We use the TelephonyRegistry as it runs in the system and thus is always
Jack Yu4a922da2023-04-14 09:17:36 -07001783 // available.
Chen Xu8eb62f92019-10-13 17:30:32 -07001784 TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
1785 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
1786 if (telephonyRegistryManager != null) {
1787 telephonyRegistryManager.addOnOpportunisticSubscriptionsChangedListener(
1788 listener, executor);
Malcolm Chen27829e22018-09-04 22:12:31 -07001789 }
1790 }
1791
1792 /**
1793 * Unregister the {@link OnOpportunisticSubscriptionsChangedListener} that is currently
1794 * listening opportunistic subscriptions change. This is not strictly necessary
1795 * as the listener will automatically be unregistered if an attempt to invoke the listener
1796 * fails.
1797 *
1798 * @param listener that is to be unregistered.
1799 */
1800 public void removeOnOpportunisticSubscriptionsChangedListener(
Malcolm Chen80e1e5c2019-02-27 15:16:05 -08001801 @NonNull OnOpportunisticSubscriptionsChangedListener listener) {
1802 Preconditions.checkNotNull(listener, "listener cannot be null");
Malcolm Chen27829e22018-09-04 22:12:31 -07001803 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
1804 if (DBG) {
1805 logd("unregister OnOpportunisticSubscriptionsChangedListener pkgForDebug="
1806 + pkgForDebug + " listener=" + listener);
1807 }
Chen Xu8eb62f92019-10-13 17:30:32 -07001808 TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
1809 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
1810 if (telephonyRegistryManager != null) {
1811 telephonyRegistryManager.removeOnOpportunisticSubscriptionsChangedListener(listener);
Wink Savillea374c3d2014-11-11 11:48:04 -08001812 }
1813 }
1814
1815 /**
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001816 * Get the active SubscriptionInfo with the input subId.
1817 *
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001818 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1819 * or that the calling app has carrier privileges (see
1820 * {@link TelephonyManager#hasCarrierPrivileges}).
1821 *
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001822 * @param subId The unique SubscriptionInfo key in database.
Wink Savilled09c4ca2014-11-22 10:08:16 -08001823 * @return SubscriptionInfo, maybe null if its not active.
joonhunshin1a225542023-12-08 08:40:54 +00001824 *
1825 * @throws UnsupportedOperationException If the device does not have
1826 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Wink Savillea374c3d2014-11-11 11:48:04 -08001827 */
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001828 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
1829 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
Wink Savilled09c4ca2014-11-22 10:08:16 -08001830 public SubscriptionInfo getActiveSubscriptionInfo(int subId) {
1831 if (VDBG) logd("[getActiveSubscriptionInfo]+ subId=" + subId);
Wink Savillea54bf652014-12-11 13:37:50 -08001832 if (!isValidSubscriptionId(subId)) {
Sanket Padawe28964eb2015-06-05 16:13:51 -07001833 if (DBG) {
1834 logd("[getActiveSubscriptionInfo]- invalid subId");
1835 }
Wink Savillefb40dd42014-06-12 17:02:31 -07001836 return null;
1837 }
1838
Wink Savillea374c3d2014-11-11 11:48:04 -08001839 SubscriptionInfo subInfo = null;
Wink Savillefb40dd42014-06-12 17:02:31 -07001840
1841 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001842 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07001843 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08001844 subInfo = iSub.getActiveSubscriptionInfo(subId, mContext.getOpPackageName(),
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08001845 mContext.getAttributionTag());
Wink Savillefb40dd42014-06-12 17:02:31 -07001846 }
1847 } catch (RemoteException ex) {
1848 // ignore it
1849 }
1850
1851 return subInfo;
Wink Savillefb40dd42014-06-12 17:02:31 -07001852 }
1853
1854 /**
sqianff8dfe72020-01-07 13:45:07 -08001855 * Gets an active SubscriptionInfo {@link SubscriptionInfo} associated with the Sim IccId.
1856 *
Wink Savillefb40dd42014-06-12 17:02:31 -07001857 * @param iccId the IccId of SIM card
Wink Savilled09c4ca2014-11-22 10:08:16 -08001858 * @return SubscriptionInfo, maybe null if its not active
sqianff8dfe72020-01-07 13:45:07 -08001859 *
joonhunshin1a225542023-12-08 08:40:54 +00001860 * @throws UnsupportedOperationException If the device does not have
1861 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Wink Savillef5bca082014-09-03 15:13:33 -07001862 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07001863 */
sqianff8dfe72020-01-07 13:45:07 -08001864 @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
1865 @Nullable
1866 @SystemApi
1867 public SubscriptionInfo getActiveSubscriptionInfoForIcc(@NonNull String iccId) {
Wink Savilled09c4ca2014-11-22 10:08:16 -08001868 if (VDBG) logd("[getActiveSubscriptionInfoForIccIndex]+ iccId=" + iccId);
Wink Savillefb40dd42014-06-12 17:02:31 -07001869 if (iccId == null) {
Wink Savilled09c4ca2014-11-22 10:08:16 -08001870 logd("[getActiveSubscriptionInfoForIccIndex]- null iccid");
Wink Savillefb40dd42014-06-12 17:02:31 -07001871 return null;
1872 }
1873
Wink Savilled09c4ca2014-11-22 10:08:16 -08001874 SubscriptionInfo result = null;
Wink Savillefb40dd42014-06-12 17:02:31 -07001875
1876 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001877 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07001878 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08001879 result = iSub.getActiveSubscriptionInfoForIccId(iccId, mContext.getOpPackageName(),
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08001880 mContext.getAttributionTag());
Wink Savillefb40dd42014-06-12 17:02:31 -07001881 }
1882 } catch (RemoteException ex) {
1883 // ignore it
1884 }
1885
1886 return result;
1887 }
1888
1889 /**
Sanket Padawe7e460252017-03-10 16:18:20 -08001890 * Get the active SubscriptionInfo associated with the slotIndex
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001891 *
1892 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1893 * or that the calling app has carrier privileges (see
1894 * {@link TelephonyManager#hasCarrierPrivileges}).
1895 *
Sanket Padawe7e460252017-03-10 16:18:20 -08001896 * @param slotIndex the slot which the subscription is inserted
Wink Savilled09c4ca2014-11-22 10:08:16 -08001897 * @return SubscriptionInfo, maybe null if its not active
joonhunshin1a225542023-12-08 08:40:54 +00001898 *
1899 * @throws UnsupportedOperationException If the device does not have
1900 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Wink Savillefb40dd42014-06-12 17:02:31 -07001901 */
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001902 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
1903 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
Sanket Padawe7e460252017-03-10 16:18:20 -08001904 public SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex) {
1905 if (VDBG) logd("[getActiveSubscriptionInfoForSimSlotIndex]+ slotIndex=" + slotIndex);
1906 if (!isValidSlotIndex(slotIndex)) {
1907 logd("[getActiveSubscriptionInfoForSimSlotIndex]- invalid slotIndex");
Wink Savillefb40dd42014-06-12 17:02:31 -07001908 return null;
1909 }
1910
Wink Savilled09c4ca2014-11-22 10:08:16 -08001911 SubscriptionInfo result = null;
Wink Savillefb40dd42014-06-12 17:02:31 -07001912
1913 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001914 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07001915 if (iSub != null) {
Sanket Padawe7e460252017-03-10 16:18:20 -08001916 result = iSub.getActiveSubscriptionInfoForSimSlotIndex(slotIndex,
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08001917 mContext.getOpPackageName(), mContext.getAttributionTag());
Wink Savillefb40dd42014-06-12 17:02:31 -07001918 }
1919 } catch (RemoteException ex) {
1920 // ignore it
1921 }
1922
1923 return result;
1924 }
1925
1926 /**
Jack Yu34730f62022-12-15 16:43:30 -08001927 * Get all subscription info records from SIMs that are inserted now or previously inserted.
Jack Yu1f1f39b2022-11-23 14:53:53 -08001928 *
1929 * <p>
1930 * If the caller does not have {@link Manifest.permission#READ_PHONE_NUMBERS} permission,
1931 * {@link SubscriptionInfo#getNumber()} will return empty string.
1932 * If the caller does not have {@link Manifest.permission#USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER},
Jack Yu34730f62022-12-15 16:43:30 -08001933 * {@link SubscriptionInfo#getIccId()} will return an empty string, and
1934 * {@link SubscriptionInfo#getGroupUuid()} will return {@code null}.
Jack Yu1f1f39b2022-11-23 14:53:53 -08001935 *
1936 * <p>
Jack Yu34730f62022-12-15 16:43:30 -08001937 * The carrier app will only get the list of subscriptions that it has carrier privilege on,
1938 * but will have non-stripped {@link SubscriptionInfo} in the list.
Jack Yu1f1f39b2022-11-23 14:53:53 -08001939 *
1940 * @return List of all {@link SubscriptionInfo} records from SIMs that are inserted or
Jack Yu34730f62022-12-15 16:43:30 -08001941 * previously inserted. Sorted by {@link SubscriptionInfo#getSimSlotIndex()}, then
Jack Yu1f1f39b2022-11-23 14:53:53 -08001942 * {@link SubscriptionInfo#getSubscriptionId()}.
1943 *
Jack Yu34730f62022-12-15 16:43:30 -08001944 * @throws SecurityException if callers do not hold the required permission.
joonhunshin1a225542023-12-08 08:40:54 +00001945 * @throws UnsupportedOperationException If the device does not have
1946 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Wink Savillefb40dd42014-06-12 17:02:31 -07001947 */
Jack Yu34730f62022-12-15 16:43:30 -08001948 @NonNull
Jack Yu1f1f39b2022-11-23 14:53:53 -08001949 @RequiresPermission(anyOf = {
1950 Manifest.permission.READ_PHONE_STATE,
Jack Yu1f1f39b2022-11-23 14:53:53 -08001951 "carrier privileges",
1952 })
Wink Savilled09c4ca2014-11-22 10:08:16 -08001953 public List<SubscriptionInfo> getAllSubscriptionInfoList() {
Wink Savillea374c3d2014-11-11 11:48:04 -08001954 List<SubscriptionInfo> result = null;
Wink Savillefb40dd42014-06-12 17:02:31 -07001955 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001956 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07001957 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08001958 result = iSub.getAllSubInfoList(mContext.getOpPackageName(),
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08001959 mContext.getAttributionTag());
Wink Savillefb40dd42014-06-12 17:02:31 -07001960 }
1961 } catch (RemoteException ex) {
1962 // ignore it
1963 }
1964
Wink Saville905bb542014-09-04 17:10:23 -07001965 if (result == null) {
Benedict Wong061b2f72020-11-02 17:52:06 -08001966 result = Collections.emptyList();
Wink Saville905bb542014-09-04 17:10:23 -07001967 }
Wink Savillefb40dd42014-06-12 17:02:31 -07001968 return result;
1969 }
1970
1971 /**
Ling Ma34891072024-05-15 17:57:21 -07001972 * Get the SubscriptionInfo(s) of the currently active SIM(s).
Ling Ma9a53a422023-11-13 14:11:09 -08001973 *
Nathan Harold1cc92772023-10-24 18:05:16 -07001974 * <p> Returned records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by
1975 * {@link SubscriptionInfo#getSubscriptionId}. Beginning with Android SDK 35, this method will
1976 * never return null.
Wink Savilled09c4ca2014-11-22 10:08:16 -08001977 *
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001978 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1979 * or that the calling app has carrier privileges (see
Jack Yu85f02b22022-12-03 01:24:28 -08001980 * {@link TelephonyManager#hasCarrierPrivileges}).
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001981 *
Nathan Harold1cc92772023-10-24 18:05:16 -07001982 * @return a list of the active {@link SubscriptionInfo} that is visible to the caller. If
1983 * an empty list or null is returned, then there are no active subscriptions that
1984 * are visible to the caller. If the number of active subscriptions available to
1985 * any caller changes, then this change will be indicated by
1986 * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged}.
joonhunshin1a225542023-12-08 08:40:54 +00001987 *
1988 * @throws UnsupportedOperationException If the device does not have
Nathan Harold1cc92772023-10-24 18:05:16 -07001989 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Wink Savillefb40dd42014-06-12 17:02:31 -07001990 */
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001991 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
Nathan Harold1cc92772023-10-24 18:05:16 -07001992 public @Nullable List<SubscriptionInfo> getActiveSubscriptionInfoList() {
Ling Ma9a53a422023-11-13 14:11:09 -08001993 List<SubscriptionInfo> activeList = null;
1994
1995 try {
1996 ISub iSub = TelephonyManager.getSubscriptionService();
1997 if (iSub != null) {
1998 activeList = iSub.getActiveSubscriptionInfoList(mContext.getOpPackageName(),
1999 mContext.getAttributionTag(), mIsForAllUserProfiles);
2000 }
2001 } catch (RemoteException ex) {
2002 // ignore it
2003 }
2004
2005 if (activeList != null) {
2006 activeList = activeList.stream().filter(subInfo -> isSubscriptionVisible(subInfo))
2007 .collect(Collectors.toList());
Nathan Harold1cc92772023-10-24 18:05:16 -07002008 } else {
2009 activeList = Collections.emptyList();
Ling Ma9a53a422023-11-13 14:11:09 -08002010 }
2011 return activeList;
Malcolm Chenc3d7de02018-12-21 17:00:30 -08002012 }
2013
2014 /**
Sooraj Sasindrane5ac4da2019-11-07 18:32:37 -08002015 * Get both hidden and visible SubscriptionInfo(s) of the currently active SIM(s).
2016 * The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex}
2017 * then by {@link SubscriptionInfo#getSubscriptionId}.
Malcolm Chenc3d7de02018-12-21 17:00:30 -08002018 *
Peter Wang01d128c2019-12-17 19:11:23 -08002019 * Hidden subscriptions refer to those are not meant visible to the users.
2020 * For example, an opportunistic subscription that is grouped with other
2021 * subscriptions should remain invisible to users as they are only functionally
2022 * supplementary to primary ones.
2023 *
Sooraj Sasindrane5ac4da2019-11-07 18:32:37 -08002024 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
2025 * or that the calling app has carrier privileges (see
2026 * {@link TelephonyManager#hasCarrierPrivileges}). In the latter case, only records accessible
2027 * to the calling app are returned.
2028 *
2029 * @return Sorted list of the currently available {@link SubscriptionInfo}
2030 * records on the device.
2031 * This is similar to {@link #getActiveSubscriptionInfoList} except that it will return
2032 * both active and hidden SubscriptionInfos.
2033 *
joonhunshin1a225542023-12-08 08:40:54 +00002034 * @throws UnsupportedOperationException If the device does not have
2035 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Malcolm Chenc3d7de02018-12-21 17:00:30 -08002036 */
Sooraj Sasindran40468062020-01-06 19:10:50 -08002037 public @NonNull List<SubscriptionInfo> getCompleteActiveSubscriptionInfoList() {
Nathan Harold1cc92772023-10-24 18:05:16 -07002038 return getActiveSubscriptionInfoList(/* userVisibleonly */ false);
Sooraj Sasindrane5ac4da2019-11-07 18:32:37 -08002039 }
2040
2041 /**
Ling Ma87862082024-01-11 00:25:16 +00002042 * Create a new subscription manager instance that can see all subscriptions across
Ling Ma9a53a422023-11-13 14:11:09 -08002043 * user profiles.
2044 *
Ling Ma539e8df2024-01-18 00:40:18 +00002045 * The permission check for accessing all subscriptions will be enforced upon calling the
2046 * individual APIs linked below.
2047 *
Ling Ma9a53a422023-11-13 14:11:09 -08002048 * @return a SubscriptionManager that can see all subscriptions regardless its user profile
2049 * association.
2050 *
2051 * @see #getActiveSubscriptionInfoList
2052 * @see #getActiveSubscriptionInfoCount
2053 * @see UserHandle
2054 */
Ling Ma87862082024-01-11 00:25:16 +00002055 @FlaggedApi(Flags.FLAG_ENFORCE_SUBSCRIPTION_USER_FILTER)
Ling Ma539e8df2024-01-18 00:40:18 +00002056 @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_PROFILES)
Ling Ma9a53a422023-11-13 14:11:09 -08002057 @NonNull public SubscriptionManager createForAllUserProfiles() {
Ling Ma87862082024-01-11 00:25:16 +00002058 return new SubscriptionManager(mContext, true/*isForAllUserProfiles*/);
Ling Ma9a53a422023-11-13 14:11:09 -08002059 }
2060
2061 /**
Sooraj Sasindrane5ac4da2019-11-07 18:32:37 -08002062 * This is similar to {@link #getActiveSubscriptionInfoList()}, but if userVisibleOnly
2063 * is true, it will filter out the hidden subscriptions.
2064 *
2065 * @hide
2066 */
Nathan Harold1cc92772023-10-24 18:05:16 -07002067 public @NonNull List<SubscriptionInfo> getActiveSubscriptionInfoList(boolean userVisibleOnly) {
Malcolm Chenc3d7de02018-12-21 17:00:30 -08002068 List<SubscriptionInfo> activeList = null;
Wink Savillefb40dd42014-06-12 17:02:31 -07002069
2070 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002071 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07002072 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08002073 activeList = iSub.getActiveSubscriptionInfoList(mContext.getOpPackageName(),
Ling Ma9a53a422023-11-13 14:11:09 -08002074 mContext.getAttributionTag(), true /*isForAllUserProfiles*/);
Wink Savillefb40dd42014-06-12 17:02:31 -07002075 }
2076 } catch (RemoteException ex) {
2077 // ignore it
2078 }
Malcolm Chenc3d7de02018-12-21 17:00:30 -08002079
Nathan Harold1cc92772023-10-24 18:05:16 -07002080 if (activeList == null || activeList.isEmpty()) {
2081 return Collections.emptyList();
2082 } else if (userVisibleOnly) {
Malcolm Chend1b4a812019-02-28 14:07:59 -08002083 return activeList.stream().filter(subInfo -> isSubscriptionVisible(subInfo))
Malcolm Chenc3d7de02018-12-21 17:00:30 -08002084 .collect(Collectors.toList());
Nathan Harold1cc92772023-10-24 18:05:16 -07002085 } else {
2086 return activeList;
Malcolm Chenc3d7de02018-12-21 17:00:30 -08002087 }
Wink Savillefb40dd42014-06-12 17:02:31 -07002088 }
2089
2090 /**
Jeff Davidsond02731f2017-04-09 14:31:09 -07002091 * Gets the SubscriptionInfo(s) of all available subscriptions, if any.
2092 *
2093 * <p>Available subscriptions include active ones (those with a non-negative
2094 * {@link SubscriptionInfo#getSimSlotIndex()}) as well as inactive but installed embedded
2095 * subscriptions.
2096 *
2097 * <p>The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by
2098 * {@link SubscriptionInfo#getSubscriptionId}.
2099 *
2100 * @return Sorted list of the current {@link SubscriptionInfo} records available on the
2101 * device.
2102 * <ul>
2103 * <li>
2104 * If null is returned the current state is unknown but if a
2105 * {@link OnSubscriptionsChangedListener} has been registered
2106 * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be invoked in the future.
2107 * <li>
2108 * If the list is empty then there are no {@link SubscriptionInfo} records currently available.
2109 * <li>
2110 * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
2111 * then by {@link SubscriptionInfo#getSubscriptionId}.
2112 * </ul>
Jiuyu Sund3bb4ae2018-02-08 16:38:26 +00002113 *
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08002114 * <p>
2115 * Permissions android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE is required
2116 * for #getAvailableSubscriptionInfoList to be invoked.
joonhunshin1a225542023-12-08 08:40:54 +00002117 *
2118 * @throws UnsupportedOperationException If the device does not have
2119 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08002120 * @hide
Jeff Davidsond02731f2017-04-09 14:31:09 -07002121 */
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08002122 @SystemApi
Nathan Harold1cc92772023-10-24 18:05:16 -07002123 public @Nullable List<SubscriptionInfo> getAvailableSubscriptionInfoList() {
Jeff Davidsond02731f2017-04-09 14:31:09 -07002124 List<SubscriptionInfo> result = null;
2125
2126 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002127 ISub iSub = TelephonyManager.getSubscriptionService();
Jeff Davidsond02731f2017-04-09 14:31:09 -07002128 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08002129 result = iSub.getAvailableSubscriptionInfoList(mContext.getOpPackageName(),
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08002130 mContext.getAttributionTag());
Jeff Davidsond02731f2017-04-09 14:31:09 -07002131 }
2132 } catch (RemoteException ex) {
2133 // ignore it
2134 }
Nathan Harold1cc92772023-10-24 18:05:16 -07002135 return (result == null) ? Collections.emptyList() : result;
Jeff Davidsond02731f2017-04-09 14:31:09 -07002136 }
2137
2138 /**
2139 * Gets the SubscriptionInfo(s) of all embedded subscriptions accessible to the calling app, if
2140 * any.
2141 *
2142 * <p>Only those subscriptions for which the calling app has carrier privileges per the
2143 * subscription metadata, if any, will be included in the returned list.
2144 *
2145 * <p>The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by
2146 * {@link SubscriptionInfo#getSubscriptionId}.
2147 *
2148 * @return Sorted list of the current embedded {@link SubscriptionInfo} records available on the
2149 * device which are accessible to the caller.
2150 * <ul>
2151 * <li>
2152 * If null is returned the current state is unknown but if a
2153 * {@link OnSubscriptionsChangedListener} has been registered
2154 * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be invoked in the future.
2155 * <li>
2156 * If the list is empty then there are no {@link SubscriptionInfo} records currently available.
2157 * <li>
2158 * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
2159 * then by {@link SubscriptionInfo#getSubscriptionId}.
2160 * </ul>
joonhunshin1a225542023-12-08 08:40:54 +00002161 *
2162 * @throws UnsupportedOperationException If the device does not have
2163 * {@link PackageManager#FEATURE_TELEPHONY_EUICC}.
Jeff Davidsond02731f2017-04-09 14:31:09 -07002164 */
Nathan Harold1cc92772023-10-24 18:05:16 -07002165 public @Nullable List<SubscriptionInfo> getAccessibleSubscriptionInfoList() {
Jeff Davidsond02731f2017-04-09 14:31:09 -07002166 List<SubscriptionInfo> result = null;
2167
2168 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002169 ISub iSub = TelephonyManager.getSubscriptionService();
Jeff Davidsond02731f2017-04-09 14:31:09 -07002170 if (iSub != null) {
2171 result = iSub.getAccessibleSubscriptionInfoList(mContext.getOpPackageName());
2172 }
2173 } catch (RemoteException ex) {
2174 // ignore it
2175 }
Nathan Harold1cc92772023-10-24 18:05:16 -07002176 return (result == null) ? Collections.emptyList() : result;
Jeff Davidsond02731f2017-04-09 14:31:09 -07002177 }
2178
2179 /**
Pengquan Mengeb7ac732018-11-29 18:33:17 -08002180 * Request a refresh of the platform cache of profile information for the eUICC which
2181 * corresponds to the card ID returned by {@link TelephonyManager#getCardIdForDefaultEuicc()}.
Jeff Davidsond02731f2017-04-09 14:31:09 -07002182 *
2183 * <p>Should be called by the EuiccService implementation whenever this information changes due
2184 * to an operation done outside the scope of a request initiated by the platform to the
2185 * EuiccService. There is no need to refresh for downloads, deletes, or other operations that
2186 * were made through the EuiccService.
2187 *
2188 * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
Pengquan Mengeb7ac732018-11-29 18:33:17 -08002189 *
Jack Yu647bbb92022-12-12 21:45:26 -08002190 * @see TelephonyManager#getCardIdForDefaultEuicc() for more information on the card ID.
Pengquan Mengeb7ac732018-11-29 18:33:17 -08002191 *
joonhunshin1a225542023-12-08 08:40:54 +00002192 * @throws UnsupportedOperationException If the device does not have
2193 * {@link PackageManager#FEATURE_TELEPHONY_EUICC}.
Jeff Davidsond02731f2017-04-09 14:31:09 -07002194 * @hide
Jeff Davidsond02731f2017-04-09 14:31:09 -07002195 */
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08002196 @SystemApi
Jeff Davidsond02731f2017-04-09 14:31:09 -07002197 public void requestEmbeddedSubscriptionInfoListRefresh() {
Pengquan Mengeb7ac732018-11-29 18:33:17 -08002198 int cardId = TelephonyManager.from(mContext).getCardIdForDefaultEuicc();
Jeff Davidsond02731f2017-04-09 14:31:09 -07002199 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002200 ISub iSub = TelephonyManager.getSubscriptionService();
Jeff Davidsond02731f2017-04-09 14:31:09 -07002201 if (iSub != null) {
Pengquan Mengeb7ac732018-11-29 18:33:17 -08002202 iSub.requestEmbeddedSubscriptionInfoListRefresh(cardId);
Jeff Davidsond02731f2017-04-09 14:31:09 -07002203 }
2204 } catch (RemoteException ex) {
Pengquan Mengeb7ac732018-11-29 18:33:17 -08002205 logd("requestEmbeddedSubscriptionInfoListFresh for card = " + cardId + " failed.");
2206 }
2207 }
2208
2209 /**
2210 * Request a refresh of the platform cache of profile information for the eUICC with the given
2211 * {@code cardId}.
2212 *
2213 * <p>Should be called by the EuiccService implementation whenever this information changes due
2214 * to an operation done outside the scope of a request initiated by the platform to the
2215 * EuiccService. There is no need to refresh for downloads, deletes, or other operations that
2216 * were made through the EuiccService.
2217 *
2218 * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
2219 *
2220 * @param cardId the card ID of the eUICC.
2221 *
Jack Yu647bbb92022-12-12 21:45:26 -08002222 * @see TelephonyManager#getCardIdForDefaultEuicc() for more information on the card ID.
Pengquan Mengeb7ac732018-11-29 18:33:17 -08002223 *
joonhunshin1a225542023-12-08 08:40:54 +00002224 * @throws UnsupportedOperationException If the device does not have
2225 * {@link PackageManager#FEATURE_TELEPHONY_EUICC}.
Pengquan Mengeb7ac732018-11-29 18:33:17 -08002226 * @hide
2227 */
2228 @SystemApi
2229 public void requestEmbeddedSubscriptionInfoListRefresh(int cardId) {
2230 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002231 ISub iSub = TelephonyManager.getSubscriptionService();
Pengquan Mengeb7ac732018-11-29 18:33:17 -08002232 if (iSub != null) {
2233 iSub.requestEmbeddedSubscriptionInfoListRefresh(cardId);
2234 }
2235 } catch (RemoteException ex) {
2236 logd("requestEmbeddedSubscriptionInfoListFresh for card = " + cardId + " failed.");
Jeff Davidsond02731f2017-04-09 14:31:09 -07002237 }
2238 }
2239
2240 /**
Ling Ma34891072024-05-15 17:57:21 -07002241 * Get the active subscription count.
Ling Ma9a53a422023-11-13 14:11:09 -08002242 *
Jack Yu85f02b22022-12-03 01:24:28 -08002243 * @return The current number of active subscriptions.
Jeff Davidson3c0415a2018-02-23 15:27:46 -08002244 *
Jack Yu85f02b22022-12-03 01:24:28 -08002245 * @see #getActiveSubscriptionInfoList()
joonhunshin1a225542023-12-08 08:40:54 +00002246 *
2247 * @throws UnsupportedOperationException If the device does not have
2248 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Wink Savillec650e0b2014-09-02 22:37:08 -07002249 */
Jeff Davidson3c0415a2018-02-23 15:27:46 -08002250 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
Wink Savilled09c4ca2014-11-22 10:08:16 -08002251 public int getActiveSubscriptionInfoCount() {
Wink Savillec650e0b2014-09-02 22:37:08 -07002252 int result = 0;
2253
2254 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002255 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillec650e0b2014-09-02 22:37:08 -07002256 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08002257 result = iSub.getActiveSubInfoCount(mContext.getOpPackageName(),
Ling Ma9a53a422023-11-13 14:11:09 -08002258 mContext.getAttributionTag(), mIsForAllUserProfiles);
Wink Savillec650e0b2014-09-02 22:37:08 -07002259 }
2260 } catch (RemoteException ex) {
2261 // ignore it
2262 }
2263
2264 return result;
2265 }
2266
2267 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -08002268 * @return the maximum number of active subscriptions that will be returned by
2269 * {@link #getActiveSubscriptionInfoList} and the value returned by
2270 * {@link #getActiveSubscriptionInfoCount}.
2271 */
2272 public int getActiveSubscriptionInfoCountMax() {
2273 int result = 0;
2274
2275 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002276 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savilled09c4ca2014-11-22 10:08:16 -08002277 if (iSub != null) {
2278 result = iSub.getActiveSubInfoCountMax();
2279 }
2280 } catch (RemoteException ex) {
2281 // ignore it
2282 }
2283
2284 return result;
2285 }
2286
2287 /**
2288 * Add a new SubscriptionInfo to SubscriptionInfo database if needed
Wink Savillefb40dd42014-06-12 17:02:31 -07002289 * @param iccId the IccId of the SIM card
Sanket Padawe7e460252017-03-10 16:18:20 -08002290 * @param slotIndex the slot which the SIM is inserted
Wink Savillefb40dd42014-06-12 17:02:31 -07002291 * @return the URL of the newly created row or the updated row
Wink Savillef5bca082014-09-03 15:13:33 -07002292 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07002293 */
Sanket Padawe7e460252017-03-10 16:18:20 -08002294 public Uri addSubscriptionInfoRecord(String iccId, int slotIndex) {
2295 if (VDBG) logd("[addSubscriptionInfoRecord]+ iccId:" + iccId + " slotIndex:" + slotIndex);
Wink Savillefb40dd42014-06-12 17:02:31 -07002296 if (iccId == null) {
Wink Savillea374c3d2014-11-11 11:48:04 -08002297 logd("[addSubscriptionInfoRecord]- null iccId");
Wink Savillefb40dd42014-06-12 17:02:31 -07002298 }
Sanket Padawe7e460252017-03-10 16:18:20 -08002299 if (!isValidSlotIndex(slotIndex)) {
2300 logd("[addSubscriptionInfoRecord]- invalid slotIndex");
Wink Savillec650e0b2014-09-02 22:37:08 -07002301 }
Wink Savillefb40dd42014-06-12 17:02:31 -07002302
Vasu Noriaea03912018-09-04 11:19:59 -07002303 addSubscriptionInfoRecord(iccId, null, slotIndex, SUBSCRIPTION_TYPE_LOCAL_SIM);
Wink Savillefb40dd42014-06-12 17:02:31 -07002304
2305 // FIXME: Always returns null?
2306 return null;
2307
2308 }
2309
2310 /**
Vasu Noriaea03912018-09-04 11:19:59 -07002311 * Add a new SubscriptionInfo to SubscriptionInfo database if needed
2312 * @param uniqueId This is the unique identifier for the subscription within the
2313 * specific subscription type.
2314 * @param displayName human-readable name of the device the subscription corresponds to.
2315 * @param slotIndex the slot assigned to this subscription. It is ignored for subscriptionType
2316 * of {@link #SUBSCRIPTION_TYPE_REMOTE_SIM}.
2317 * @param subscriptionType the {@link #SUBSCRIPTION_TYPE}
joonhunshin1a225542023-12-08 08:40:54 +00002318 *
2319 * @throws UnsupportedOperationException If the device does not have
2320 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Vasu Noriaea03912018-09-04 11:19:59 -07002321 * @hide
2322 */
Etienne Ruffieux6a646db2021-07-27 10:06:27 +00002323 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
2324 public void addSubscriptionInfoRecord(@NonNull String uniqueId, @Nullable String displayName,
Etienne Ruffieux036f3012022-02-24 10:33:04 +00002325 int slotIndex, @SubscriptionType int subscriptionType) {
Vasu Noriaea03912018-09-04 11:19:59 -07002326 if (VDBG) {
2327 logd("[addSubscriptionInfoRecord]+ uniqueId:" + uniqueId
2328 + ", displayName:" + displayName + ", slotIndex:" + slotIndex
2329 + ", subscriptionType: " + subscriptionType);
2330 }
2331 if (uniqueId == null) {
2332 Log.e(LOG_TAG, "[addSubscriptionInfoRecord]- uniqueId is null");
2333 return;
2334 }
2335
2336 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002337 ISub iSub = TelephonyManager.getSubscriptionService();
Vasu Noriaea03912018-09-04 11:19:59 -07002338 if (iSub == null) {
2339 Log.e(LOG_TAG, "[addSubscriptionInfoRecord]- ISub service is null");
2340 return;
2341 }
2342 int result = iSub.addSubInfo(uniqueId, displayName, slotIndex, subscriptionType);
2343 if (result < 0) {
2344 Log.e(LOG_TAG, "Adding of subscription didn't succeed: error = " + result);
2345 } else {
2346 logd("successfully added new subscription");
2347 }
2348 } catch (RemoteException ex) {
2349 // ignore it
2350 }
2351 }
2352
2353 /**
Jack Yu647bbb92022-12-12 21:45:26 -08002354 * Remove subscription info record from the subscription database.
2355 *
Vasu Noriaea03912018-09-04 11:19:59 -07002356 * @param uniqueId This is the unique identifier for the subscription within the specific
Jack Yu647bbb92022-12-12 21:45:26 -08002357 * subscription type.
2358 * @param subscriptionType the type of subscription to be removed.
2359 *
2360 * @throws NullPointerException if {@code uniqueId} is {@code null}.
2361 * @throws SecurityException if callers do not hold the required permission.
2362 *
joonhunshin1a225542023-12-08 08:40:54 +00002363 * @throws UnsupportedOperationException If the device does not have
2364 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Vasu Noriaea03912018-09-04 11:19:59 -07002365 * @hide
2366 */
Etienne Ruffieux6a646db2021-07-27 10:06:27 +00002367 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
Etienne Ruffieux036f3012022-02-24 10:33:04 +00002368 public void removeSubscriptionInfoRecord(@NonNull String uniqueId,
2369 @SubscriptionType int subscriptionType) {
Vasu Noriaea03912018-09-04 11:19:59 -07002370 if (VDBG) {
2371 logd("[removeSubscriptionInfoRecord]+ uniqueId:" + uniqueId
2372 + ", subscriptionType: " + subscriptionType);
2373 }
2374 if (uniqueId == null) {
2375 Log.e(LOG_TAG, "[addSubscriptionInfoRecord]- uniqueId is null");
2376 return;
2377 }
2378
2379 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002380 ISub iSub = TelephonyManager.getSubscriptionService();
Vasu Noriaea03912018-09-04 11:19:59 -07002381 if (iSub == null) {
2382 Log.e(LOG_TAG, "[removeSubscriptionInfoRecord]- ISub service is null");
2383 return;
2384 }
Jack Yu4a922da2023-04-14 09:17:36 -07002385 boolean result = iSub.removeSubInfo(uniqueId, subscriptionType);
2386 if (!result) {
2387 Log.e(LOG_TAG, "Removal of subscription didn't succeed");
Vasu Noriaea03912018-09-04 11:19:59 -07002388 } else {
2389 logd("successfully removed subscription");
2390 }
2391 } catch (RemoteException ex) {
2392 // ignore it
2393 }
2394 }
2395
2396 /**
changbetty23eee52e2019-12-18 18:09:56 +08002397 * Set SIM icon tint color for subscription ID
Wink Savilled09c4ca2014-11-22 10:08:16 -08002398 * @param tint the RGB value of icon tint color of the SIM
Jack Yu4fcc4902022-12-04 18:04:33 -08002399 * @param subId the unique subscription ID in database
Wink Savillefb40dd42014-06-12 17:02:31 -07002400 * @return the number of records updated
Wink Savillef5bca082014-09-03 15:13:33 -07002401 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07002402 */
changbetty23eee52e2019-12-18 18:09:56 +08002403 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
2404 public int setIconTint(@ColorInt int tint, int subId) {
Stuart Scottab45ec12014-10-28 09:29:01 -07002405 if (VDBG) logd("[setIconTint]+ tint:" + tint + " subId:" + subId);
Malcolm Chenbd4ae762018-08-03 17:24:07 -07002406 return setSubscriptionPropertyHelper(subId, "setIconTint",
Jack Yu4fcc4902022-12-04 18:04:33 -08002407 (iSub)-> iSub.setIconTint(subId, tint)
Malcolm Chenbd4ae762018-08-03 17:24:07 -07002408 );
Wink Savillefb40dd42014-06-12 17:02:31 -07002409 }
2410
2411 /**
changbetty23eee52e2019-12-18 18:09:56 +08002412 * Set the display name for a subscription ID
Wink Savillefb40dd42014-06-12 17:02:31 -07002413 * @param displayName the display name of SIM card
changbetty23eee52e2019-12-18 18:09:56 +08002414 * @param subId the unique Subscritpion ID in database
Jack Yu5c6eb0e2019-10-16 09:16:54 -07002415 * @param nameSource SIM display name source
Wink Saville98513d72014-12-08 12:44:16 -08002416 * @return the number of records updated or < 0 if invalid subId
Wink Savillef5bca082014-09-03 15:13:33 -07002417 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07002418 */
changbetty23eee52e2019-12-18 18:09:56 +08002419 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
2420 public int setDisplayName(@Nullable String displayName, int subId,
2421 @SimDisplayNameSource int nameSource) {
Wink Savillec650e0b2014-09-02 22:37:08 -07002422 if (VDBG) {
2423 logd("[setDisplayName]+ displayName:" + displayName + " subId:" + subId
2424 + " nameSource:" + nameSource);
2425 }
Malcolm Chenbd4ae762018-08-03 17:24:07 -07002426 return setSubscriptionPropertyHelper(subId, "setDisplayName",
2427 (iSub)-> iSub.setDisplayNameUsingSrc(displayName, subId, nameSource)
2428 );
Wink Savillefb40dd42014-06-12 17:02:31 -07002429 }
2430
2431 /**
2432 * Set phone number by subId
Wink Savillefb40dd42014-06-12 17:02:31 -07002433 * @param number the phone number of the SIM
Wink Savillea374c3d2014-11-11 11:48:04 -08002434 * @param subId the unique SubscriptionInfo index in database
Wink Savillefb40dd42014-06-12 17:02:31 -07002435 * @return the number of records updated
Wink Savillef5bca082014-09-03 15:13:33 -07002436 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07002437 */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +00002438 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Wink Savilled09c4ca2014-11-22 10:08:16 -08002439 public int setDisplayNumber(String number, int subId) {
Malcolm Chenbd4ae762018-08-03 17:24:07 -07002440 if (number == null) {
Wink Savillec650e0b2014-09-02 22:37:08 -07002441 logd("[setDisplayNumber]- fail");
Wink Savillefb40dd42014-06-12 17:02:31 -07002442 return -1;
2443 }
Malcolm Chenbd4ae762018-08-03 17:24:07 -07002444 return setSubscriptionPropertyHelper(subId, "setDisplayNumber",
2445 (iSub)-> iSub.setDisplayNumber(number, subId)
2446 );
Wink Savillefb40dd42014-06-12 17:02:31 -07002447 }
2448
2449 /**
Wink Savillefb40dd42014-06-12 17:02:31 -07002450 * Set data roaming by simInfo index
Wink Savillefb40dd42014-06-12 17:02:31 -07002451 * @param roaming 0:Don't allow data when roaming, 1:Allow data when roaming
Wink Savillea374c3d2014-11-11 11:48:04 -08002452 * @param subId the unique SubscriptionInfo index in database
Wink Savillefb40dd42014-06-12 17:02:31 -07002453 * @return the number of records updated
Wink Savillef5bca082014-09-03 15:13:33 -07002454 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07002455 */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +00002456 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Wink Savilled09c4ca2014-11-22 10:08:16 -08002457 public int setDataRoaming(int roaming, int subId) {
Wink Savillefb40dd42014-06-12 17:02:31 -07002458 if (VDBG) logd("[setDataRoaming]+ roaming:" + roaming + " subId:" + subId);
Malcolm Chenbd4ae762018-08-03 17:24:07 -07002459 return setSubscriptionPropertyHelper(subId, "setDataRoaming",
2460 (iSub)->iSub.setDataRoaming(roaming, subId)
2461 );
Wink Savillefb40dd42014-06-12 17:02:31 -07002462 }
2463
Wink Saville905bb542014-09-04 17:10:23 -07002464 /**
Sanket Padawe7e460252017-03-10 16:18:20 -08002465 * Get slotIndex associated with the subscription.
sqian996a3182018-10-12 18:41:19 -07002466 *
2467 * @param subscriptionId the unique SubscriptionInfo index in database
2468 * @return slotIndex as a positive integer or {@link #INVALID_SIM_SLOT_INDEX} if the supplied
2469 * subscriptionId doesn't have an associated slot index.
Wink Saville905bb542014-09-04 17:10:23 -07002470 */
sqian996a3182018-10-12 18:41:19 -07002471 public static int getSlotIndex(int subscriptionId) {
Jack Yu4a922da2023-04-14 09:17:36 -07002472 return sGetSlotIndexCache.query(subscriptionId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002473 }
2474
sqiancd4dafb2018-08-29 13:58:49 -07002475 /**
Jack Yu443dcaf2023-02-20 21:15:54 -08002476 * Get an array of subscription ids for the specified logical SIM slot Index. The maximum size
2477 * of the array is 1. This API was mistakenly designed to return multiple subscription ids,
2478 * which is not possible in the current Android telephony architecture.
Jack Yu34730f62022-12-15 16:43:30 -08002479 *
2480 * @param slotIndex The logical SIM slot index.
2481 *
Jack Yu443dcaf2023-02-20 21:15:54 -08002482 * @return Subscription id of the active subscription on the specified logical SIM slot index.
2483 * If SIM is absent on the slot, a single element array of {@link #INVALID_SUBSCRIPTION_ID} will
2484 * be returned. {@code null} if the provided {@code slotIndex} is not valid.
Jack Yu34730f62022-12-15 16:43:30 -08002485 *
2486 * @deprecated Use {@link #getSubscriptionId(int)} instead.
sqiancd4dafb2018-08-29 13:58:49 -07002487 */
Jack Yu34730f62022-12-15 16:43:30 -08002488 @Deprecated
sqianf8ace212018-10-19 19:01:42 -07002489 @Nullable
sqiand8c30b92018-10-30 16:58:20 -07002490 public int[] getSubscriptionIds(int slotIndex) {
Jack Yu443dcaf2023-02-20 21:15:54 -08002491 if (!isValidSlotIndex(slotIndex)) {
Jack Yu34730f62022-12-15 16:43:30 -08002492 return null;
2493 }
Jack Yu24839812022-11-19 22:24:29 -08002494 return new int[]{getSubscriptionId(slotIndex)};
sqiancd4dafb2018-08-29 13:58:49 -07002495 }
2496
Jack Yu443dcaf2023-02-20 21:15:54 -08002497 /**
2498 * Get an array of subscription ids for the specified logical SIM slot Index. The maximum size
2499 * of the array is 1. This API was mistakenly designed to return multiple subscription ids,
2500 * which is not possible in the current Android telephony architecture.
2501 *
2502 * @param slotIndex The logical SIM slot index.
2503 *
2504 * @return Subscription id of the active subscription on the specified logical SIM slot index.
2505 * If SIM is absent on the slot, a single element array of {@link #INVALID_SUBSCRIPTION_ID} will
2506 * be returned. {@code null} if the provided {@code slotIndex} is not valid.
2507 *
2508 * @deprecated Use {@link #getSubscriptionId(int)} instead.
2509 * @hide
2510 */
joonhunshin1a225542023-12-08 08:40:54 +00002511 @Deprecated
Sanket Padawe7e460252017-03-10 16:18:20 -08002512 public static int[] getSubId(int slotIndex) {
2513 if (!isValidSlotIndex(slotIndex)) {
Wink Savillec650e0b2014-09-02 22:37:08 -07002514 return null;
2515 }
Jack Yu443dcaf2023-02-20 21:15:54 -08002516 return new int[]{getSubscriptionId(slotIndex)};
Wink Savillefb40dd42014-06-12 17:02:31 -07002517 }
2518
Jack Yu24839812022-11-19 22:24:29 -08002519 /**
Jack Yu34730f62022-12-15 16:43:30 -08002520 * Get the subscription id for specified logical SIM slot index.
Jack Yu24839812022-11-19 22:24:29 -08002521 *
Jack Yu34730f62022-12-15 16:43:30 -08002522 * @param slotIndex The logical SIM slot index.
Jack Yu24839812022-11-19 22:24:29 -08002523 * @return The subscription id. {@link #INVALID_SUBSCRIPTION_ID} if SIM is absent.
Jack Yu24839812022-11-19 22:24:29 -08002524 */
2525 public static int getSubscriptionId(int slotIndex) {
2526 if (!isValidSlotIndex(slotIndex)) {
2527 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2528 }
2529
Jack Yu4a922da2023-04-14 09:17:36 -07002530 return sGetSubIdCache.query(slotIndex);
Jack Yu24839812022-11-19 22:24:29 -08002531 }
2532
Wink Savillef5bca082014-09-03 15:13:33 -07002533 /** @hide */
Chen Xu4c0b06d2018-10-22 16:54:39 +00002534 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
Wink Saville63f03dd2014-10-23 10:44:45 -07002535 public static int getPhoneId(int subId) {
Jack Yu4a922da2023-04-14 09:17:36 -07002536 return sGetPhoneIdCache.query(subId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002537 }
2538
Wink Savillefb40dd42014-06-12 17:02:31 -07002539 private static void logd(String msg) {
Wink Savilled09c4ca2014-11-22 10:08:16 -08002540 Rlog.d(LOG_TAG, msg);
Wink Savillefb40dd42014-06-12 17:02:31 -07002541 }
2542
Malcolm Chen4674a792019-03-20 20:32:27 -07002543 private static void loge(String msg) {
2544 Rlog.e(LOG_TAG, msg);
2545 }
2546
Wink Savillefb40dd42014-06-12 17:02:31 -07002547 /**
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002548 * Returns the system's default subscription id.
2549 *
2550 * For a voice capable device, it will return getDefaultVoiceSubscriptionId.
2551 * For a data only device, it will return the getDefaultDataSubscriptionId.
2552 * May return an INVALID_SUBSCRIPTION_ID on error.
2553 *
2554 * @return the "system" default subscription id.
Wink Savillefb40dd42014-06-12 17:02:31 -07002555 */
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002556 public static int getDefaultSubscriptionId() {
Ling Ma19cfc632023-10-31 06:27:35 +00002557 return sGetDefaultSubIdCacheAsUser.query(Process.myUserHandle().getIdentifier());
Wink Savillefb40dd42014-06-12 17:02:31 -07002558 }
2559
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002560 /**
2561 * Returns the system's default voice subscription id.
2562 *
2563 * On a data only device or on error, will return INVALID_SUBSCRIPTION_ID.
2564 *
2565 * @return the default voice subscription Id.
joonhunshin1a225542023-12-08 08:40:54 +00002566 *
2567 * @throws UnsupportedOperationException If the device does not have
2568 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002569 */
2570 public static int getDefaultVoiceSubscriptionId() {
Wink Savilled09c4ca2014-11-22 10:08:16 -08002571 int subId = INVALID_SUBSCRIPTION_ID;
Wink Savillefb40dd42014-06-12 17:02:31 -07002572
2573 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002574 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07002575 if (iSub != null) {
Ling Ma19cfc632023-10-31 06:27:35 +00002576 subId = iSub.getDefaultVoiceSubIdAsUser(Process.myUserHandle().getIdentifier());
Wink Savillefb40dd42014-06-12 17:02:31 -07002577 }
2578 } catch (RemoteException ex) {
2579 // ignore it
2580 }
2581
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002582 if (VDBG) logd("getDefaultVoiceSubscriptionId, sub id = " + subId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002583 return subId;
2584 }
2585
Hall Liud2f962a2019-10-31 15:17:58 -07002586 /**
2587 * Sets the system's default voice subscription id.
2588 *
2589 * On a data-only device, this is a no-op.
2590 *
2591 * May throw a {@link RuntimeException} if the provided subscription id is equal to
2592 * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}
2593 *
2594 * @param subscriptionId A valid subscription ID to set as the system default, or
2595 * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}
joonhunshin1a225542023-12-08 08:40:54 +00002596 *
2597 * @throws UnsupportedOperationException If the device does not have
2598 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Hall Liud2f962a2019-10-31 15:17:58 -07002599 * @hide
2600 */
2601 @SystemApi
Hall Liud2f962a2019-10-31 15:17:58 -07002602 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
2603 public void setDefaultVoiceSubscriptionId(int subscriptionId) {
2604 if (VDBG) logd("setDefaultVoiceSubId sub id = " + subscriptionId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002605 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002606 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07002607 if (iSub != null) {
Hall Liud2f962a2019-10-31 15:17:58 -07002608 iSub.setDefaultVoiceSubId(subscriptionId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002609 }
2610 } catch (RemoteException ex) {
Wink Savillec650e0b2014-09-02 22:37:08 -07002611 // ignore it
Wink Savillefb40dd42014-06-12 17:02:31 -07002612 }
2613 }
2614
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002615 /**
Hall Liud2f962a2019-10-31 15:17:58 -07002616 * Same as {@link #setDefaultVoiceSubscriptionId(int)}, but preserved for backwards
2617 * compatibility.
joonhunshin1a225542023-12-08 08:40:54 +00002618 *
2619 * @throws UnsupportedOperationException If the device does not have
2620 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Hall Liud2f962a2019-10-31 15:17:58 -07002621 * @hide
2622 */
2623 public void setDefaultVoiceSubId(int subId) {
2624 setDefaultVoiceSubscriptionId(subId);
2625 }
2626
2627 /**
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002628 * Return the SubscriptionInfo for default voice subscription.
2629 *
2630 * Will return null on data only devices, or on error.
2631 *
2632 * @return the SubscriptionInfo for the default voice subscription.
2633 * @hide
2634 */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +00002635 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Wink Savilled09c4ca2014-11-22 10:08:16 -08002636 public SubscriptionInfo getDefaultVoiceSubscriptionInfo() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002637 return getActiveSubscriptionInfo(getDefaultVoiceSubscriptionId());
Wink Savillefb40dd42014-06-12 17:02:31 -07002638 }
2639
Wink Savillef5bca082014-09-03 15:13:33 -07002640 /** @hide */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +00002641 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Wink Savillec650e0b2014-09-02 22:37:08 -07002642 public static int getDefaultVoicePhoneId() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002643 return getPhoneId(getDefaultVoiceSubscriptionId());
Wink Savillefb40dd42014-06-12 17:02:31 -07002644 }
2645
Wink Saville905bb542014-09-04 17:10:23 -07002646 /**
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002647 * Returns the system's default SMS subscription id.
Wink Savilled09c4ca2014-11-22 10:08:16 -08002648 *
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002649 * On a data only device or on error, will return INVALID_SUBSCRIPTION_ID.
2650 *
2651 * @return the default SMS subscription Id.
Wink Saville905bb542014-09-04 17:10:23 -07002652 */
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002653 public static int getDefaultSmsSubscriptionId() {
Ling Ma19cfc632023-10-31 06:27:35 +00002654 return sGetDefaultSmsSubIdCacheAsUser.query(Process.myUserHandle().getIdentifier());
Wink Savillec650e0b2014-09-02 22:37:08 -07002655 }
2656
sqiandb496412018-11-12 18:14:18 -08002657 /**
2658 * Set the subscription which will be used by default for SMS, with the subscription which
2659 * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied
2660 * subscription ID is not usable (check with {@link #isUsableSubscriptionId(int)}).
2661 *
2662 * @param subscriptionId the supplied subscription ID
2663 *
joonhunshin1a225542023-12-08 08:40:54 +00002664 * @throws UnsupportedOperationException If the device does not have
2665 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
sqiandb496412018-11-12 18:14:18 -08002666 * @hide
2667 */
2668 @SystemApi
2669 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
2670 public void setDefaultSmsSubId(int subscriptionId) {
2671 if (VDBG) logd("setDefaultSmsSubId sub id = " + subscriptionId);
Wink Savillec650e0b2014-09-02 22:37:08 -07002672 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002673 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillec650e0b2014-09-02 22:37:08 -07002674 if (iSub != null) {
sqiandb496412018-11-12 18:14:18 -08002675 iSub.setDefaultSmsSubId(subscriptionId);
Wink Savillec650e0b2014-09-02 22:37:08 -07002676 }
2677 } catch (RemoteException ex) {
sqiana31ef442019-02-13 14:41:44 -08002678 ex.rethrowFromSystemServer();
Wink Savillec650e0b2014-09-02 22:37:08 -07002679 }
2680 }
2681
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002682 /**
2683 * Returns the system's default data subscription id.
2684 *
2685 * On a voice only device or on error, will return INVALID_SUBSCRIPTION_ID.
2686 *
2687 * @return the default data subscription Id.
2688 */
2689 public static int getDefaultDataSubscriptionId() {
Jack Yu4a922da2023-04-14 09:17:36 -07002690 return sGetDefaultDataSubIdCache.query(null);
Wink Savillefb40dd42014-06-12 17:02:31 -07002691 }
2692
sqiandb496412018-11-12 18:14:18 -08002693 /**
2694 * Set the subscription which will be used by default for data, with the subscription which
2695 * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied
2696 * subscription ID is not usable (check with {@link #isUsableSubscriptionId(int)}).
2697 *
2698 * @param subscriptionId the supplied subscription ID
2699 *
joonhunshin1a225542023-12-08 08:40:54 +00002700 * @throws UnsupportedOperationException If the device does not have
2701 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
sqiandb496412018-11-12 18:14:18 -08002702 * @hide
2703 */
2704 @SystemApi
2705 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
2706 public void setDefaultDataSubId(int subscriptionId) {
2707 if (VDBG) logd("setDataSubscription sub id = " + subscriptionId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002708 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002709 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07002710 if (iSub != null) {
sqiandb496412018-11-12 18:14:18 -08002711 iSub.setDefaultDataSubId(subscriptionId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002712 }
2713 } catch (RemoteException ex) {
Wink Savillec650e0b2014-09-02 22:37:08 -07002714 // ignore it
Wink Savillefb40dd42014-06-12 17:02:31 -07002715 }
2716 }
2717
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002718 /**
2719 * Return the SubscriptionInfo for default data subscription.
2720 *
2721 * Will return null on voice only devices, or on error.
2722 *
2723 * @return the SubscriptionInfo for the default data subscription.
joonhunshin1a225542023-12-08 08:40:54 +00002724 *
2725 * @throws UnsupportedOperationException If the device does not have
2726 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002727 * @hide
2728 */
Mathew Inwooda8382062018-08-16 17:01:12 +01002729 @UnsupportedAppUsage
Wink Savilled09c4ca2014-11-22 10:08:16 -08002730 public SubscriptionInfo getDefaultDataSubscriptionInfo() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002731 return getActiveSubscriptionInfo(getDefaultDataSubscriptionId());
Wink Savillec650e0b2014-09-02 22:37:08 -07002732 }
Wink Savillefb40dd42014-06-12 17:02:31 -07002733
Wink Savillec650e0b2014-09-02 22:37:08 -07002734 /**
sqian0bcdd6c2018-10-30 13:55:23 -07002735 * Check if the supplied subscription ID is valid.
2736 *
2737 * <p>A valid subscription ID is not necessarily an active subscription ID
2738 * (see {@link #isActiveSubscriptionId(int)}) or an usable subscription ID
2739 * (see {@link #isUsableSubscriptionId(int)}). Unless specifically noted, subscription
2740 * APIs work with a valid subscription ID.
sqian00dae7e02018-08-30 11:53:14 -07002741 *
2742 * @param subscriptionId The subscription ID.
sqian0bcdd6c2018-10-30 13:55:23 -07002743 * @return {@code true} if the supplied subscriptionId is valid; {@code false} otherwise.
Wink Saville905bb542014-09-04 17:10:23 -07002744 */
sqian00dae7e02018-08-30 11:53:14 -07002745 public static boolean isValidSubscriptionId(int subscriptionId) {
2746 return subscriptionId > INVALID_SUBSCRIPTION_ID;
Wink Savillec650e0b2014-09-02 22:37:08 -07002747 }
2748
Wink Saville8eab2b62014-09-23 14:20:58 -07002749 /**
sqian0bcdd6c2018-10-30 13:55:23 -07002750 * Check if the supplied subscription ID is usable.
sqian798da562018-09-12 16:31:17 -07002751 *
sqian0bcdd6c2018-10-30 13:55:23 -07002752 * <p>A usable subscription ID is a valid subscription ID, but not necessarily an active
2753 * subscription ID (see {@link #isActiveSubscriptionId(int)}). Some subscription APIs
2754 * require a usable subscription ID, and this is noted in their documentation; otherwise, a
2755 * subscription ID does not need to be usable for subscription functions, only valid.
sqian798da562018-09-12 16:31:17 -07002756 *
2757 * @param subscriptionId the subscription ID
2758 * @return {@code true} if the subscription ID is usable; {@code false} otherwise.
2759 */
2760 public static boolean isUsableSubscriptionId(int subscriptionId) {
2761 return isUsableSubIdValue(subscriptionId);
2762 }
2763
2764 /**
Wink Saville8eab2b62014-09-23 14:20:58 -07002765 * @return true if subId is an usable subId value else false. A
Wink Saville98513d72014-12-08 12:44:16 -08002766 * usable subId means its neither a INVALID_SUBSCRIPTION_ID nor a DEFAULT_SUB_ID.
Wink Saville8eab2b62014-09-23 14:20:58 -07002767 * @hide
2768 */
Chen Xu4c0b06d2018-10-22 16:54:39 +00002769 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
Wink Saville63f03dd2014-10-23 10:44:45 -07002770 public static boolean isUsableSubIdValue(int subId) {
Wink Savilled09c4ca2014-11-22 10:08:16 -08002771 return subId >= MIN_SUBSCRIPTION_ID_VALUE && subId <= MAX_SUBSCRIPTION_ID_VALUE;
Wink Saville8eab2b62014-09-23 14:20:58 -07002772 }
2773
Wink Savillef5bca082014-09-03 15:13:33 -07002774 /** @hide */
Mathew Inwood45d2c252018-09-14 12:35:36 +01002775 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Sanket Padawe7e460252017-03-10 16:18:20 -08002776 public static boolean isValidSlotIndex(int slotIndex) {
Malcolm Chena43e23f2019-10-21 14:22:18 -07002777 return slotIndex >= 0 && slotIndex < TelephonyManager.getDefault().getActiveModemCount();
Wink Savillec650e0b2014-09-02 22:37:08 -07002778 }
2779
Wink Savillef5bca082014-09-03 15:13:33 -07002780 /** @hide */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +00002781 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Wink Savillec650e0b2014-09-02 22:37:08 -07002782 public static boolean isValidPhoneId(int phoneId) {
Malcolm Chena43e23f2019-10-21 14:22:18 -07002783 return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getActiveModemCount();
Malcolm Chenf87292f2019-09-23 14:06:19 -07002784 }
2785
Wink Savillef5bca082014-09-03 15:13:33 -07002786 /** @hide */
Chen Xu4c0b06d2018-10-22 16:54:39 +00002787 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
Wink Savillefb40dd42014-06-12 17:02:31 -07002788 public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId) {
Jack Yu24839812022-11-19 22:24:29 -08002789 int subId = SubscriptionManager.getSubscriptionId(phoneId);
2790 if (isValidSubscriptionId(subId)) {
2791 putPhoneIdAndSubIdExtra(intent, phoneId, subId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002792 } else {
2793 logd("putPhoneIdAndSubIdExtra: no valid subs");
Amit Mahajanba71c5f2019-02-07 12:29:55 -08002794 intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
Daniel Bright71d3dac2020-01-15 12:10:53 -08002795 intent.putExtra(EXTRA_SLOT_INDEX, phoneId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002796 }
2797 }
Wink Savilleeeacf932014-06-18 01:07:10 -07002798
Wink Savillef5bca082014-09-03 15:13:33 -07002799 /** @hide */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +00002800 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Wink Saville63f03dd2014-10-23 10:44:45 -07002801 public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId, int subId) {
Wink Savilleeeacf932014-06-18 01:07:10 -07002802 if (VDBG) logd("putPhoneIdAndSubIdExtra: phoneId=" + phoneId + " subId=" + subId);
Jack Yud8104ec2019-09-18 09:31:28 -07002803 intent.putExtra(EXTRA_SLOT_INDEX, phoneId);
Wink Savillec650e0b2014-09-02 22:37:08 -07002804 intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
Daniel Bright0b5d2852020-01-09 21:58:16 -08002805 putSubscriptionIdExtra(intent, subId);
Wink Savillec650e0b2014-09-02 22:37:08 -07002806 }
2807
2808 /**
Peter Wang01d128c2019-12-17 19:11:23 -08002809 * Get visible subscription Id(s) of the currently active SIM(s).
Hunter Knepshieldb26cbbd2019-07-03 14:22:32 -07002810 *
Wink Saville8a38a202014-09-03 12:22:54 -07002811 * @return the list of subId's that are active,
Peter Wang01d128c2019-12-17 19:11:23 -08002812 * is never null but the length may be 0.
joonhunshin1a225542023-12-08 08:40:54 +00002813 *
2814 * @throws UnsupportedOperationException If the device does not have
2815 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Wink Savillef5bca082014-09-03 15:13:33 -07002816 * @hide
Wink Savillec650e0b2014-09-02 22:37:08 -07002817 */
Peter Wang01d128c2019-12-17 19:11:23 -08002818 @SystemApi
Peter Wangc061cdf2020-03-16 04:45:23 -07002819 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
Jeff Sharkey32566012014-12-02 18:30:14 -08002820 public @NonNull int[] getActiveSubscriptionIdList() {
Hunter Knepshieldb26cbbd2019-07-03 14:22:32 -07002821 return getActiveSubscriptionIdList(/* visibleOnly */ true);
2822 }
Wink Savillec650e0b2014-09-02 22:37:08 -07002823
Hunter Knepshieldb26cbbd2019-07-03 14:22:32 -07002824 /**
Peter Wang01d128c2019-12-17 19:11:23 -08002825 * Get both hidden and visible subscription Id(s) of the currently active SIM(s).
Hunter Knepshieldb26cbbd2019-07-03 14:22:32 -07002826 *
Peter Wang01d128c2019-12-17 19:11:23 -08002827 * Hidden subscriptions refer to those are not meant visible to the users.
2828 * For example, an opportunistic subscription that is grouped with other
2829 * subscriptions should remain invisible to users as they are only functionally
2830 * supplementary to primary ones.
2831 *
2832 * @return the list of subId's that are active,
2833 * is never null but the length may be 0.
joonhunshin1a225542023-12-08 08:40:54 +00002834 *
2835 * @throws UnsupportedOperationException If the device does not have
2836 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Peter Wang01d128c2019-12-17 19:11:23 -08002837 * @hide
2838 */
2839 @SystemApi
Peter Wangc061cdf2020-03-16 04:45:23 -07002840 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
2841 public @NonNull int[] getCompleteActiveSubscriptionIdList() {
Peter Wang01d128c2019-12-17 19:11:23 -08002842 return getActiveSubscriptionIdList(/* visibleOnly */false);
2843 }
2844
2845 /**
Hunter Knepshieldb26cbbd2019-07-03 14:22:32 -07002846 * @return a non-null list of subId's that are active.
2847 *
2848 * @hide
2849 */
2850 public @NonNull int[] getActiveSubscriptionIdList(boolean visibleOnly) {
Wink Savillec650e0b2014-09-02 22:37:08 -07002851 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002852 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillec650e0b2014-09-02 22:37:08 -07002853 if (iSub != null) {
Hunter Knepshieldb26cbbd2019-07-03 14:22:32 -07002854 int[] subId = iSub.getActiveSubIdList(visibleOnly);
2855 if (subId != null) return subId;
Wink Savillec650e0b2014-09-02 22:37:08 -07002856 }
2857 } catch (RemoteException ex) {
2858 // ignore it
2859 }
2860
Hunter Knepshieldb26cbbd2019-07-03 14:22:32 -07002861 return new int[0];
Wink Savilleeeacf932014-06-18 01:07:10 -07002862 }
Wink Savilled09c4ca2014-11-22 10:08:16 -08002863
2864 /**
2865 * Returns true if the device is considered roaming on the current
2866 * network for a subscription.
2867 * <p>
2868 * Availability: Only when user registered to a network.
2869 *
2870 * @param subId The subscription ID
2871 * @return true if the network for the subscription is roaming, false otherwise
2872 */
2873 public boolean isNetworkRoaming(int subId) {
2874 final int phoneId = getPhoneId(subId);
2875 if (phoneId < 0) {
2876 // What else can we do?
2877 return false;
2878 }
Legler Wu85973dc2015-01-29 15:07:39 +08002879 return TelephonyManager.getDefault().isNetworkRoaming(subId);
Wink Savilled09c4ca2014-11-22 10:08:16 -08002880 }
Wink Saville47920fa2014-12-02 17:08:14 -08002881
2882 /**
Jack Yub0f281b2022-12-10 02:11:18 -08002883 * Set a field in the subscription database. Note not all fields are supported.
2884 *
2885 * @param subscriptionId Subscription Id of Subscription.
2886 * @param columnName Column name in the database. Note not all fields are supported.
2887 * @param value Value to store in the database.
2888 *
2889 * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not
2890 * exposed.
2891 * @throws SecurityException if callers do not hold the required permission.
2892 *
2893 * @see android.provider.Telephony.SimInfo for all the columns.
2894 *
Sanket Padawedc493092015-07-14 14:21:43 -07002895 * @hide
2896 */
Jack Yub0f281b2022-12-10 02:11:18 -08002897 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
2898 public static void setSubscriptionProperty(int subscriptionId, @NonNull String columnName,
2899 @NonNull String value) {
Sanket Padawedc493092015-07-14 14:21:43 -07002900 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002901 ISub iSub = TelephonyManager.getSubscriptionService();
Sanket Padawedc493092015-07-14 14:21:43 -07002902 if (iSub != null) {
Jack Yub0f281b2022-12-10 02:11:18 -08002903 iSub.setSubscriptionProperty(subscriptionId, columnName, value);
Sanket Padawedc493092015-07-14 14:21:43 -07002904 }
2905 } catch (RemoteException ex) {
2906 // ignore it
2907 }
2908 }
2909
2910 /**
Grace Jia2bd23cf2021-03-18 14:47:31 -07002911 * Serialize list of contacts uri to string
2912 * @hide
2913 */
2914 public static String serializeUriLists(List<Uri> uris) {
2915 List<String> contacts = new ArrayList<>();
2916 for (Uri uri : uris) {
2917 contacts.add(uri.toString());
2918 }
2919 try {
2920 ByteArrayOutputStream bos = new ByteArrayOutputStream();
2921 ObjectOutputStream oos = new ObjectOutputStream(bos);
2922 oos.writeObject(contacts);
2923 oos.flush();
2924 return Base64.encodeToString(bos.toByteArray(), Base64.DEFAULT);
2925 } catch (IOException e) {
2926 logd("serializeUriLists IO exception");
2927 }
2928 return "";
2929 }
2930
2931 /**
Jack Yub0f281b2022-12-10 02:11:18 -08002932 * Get specific field in string format from the subscription info database.
2933 *
2934 * @param context The calling context.
2935 * @param subscriptionId Subscription id of the subscription.
2936 * @param columnName Column name in subscription database.
2937 *
2938 * @return Value in string format associated with {@code subscriptionId} and {@code columnName}
Jack Yu43169452023-01-15 02:39:40 -08002939 * from the database. Empty string if the {@code subscriptionId} is invalid (for backward
2940 * compatible).
Jack Yub0f281b2022-12-10 02:11:18 -08002941 *
Jack Yu43169452023-01-15 02:39:40 -08002942 * @throws IllegalArgumentException if the field is not exposed.
Jack Yub0f281b2022-12-10 02:11:18 -08002943 *
2944 * @see android.provider.Telephony.SimInfo for all the columns.
2945 *
Grace Jia2bd23cf2021-03-18 14:47:31 -07002946 * @hide
2947 */
Jack Yub0f281b2022-12-10 02:11:18 -08002948 @NonNull
2949 @RequiresPermission(anyOf = {
2950 Manifest.permission.READ_PHONE_STATE,
2951 Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
2952 "carrier privileges",
2953 })
2954 private static String getStringSubscriptionProperty(@NonNull Context context,
2955 int subscriptionId, @NonNull String columnName) {
Sanket Padawedc493092015-07-14 14:21:43 -07002956 String resultValue = null;
2957 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002958 ISub iSub = TelephonyManager.getSubscriptionService();
Sanket Padawedc493092015-07-14 14:21:43 -07002959 if (iSub != null) {
Jack Yub0f281b2022-12-10 02:11:18 -08002960 resultValue = iSub.getSubscriptionProperty(subscriptionId, columnName,
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08002961 context.getOpPackageName(), context.getAttributionTag());
Sanket Padawedc493092015-07-14 14:21:43 -07002962 }
2963 } catch (RemoteException ex) {
2964 // ignore it
2965 }
Jack Yub0f281b2022-12-10 02:11:18 -08002966 return TextUtils.emptyIfNull(resultValue);
Sanket Padawedc493092015-07-14 14:21:43 -07002967 }
2968
2969 /**
Jack Yub0f281b2022-12-10 02:11:18 -08002970 * Get specific field in {@code boolean} format from the subscription info database.
2971 *
2972 * @param subscriptionId Subscription id of the subscription.
2973 * @param columnName Column name in subscription database.
2974 * @param defaultValue Default value in case not found or error.
2975 * @param context The calling context.
2976 *
2977 * @return Value in {@code boolean} format associated with {@code subscriptionId} and
2978 * {@code columnName} from the database, or {@code defaultValue} if not found or error.
2979 *
2980 * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not
2981 * exposed.
2982 *
2983 * @see android.provider.Telephony.SimInfo for all the columns.
2984 *
Sanket Padawedc493092015-07-14 14:21:43 -07002985 * @hide
2986 */
Jack Yub0f281b2022-12-10 02:11:18 -08002987 @RequiresPermission(anyOf = {
2988 Manifest.permission.READ_PHONE_STATE,
2989 Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
2990 "carrier privileges",
2991 })
2992 public static boolean getBooleanSubscriptionProperty(int subscriptionId,
2993 @NonNull String columnName, boolean defaultValue, @NonNull Context context) {
2994 String result = getStringSubscriptionProperty(context, subscriptionId, columnName);
2995 if (!result.isEmpty()) {
Sanket Padawedc493092015-07-14 14:21:43 -07002996 try {
2997 return Integer.parseInt(result) == 1;
2998 } catch (NumberFormatException err) {
2999 logd("getBooleanSubscriptionProperty NumberFormat exception");
3000 }
3001 }
Jack Yub0f281b2022-12-10 02:11:18 -08003002 return defaultValue;
Sanket Padawedc493092015-07-14 14:21:43 -07003003 }
3004
3005 /**
Jack Yub0f281b2022-12-10 02:11:18 -08003006 * Get specific field in {@code integer} format from the subscription info database.
3007 *
3008 * @param subscriptionId Subscription id of the subscription.
3009 * @param columnName Column name in subscription database.
3010 * @param defaultValue Default value in case not found or error.
3011 * @param context The calling context.
3012 *
3013 * @return Value in {@code integer} format associated with {@code subscriptionId} and
3014 * {@code columnName} from the database, or {@code defaultValue} if not found or error.
3015 *
3016 * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not
3017 * exposed.
3018 *
3019 * @see android.provider.Telephony.SimInfo for all the columns.
3020 *
Sanket Padawedc493092015-07-14 14:21:43 -07003021 * @hide
3022 */
Jack Yub0f281b2022-12-10 02:11:18 -08003023 @RequiresPermission(anyOf = {
3024 Manifest.permission.READ_PHONE_STATE,
3025 Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
3026 "carrier privileges",
3027 })
3028 public static int getIntegerSubscriptionProperty(int subscriptionId, @NonNull String columnName,
3029 int defaultValue, @NonNull Context context) {
3030 String result = getStringSubscriptionProperty(context, subscriptionId, columnName);
3031 if (!result.isEmpty()) {
Sanket Padawedc493092015-07-14 14:21:43 -07003032 try {
3033 return Integer.parseInt(result);
3034 } catch (NumberFormatException err) {
calvinpand77e0bd2020-01-14 20:37:31 +08003035 logd("getIntegerSubscriptionProperty NumberFormat exception");
3036 }
3037 }
Jack Yub0f281b2022-12-10 02:11:18 -08003038 return defaultValue;
calvinpand77e0bd2020-01-14 20:37:31 +08003039 }
3040
3041 /**
Jack Yub0f281b2022-12-10 02:11:18 -08003042 * Get specific field in {@code long} format from the subscription info database.
3043 *
3044 * @param subscriptionId Subscription id of the subscription.
3045 * @param columnName Column name in subscription database.
3046 * @param defaultValue Default value in case not found or error.
3047 * @param context The calling context.
3048 *
3049 * @return Value in {@code long} format associated with {@code subscriptionId} and
3050 * {@code columnName} from the database, or {@code defaultValue} if not found or error.
3051 *
3052 * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not
3053 * exposed.
3054 *
3055 * @see android.provider.Telephony.SimInfo for all the columns.
3056 *
calvinpand77e0bd2020-01-14 20:37:31 +08003057 * @hide
3058 */
Jack Yub0f281b2022-12-10 02:11:18 -08003059 @RequiresPermission(anyOf = {
3060 Manifest.permission.READ_PHONE_STATE,
3061 Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
3062 "carrier privileges",
3063 })
3064 public static long getLongSubscriptionProperty(int subscriptionId, @NonNull String columnName,
3065 long defaultValue, @NonNull Context context) {
3066 String result = getStringSubscriptionProperty(context, subscriptionId, columnName);
3067 if (!result.isEmpty()) {
calvinpand77e0bd2020-01-14 20:37:31 +08003068 try {
3069 return Long.parseLong(result);
3070 } catch (NumberFormatException err) {
3071 logd("getLongSubscriptionProperty NumberFormat exception");
Sanket Padawedc493092015-07-14 14:21:43 -07003072 }
3073 }
Jack Yub0f281b2022-12-10 02:11:18 -08003074 return defaultValue;
Sanket Padawedc493092015-07-14 14:21:43 -07003075 }
3076
3077 /**
Jordan Liue4141f02019-08-16 14:07:03 -07003078 * Returns the {@link Resources} from the given {@link Context} for the MCC/MNC associated with
3079 * the subscription. If the subscription ID is invalid, the base resources are returned instead.
3080 *
3081 * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
3082 *
Sanket Padawedc493092015-07-14 14:21:43 -07003083 * @param context Context object
Jordan Liue4141f02019-08-16 14:07:03 -07003084 * @param subId Subscription Id of Subscription whose resources are required
Sanket Padawedc493092015-07-14 14:21:43 -07003085 * @return Resources associated with Subscription.
joonhunshin1a225542023-12-08 08:40:54 +00003086 *
3087 * @throws UnsupportedOperationException If the device does not have
3088 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Sanket Padawedc493092015-07-14 14:21:43 -07003089 * @hide
3090 */
Jordan Liue4141f02019-08-16 14:07:03 -07003091 @NonNull
3092 @SystemApi
3093 public static Resources getResourcesForSubId(@NonNull Context context, int subId) {
Torbjorn Eklund99c11d82018-08-21 16:06:47 +02003094 return getResourcesForSubId(context, subId, false);
3095 }
3096
3097 /**
3098 * Returns the resources associated with Subscription.
3099 * @param context Context object
3100 * @param subId Subscription Id of Subscription who's resources are required
3101 * @param useRootLocale if root locale should be used. Localized locale is used if false.
3102 * @return Resources associated with Subscription.
3103 * @hide
3104 */
Torbjorn Eklundf8899f02019-11-20 10:59:59 +01003105 @NonNull
Torbjorn Eklund99c11d82018-08-21 16:06:47 +02003106 public static Resources getResourcesForSubId(Context context, int subId,
3107 boolean useRootLocale) {
sangyun62c0da52023-08-07 15:31:24 +09003108 // Check if the Resources already exists in the cache based on the given context. Find a
3109 // Resource that match Configuration.
3110 Pair<String, Configuration> cacheKey = null;
3111 if (isValidSubscriptionId(subId)) {
3112 Configuration configurationKey =
3113 new Configuration(context.getResources().getConfiguration());
3114 if (useRootLocale) {
3115 configurationKey.setLocale(Locale.ROOT);
3116 }
sangyun6beccf22024-04-05 16:35:01 +09003117 cacheKey = Pair.create(context.getPackageName() + ", subid=" + subId, configurationKey);
sangyunfbcde602023-08-23 10:40:55 +09003118 synchronized (sResourcesCache) {
3119 Resources cached = sResourcesCache.get(cacheKey);
3120 if (cached != null) {
3121 // Cache hit. Use cached Resources.
3122 return cached;
3123 }
Torbjorn Eklundf8899f02019-11-20 10:59:59 +01003124 }
3125 }
3126
Sanket Padawedc493092015-07-14 14:21:43 -07003127 final SubscriptionInfo subInfo =
3128 SubscriptionManager.from(context).getActiveSubscriptionInfo(subId);
3129
Jordan Liu0e161082020-01-21 10:55:08 -08003130 Configuration overrideConfig = new Configuration();
Sanket Padawedc493092015-07-14 14:21:43 -07003131 if (subInfo != null) {
Jordan Liu0e161082020-01-21 10:55:08 -08003132 overrideConfig.mcc = subInfo.getMcc();
3133 overrideConfig.mnc = subInfo.getMnc();
Willy Hu138b89d2021-03-22 11:36:54 +08003134 if (overrideConfig.mnc == 0) {
3135 overrideConfig.mnc = Configuration.MNC_ZERO;
3136 cacheKey = null;
3137 }
Hui Wang00e633c2022-03-15 21:53:49 +00003138 } else {
3139 cacheKey = null;
Sanket Padawedc493092015-07-14 14:21:43 -07003140 }
Torbjorn Eklund99c11d82018-08-21 16:06:47 +02003141
3142 if (useRootLocale) {
Jordan Liu0e161082020-01-21 10:55:08 -08003143 overrideConfig.setLocale(Locale.ROOT);
Torbjorn Eklund99c11d82018-08-21 16:06:47 +02003144 }
3145
Jordan Liu0e161082020-01-21 10:55:08 -08003146 // Create new context with new configuration so that we can avoid modifying the passed in
3147 // context.
3148 // Note that if the original context configuration changes, the resources here will also
3149 // change for all values except those overridden by newConfig (e.g. if the device has an
3150 // orientation change).
3151 Context newContext = context.createConfigurationContext(overrideConfig);
3152 Resources res = newContext.getResources();
Torbjorn Eklundf8899f02019-11-20 10:59:59 +01003153
3154 if (cacheKey != null) {
sangyunfbcde602023-08-23 10:40:55 +09003155 synchronized (sResourcesCache) {
3156 // Save the newly created Resources in the resource cache.
3157 sResourcesCache.put(cacheKey, res);
3158 }
Torbjorn Eklundf8899f02019-11-20 10:59:59 +01003159 }
3160 return res;
Sanket Padawedc493092015-07-14 14:21:43 -07003161 }
3162
3163 /**
sqian0bcdd6c2018-10-30 13:55:23 -07003164 * Checks if the supplied subscription ID corresponds to a subscription which is actively in
3165 * use on the device. An active subscription ID is a valid and usable subscription ID.
sqianec149462018-09-10 19:05:51 -07003166 *
3167 * @param subscriptionId the subscription ID.
3168 * @return {@code true} if the supplied subscription ID corresponds to an active subscription;
3169 * {@code false} if it does not correspond to an active subscription; or throw a
3170 * SecurityException if the caller hasn't got the right permission.
joonhunshin1a225542023-12-08 08:40:54 +00003171 *i
3172 * @throws UnsupportedOperationException If the device does not have
3173 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
sqianec149462018-09-10 19:05:51 -07003174 */
3175 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
3176 public boolean isActiveSubscriptionId(int subscriptionId) {
3177 return isActiveSubId(subscriptionId);
3178 }
3179
3180 /**
Shishir Agrawal0ced7922014-12-10 10:20:39 -08003181 * @return true if the sub ID is active. i.e. The sub ID corresponds to a known subscription
3182 * and the SIM providing the subscription is present in a slot and in "LOADED" state.
3183 * @hide
3184 */
Mathew Inwooda8382062018-08-16 17:01:12 +01003185 @UnsupportedAppUsage
Shishir Agrawal0ced7922014-12-10 10:20:39 -08003186 public boolean isActiveSubId(int subId) {
3187 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003188 ISub iSub = TelephonyManager.getSubscriptionService();
Sanket Padawe330dcac2015-06-18 12:08:01 -07003189 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08003190 return iSub.isActiveSubId(subId, mContext.getOpPackageName(),
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08003191 mContext.getAttributionTag());
Sanket Padawe330dcac2015-06-18 12:08:01 -07003192 }
Shishir Agrawal0ced7922014-12-10 10:20:39 -08003193 } catch (RemoteException ex) {
3194 }
3195 return false;
3196 }
Jeff Sharkey53313d72017-07-13 16:47:32 -06003197
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003198 /**
3199 * Get the description of the billing relationship plan between a carrier
3200 * and a specific subscriber.
3201 * <p>
3202 * This method is only accessible to the following narrow set of apps:
3203 * <ul>
3204 * <li>The carrier app for this subscriberId, as determined by
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07003205 * {@link TelephonyManager#hasCarrierPrivileges()}.
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003206 * <li>The carrier app explicitly delegated access through
3207 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
3208 * </ul>
3209 *
3210 * @param subId the subscriber this relationship applies to
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06003211 * @throws SecurityException if the caller doesn't meet the requirements
3212 * outlined above.
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003213 */
Jeff Sharkey53313d72017-07-13 16:47:32 -06003214 public @NonNull List<SubscriptionPlan> getSubscriptionPlans(int subId) {
Aaron Huang21089442020-01-16 23:31:02 +08003215 SubscriptionPlan[] subscriptionPlans =
3216 getNetworkPolicyManager().getSubscriptionPlans(subId, mContext.getOpPackageName());
3217 return subscriptionPlans == null
3218 ? Collections.emptyList() : Arrays.asList(subscriptionPlans);
Jeff Sharkey53313d72017-07-13 16:47:32 -06003219 }
3220
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003221 /**
3222 * Set the description of the billing relationship plan between a carrier
3223 * and a specific subscriber.
3224 * <p>
3225 * This method is only accessible to the following narrow set of apps:
3226 * <ul>
3227 * <li>The carrier app for this subscriberId, as determined by
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07003228 * {@link TelephonyManager#hasCarrierPrivileges()}.
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003229 * <li>The carrier app explicitly delegated access through
3230 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
3231 * </ul>
3232 *
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06003233 * @param subId the subscriber this relationship applies to. An empty list
3234 * may be sent to clear any existing plans.
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003235 * @param plans the list of plans. The first plan is always the primary and
3236 * most important plan. Any additional plans are secondary and
3237 * may not be displayed or used by decision making logic.
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06003238 * @throws SecurityException if the caller doesn't meet the requirements
3239 * outlined above.
Sarah Chin80b73b92019-09-26 11:37:13 -07003240 * @throws IllegalArgumentException if plans don't meet the requirements
Sarah Chinc9e48d92019-10-29 15:30:24 -07003241 * defined in {@link SubscriptionPlan}.
Sarah Chine6f17fe2022-01-31 19:10:14 -08003242 * @deprecated use {@link #setSubscriptionPlans(int, List, long)} instead.
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003243 */
Sarah Chine6f17fe2022-01-31 19:10:14 -08003244 @Deprecated
Jeff Sharkey53313d72017-07-13 16:47:32 -06003245 public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans) {
Sarah Chine6f17fe2022-01-31 19:10:14 -08003246 setSubscriptionPlans(subId, plans, 0);
3247 }
3248
3249 /**
3250 * Set the description of the billing relationship plan between a carrier
3251 * and a specific subscriber.
3252 * <p>
3253 * This method is only accessible to the following narrow set of apps:
3254 * <ul>
3255 * <li>The carrier app for this subscriberId, as determined by
3256 * {@link TelephonyManager#hasCarrierPrivileges()}.
3257 * <li>The carrier app explicitly delegated access through
3258 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
3259 * </ul>
3260 *
3261 * @param subId the subscriber this relationship applies to. An empty list
3262 * may be sent to clear any existing plans.
3263 * @param plans the list of plans. The first plan is always the primary and
3264 * most important plan. Any additional plans are secondary and
3265 * may not be displayed or used by decision making logic.
3266 * @param expirationDurationMillis the duration after which the subscription plans
3267 * will be automatically cleared, or {@code 0} to leave the plans until
3268 * explicitly cleared, or the next reboot, whichever happens first.
3269 * @throws SecurityException if the caller doesn't meet the requirements
3270 * outlined above.
3271 * @throws IllegalArgumentException if plans don't meet the requirements
3272 * defined in {@link SubscriptionPlan}.
3273 */
3274 public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans,
3275 @DurationMillisLong long expirationDurationMillis) {
Aaron Huang21089442020-01-16 23:31:02 +08003276 getNetworkPolicyManager().setSubscriptionPlans(subId,
Sarah Chine6f17fe2022-01-31 19:10:14 -08003277 plans.toArray(new SubscriptionPlan[0]), expirationDurationMillis,
3278 mContext.getOpPackageName());
Jeff Sharkey53313d72017-07-13 16:47:32 -06003279 }
Jeff Sharkey717f52f2018-01-04 16:04:11 -07003280
Jeff Sharkey717f52f2018-01-04 16:04:11 -07003281 /**
Jeff Sharkey9252b342018-01-19 07:58:35 +09003282 * Temporarily override the billing relationship plan between a carrier and
3283 * a specific subscriber to be considered unmetered. This will be reflected
3284 * to apps via {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED}.
3285 * <p>
3286 * This method is only accessible to the following narrow set of apps:
3287 * <ul>
3288 * <li>The carrier app for this subscriberId, as determined by
3289 * {@link TelephonyManager#hasCarrierPrivileges()}.
3290 * <li>The carrier app explicitly delegated access through
3291 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
3292 * </ul>
3293 *
3294 * @param subId the subscriber this override applies to.
3295 * @param overrideUnmetered set if the billing relationship should be
3296 * considered unmetered.
Sarah Chine6f17fe2022-01-31 19:10:14 -08003297 * @param expirationDurationMillis the duration after which the requested override
3298 * will be automatically cleared, or {@code 0} to leave in the
Jeff Sharkey9252b342018-01-19 07:58:35 +09003299 * requested state until explicitly cleared, or the next reboot,
3300 * whichever happens first.
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06003301 * @throws SecurityException if the caller doesn't meet the requirements
Sarah Chinb321fb52021-01-07 16:40:16 -08003302 * outlined above.
Jeff Sharkey9252b342018-01-19 07:58:35 +09003303 */
Jeff Sharkey9252b342018-01-19 07:58:35 +09003304 public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered,
Sarah Chine6f17fe2022-01-31 19:10:14 -08003305 @DurationMillisLong long expirationDurationMillis) {
Sarah Chinb321fb52021-01-07 16:40:16 -08003306 setSubscriptionOverrideUnmetered(subId, overrideUnmetered,
Sarah Chine6f17fe2022-01-31 19:10:14 -08003307 TelephonyManager.getAllNetworkTypes(), expirationDurationMillis);
Sarah Chinb321fb52021-01-07 16:40:16 -08003308 }
Aaron Huang21089442020-01-16 23:31:02 +08003309
Sarah Chinb321fb52021-01-07 16:40:16 -08003310 /**
3311 * Temporarily override the billing relationship plan between a carrier and
3312 * a specific subscriber to be considered unmetered. This will be reflected
3313 * to apps via {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED}.
3314 * <p>
3315 * This method is only accessible to the following narrow set of apps:
3316 * <ul>
3317 * <li>The carrier app for this subscriberId, as determined by
3318 * {@link TelephonyManager#hasCarrierPrivileges()}.
3319 * <li>The carrier app explicitly delegated access through
3320 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
3321 * </ul>
3322 *
3323 * @param subId the subscriber this override applies to.
3324 * @param overrideUnmetered set if the billing relationship should be
3325 * considered unmetered.
Sarah Chinf7e9c832021-04-15 19:40:25 -07003326 * @param networkTypes the network types this override applies to. If no
3327 * network types are specified, override values will be ignored.
Sarah Chine6f17fe2022-01-31 19:10:14 -08003328 * @param expirationDurationMillis the duration after which the requested override
3329 * will be automatically cleared, or {@code 0} to leave in the
Sarah Chinb321fb52021-01-07 16:40:16 -08003330 * requested state until explicitly cleared, or the next reboot,
3331 * whichever happens first.
3332 * @throws SecurityException if the caller doesn't meet the requirements
3333 * outlined above.
3334 */
3335 public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered,
3336 @NonNull @Annotation.NetworkType int[] networkTypes,
Sarah Chine6f17fe2022-01-31 19:10:14 -08003337 @DurationMillisLong long expirationDurationMillis) {
Aaron Huang21089442020-01-16 23:31:02 +08003338 final int overrideValue = overrideUnmetered ? SUBSCRIPTION_OVERRIDE_UNMETERED : 0;
3339 getNetworkPolicyManager().setSubscriptionOverride(subId, SUBSCRIPTION_OVERRIDE_UNMETERED,
Sarah Chine6f17fe2022-01-31 19:10:14 -08003340 overrideValue, networkTypes, expirationDurationMillis, mContext.getOpPackageName());
Jeff Sharkey9252b342018-01-19 07:58:35 +09003341 }
3342
3343 /**
3344 * Temporarily override the billing relationship plan between a carrier and
3345 * a specific subscriber to be considered congested. This will cause the
3346 * device to delay certain network requests when possible, such as developer
3347 * jobs that are willing to run in a flexible time window.
3348 * <p>
3349 * This method is only accessible to the following narrow set of apps:
3350 * <ul>
3351 * <li>The carrier app for this subscriberId, as determined by
3352 * {@link TelephonyManager#hasCarrierPrivileges()}.
3353 * <li>The carrier app explicitly delegated access through
3354 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
3355 * </ul>
3356 *
3357 * @param subId the subscriber this override applies to.
3358 * @param overrideCongested set if the subscription should be considered
3359 * congested.
Sarah Chine6f17fe2022-01-31 19:10:14 -08003360 * @param expirationDurationMillis the duration after which the requested override
3361 * will be automatically cleared, or {@code 0} to leave in the
Jeff Sharkey9252b342018-01-19 07:58:35 +09003362 * requested state until explicitly cleared, or the next reboot,
3363 * whichever happens first.
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06003364 * @throws SecurityException if the caller doesn't meet the requirements
Sarah Chinb321fb52021-01-07 16:40:16 -08003365 * outlined above.
Jeff Sharkey9252b342018-01-19 07:58:35 +09003366 */
Jeff Sharkey9252b342018-01-19 07:58:35 +09003367 public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested,
Sarah Chine6f17fe2022-01-31 19:10:14 -08003368 @DurationMillisLong long expirationDurationMillis) {
Sarah Chinb321fb52021-01-07 16:40:16 -08003369 setSubscriptionOverrideCongested(subId, overrideCongested,
Sarah Chine6f17fe2022-01-31 19:10:14 -08003370 TelephonyManager.getAllNetworkTypes(), expirationDurationMillis);
Sarah Chinb321fb52021-01-07 16:40:16 -08003371 }
3372
3373 /**
3374 * Temporarily override the billing relationship plan between a carrier and
3375 * a specific subscriber to be considered congested. This will cause the
3376 * device to delay certain network requests when possible, such as developer
3377 * jobs that are willing to run in a flexible time window.
3378 * <p>
3379 * This method is only accessible to the following narrow set of apps:
3380 * <ul>
3381 * <li>The carrier app for this subscriberId, as determined by
3382 * {@link TelephonyManager#hasCarrierPrivileges()}.
3383 * <li>The carrier app explicitly delegated access through
3384 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
3385 * </ul>
3386 *
3387 * @param subId the subscriber this override applies to.
Jack Yu647bbb92022-12-12 21:45:26 -08003388 * @param overrideCongested set if the subscription should be considered congested.
3389 * @param networkTypes the network types this override applies to. If no network types are
3390 * specified, override values will be ignored.
Sarah Chine6f17fe2022-01-31 19:10:14 -08003391 * @param expirationDurationMillis the duration after which the requested override
Jack Yu647bbb92022-12-12 21:45:26 -08003392 * will be automatically cleared, or {@code 0} to leave in the requested state until explicitly
3393 * cleared, or the next reboot, whichever happens first.
3394 *
3395 * @throws SecurityException if the caller doesn't meet the requirements outlined above.
Sarah Chinb321fb52021-01-07 16:40:16 -08003396 */
3397 public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested,
3398 @NonNull @Annotation.NetworkType int[] networkTypes,
Sarah Chine6f17fe2022-01-31 19:10:14 -08003399 @DurationMillisLong long expirationDurationMillis) {
Aaron Huang21089442020-01-16 23:31:02 +08003400 final int overrideValue = overrideCongested ? SUBSCRIPTION_OVERRIDE_CONGESTED : 0;
3401 getNetworkPolicyManager().setSubscriptionOverride(subId, SUBSCRIPTION_OVERRIDE_CONGESTED,
Sarah Chine6f17fe2022-01-31 19:10:14 -08003402 overrideValue, networkTypes, expirationDurationMillis, mContext.getOpPackageName());
Jeff Sharkey9252b342018-01-19 07:58:35 +09003403 }
3404
3405 /**
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003406 * Checks whether the app with the given context is authorized to manage the given subscription
Malcolm Chen2619a9b2019-12-26 13:17:34 -08003407 * according to its metadata.
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003408 *
Sarah Chin172f15e2021-02-23 12:21:24 -08003409 * Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded} returns
3410 * true). To check for permissions for non-embedded subscription as well,
Aishwarya Mallampatibbdfda72023-03-31 01:11:54 +00003411 * see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}.
Sarah Chin172f15e2021-02-23 12:21:24 -08003412 *
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003413 * @param info The subscription to check.
3414 * @return whether the app is authorized to manage this subscription per its metadata.
Jack Yu647bbb92022-12-12 21:45:26 -08003415 * @see android.telephony.TelephonyManager#hasCarrierPrivileges
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003416 */
3417 public boolean canManageSubscription(SubscriptionInfo info) {
3418 return canManageSubscription(info, mContext.getPackageName());
3419 }
3420
3421 /**
Holly Jiuyu Sun59159c42018-03-15 18:06:42 -07003422 * Checks whether the given app is authorized to manage the given subscription. An app can only
3423 * be authorized if it is included in the {@link android.telephony.UiccAccessRule} of the
3424 * {@link android.telephony.SubscriptionInfo} with the access status.
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003425 *
Sarah Chin172f15e2021-02-23 12:21:24 -08003426 * Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded} returns
3427 * true). To check for permissions for non-embedded subscription as well,
Aishwarya Mallampatibbdfda72023-03-31 01:11:54 +00003428 * see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}.
Sarah Chin172f15e2021-02-23 12:21:24 -08003429 *
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003430 * @param info The subscription to check.
3431 * @param packageName Package name of the app to check.
Jack Yu647bbb92022-12-12 21:45:26 -08003432 *
Holly Jiuyu Sun59159c42018-03-15 18:06:42 -07003433 * @return whether the app is authorized to manage this subscription per its access rules.
Jack Yu647bbb92022-12-12 21:45:26 -08003434 * @see android.telephony.TelephonyManager#hasCarrierPrivileges
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003435 * @hide
3436 */
Malcolm Chen2619a9b2019-12-26 13:17:34 -08003437 @SystemApi
Malcolm Chen05d1ed12020-02-25 17:50:05 -08003438 public boolean canManageSubscription(@NonNull SubscriptionInfo info,
3439 @NonNull String packageName) {
Jack Yu27209092022-09-14 00:40:57 -07003440 if (info == null || info.getAccessRules() == null || packageName == null) {
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003441 return false;
3442 }
3443 PackageManager packageManager = mContext.getPackageManager();
3444 PackageInfo packageInfo;
3445 try {
Cheonho Park51586d52019-07-31 14:19:41 +09003446 packageInfo = packageManager.getPackageInfo(packageName,
3447 PackageManager.GET_SIGNING_CERTIFICATES);
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003448 } catch (PackageManager.NameNotFoundException e) {
Nazanin Bakhshi293ecad2019-08-29 16:19:12 -07003449 logd("Unknown package: " + packageName);
3450 return false;
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003451 }
Jack Yu27209092022-09-14 00:40:57 -07003452 for (UiccAccessRule rule : info.getAccessRules()) {
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003453 if (rule.getCarrierPrivilegeStatus(packageInfo)
3454 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
3455 return true;
3456 }
3457 }
3458 return false;
3459 }
Malcolm Chenbd4ae762018-08-03 17:24:07 -07003460
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003461 /**
Malcolm Chen009f0a92018-10-22 20:03:46 -07003462 * Set which subscription is preferred for cellular data.
3463 * It's also usually the subscription we set up internet connection on.
Malcolm Chen8cf1b782018-09-24 20:00:08 -07003464 *
3465 * PreferredData overwrites user setting of default data subscription. And it's used
Malcolm Chen009f0a92018-10-22 20:03:46 -07003466 * by AlternativeNetworkService or carrier apps to switch primary and CBRS
Malcolm Chenc1873af2018-09-24 20:01:32 -07003467 * subscription dynamically in multi-SIM devices.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003468 *
Malcolm Chen009f0a92018-10-22 20:03:46 -07003469 * @param subId which subscription is preferred to for cellular data. If it's
Malcolm Chen003c8e52018-11-12 20:13:29 -08003470 * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}, it means
Malcolm Chen009f0a92018-10-22 20:03:46 -07003471 * it's unset and {@link SubscriptionManager#getDefaultDataSubscriptionId()}
3472 * is used to determine which modem is preferred.
Malcolm Chenfe577d32019-03-18 17:26:43 -07003473 * @param needValidation whether Telephony will wait until the network is validated by
3474 * connectivity service before switching data to it. More details see
3475 * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED}.
Malcolm Chenfd11df22019-02-05 17:19:48 -08003476 * @param executor The executor of where the callback will execute.
3477 * @param callback Callback will be triggered once it succeeds or failed.
Malcolm Chen9ee14732019-03-29 18:30:23 -07003478 * Pass null if don't care about the result.
Malcolm Chenfd11df22019-02-05 17:19:48 -08003479 *
Jack Yu58ac8382022-07-20 01:09:19 -07003480 * @throws IllegalStateException when subscription manager service is not available.
3481 * @throws SecurityException when clients do not have MODIFY_PHONE_STATE permission.
joonhunshin1a225542023-12-08 08:40:54 +00003482 * @throws UnsupportedOperationException If the device does not have
3483 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003484 * @hide
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003485 */
Malcolm Chenfd11df22019-02-05 17:19:48 -08003486 @SystemApi
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003487 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
Malcolm Chenfd11df22019-02-05 17:19:48 -08003488 public void setPreferredDataSubscriptionId(int subId, boolean needValidation,
Malcolm Chen9ee14732019-03-29 18:30:23 -07003489 @Nullable @CallbackExecutor Executor executor, @Nullable
3490 @TelephonyManager.SetOpportunisticSubscriptionResult Consumer<Integer> callback) {
Nazanin Bakhshie0215a72019-01-04 17:38:36 -08003491 if (VDBG) logd("[setPreferredDataSubscriptionId]+ subId:" + subId);
Malcolm Chend78dac02019-01-24 16:33:51 -08003492 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003493 ISub iSub = TelephonyManager.getSubscriptionService();
Jack Yu58ac8382022-07-20 01:09:19 -07003494 if (iSub == null) {
3495 throw new IllegalStateException("subscription manager service is null.");
3496 }
Malcolm Chenfd11df22019-02-05 17:19:48 -08003497
3498 ISetOpportunisticDataCallback callbackStub = new ISetOpportunisticDataCallback.Stub() {
3499 @Override
3500 public void onComplete(int result) {
Sooraj Sasindran3b09d712019-02-28 14:46:14 -08003501 if (executor == null || callback == null) {
3502 return;
3503 }
Sooraj Sasindrane6a2c0a2019-11-26 13:56:49 -08003504 final long identity = Binder.clearCallingIdentity();
3505 try {
3506 executor.execute(() -> {
3507 callback.accept(result);
3508 });
3509 } finally {
3510 Binder.restoreCallingIdentity(identity);
3511 }
Malcolm Chenfd11df22019-02-05 17:19:48 -08003512 }
3513 };
3514 iSub.setPreferredDataSubscriptionId(subId, needValidation, callbackStub);
Malcolm Chend78dac02019-01-24 16:33:51 -08003515 } catch (RemoteException ex) {
Jack Yu58ac8382022-07-20 01:09:19 -07003516 loge("setPreferredDataSubscriptionId RemoteException=" + ex);
3517 ex.rethrowFromSystemServer();
Malcolm Chend78dac02019-01-24 16:33:51 -08003518 }
Nazanin Bakhshie0215a72019-01-04 17:38:36 -08003519 }
3520
3521 /**
3522 * Get which subscription is preferred for cellular data.
3523 * It's also usually the subscription we set up internet connection on.
3524 *
3525 * PreferredData overwrites user setting of default data subscription. And it's used
3526 * by AlternativeNetworkService or carrier apps to switch primary and CBRS
3527 * subscription dynamically in multi-SIM devices.
3528 *
3529 * @return preferred subscription id for cellular data. {@link DEFAULT_SUBSCRIPTION_ID} if
3530 * there's no prefered subscription.
3531 *
3532 * @hide
3533 *
3534 */
3535 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
3536 public int getPreferredDataSubscriptionId() {
3537 int preferredSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
3538 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003539 ISub iSub = TelephonyManager.getSubscriptionService();
Nazanin Bakhshie0215a72019-01-04 17:38:36 -08003540 if (iSub != null) {
3541 preferredSubId = iSub.getPreferredDataSubscriptionId();
3542 }
3543 } catch (RemoteException ex) {
3544 // ignore it
3545 }
3546
3547 return preferredSubId;
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003548 }
3549
3550 /**
Malcolm Chen44137862018-10-23 18:44:03 -07003551 * Return opportunistic subscriptions that can be visible to the caller.
3552 * Opportunistic subscriptions are for opportunistic networks, which are cellular
3553 * networks with limited capabilities and coverage, for example, CBRS.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003554 *
Malcolm Chen44137862018-10-23 18:44:03 -07003555 * <p>Requires Permission:
3556 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
3557 * or that the calling app has carrier privileges (see
3558 * {@link TelephonyManager#hasCarrierPrivileges}).
3559 *
3560 * @return the list of opportunistic subscription info. If none exists, an empty list.
joonhunshin1a225542023-12-08 08:40:54 +00003561 *
3562 * @throws UnsupportedOperationException If the device does not have
3563 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003564 */
Malcolm Chen44137862018-10-23 18:44:03 -07003565 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003566 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
Malcolm Chen44137862018-10-23 18:44:03 -07003567 public @NonNull List<SubscriptionInfo> getOpportunisticSubscriptions() {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08003568 String contextPkg = mContext != null ? mContext.getOpPackageName() : "<unknown>";
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08003569 String contextAttributionTag = mContext != null ? mContext.getAttributionTag() : null;
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003570 List<SubscriptionInfo> subInfoList = null;
3571
3572 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003573 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003574 if (iSub != null) {
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08003575 subInfoList = iSub.getOpportunisticSubscriptions(contextPkg,
3576 contextAttributionTag);
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003577 }
3578 } catch (RemoteException ex) {
3579 // ignore it
3580 }
3581
3582 if (subInfoList == null) {
3583 subInfoList = new ArrayList<>();
3584 }
3585
3586 return subInfoList;
3587 }
3588
3589 /**
3590 * Switch to a certain subscription
3591 *
3592 * @param subId sub id
3593 * @param callbackIntent pending intent that will be sent after operation is done.
sandeepjsb061a762022-03-24 10:30:59 +00003594 *
sandeepjs87b55752022-09-16 08:58:14 +00003595 * @deprecated this API is a duplicate of {@link EuiccManager#switchToSubscription(int,
sandeepjsb061a762022-03-24 10:30:59 +00003596 * PendingIntent)} and does not support Multiple Enabled Profile(MEP). Apps should use
3597 * {@link EuiccManager#switchToSubscription(int, PendingIntent)} or
3598 * {@link EuiccManager#switchToSubscription(int, int, PendingIntent)} instead.
joonhunshin1a225542023-12-08 08:40:54 +00003599 *
3600 * @throws UnsupportedOperationException If the device does not have
3601 * {@link PackageManager#FEATURE_TELEPHONY_EUICC}.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003602 */
3603 @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
joonhunshin1a225542023-12-08 08:40:54 +00003604 @RequiresFeature(PackageManager.FEATURE_TELEPHONY_EUICC)
sandeepjs87b55752022-09-16 08:58:14 +00003605 @Deprecated
Malcolm Chen80e1e5c2019-02-27 15:16:05 -08003606 public void switchToSubscription(int subId, @NonNull PendingIntent callbackIntent) {
3607 Preconditions.checkNotNull(callbackIntent, "callbackIntent cannot be null");
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003608 EuiccManager euiccManager = new EuiccManager(mContext);
3609 euiccManager.switchToSubscription(subId, callbackIntent);
3610 }
3611
3612 /**
Malcolm Chend4dc4ee2018-12-11 13:56:53 -08003613 * Set whether a subscription is opportunistic, that is, whether the network it connects
3614 * to has limited coverage. For example, CBRS. Setting a subscription opportunistic has
3615 * following impacts:
3616 * 1) Even if it's active, it will be dormant most of the time. The modem will not try
3617 * to scan or camp until it knows an available network is nearby to save power.
3618 * 2) Telephony relies on system app or carrier input to notify nearby available networks.
danielwbhuanga3358802019-03-11 11:52:10 +08003619 * See {@link TelephonyManager#updateAvailableNetworks(List, Executor, Consumer)}
3620 * for more information.
Malcolm Chend4dc4ee2018-12-11 13:56:53 -08003621 * 3) In multi-SIM devices, when the network is nearby and camped, system may automatically
3622 * switch internet data between it and default data subscription, based on carrier
3623 * recommendation and its signal strength and metered-ness, etc.
3624 *
3625 *
3626 * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE} or carrier
3627 * privilege permission of the subscription.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003628 *
3629 * @param opportunistic whether it’s opportunistic subscription.
3630 * @param subId the unique SubscriptionInfo index in database
Malcolm Chend4dc4ee2018-12-11 13:56:53 -08003631 * @return {@code true} if the operation is succeed, {@code false} otherwise.
joonhunshin1a225542023-12-08 08:40:54 +00003632 *
3633 * @throws UnsupportedOperationException If the device does not have
3634 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003635 */
Malcolm Chend4dc4ee2018-12-11 13:56:53 -08003636 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003637 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
Malcolm Chend4dc4ee2018-12-11 13:56:53 -08003638 public boolean setOpportunistic(boolean opportunistic, int subId) {
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003639 if (VDBG) logd("[setOpportunistic]+ opportunistic:" + opportunistic + " subId:" + subId);
3640 return setSubscriptionPropertyHelper(subId, "setOpportunistic",
Malcolm Chend4dc4ee2018-12-11 13:56:53 -08003641 (iSub)-> iSub.setOpportunistic(
3642 opportunistic, subId, mContext.getOpPackageName())) == 1;
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003643 }
3644
3645 /**
Malcolm Chenaea9b022018-10-31 20:18:02 -07003646 * Inform SubscriptionManager that subscriptions in the list are bundled
Malcolm Chen4674a792019-03-20 20:32:27 -07003647 * as a group. It can be multiple primary (non-opportunistic) subscriptions,
3648 * or one or more primary plus one or more opportunistic subscriptions.
3649 *
3650 * This API will always create a new immutable group and assign group UUID to all the
3651 * subscriptions, regardless whether they are in a group already or not.
3652 *
3653 * Grouped subscriptions will have below behaviors:
3654 * 1) They will share the same user settings.
3655 * 2) The opportunistic subscriptions in the group is considered invisible and will not
3656 * return from {@link #getActiveSubscriptionInfoList()}, unless caller has carrier
3657 * privilege permission of the subscriptions.
3658 * 3) The opportunistic subscriptions in the group can't be active by itself. If all other
3659 * non-opportunistic ones are deactivated (unplugged or disabled in Settings),
3660 * the opportunistic ones will be deactivated automatically.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003661 *
John Reckc877f582018-11-16 15:46:02 -08003662 * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003663 * permission or had carrier privilege permission on the subscriptions:
Malcolm Chen18350e42018-12-12 10:29:16 -08003664 * {@link TelephonyManager#hasCarrierPrivileges()} or
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003665 * {@link #canManageSubscription(SubscriptionInfo)}
3666 *
3667 * @throws SecurityException if the caller doesn't meet the requirements
3668 * outlined above.
Malcolm Chen3c976932019-04-03 18:39:21 -07003669 * @throws IllegalArgumentException if any of the subscriptions in the list doesn't exist.
3670 * @throws IllegalStateException if Telephony service is in bad state.
joonhunshin1a225542023-12-08 08:40:54 +00003671 * @throws UnsupportedOperationException If the device does not have
3672 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Malcolm Chenaea9b022018-10-31 20:18:02 -07003673 *
3674 * @param subIdList list of subId that will be in the same group
Malcolm Chen4674a792019-03-20 20:32:27 -07003675 * @return groupUUID a UUID assigned to the subscription group.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003676 *
3677 */
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003678 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003679 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
Malcolm Chen4674a792019-03-20 20:32:27 -07003680 public @NonNull ParcelUuid createSubscriptionGroup(@NonNull List<Integer> subIdList) {
3681 Preconditions.checkNotNull(subIdList, "can't create group for null subId list");
Malcolm Chenaea9b022018-10-31 20:18:02 -07003682 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
3683 if (VDBG) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003684 logd("[createSubscriptionGroup]");
Malcolm Chenaea9b022018-10-31 20:18:02 -07003685 }
3686
Malcolm Chen4674a792019-03-20 20:32:27 -07003687 ParcelUuid groupUuid = null;
3688 int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray();
Malcolm Chenaea9b022018-10-31 20:18:02 -07003689 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003690 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chenaea9b022018-10-31 20:18:02 -07003691 if (iSub != null) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003692 groupUuid = iSub.createSubscriptionGroup(subIdArray, pkgForDebug);
3693 } else {
Nathan Haroldc59761c2023-08-15 15:44:55 -07003694 throw new IllegalStateException("telephony service is null.");
Malcolm Chenaea9b022018-10-31 20:18:02 -07003695 }
3696 } catch (RemoteException ex) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003697 loge("createSubscriptionGroup RemoteException " + ex);
Nathan Haroldc59761c2023-08-15 15:44:55 -07003698 ex.rethrowAsRuntimeException();
Malcolm Chenaea9b022018-10-31 20:18:02 -07003699 }
3700
Malcolm Chen4674a792019-03-20 20:32:27 -07003701 return groupUuid;
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003702 }
3703
Nazanin Bakhshib9b87be2018-11-21 16:32:05 -08003704 /**
Malcolm Chen4674a792019-03-20 20:32:27 -07003705 * Add a list of subscriptions into a group.
3706 * See {@link #createSubscriptionGroup(List)} for more details.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003707 *
3708 * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
3709 * permission or had carrier privilege permission on the subscriptions:
Malcolm Chen18350e42018-12-12 10:29:16 -08003710 * {@link TelephonyManager#hasCarrierPrivileges()} or
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003711 * {@link #canManageSubscription(SubscriptionInfo)}
3712 *
3713 * @throws SecurityException if the caller doesn't meet the requirements
3714 * outlined above.
Malcolm Chen710a09a2019-08-22 13:07:30 -07003715 * @throws IllegalArgumentException if the some subscriptions in the list doesn't exist.
Malcolm Chen3c976932019-04-03 18:39:21 -07003716 * @throws IllegalStateException if Telephony service is in bad state.
joonhunshin1a225542023-12-08 08:40:54 +00003717 * @throws UnsupportedOperationException If the device does not have
3718 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003719 *
Malcolm Chen4674a792019-03-20 20:32:27 -07003720 * @param subIdList list of subId that need adding into the group
3721 * @param groupUuid the groupUuid the subscriptions are being added to.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003722 *
3723 */
3724 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
3725 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
Malcolm Chen4674a792019-03-20 20:32:27 -07003726 public void addSubscriptionsIntoGroup(@NonNull List<Integer> subIdList,
3727 @NonNull ParcelUuid groupUuid) {
3728 Preconditions.checkNotNull(subIdList, "subIdList can't be null.");
3729 Preconditions.checkNotNull(groupUuid, "groupUuid can't be null.");
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003730 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
3731 if (VDBG) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003732 logd("[addSubscriptionsIntoGroup]");
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003733 }
3734
Malcolm Chen4674a792019-03-20 20:32:27 -07003735 int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray();
3736
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003737 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003738 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003739 if (iSub != null) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003740 iSub.addSubscriptionsIntoGroup(subIdArray, groupUuid, pkgForDebug);
3741 } else {
Nathan Haroldc59761c2023-08-15 15:44:55 -07003742 throw new IllegalStateException("telephony service is null.");
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003743 }
3744 } catch (RemoteException ex) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003745 loge("addSubscriptionsIntoGroup RemoteException " + ex);
Nathan Haroldc59761c2023-08-15 15:44:55 -07003746 ex.rethrowAsRuntimeException();
Malcolm Chen4674a792019-03-20 20:32:27 -07003747 }
3748 }
3749
3750 private boolean isSystemProcess() {
3751 return Process.myUid() == Process.SYSTEM_UID;
3752 }
3753
3754 /**
3755 * Remove a list of subscriptions from their subscription group.
Malcolm Chen4674a792019-03-20 20:32:27 -07003756 *
3757 * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
Jack Yu647bbb92022-12-12 21:45:26 -08003758 * permission or has carrier privilege permission on all of the subscriptions provided in
3759 * {@code subIdList}.
Malcolm Chen4674a792019-03-20 20:32:27 -07003760 *
3761 * @param subIdList list of subId that need removing from their groups.
Jack Yu647bbb92022-12-12 21:45:26 -08003762 * @param groupUuid The UUID of the subscription group.
Malcolm Chen4674a792019-03-20 20:32:27 -07003763 *
Jack Yu647bbb92022-12-12 21:45:26 -08003764 * @throws SecurityException if the caller doesn't meet the requirements outlined above.
3765 * @throws IllegalArgumentException if the some subscriptions in the list doesn't belong the
3766 * specified group.
3767 * @throws IllegalStateException if Telephony service is in bad state.
joonhunshin1a225542023-12-08 08:40:54 +00003768 * @throws UnsupportedOperationException If the device does not have
3769 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Jack Yu647bbb92022-12-12 21:45:26 -08003770 *
3771 * @see #createSubscriptionGroup(List)
Malcolm Chen4674a792019-03-20 20:32:27 -07003772 */
3773 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
3774 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
3775 public void removeSubscriptionsFromGroup(@NonNull List<Integer> subIdList,
3776 @NonNull ParcelUuid groupUuid) {
3777 Preconditions.checkNotNull(subIdList, "subIdList can't be null.");
3778 Preconditions.checkNotNull(groupUuid, "groupUuid can't be null.");
Jack Yu647bbb92022-12-12 21:45:26 -08003779 String callingPackage = mContext != null ? mContext.getOpPackageName() : "<unknown>";
Malcolm Chen4674a792019-03-20 20:32:27 -07003780 if (VDBG) {
3781 logd("[removeSubscriptionsFromGroup]");
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003782 }
3783
Malcolm Chen4674a792019-03-20 20:32:27 -07003784 int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray();
3785
3786 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003787 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chen4674a792019-03-20 20:32:27 -07003788 if (iSub != null) {
Jack Yu647bbb92022-12-12 21:45:26 -08003789 iSub.removeSubscriptionsFromGroup(subIdArray, groupUuid, callingPackage);
Malcolm Chen4674a792019-03-20 20:32:27 -07003790 } else {
Nathan Haroldc59761c2023-08-15 15:44:55 -07003791 throw new IllegalStateException("telephony service is null.");
Malcolm Chen4674a792019-03-20 20:32:27 -07003792 }
3793 } catch (RemoteException ex) {
3794 loge("removeSubscriptionsFromGroup RemoteException " + ex);
Nathan Haroldc59761c2023-08-15 15:44:55 -07003795 ex.rethrowAsRuntimeException();
Malcolm Chen4674a792019-03-20 20:32:27 -07003796 }
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003797 }
3798
3799 /**
3800 * Get subscriptionInfo list of subscriptions that are in the same group of given subId.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003801 *
hyosun91934802022-04-26 13:24:27 +00003802 * Caller must have {@link android.Manifest.permission#READ_PHONE_STATE}
3803 * or carrier privilege permission on the subscription.
Malcolm Chen18350e42018-12-12 10:29:16 -08003804 * {@link TelephonyManager#hasCarrierPrivileges()}
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003805 *
hyosun91934802022-04-26 13:24:27 +00003806 * <p>Starting with API level 33, the caller also needs permission to access device identifiers
3807 * to get the list of subscriptions associated with a group UUID.
3808 * This method can be invoked if one of the following requirements is met:
3809 * <ul>
3810 * <li>If the app has carrier privilege permission.
3811 * {@link TelephonyManager#hasCarrierPrivileges()}
3812 * <li>If the app has {@link android.Manifest.permission#READ_PHONE_STATE} permission and
3813 * access to device identifiers.
3814 * </ul>
3815 *
Malcolm Chen4f609c72019-11-06 14:02:46 -08003816 * @throws IllegalStateException if Telephony service is in bad state.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003817 * @throws SecurityException if the caller doesn't meet the requirements
3818 * outlined above.
joonhunshin1a225542023-12-08 08:40:54 +00003819 * @throws UnsupportedOperationException If the device does not have
3820 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003821 *
Malcolm Chen4674a792019-03-20 20:32:27 -07003822 * @param groupUuid of which list of subInfo will be returned.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003823 * @return list of subscriptionInfo that belong to the same group, including the given
Malcolm Chen4674a792019-03-20 20:32:27 -07003824 * subscription itself. It will return an empty list if no subscription belongs to the group.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003825 */
3826 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
3827 @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
Malcolm Chen4674a792019-03-20 20:32:27 -07003828 public @NonNull List<SubscriptionInfo> getSubscriptionsInGroup(@NonNull ParcelUuid groupUuid) {
3829 Preconditions.checkNotNull(groupUuid, "groupUuid can't be null");
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08003830 String contextPkg = mContext != null ? mContext.getOpPackageName() : "<unknown>";
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08003831 String contextAttributionTag = mContext != null ? mContext.getAttributionTag() : null;
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003832 if (VDBG) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003833 logd("[getSubscriptionsInGroup]+ groupUuid:" + groupUuid);
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003834 }
3835
3836 List<SubscriptionInfo> result = null;
3837 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003838 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003839 if (iSub != null) {
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08003840 result = iSub.getSubscriptionsInGroup(groupUuid, contextPkg,
3841 contextAttributionTag);
Malcolm Chen4674a792019-03-20 20:32:27 -07003842 } else {
3843 if (!isSystemProcess()) {
3844 throw new IllegalStateException("telephony service is null.");
3845 }
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003846 }
3847 } catch (RemoteException ex) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003848 loge("removeSubscriptionsFromGroup RemoteException " + ex);
3849 if (!isSystemProcess()) {
3850 ex.rethrowAsRuntimeException();
3851 }
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003852 }
3853
Nathan Haroldc59761c2023-08-15 15:44:55 -07003854 // TODO(b/296125268) Really this method should throw, but it's common enough that for
3855 // system callers it's worth having a little magic for the system process until it's
3856 // made safer.
3857 if (result == null) result = Collections.emptyList();
3858
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003859 return result;
3860 }
3861
3862 /**
Malcolm Chend1b4a812019-02-28 14:07:59 -08003863 * Whether a subscription is visible to API caller. If it's a bundled opportunistic
3864 * subscription, it should be hidden anywhere in Settings, dialer, status bar etc.
3865 * Exception is if caller owns carrier privilege, in which case they will
Malcolm Chen31071852019-02-12 17:29:59 -08003866 * want to see their own hidden subscriptions.
Malcolm Chen0db9aa12018-12-06 11:19:03 -08003867 *
3868 * @param info the subscriptionInfo to check against.
Jack Yub0f281b2022-12-10 02:11:18 -08003869 *
3870 * @return {@code true} if this subscription should be visible to the API caller.
Malcolm Chen0db9aa12018-12-06 11:19:03 -08003871 *
Qingxi Lie0662472019-05-17 15:16:21 -07003872 * @hide
Malcolm Chen0db9aa12018-12-06 11:19:03 -08003873 */
Qingxi Lie0662472019-05-17 15:16:21 -07003874 public boolean isSubscriptionVisible(SubscriptionInfo info) {
Malcolm Chen31071852019-02-12 17:29:59 -08003875 if (info == null) return false;
Malcolm Chend1b4a812019-02-28 14:07:59 -08003876 // If subscription is NOT grouped opportunistic subscription, it's visible.
Malcolm Chen4674a792019-03-20 20:32:27 -07003877 if (info.getGroupUuid() == null || !info.isOpportunistic()) return true;
Malcolm Chen31071852019-02-12 17:29:59 -08003878
Malcolm Chend1b4a812019-02-28 14:07:59 -08003879 // If the caller is the carrier app and owns the subscription, it should be visible
3880 // to the caller.
3881 boolean hasCarrierPrivilegePermission = TelephonyManager.from(mContext)
3882 .hasCarrierPrivileges(info.getSubscriptionId())
Nazanin Bakhshi65371b22019-08-19 16:36:07 -07003883 || canManageSubscription(info);
Malcolm Chend1b4a812019-02-28 14:07:59 -08003884 return hasCarrierPrivilegePermission;
Malcolm Chen0db9aa12018-12-06 11:19:03 -08003885 }
3886
3887 /**
3888 * Return a list of subscriptions that are available and visible to the user.
3889 * Used by Settings app to show a list of subscriptions for user to pick.
3890 *
3891 * <p>
3892 * Permissions android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE is required
3893 * for getSelectableSubscriptionInfoList to be invoked.
3894 * @return list of user selectable subscriptions.
3895 *
3896 * @hide
3897 */
3898 public @Nullable List<SubscriptionInfo> getSelectableSubscriptionInfoList() {
3899 List<SubscriptionInfo> availableList = getAvailableSubscriptionInfoList();
3900 if (availableList == null) {
3901 return null;
3902 } else {
Malcolm Chenb82864c2019-02-26 16:48:40 -08003903 // Multiple subscriptions in a group should only have one representative.
3904 // It should be the current active primary subscription if any, or any
3905 // primary subscription.
3906 List<SubscriptionInfo> selectableList = new ArrayList<>();
Malcolm Chen4674a792019-03-20 20:32:27 -07003907 Map<ParcelUuid, SubscriptionInfo> groupMap = new HashMap<>();
Malcolm Chenb82864c2019-02-26 16:48:40 -08003908
3909 for (SubscriptionInfo info : availableList) {
Steve Statiac6677ab2023-12-21 20:14:33 +00003910 // Grouped opportunistic subscriptions are considered invisible
Malcolm Chenb82864c2019-02-26 16:48:40 -08003911 // to users so they should never be returned.
Steve Statiac6677ab2023-12-21 20:14:33 +00003912 if (info.getGroupUuid() != null && info.isOpportunistic()) continue;
Malcolm Chenb82864c2019-02-26 16:48:40 -08003913
Malcolm Chen4674a792019-03-20 20:32:27 -07003914 ParcelUuid groupUuid = info.getGroupUuid();
Malcolm Chenb82864c2019-02-26 16:48:40 -08003915 if (groupUuid == null) {
3916 // Doesn't belong to any group. Add in the list.
3917 selectableList.add(info);
3918 } else if (!groupMap.containsKey(groupUuid)
3919 || (groupMap.get(groupUuid).getSimSlotIndex() == INVALID_SIM_SLOT_INDEX
3920 && info.getSimSlotIndex() != INVALID_SIM_SLOT_INDEX)) {
3921 // If it belongs to a group that has never been recorded or it's the current
3922 // active subscription, add it in the list.
3923 selectableList.remove(groupMap.get(groupUuid));
3924 selectableList.add(info);
3925 groupMap.put(groupUuid, info);
3926 }
3927
3928 }
3929 return selectableList;
Malcolm Chen0db9aa12018-12-06 11:19:03 -08003930 }
3931 }
3932
Malcolm Chen77b2b552018-12-13 19:24:03 -08003933 /**
Jack Yu53129a72023-03-28 22:47:41 -07003934 * Enable or disable a subscription. This method is same as
3935 * {@link #setUiccApplicationsEnabled(int, boolean)}.
Malcolm Chen4c7c1b22019-11-19 15:27:55 -08003936 *
Jack Yu53129a72023-03-28 22:47:41 -07003937 * @param subscriptionId Subscription to be enabled or disabled.
Malcolm Chen77b2b552018-12-13 19:24:03 -08003938 * @param enable whether user is turning it on or off.
Malcolm Chen77b2b552018-12-13 19:24:03 -08003939 *
3940 * @return whether the operation is successful.
3941 *
joonhunshin1a225542023-12-08 08:40:54 +00003942 * @throws UnsupportedOperationException If the device does not have
3943 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Malcolm Chen77b2b552018-12-13 19:24:03 -08003944 * @hide
3945 */
3946 @SystemApi
3947 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
3948 public boolean setSubscriptionEnabled(int subscriptionId, boolean enable) {
Malcolm Chen77b2b552018-12-13 19:24:03 -08003949 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003950 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chen77b2b552018-12-13 19:24:03 -08003951 if (iSub != null) {
Jack Yu53129a72023-03-28 22:47:41 -07003952 iSub.setUiccApplicationsEnabled(enable, subscriptionId);
Malcolm Chen77b2b552018-12-13 19:24:03 -08003953 }
3954 } catch (RemoteException ex) {
Jack Yu53129a72023-03-28 22:47:41 -07003955 return false;
Malcolm Chen77b2b552018-12-13 19:24:03 -08003956 }
Jack Yu53129a72023-03-28 22:47:41 -07003957 return true;
Malcolm Chen77b2b552018-12-13 19:24:03 -08003958 }
3959
3960 /**
Malcolm Chen4ece3db2019-12-16 14:01:50 -08003961 * Set uicc applications being enabled or disabled.
3962 * The value will be remembered on the subscription and will be applied whenever it's present.
3963 * If the subscription in currently present, it will also apply the setting to modem
Jordan Liu02939242021-04-27 13:34:31 -07003964 * immediately (the setting in the modem will not change until the modem receives and responds
3965 * to the request, but typically this should only take a few seconds. The user visible setting
3966 * available from SubscriptionInfo.areUiccApplicationsEnabled() will be updated
3967 * immediately.)
Malcolm Chen4ece3db2019-12-16 14:01:50 -08003968 *
Malcolm Chen4ece3db2019-12-16 14:01:50 -08003969 * @param subscriptionId which subscription to operate on.
Malcolm Chen91056a42020-02-21 17:11:57 -08003970 * @param enabled whether uicc applications are enabled or disabled.
joonhunshin1a225542023-12-08 08:40:54 +00003971 *
3972 * @throws UnsupportedOperationException If the device does not have
3973 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Malcolm Chen4ece3db2019-12-16 14:01:50 -08003974 * @hide
3975 */
3976 @SystemApi
3977 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
Malcolm Chen91056a42020-02-21 17:11:57 -08003978 public void setUiccApplicationsEnabled(int subscriptionId, boolean enabled) {
Malcolm Chen4ece3db2019-12-16 14:01:50 -08003979 if (VDBG) {
3980 logd("setUiccApplicationsEnabled subId= " + subscriptionId + " enable " + enabled);
3981 }
3982 try {
Jack Yu53129a72023-03-28 22:47:41 -07003983 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chen4ece3db2019-12-16 14:01:50 -08003984 if (iSub != null) {
3985 iSub.setUiccApplicationsEnabled(enabled, subscriptionId);
3986 }
3987 } catch (RemoteException ex) {
3988 // ignore it
3989 }
3990 }
3991
3992 /**
Malcolm Chen4c7c1b22019-11-19 15:27:55 -08003993 * Whether it's supported to disable / re-enable a subscription on a physical (non-euicc) SIM.
3994 *
3995 * Physical SIM refers non-euicc, or aka non-programmable SIM.
3996 *
3997 * It provides whether a physical SIM card can be disabled without taking it out, which is done
3998 * via {@link #setSubscriptionEnabled(int, boolean)} API.
3999 *
Malcolm Chen4c7c1b22019-11-19 15:27:55 -08004000 * @return whether can disable subscriptions on physical SIMs.
4001 *
joonhunshin1a225542023-12-08 08:40:54 +00004002 * @throws UnsupportedOperationException If the device does not have
4003 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Malcolm Chen4c7c1b22019-11-19 15:27:55 -08004004 * @hide
4005 */
4006 @SystemApi
4007 @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
4008 public boolean canDisablePhysicalSubscription() {
4009 if (VDBG) {
4010 logd("canDisablePhysicalSubscription");
4011 }
4012 try {
Jack Yu53129a72023-03-28 22:47:41 -07004013 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chen4c7c1b22019-11-19 15:27:55 -08004014 if (iSub != null) {
4015 return iSub.canDisablePhysicalSubscription();
4016 }
4017 } catch (RemoteException ex) {
4018 // ignore it
4019 }
4020
4021 return false;
4022 }
4023
4024 /**
Jack Yub0f281b2022-12-10 02:11:18 -08004025 * Check if the subscription is currently active in any slot.
Jack Yu37742192022-12-09 02:20:59 -08004026 *
Jack Yub0f281b2022-12-10 02:11:18 -08004027 * @param subscriptionId The subscription id.
Jack Yu37742192022-12-09 02:20:59 -08004028 *
joonhunshin1a225542023-12-08 08:40:54 +00004029 * @throws UnsupportedOperationException If the device does not have
4030 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Malcolm Chen77b2b552018-12-13 19:24:03 -08004031 * @hide
4032 */
4033 @SystemApi
4034 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
4035 public boolean isSubscriptionEnabled(int subscriptionId) {
4036 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07004037 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chen77b2b552018-12-13 19:24:03 -08004038 if (iSub != null) {
4039 return iSub.isSubscriptionEnabled(subscriptionId);
4040 }
4041 } catch (RemoteException ex) {
4042 // ignore it
4043 }
4044
4045 return false;
4046 }
4047
4048 /**
Jack Yub0f281b2022-12-10 02:11:18 -08004049 * Set the device to device status sharing user preference for a subscription id. The setting
Grace Jiab53cb662021-02-12 15:29:29 -08004050 * app uses this method to indicate with whom they wish to share device to device status
4051 * information.
Jack Yu37742192022-12-09 02:20:59 -08004052 *
Jack Yub0f281b2022-12-10 02:11:18 -08004053 * @param subscriptionId The subscription id.
4054 * @param sharing The status sharing preference.
Jack Yu37742192022-12-09 02:20:59 -08004055 *
Jack Yub0f281b2022-12-10 02:11:18 -08004056 * @throws SecurityException if the caller doesn't have permissions required.
joonhunshin1a225542023-12-08 08:40:54 +00004057 * @throws UnsupportedOperationException If the device does not have
4058 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Grace Jiab53cb662021-02-12 15:29:29 -08004059 */
4060 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
Grace Jia25a8bdb2021-03-29 22:56:57 -07004061 public void setDeviceToDeviceStatusSharingPreference(int subscriptionId,
4062 @DeviceToDeviceStatusSharingPreference int sharing) {
Grace Jiab53cb662021-02-12 15:29:29 -08004063 if (VDBG) {
Grace Jiaaeea4ec2021-03-10 14:00:43 -08004064 logd("[setDeviceToDeviceStatusSharing] + sharing: " + sharing + " subId: "
4065 + subscriptionId);
Grace Jiab53cb662021-02-12 15:29:29 -08004066 }
Grace Jiaaeea4ec2021-03-10 14:00:43 -08004067 setSubscriptionPropertyHelper(subscriptionId, "setDeviceToDeviceSharingStatus",
4068 (iSub)->iSub.setDeviceToDeviceStatusSharing(sharing, subscriptionId));
Grace Jiab53cb662021-02-12 15:29:29 -08004069 }
4070
4071 /**
4072 * Returns the user-chosen device to device status sharing preference
Grace Jiaaeea4ec2021-03-10 14:00:43 -08004073 * @param subscriptionId Subscription id of subscription
Grace Jiab53cb662021-02-12 15:29:29 -08004074 * @return The device to device status sharing preference
Jack Yub0f281b2022-12-10 02:11:18 -08004075 *
4076 * @throws SecurityException if the caller doesn't have permissions required.
joonhunshin1a225542023-12-08 08:40:54 +00004077 * @throws UnsupportedOperationException If the device does not have
4078 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Grace Jiab53cb662021-02-12 15:29:29 -08004079 */
Grace Jiaaeea4ec2021-03-10 14:00:43 -08004080 public @DeviceToDeviceStatusSharingPreference int getDeviceToDeviceStatusSharingPreference(
4081 int subscriptionId) {
Grace Jiab53cb662021-02-12 15:29:29 -08004082 if (VDBG) {
Grace Jiaaeea4ec2021-03-10 14:00:43 -08004083 logd("[getDeviceToDeviceStatusSharing] + subId: " + subscriptionId);
Grace Jiab53cb662021-02-12 15:29:29 -08004084 }
Grace Jiaaeea4ec2021-03-10 14:00:43 -08004085 return getIntegerSubscriptionProperty(subscriptionId, D2D_STATUS_SHARING,
4086 D2D_SHARING_DISABLED, mContext);
Grace Jiab53cb662021-02-12 15:29:29 -08004087 }
4088
4089 /**
Jack Yub0f281b2022-12-10 02:11:18 -08004090 * Set the list of contacts that allow device to device status sharing for a subscription id.
Grace Jia2bd23cf2021-03-18 14:47:31 -07004091 * The setting app uses this method to indicate with whom they wish to share device to device
4092 * status information.
Jack Yu37742192022-12-09 02:20:59 -08004093 *
Jack Yub0f281b2022-12-10 02:11:18 -08004094 * @param subscriptionId The subscription id.
Jack Yu37742192022-12-09 02:20:59 -08004095 * @param contacts The list of contacts that allow device to device status sharing.
4096 *
Jack Yub0f281b2022-12-10 02:11:18 -08004097 * @throws SecurityException if the caller doesn't have permissions required.
joonhunshin1a225542023-12-08 08:40:54 +00004098 * @throws UnsupportedOperationException If the device does not have
4099 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Grace Jia2bd23cf2021-03-18 14:47:31 -07004100 */
4101 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
Grace Jia25a8bdb2021-03-29 22:56:57 -07004102 public void setDeviceToDeviceStatusSharingContacts(int subscriptionId,
4103 @NonNull List<Uri> contacts) {
Grace Jia2bd23cf2021-03-18 14:47:31 -07004104 String contactString = serializeUriLists(contacts);
4105 if (VDBG) {
4106 logd("[setDeviceToDeviceStatusSharingContacts] + contacts: " + contactString
4107 + " subId: " + subscriptionId);
4108 }
4109 setSubscriptionPropertyHelper(subscriptionId, "setDeviceToDeviceSharingStatus",
4110 (iSub)->iSub.setDeviceToDeviceStatusSharingContacts(serializeUriLists(contacts),
4111 subscriptionId));
4112 }
4113
4114 /**
Jack Yub0f281b2022-12-10 02:11:18 -08004115 * Get the list of contacts that allow device to device status sharing.
4116 *
4117 * @param subscriptionId Subscription id.
4118 *
4119 * @return The list of contacts that allow device to device status sharing.
joonhunshin1a225542023-12-08 08:40:54 +00004120 *
4121 * @throws UnsupportedOperationException If the device does not have
4122 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Grace Jia2bd23cf2021-03-18 14:47:31 -07004123 */
Jack Yub0f281b2022-12-10 02:11:18 -08004124 public @NonNull List<Uri> getDeviceToDeviceStatusSharingContacts(int subscriptionId) {
4125 String result = getStringSubscriptionProperty(mContext, subscriptionId,
4126 D2D_STATUS_SHARING_SELECTED_CONTACTS);
4127 if (result != null) {
4128 try {
4129 byte[] b = Base64.decode(result, Base64.DEFAULT);
4130 ByteArrayInputStream bis = new ByteArrayInputStream(b);
4131 ObjectInputStream ois = new ObjectInputStream(bis);
4132 List<String> contacts = ArrayList.class.cast(ois.readObject());
4133 List<Uri> uris = new ArrayList<>();
4134 for (String contact : contacts) {
4135 uris.add(Uri.parse(contact));
4136 }
4137 return uris;
4138 } catch (IOException e) {
4139 logd("getDeviceToDeviceStatusSharingContacts IO exception");
4140 } catch (ClassNotFoundException e) {
4141 logd("getDeviceToDeviceStatusSharingContacts ClassNotFound exception");
4142 }
Grace Jia2bd23cf2021-03-18 14:47:31 -07004143 }
Jack Yub0f281b2022-12-10 02:11:18 -08004144 return new ArrayList<>();
Grace Jia2bd23cf2021-03-18 14:47:31 -07004145 }
4146
4147 /**
Jack Yu53129a72023-03-28 22:47:41 -07004148 * Get the active subscription id by logical SIM slot index.
4149 *
4150 * @param slotIndex The logical SIM slot index.
4151 * @return The active subscription id.
4152 *
4153 * @throws IllegalArgumentException if the provided slot index is invalid.
4154 * @throws SecurityException if callers do not hold the required permission.
joonhunshin1a225542023-12-08 08:40:54 +00004155 * @throws UnsupportedOperationException If the device does not have
4156 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Jack Yu53129a72023-03-28 22:47:41 -07004157 *
Malcolm Chen77b2b552018-12-13 19:24:03 -08004158 * @hide
4159 */
4160 @SystemApi
4161 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
4162 public int getEnabledSubscriptionId(int slotIndex) {
4163 int subId = INVALID_SUBSCRIPTION_ID;
4164
4165 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07004166 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chen77b2b552018-12-13 19:24:03 -08004167 if (iSub != null) {
4168 subId = iSub.getEnabledSubscriptionId(slotIndex);
4169 }
4170 } catch (RemoteException ex) {
4171 // ignore it
4172 }
4173
4174 if (VDBG) logd("getEnabledSubscriptionId, subId = " + subId);
4175 return subId;
4176 }
4177
Malcolm Chenbd4ae762018-08-03 17:24:07 -07004178 private interface CallISubMethodHelper {
4179 int callMethod(ISub iSub) throws RemoteException;
4180 }
4181
4182 private int setSubscriptionPropertyHelper(int subId, String methodName,
4183 CallISubMethodHelper helper) {
4184 if (!isValidSubscriptionId(subId)) {
4185 logd("[" + methodName + "]" + "- fail");
4186 return -1;
4187 }
4188
4189 int result = 0;
4190
4191 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07004192 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chenbd4ae762018-08-03 17:24:07 -07004193 if (iSub != null) {
4194 result = helper.callMethod(iSub);
4195 }
4196 } catch (RemoteException ex) {
4197 // ignore it
4198 }
4199
4200 return result;
4201 }
Jack Yu807a82b2019-06-06 17:13:06 -07004202
4203 /**
Jayachandran C9ecb50e2019-11-08 00:47:34 -08004204 * Get active data subscription id. Active data subscription refers to the subscription
4205 * currently chosen to provide cellular internet connection to the user. This may be
Jack Yub0f281b2022-12-10 02:11:18 -08004206 * different from {@link #getDefaultDataSubscriptionId()}.
Jayachandran C9ecb50e2019-11-08 00:47:34 -08004207 *
Jack Yu37742192022-12-09 02:20:59 -08004208 * @return Active data subscription id if any is chosen, or {@link #INVALID_SUBSCRIPTION_ID} if
4209 * not.
Jack Yu807a82b2019-06-06 17:13:06 -07004210 *
Jack Yu37742192022-12-09 02:20:59 -08004211 * @see TelephonyCallback.ActiveDataSubscriptionIdListener
Jack Yu807a82b2019-06-06 17:13:06 -07004212 */
4213 public static int getActiveDataSubscriptionId() {
Jack Yu4a922da2023-04-14 09:17:36 -07004214 return sGetActiveDataSubscriptionIdCache.query(null);
Jack Yu807a82b2019-06-06 17:13:06 -07004215 }
Daniel Bright0b5d2852020-01-09 21:58:16 -08004216
4217 /**
4218 * Helper method that puts a subscription id on an intent with the constants:
4219 * PhoneConstant.SUBSCRIPTION_KEY and SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX.
4220 * Both constants are used to support backwards compatibility. Once we know we got all places,
4221 * we can remove PhoneConstants.SUBSCRIPTION_KEY.
4222 * @param intent Intent to put sub id on.
4223 * @param subId SubscriptionId to put on intent.
4224 *
4225 * @hide
4226 */
4227 public static void putSubscriptionIdExtra(Intent intent, int subId) {
4228 intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
4229 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
4230 }
Collin Fijalkovich4ffdedf2019-12-10 09:52:14 -08004231
4232 /** @hide */
Jack Yu50de0612022-11-26 01:19:17 -08004233 public static void invalidateSubscriptionManagerServiceCaches() {
4234 PropertyInvalidatedCache.invalidateCache(CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY);
4235 }
4236
Collin Fijalkovich7d7ce512020-04-02 13:32:32 -07004237 /**
4238 * Allows a test process to disable client-side caching operations.
4239 *
4240 * @hide
4241 */
4242 public static void disableCaching() {
Ling Ma19cfc632023-10-31 06:27:35 +00004243 sGetDefaultSubIdCacheAsUser.disableLocal();
Jack Yu50de0612022-11-26 01:19:17 -08004244 sGetDefaultDataSubIdCache.disableLocal();
4245 sGetActiveDataSubscriptionIdCache.disableLocal();
Ling Ma19cfc632023-10-31 06:27:35 +00004246 sGetDefaultSmsSubIdCacheAsUser.disableLocal();
Jack Yu50de0612022-11-26 01:19:17 -08004247 sGetSlotIndexCache.disableLocal();
4248 sGetSubIdCache.disableLocal();
4249 sGetPhoneIdCache.disableLocal();
Collin Fijalkovich41f94622020-04-10 14:01:42 -07004250 }
4251
4252 /**
4253 * Clears all process-local binder caches.
4254 *
4255 * @hide */
4256 public static void clearCaches() {
Ling Ma19cfc632023-10-31 06:27:35 +00004257 sGetDefaultSubIdCacheAsUser.clear();
Jack Yu50de0612022-11-26 01:19:17 -08004258 sGetDefaultDataSubIdCache.clear();
4259 sGetActiveDataSubscriptionIdCache.clear();
Ling Ma19cfc632023-10-31 06:27:35 +00004260 sGetDefaultSmsSubIdCacheAsUser.clear();
Jack Yu50de0612022-11-26 01:19:17 -08004261 sGetSlotIndexCache.clear();
4262 sGetSubIdCache.clear();
4263 sGetPhoneIdCache.clear();
Collin Fijalkovich4ffdedf2019-12-10 09:52:14 -08004264 }
Jack Nudelmane2ea4282021-01-13 18:46:57 -08004265
4266 /**
4267 * Called to retrieve SIM-specific settings data to be backed up.
4268 *
4269 * @return data in byte[] to be backed up.
4270 *
4271 * @hide
4272 */
4273 @NonNull
4274 @SystemApi
4275 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
4276 public byte[] getAllSimSpecificSettingsForBackup() {
4277 Bundle bundle = mContext.getContentResolver().call(
4278 SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
4279 GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME, null, null);
4280 return bundle.getByteArray(SubscriptionManager.KEY_SIM_SPECIFIC_SETTINGS_DATA);
4281 }
4282
4283 /**
Jack Nudelmane2ea4282021-01-13 18:46:57 -08004284 * Called during setup wizard restore flow to attempt to restore the backed up sim-specific
Jack Yu66b2b6c2023-02-12 23:35:26 -08004285 * configs to device for all existing SIMs in the subscription database {@link SimInfo}.
4286 * Internally, it will store the backup data in an internal file. This file will persist on
4287 * device for device's lifetime and will be used later on when a SIM is inserted to restore that
4288 * specific SIM's settings. End result is subscription database is modified to match any backed
4289 * up configs for the appropriate inserted SIMs.
Jack Nudelmane2ea4282021-01-13 18:46:57 -08004290 *
4291 * <p>
Jack Yu66b2b6c2023-02-12 23:35:26 -08004292 * The {@link Uri} {@link #SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI} is notified if any
4293 * {@link SimInfo} entry is updated as the result of this method call.
Jack Nudelmane2ea4282021-01-13 18:46:57 -08004294 *
4295 * @param data with the sim specific configs to be backed up.
4296 *
joonhunshin1a225542023-12-08 08:40:54 +00004297 * @throws UnsupportedOperationException If the device does not have
4298 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Jack Nudelmane2ea4282021-01-13 18:46:57 -08004299 * @hide
4300 */
4301 @SystemApi
4302 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
4303 public void restoreAllSimSpecificSettingsFromBackup(@NonNull byte[] data) {
Jack Yu66b2b6c2023-02-12 23:35:26 -08004304 try {
4305 ISub iSub = TelephonyManager.getSubscriptionService();
4306 if (iSub != null) {
4307 iSub.restoreAllSimSpecificSettingsFromBackup(data);
4308 } else {
4309 throw new IllegalStateException("subscription service unavailable.");
4310 }
4311 } catch (RemoteException ex) {
4312 if (!isSystemProcess()) {
4313 ex.rethrowAsRuntimeException();
4314 }
4315 }
Jack Nudelmane2ea4282021-01-13 18:46:57 -08004316 }
Meng Wang0594b4f2021-10-26 13:12:47 -07004317
4318 /**
Meng Wangbbb01fc2021-11-17 13:43:02 -08004319 * Returns the phone number for the given {@code subscriptionId} and {@code source},
Meng Wang0594b4f2021-10-26 13:12:47 -07004320 * or an empty string if not available.
4321 *
Meng Wangbbb01fc2021-11-17 13:43:02 -08004322 * <p>General apps that need to know the phone number should use {@link #getPhoneNumber(int)}
4323 * instead. This API may be suitable specific apps that needs to know the phone number from
4324 * a specific source. For example, a carrier app needs to know exactly what's on
4325 * {@link #PHONE_NUMBER_SOURCE_UICC UICC} and decide if the previously set phone number
4326 * of source {@link #PHONE_NUMBER_SOURCE_CARRIER carrier} should be updated.
4327 *
Meng Wang355b2542022-01-13 22:36:59 +00004328 * <p>The API provides no guarantees of what format the number is in: the format can vary
4329 * depending on the {@code source} and the network etc. Programmatic parsing should be done
4330 * cautiously, for example, after formatting the number to a consistent format with
4331 * {@link android.telephony.PhoneNumberUtils#formatNumberToE164(String, String)}.
4332 *
Meng Wangbbb01fc2021-11-17 13:43:02 -08004333 * <p>Note the assumption is that one subscription (which usually means one SIM) has
4334 * only one phone number. The multiple sources backup each other so hopefully at least one
Greg Piecyk06fc58c2024-02-09 01:19:52 +00004335 * is available. For example, for a carrier that doesn't typically set phone numbers
Meng Wangbbb01fc2021-11-17 13:43:02 -08004336 * on {@link #PHONE_NUMBER_SOURCE_UICC UICC}, the source {@link #PHONE_NUMBER_SOURCE_IMS IMS}
4337 * may provide one. Or, a carrier may decide to provide the phone number via source
4338 * {@link #PHONE_NUMBER_SOURCE_CARRIER carrier} if neither source UICC nor IMS is available.
Meng Wang0594b4f2021-10-26 13:12:47 -07004339 *
Erik Han4dfd4202022-10-05 18:17:00 +00004340 * <p>The availability and correctness of the phone number depends on the underlying source
4341 * and the network etc. Additional verification is needed to use this number for
4342 * security-related or other sensitive scenarios.
4343 *
Meng Wang0594b4f2021-10-26 13:12:47 -07004344 * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID}
Jack Yu647bbb92022-12-12 21:45:26 -08004345 * for the default one.
Meng Wang0594b4f2021-10-26 13:12:47 -07004346 * @param source the source of the phone number, one of the PHONE_NUMBER_SOURCE_* constants.
Jack Yu647bbb92022-12-12 21:45:26 -08004347 *
Meng Wang0594b4f2021-10-26 13:12:47 -07004348 * @return the phone number, or an empty string if not available.
Jack Yu647bbb92022-12-12 21:45:26 -08004349 *
Meng Wang0594b4f2021-10-26 13:12:47 -07004350 * @throws IllegalArgumentException if {@code source} is invalid.
4351 * @throws IllegalStateException if the telephony process is not currently available.
4352 * @throws SecurityException if the caller doesn't have permissions required.
joonhunshin1a225542023-12-08 08:40:54 +00004353 * @throws UnsupportedOperationException If the device does not have
4354 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Jack Yu647bbb92022-12-12 21:45:26 -08004355 *
Meng Wang0594b4f2021-10-26 13:12:47 -07004356 * @see #PHONE_NUMBER_SOURCE_UICC
4357 * @see #PHONE_NUMBER_SOURCE_CARRIER
4358 * @see #PHONE_NUMBER_SOURCE_IMS
4359 */
Meng Wang0594b4f2021-10-26 13:12:47 -07004360 @RequiresPermission(anyOf = {
4361 android.Manifest.permission.READ_PHONE_NUMBERS,
4362 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
Meng Wangbbb01fc2021-11-17 13:43:02 -08004363 "carrier privileges",
Meng Wang0594b4f2021-10-26 13:12:47 -07004364 })
4365 @NonNull
4366 public String getPhoneNumber(int subscriptionId, @PhoneNumberSource int source) {
4367 if (subscriptionId == DEFAULT_SUBSCRIPTION_ID) {
4368 subscriptionId = getDefaultSubscriptionId();
4369 }
4370 if (source != PHONE_NUMBER_SOURCE_UICC
4371 && source != PHONE_NUMBER_SOURCE_CARRIER
4372 && source != PHONE_NUMBER_SOURCE_IMS) {
4373 throw new IllegalArgumentException("invalid source " + source);
4374 }
4375 try {
4376 ISub iSub = TelephonyManager.getSubscriptionService();
4377 if (iSub != null) {
4378 return iSub.getPhoneNumber(subscriptionId, source,
4379 mContext.getOpPackageName(), mContext.getAttributionTag());
4380 } else {
4381 throw new IllegalStateException("subscription service unavailable.");
4382 }
4383 } catch (RemoteException ex) {
4384 throw ex.rethrowAsRuntimeException();
4385 }
4386 }
4387
4388 /**
4389 * Returns the phone number for the given {@code subId}, or an empty string if
4390 * not available.
4391 *
Meng Wangbbb01fc2021-11-17 13:43:02 -08004392 * <p>This API is suitable for general apps that needs to know the phone number.
4393 * For specific apps that needs to know the phone number provided by a specific source,
4394 * {@link #getPhoneNumber(int, int)} may be suitable.
4395 *
Meng Wang0594b4f2021-10-26 13:12:47 -07004396 * <p>This API is built up on {@link #getPhoneNumber(int, int)}, but picks
4397 * from available sources in the following order: {@link #PHONE_NUMBER_SOURCE_CARRIER}
4398 * > {@link #PHONE_NUMBER_SOURCE_UICC} > {@link #PHONE_NUMBER_SOURCE_IMS}.
4399 *
Meng Wang355b2542022-01-13 22:36:59 +00004400 * <p>The API provides no guarantees of what format the number is in: the format can vary
4401 * depending on the underlying source and the network etc. Programmatic parsing should be done
4402 * cautiously, for example, after formatting the number to a consistent format with
4403 * {@link android.telephony.PhoneNumberUtils#formatNumberToE164(String, String)}.
4404 *
Andrew Solovay97e99a72022-10-28 22:58:49 +00004405 * <p>The availability and correctness of the phone number depends on the underlying source
4406 * and the network etc. Additional verification is needed to use this number for
4407 * security-related or other sensitive scenarios.
4408 *
Meng Wang0594b4f2021-10-26 13:12:47 -07004409 * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID}
4410 * for the default one.
4411 * @return the phone number, or an empty string if not available.
Jack Yu647bbb92022-12-12 21:45:26 -08004412 *
Meng Wang0594b4f2021-10-26 13:12:47 -07004413 * @throws IllegalStateException if the telephony process is not currently available.
4414 * @throws SecurityException if the caller doesn't have permissions required.
joonhunshin1a225542023-12-08 08:40:54 +00004415 * @throws UnsupportedOperationException If the device does not have
4416 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Jack Yu647bbb92022-12-12 21:45:26 -08004417 *
Meng Wang0594b4f2021-10-26 13:12:47 -07004418 * @see #getPhoneNumber(int, int)
4419 */
Meng Wang0594b4f2021-10-26 13:12:47 -07004420 @RequiresPermission(anyOf = {
4421 android.Manifest.permission.READ_PHONE_NUMBERS,
4422 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
Meng Wangbbb01fc2021-11-17 13:43:02 -08004423 "carrier privileges",
Meng Wang0594b4f2021-10-26 13:12:47 -07004424 })
4425 @NonNull
4426 public String getPhoneNumber(int subscriptionId) {
4427 if (subscriptionId == DEFAULT_SUBSCRIPTION_ID) {
4428 subscriptionId = getDefaultSubscriptionId();
4429 }
4430 try {
4431 ISub iSub = TelephonyManager.getSubscriptionService();
4432 if (iSub != null) {
4433 return iSub.getPhoneNumberFromFirstAvailableSource(subscriptionId,
4434 mContext.getOpPackageName(), mContext.getAttributionTag());
4435 } else {
4436 throw new IllegalStateException("subscription service unavailable.");
4437 }
4438 } catch (RemoteException ex) {
4439 throw ex.rethrowAsRuntimeException();
4440 }
4441 }
4442
4443 /**
4444 * Sets the phone number for the given {@code subId} for source
4445 * {@link #PHONE_NUMBER_SOURCE_CARRIER carrier}.
4446 * Sets an empty string to remove the previously set phone number.
4447 *
Meng Wangbbb01fc2021-11-17 13:43:02 -08004448 * <p>The API is suitable for carrier apps to provide a phone number, for example when
4449 * it's not possible to update {@link #PHONE_NUMBER_SOURCE_UICC UICC} directly.
Meng Wang0594b4f2021-10-26 13:12:47 -07004450 *
Meng Wang355b2542022-01-13 22:36:59 +00004451 * <p>It's recommended that the phone number is formatted to well-known formats,
4452 * for example, by {@link PhoneNumberUtils} {@code formatNumber*} methods.
4453 *
Meng Wang0594b4f2021-10-26 13:12:47 -07004454 * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID}
4455 * for the default one.
4456 * @param number the phone number, or an empty string to remove the previously set number.
4457 * @throws IllegalStateException if the telephony process is not currently available.
4458 * @throws NullPointerException if {@code number} is {@code null}.
4459 * @throws SecurityException if the caller doesn't have permissions required.
joonhunshin1a225542023-12-08 08:40:54 +00004460 * @throws UnsupportedOperationException If the device does not have
4461 * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
Meng Wang0594b4f2021-10-26 13:12:47 -07004462 */
Meng Wangbbb01fc2021-11-17 13:43:02 -08004463 @RequiresPermission("carrier privileges")
Meng Wang0594b4f2021-10-26 13:12:47 -07004464 public void setCarrierPhoneNumber(int subscriptionId, @NonNull String number) {
4465 if (subscriptionId == DEFAULT_SUBSCRIPTION_ID) {
4466 subscriptionId = getDefaultSubscriptionId();
4467 }
4468 if (number == null) {
4469 throw new NullPointerException("invalid number null");
4470 }
4471 try {
4472 ISub iSub = TelephonyManager.getSubscriptionService();
4473 if (iSub != null) {
4474 iSub.setPhoneNumber(subscriptionId, PHONE_NUMBER_SOURCE_CARRIER, number,
4475 mContext.getOpPackageName(), mContext.getAttributionTag());
4476 } else {
4477 throw new IllegalStateException("subscription service unavailable.");
4478 }
4479 } catch (RemoteException ex) {
4480 throw ex.rethrowAsRuntimeException();
4481 }
4482 }
Nathan Harolde93321c2021-11-03 15:56:27 -07004483
4484 /**
4485 * Set the preferred usage setting.
4486 *
4487 * The cellular usage setting is a switch which controls the mode of operation for the cellular
4488 * radio to either require or not require voice service. It is not managed via Android’s
4489 * Settings.
4490 *
4491 * @param subscriptionId the subId of the subscription.
4492 * @param usageSetting the requested usage setting.
4493 *
4494 * @throws IllegalStateException if a specific mode or setting the mode is not supported on a
4495 * particular device.
4496 *
4497 * <p>Requires {@link android.Manifest.permission#MODIFY_PHONE_STATE}
4498 * or that the calling app has CarrierPrivileges for the given subscription.
4499 *
4500 * Note: This method will not allow the setting of USAGE_SETTING_UNKNOWN.
4501 *
4502 * @hide
4503 */
4504 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
4505 void setUsageSetting(int subscriptionId, @UsageSetting int usageSetting) {
4506 if (VDBG) logd("[setUsageSetting]+ setting:" + usageSetting + " subId:" + subscriptionId);
4507 setSubscriptionPropertyHelper(subscriptionId, "setUsageSetting",
4508 (iSub)-> iSub.setUsageSetting(
4509 usageSetting, subscriptionId, mContext.getOpPackageName()));
4510 }
Jack Yuc8b8a4e2022-10-13 01:59:43 -07004511
4512 /**
Jack Yu1f1f39b2022-11-23 14:53:53 -08004513 * Convert phone number source to string.
4514 *
4515 * @param source The phone name source.
4516 *
4517 * @return The phone name source in string format.
4518 *
4519 * @hide
4520 */
4521 @NonNull
4522 public static String phoneNumberSourceToString(@PhoneNumberSource int source) {
4523 switch (source) {
4524 case SubscriptionManager.PHONE_NUMBER_SOURCE_UICC: return "UICC";
4525 case SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER: return "CARRIER";
4526 case SubscriptionManager.PHONE_NUMBER_SOURCE_IMS: return "IMS";
4527 default:
4528 return "UNKNOWN(" + source + ")";
4529 }
4530 }
4531
4532 /**
Jack Yuc8b8a4e2022-10-13 01:59:43 -07004533 * Convert display name source to string.
4534 *
4535 * @param source The display name source.
4536 * @return The display name source in string format.
4537 *
4538 * @hide
4539 */
4540 @NonNull
4541 public static String displayNameSourceToString(
4542 @SubscriptionManager.SimDisplayNameSource int source) {
4543 switch (source) {
4544 case SubscriptionManager.NAME_SOURCE_UNKNOWN: return "UNKNOWN";
4545 case SubscriptionManager.NAME_SOURCE_CARRIER_ID: return "CARRIER_ID";
4546 case SubscriptionManager.NAME_SOURCE_SIM_SPN: return "SIM_SPN";
4547 case SubscriptionManager.NAME_SOURCE_USER_INPUT: return "USER_INPUT";
4548 case SubscriptionManager.NAME_SOURCE_CARRIER: return "CARRIER";
4549 case SubscriptionManager.NAME_SOURCE_SIM_PNN: return "SIM_PNN";
4550 default:
4551 return "UNKNOWN(" + source + ")";
4552 }
4553 }
4554
4555 /**
4556 * Convert subscription type to string.
4557 *
4558 * @param type The subscription type.
4559 * @return The subscription type in string format.
4560 *
4561 * @hide
4562 */
4563 @NonNull
4564 public static String subscriptionTypeToString(@SubscriptionManager.SubscriptionType int type) {
4565 switch (type) {
4566 case SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM: return "LOCAL_SIM";
4567 case SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM: return "REMOTE_SIM";
4568 default:
4569 return "UNKNOWN(" + type + ")";
4570 }
4571 }
4572
4573 /**
4574 * Convert usage setting to string.
4575 *
4576 * @param usageSetting Usage setting.
4577 * @return The usage setting in string format.
4578 *
4579 * @hide
4580 */
4581 @NonNull
4582 public static String usageSettingToString(@SubscriptionManager.UsageSetting int usageSetting) {
4583 switch (usageSetting) {
4584 case SubscriptionManager.USAGE_SETTING_UNKNOWN: return "UNKNOWN";
4585 case SubscriptionManager.USAGE_SETTING_DEFAULT: return "DEFAULT";
4586 case SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC: return "VOICE_CENTRIC";
4587 case SubscriptionManager.USAGE_SETTING_DATA_CENTRIC: return "DATA_CENTRIC";
4588 default:
4589 return "UNKNOWN(" + usageSetting + ")";
4590 }
4591 }
Aishwarya Mallampati4f838952022-09-22 22:21:41 +00004592
4593 /**
Ayush Sharma9195fc22024-03-27 19:12:50 +00004594 * Set owner for this subscription.
4595 *
4596 * @param subscriptionId the subId of the subscription.
4597 * @param groupOwner The group owner to assign to the subscription
4598 *
4599 * @throws SecurityException if caller is not authorized.
4600 *
4601 * @hide
4602 */
4603 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
4604 public void setGroupOwner(int subscriptionId, @NonNull String groupOwner) {
4605 try {
4606 ISub iSub = TelephonyManager.getSubscriptionService();
4607 if (iSub != null) {
4608 iSub.setGroupOwner(subscriptionId, groupOwner);
4609 } else {
4610 throw new IllegalStateException("[setGroupOwner]: "
4611 + "subscription service unavailable");
4612 }
4613 } catch (RemoteException ex) {
4614 ex.rethrowAsRuntimeException();
4615 }
4616 }
4617
4618 /**
Aishwarya Mallampati4f838952022-09-22 22:21:41 +00004619 * Set userHandle for a subscription.
4620 *
4621 * Used to set an association between a subscription and a user on the device so that voice
4622 * calling and SMS from that subscription can be associated with that user.
4623 * Data services are always shared between users on the device.
4624 *
4625 * @param subscriptionId the subId of the subscription.
4626 * @param userHandle the userHandle associated with the subscription.
4627 * Pass {@code null} user handle to clear the association.
4628 *
4629 * @throws IllegalArgumentException if subscription is invalid.
4630 * @throws SecurityException if the caller doesn't have permissions required.
4631 * @throws IllegalStateException if subscription service is not available.
4632 *
4633 * @hide
4634 */
Aishwarya Mallampati4f838952022-09-22 22:21:41 +00004635 @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION)
Aishwarya Mallampati9bea0152022-10-25 20:35:17 +00004636 public void setSubscriptionUserHandle(int subscriptionId, @Nullable UserHandle userHandle) {
Aishwarya Mallampati4f838952022-09-22 22:21:41 +00004637 if (!isValidSubscriptionId(subscriptionId)) {
Aishwarya Mallampati9bea0152022-10-25 20:35:17 +00004638 throw new IllegalArgumentException("[setSubscriptionUserHandle]: "
4639 + "Invalid subscriptionId: " + subscriptionId);
Aishwarya Mallampati4f838952022-09-22 22:21:41 +00004640 }
4641
4642 try {
4643 ISub iSub = TelephonyManager.getSubscriptionService();
4644 if (iSub != null) {
Aishwarya Mallampati9bea0152022-10-25 20:35:17 +00004645 iSub.setSubscriptionUserHandle(userHandle, subscriptionId);
Aishwarya Mallampati4f838952022-09-22 22:21:41 +00004646 } else {
Aishwarya Mallampati9bea0152022-10-25 20:35:17 +00004647 throw new IllegalStateException("[setSubscriptionUserHandle]: "
Aishwarya Mallampati4f838952022-09-22 22:21:41 +00004648 + "subscription service unavailable");
4649 }
4650 } catch (RemoteException ex) {
4651 ex.rethrowAsRuntimeException();
4652 }
4653 }
4654
4655 /**
4656 * Get UserHandle of this subscription.
4657 *
4658 * Used to get user handle associated with this subscription.
4659 *
4660 * @param subscriptionId the subId of the subscription.
4661 * @return userHandle associated with this subscription
4662 * or {@code null} if subscription is not associated with any user.
4663 *
4664 * @throws IllegalArgumentException if subscription is invalid.
4665 * @throws SecurityException if the caller doesn't have permissions required.
Aishwarya Mallampati4f838952022-09-22 22:21:41 +00004666 *
4667 * @hide
4668 */
Aishwarya Mallampati4f838952022-09-22 22:21:41 +00004669 @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION)
Aishwarya Mallampati9bea0152022-10-25 20:35:17 +00004670 public @Nullable UserHandle getSubscriptionUserHandle(int subscriptionId) {
Aishwarya Mallampati4f838952022-09-22 22:21:41 +00004671 if (!isValidSubscriptionId(subscriptionId)) {
Aishwarya Mallampati9bea0152022-10-25 20:35:17 +00004672 throw new IllegalArgumentException("[getSubscriptionUserHandle]: "
4673 + "Invalid subscriptionId: " + subscriptionId);
Aishwarya Mallampati4f838952022-09-22 22:21:41 +00004674 }
4675
4676 try {
4677 ISub iSub = TelephonyManager.getSubscriptionService();
4678 if (iSub != null) {
Aishwarya Mallampati9bea0152022-10-25 20:35:17 +00004679 return iSub.getSubscriptionUserHandle(subscriptionId);
Aishwarya Mallampati4f838952022-09-22 22:21:41 +00004680 } else {
Jack Yuad70b912023-02-23 17:44:05 -08004681 Log.e(LOG_TAG, "[getSubscriptionUserHandle]: subscription service unavailable");
Aishwarya Mallampati4f838952022-09-22 22:21:41 +00004682 }
4683 } catch (RemoteException ex) {
4684 ex.rethrowAsRuntimeException();
4685 }
4686 return null;
4687 }
Aishwarya Mallampati425e7092022-12-02 18:55:07 +00004688
4689 /**
4690 * Check if subscription and user are associated with each other.
4691 *
4692 * @param subscriptionId the subId of the subscription
4693 * @param userHandle user handle of the user
4694 * @return {@code true} if subscription is associated with user
Aishwarya Mallampati425e7092022-12-02 18:55:07 +00004695 * else {@code false} if subscription is not associated with user.
4696 *
Ling Ma1f2ea352023-09-19 16:00:43 -07004697 * @throws IllegalArgumentException if subscription doesn't exist.
Aishwarya Mallampati425e7092022-12-02 18:55:07 +00004698 * @throws SecurityException if the caller doesn't have permissions required.
Aishwarya Mallampati425e7092022-12-02 18:55:07 +00004699 *
4700 * @hide
4701 */
4702 @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION)
4703 public boolean isSubscriptionAssociatedWithUser(int subscriptionId,
4704 @NonNull UserHandle userHandle) {
4705 if (!isValidSubscriptionId(subscriptionId)) {
4706 throw new IllegalArgumentException("[isSubscriptionAssociatedWithUser]: "
4707 + "Invalid subscriptionId: " + subscriptionId);
4708 }
4709
4710 try {
4711 ISub iSub = TelephonyManager.getSubscriptionService();
4712 if (iSub != null) {
4713 return iSub.isSubscriptionAssociatedWithUser(subscriptionId, userHandle);
4714 } else {
Jack Yu3bbdae42023-03-16 23:15:48 -07004715 Log.e(LOG_TAG, "[isSubscriptionAssociatedWithUser]: subscription service "
4716 + "unavailable");
Aishwarya Mallampati425e7092022-12-02 18:55:07 +00004717 }
4718 } catch (RemoteException ex) {
4719 ex.rethrowAsRuntimeException();
4720 }
4721 return false;
4722 }
4723
4724 /**
Adam Bookatz855c6212024-02-13 16:14:33 -08004725 * Returns whether the given subscription is associated with the calling user.
4726 *
4727 * @param subscriptionId the subscription ID of the subscription
4728 * @return {@code true} if the subscription is associated with the user that the current process
4729 * is running in; {@code false} otherwise.
4730 *
4731 * @throws IllegalArgumentException if subscription doesn't exist.
4732 * @throws SecurityException if the caller doesn't have permissions required.
4733 */
4734 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
4735 @FlaggedApi(Flags.FLAG_SUBSCRIPTION_USER_ASSOCIATION_QUERY)
4736 public boolean isSubscriptionAssociatedWithUser(int subscriptionId) {
4737 if (!isValidSubscriptionId(subscriptionId)) {
4738 throw new IllegalArgumentException("[isSubscriptionAssociatedWithCallingUser]: "
4739 + "Invalid subscriptionId: " + subscriptionId);
4740 }
4741
4742 try {
4743 ISub iSub = TelephonyManager.getSubscriptionService();
4744 if (iSub != null) {
4745 return iSub.isSubscriptionAssociatedWithCallingUser(subscriptionId);
4746 } else {
4747 throw new IllegalStateException("subscription service unavailable.");
4748 }
4749 } catch (RemoteException ex) {
4750 ex.rethrowAsRuntimeException();
4751 }
4752 return false;
4753 }
4754
4755 /**
Aishwarya Mallampati425e7092022-12-02 18:55:07 +00004756 * Get list of subscriptions associated with user.
4757 *
4758 * @param userHandle user handle of the user
4759 * @return list of subscriptionInfo associated with the user.
4760 *
4761 * @throws SecurityException if the caller doesn't have permissions required.
4762 * @throws IllegalStateException if subscription service is not available.
4763 *
4764 * @hide
4765 */
4766 @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION)
4767 public @NonNull List<SubscriptionInfo> getSubscriptionInfoListAssociatedWithUser(
4768 @NonNull UserHandle userHandle) {
4769 try {
4770 ISub iSub = TelephonyManager.getSubscriptionService();
4771 if (iSub != null) {
4772 return iSub.getSubscriptionInfoListAssociatedWithUser(userHandle);
4773 } else {
Jack Yu3bbdae42023-03-16 23:15:48 -07004774 Log.e(LOG_TAG, "[getSubscriptionInfoListAssociatedWithUser]: "
Aishwarya Mallampati425e7092022-12-02 18:55:07 +00004775 + "subscription service unavailable");
4776 }
4777 } catch (RemoteException ex) {
4778 ex.rethrowAsRuntimeException();
4779 }
4780 return new ArrayList<>();
4781 }
rambowang558016e2023-12-04 10:22:13 -06004782
4783 /**
4784 * @return the bitmasks combination of all service capabilities.
4785 * @hide
4786 */
4787 public static int getAllServiceCapabilityBitmasks() {
4788 return SERVICE_CAPABILITY_VOICE_BITMASK | SERVICE_CAPABILITY_SMS_BITMASK
4789 | SERVICE_CAPABILITY_DATA_BITMASK;
4790 }
4791
4792 /**
4793 * @return The set of service capability from a bitmask combined one.
4794 * @hide
4795 */
4796 @NonNull
4797 @ServiceCapability
4798 public static Set<Integer> getServiceCapabilitiesSet(int combinedServiceCapabilities) {
4799 Set<Integer> capabilities = new HashSet<>();
4800 for (int i = SERVICE_CAPABILITY_VOICE; i <= SERVICE_CAPABILITY_MAX; i++) {
4801 final int capabilityBitmask = serviceCapabilityToBitmask(i);
4802 if ((combinedServiceCapabilities & capabilityBitmask) == capabilityBitmask) {
4803 capabilities.add(i);
4804 }
4805 }
4806 return Collections.unmodifiableSet(capabilities);
4807 }
4808
4809 /**
4810 * @return The service capability bitmask from a {@link ServiceCapability} value.
4811 * @hide
4812 */
4813 public static int serviceCapabilityToBitmask(@ServiceCapability int capability) {
4814 return 1 << (capability - 1);
4815 }
Hyunhoaeba1f22024-01-11 08:52:29 +00004816
4817 /**
4818 * Set the transfer status of the subscriptionInfo of the subId.
4819 * @param subscriptionId The unique SubscriptionInfo key in database.
4820 * @param status The transfer status to change.
4821 *
4822 *
4823 * @hide
4824 */
4825 @FlaggedApi(Flags.FLAG_SUPPORT_PSIM_TO_ESIM_CONVERSION)
4826 @SystemApi
4827 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
4828 public void setTransferStatus(int subscriptionId, @TransferStatus int status) {
4829 try {
4830 ISub iSub = TelephonyManager.getSubscriptionService();
4831 if (iSub != null) {
4832 iSub.setTransferStatus(subscriptionId, status);
4833 }
4834 } catch (RemoteException ex) {
4835 logd("setTransferStatus for subId = " + subscriptionId + " failed.");
4836 throw ex.rethrowFromSystemServer();
4837 }
4838 }
Wink Savillefb40dd42014-06-12 17:02:31 -07004839}