blob: d3f58e9e1e80cda18ec3464ed8a95a254293e87f [file] [log] [blame]
Wink Savillefb40dd42014-06-12 17:02:31 -07001/*
Wink Savillef5bca082014-09-03 15:13:33 -07002 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Wink Savillefb40dd42014-06-12 17:02:31 -070016
17package android.telephony;
18
Aaron Huang79f52ea2019-12-30 20:11:36 +080019import static android.net.NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_CONGESTED;
20import static android.net.NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED;
Jeff Sharkey9252b342018-01-19 07:58:35 +090021
Malcolm Chenbe9240b2018-12-03 20:29:33 -080022import android.Manifest;
Malcolm Chen27829e22018-09-04 22:12:31 -070023import android.annotation.CallbackExecutor;
changbetty23eee52e2019-12-18 18:09:56 +080024import android.annotation.ColorInt;
Jeff Sharkey9252b342018-01-19 07:58:35 +090025import android.annotation.DurationMillisLong;
Grace Chen5be6e9c2018-12-20 22:50:18 -080026import android.annotation.IntDef;
Jeff Sharkey32566012014-12-02 18:30:14 -080027import android.annotation.NonNull;
Jeff Sharkey717f52f2018-01-04 16:04:11 -070028import android.annotation.Nullable;
Hui Wangc47df7f2021-12-14 20:37:47 +000029import android.annotation.RequiresFeature;
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -070030import android.annotation.RequiresPermission;
Wink Savillec650e0b2014-09-02 22:37:08 -070031import android.annotation.SdkConstant;
32import android.annotation.SdkConstant.SdkConstantType;
Jeff Davidson3c0415a2018-02-23 15:27:46 -080033import android.annotation.SuppressAutoDoc;
Jeff Sharkey717f52f2018-01-04 16:04:11 -070034import android.annotation.SystemApi;
Jeff Sharkey17bebd22017-07-19 21:00:38 -060035import android.annotation.SystemService;
Malcolm Chen0ac24ef2018-08-07 15:03:32 -070036import android.app.PendingIntent;
Collin Fijalkovich4ffdedf2019-12-10 09:52:14 -080037import android.app.PropertyInvalidatedCache;
Artur Satayev54af4fc2019-12-10 17:47:56 +000038import android.compat.annotation.UnsupportedAppUsage;
Wink Savillea374c3d2014-11-11 11:48:04 -080039import android.content.Context;
Wink Savillefb40dd42014-06-12 17:02:31 -070040import android.content.Intent;
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -080041import android.content.pm.PackageInfo;
Jeff Sharkey717f52f2018-01-04 16:04:11 -070042import android.content.pm.PackageManager;
Sanket Padawedc493092015-07-14 14:21:43 -070043import android.content.res.Configuration;
44import android.content.res.Resources;
chen xua0007492018-10-02 19:34:10 -070045import android.database.ContentObserver;
Jeff Sharkey9252b342018-01-19 07:58:35 +090046import android.net.NetworkCapabilities;
Aaron Huang21089442020-01-16 23:31:02 +080047import android.net.NetworkPolicyManager;
Wink Savillefb40dd42014-06-12 17:02:31 -070048import android.net.Uri;
Malcolm Chenb2129eb2018-10-16 18:18:51 -070049import android.os.Binder;
Mathew Inwood45d2c252018-09-14 12:35:36 +010050import android.os.Build;
Jack Nudelmane2ea4282021-01-13 18:46:57 -080051import android.os.Bundle;
Wink Savilled09c4ca2014-11-22 10:08:16 -080052import android.os.Handler;
Jack He9fc75742017-11-16 15:54:14 -080053import android.os.Looper;
Malcolm Chen4674a792019-03-20 20:32:27 -070054import android.os.ParcelUuid;
55import android.os.Process;
Wink Savillefb40dd42014-06-12 17:02:31 -070056import android.os.RemoteException;
Aishwarya Mallampati4f838952022-09-22 22:21:41 +000057import android.os.UserHandle;
changbetty239b6ce2019-12-02 15:04:49 +080058import android.provider.Telephony.SimInfo;
Malcolm Chen0ac24ef2018-08-07 15:03:32 -070059import android.telephony.euicc.EuiccManager;
chen xubf38b062018-11-01 00:08:37 -070060import android.telephony.ims.ImsMmTelManager;
Grace Jia2bd23cf2021-03-18 14:47:31 -070061import android.util.Base64;
Malcolm Chen27829e22018-09-04 22:12:31 -070062import android.util.Log;
Torbjorn Eklundf8899f02019-11-20 10:59:59 +010063import android.util.Pair;
Jeff Sharkey717f52f2018-01-04 16:04:11 -070064
Malcolm Chenfd11df22019-02-05 17:19:48 -080065import com.android.internal.telephony.ISetOpportunisticDataCallback;
Jeff Davidsond02731f2017-04-09 14:31:09 -070066import com.android.internal.telephony.ISub;
Wink Savillefb40dd42014-06-12 17:02:31 -070067import com.android.internal.telephony.PhoneConstants;
Sooraj Sasindran041a6d32019-12-02 13:08:23 -080068import com.android.internal.telephony.util.HandlerExecutor;
Hall Liu29b1874f2020-04-07 18:23:09 -070069import com.android.internal.util.FunctionalUtils;
Malcolm Chen80e1e5c2019-02-27 15:16:05 -080070import com.android.internal.util.Preconditions;
Meng Wange3387ef92020-01-30 12:38:32 -080071import com.android.telephony.Rlog;
Jeff Sharkey717f52f2018-01-04 16:04:11 -070072
Grace Jia2bd23cf2021-03-18 14:47:31 -070073import java.io.ByteArrayInputStream;
74import java.io.ByteArrayOutputStream;
75import java.io.IOException;
76import java.io.ObjectInputStream;
77import java.io.ObjectOutputStream;
Grace Chen5be6e9c2018-12-20 22:50:18 -080078import java.lang.annotation.Retention;
79import java.lang.annotation.RetentionPolicy;
Wink Saville905bb542014-09-04 17:10:23 -070080import java.util.ArrayList;
Jeff Sharkey53313d72017-07-13 16:47:32 -060081import java.util.Arrays;
Rajeev Kumarc8ac4f3b2017-07-26 15:59:08 -070082import java.util.Collections;
Malcolm Chenb82864c2019-02-26 16:48:40 -080083import java.util.HashMap;
Wink Savillefb40dd42014-06-12 17:02:31 -070084import java.util.List;
Torbjorn Eklund99c11d82018-08-21 16:06:47 +020085import java.util.Locale;
Malcolm Chenb82864c2019-02-26 16:48:40 -080086import java.util.Map;
Torbjorn Eklundf8899f02019-11-20 10:59:59 +010087import java.util.concurrent.ConcurrentHashMap;
Malcolm Chen27829e22018-09-04 22:12:31 -070088import java.util.concurrent.Executor;
Malcolm Chenfd11df22019-02-05 17:19:48 -080089import java.util.function.Consumer;
Malcolm Chen0db9aa12018-12-06 11:19:03 -080090import java.util.stream.Collectors;
Wink Savillefb40dd42014-06-12 17:02:31 -070091
92/**
Wink Savillef5bca082014-09-03 15:13:33 -070093 * SubscriptionManager is the application interface to SubscriptionController
94 * and provides information about the current Telephony Subscriptions.
Wink Savillefb40dd42014-06-12 17:02:31 -070095 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060096@SystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)
Hui Wangc47df7f2021-12-14 20:37:47 +000097@RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
Wink Savilled09c4ca2014-11-22 10:08:16 -080098public class SubscriptionManager {
99 private static final String LOG_TAG = "SubscriptionManager";
100 private static final boolean DBG = false;
Wink Savillefb40dd42014-06-12 17:02:31 -0700101 private static final boolean VDBG = false;
102
Wink Savillea374c3d2014-11-11 11:48:04 -0800103 /** An invalid subscription identifier */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800104 public static final int INVALID_SUBSCRIPTION_ID = -1;
105
Tyler Gunn460360d2020-07-29 10:21:45 -0700106 /** Base value for placeholder SUBSCRIPTION_ID's. */
107 /** @hide */
108 public static final int PLACEHOLDER_SUBSCRIPTION_ID_BASE = INVALID_SUBSCRIPTION_ID - 1;
Wink Savillefb40dd42014-06-12 17:02:31 -0700109
Wink Savillea374c3d2014-11-11 11:48:04 -0800110 /** An invalid phone identifier */
111 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800112 public static final int INVALID_PHONE_INDEX = -1;
Wink Savillec650e0b2014-09-02 22:37:08 -0700113
sqian996a3182018-10-12 18:41:19 -0700114 /** Indicates invalid sim slot. This can be returned by {@link #getSlotIndex(int)}. */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800115 public static final int INVALID_SIM_SLOT_INDEX = -1;
Wink Savillea374c3d2014-11-11 11:48:04 -0800116
sqian798da562018-09-12 16:31:17 -0700117 /** Indicates the default subscription ID in Telephony. */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800118 public static final int DEFAULT_SUBSCRIPTION_ID = Integer.MAX_VALUE;
Wink Savillea374c3d2014-11-11 11:48:04 -0800119
Wink Savilled09c4ca2014-11-22 10:08:16 -0800120 /**
121 * Indicates the caller wants the default phone id.
Jack Yu67140302015-12-10 12:27:58 -0800122 * Used in SubscriptionController and Phone but do we really need it???
Wink Savilled09c4ca2014-11-22 10:08:16 -0800123 * @hide
124 */
125 public static final int DEFAULT_PHONE_INDEX = Integer.MAX_VALUE;
Wink Saville2d1ee982014-11-20 20:29:51 +0000126
Wink Savilled09c4ca2014-11-22 10:08:16 -0800127 /** Indicates the caller wants the default slot id. NOT used remove? */
Wink Saville2d1ee982014-11-20 20:29:51 +0000128 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800129 public static final int DEFAULT_SIM_SLOT_INDEX = Integer.MAX_VALUE;
Wink Savillec650e0b2014-09-02 22:37:08 -0700130
Wink Saville8eab2b62014-09-23 14:20:58 -0700131 /** Minimum possible subid that represents a subscription */
132 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800133 public static final int MIN_SUBSCRIPTION_ID_VALUE = 0;
Wink Saville8eab2b62014-09-23 14:20:58 -0700134
135 /** Maximum possible subid that represents a subscription */
136 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800137 public static final int MAX_SUBSCRIPTION_ID_VALUE = DEFAULT_SUBSCRIPTION_ID - 1;
Wink Saville8eab2b62014-09-23 14:20:58 -0700138
Wink Savillef5bca082014-09-03 15:13:33 -0700139 /** @hide */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +0000140 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
changbetty239b6ce2019-12-02 15:04:49 +0800141 public static final Uri CONTENT_URI = SimInfo.CONTENT_URI;
Wink Savillefb40dd42014-06-12 17:02:31 -0700142
Jack Yufbba7fb2022-08-16 17:54:05 -0700143 private static final String CACHE_KEY_DEFAULT_SUB_ID_PROPERTY =
Collin Fijalkovich4ffdedf2019-12-10 09:52:14 -0800144 "cache_key.telephony.get_default_sub_id";
145
Jack Yufbba7fb2022-08-16 17:54:05 -0700146 private static final String CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY =
Collin Fijalkovichce43a592020-03-25 14:30:21 -0700147 "cache_key.telephony.get_default_data_sub_id";
148
Jack Yufbba7fb2022-08-16 17:54:05 -0700149 private static final String CACHE_KEY_DEFAULT_SMS_SUB_ID_PROPERTY =
Collin Fijalkovich02e5c592020-04-06 10:54:28 -0700150 "cache_key.telephony.get_default_sms_sub_id";
151
Jack Yufbba7fb2022-08-16 17:54:05 -0700152 private static final String CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY =
Collin Fijalkovich7d7ce512020-04-02 13:32:32 -0700153 "cache_key.telephony.get_active_data_sub_id";
154
Jack Yufbba7fb2022-08-16 17:54:05 -0700155 private static final String CACHE_KEY_SLOT_INDEX_PROPERTY =
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700156 "cache_key.telephony.get_slot_index";
157
Jack Nudelmane2ea4282021-01-13 18:46:57 -0800158 /** @hide */
159 public static final String GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME = "getSimSpecificSettings";
160
161 /** @hide */
162 public static final String RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME =
163 "restoreSimSpecificSettings";
164
165 /**
166 * Key to the backup & restore data byte array in the Bundle that is returned by {@link
167 * #getAllSimSpecificSettingsForBackup()} or to be pass in to {@link
168 * #restoreAllSimSpecificSettings()}.
169 *
170 * @hide
171 */
172 public static final String KEY_SIM_SPECIFIC_SETTINGS_DATA = "KEY_SIM_SPECIFIC_SETTINGS_DATA";
173
Collin Fijalkovichce43a592020-03-25 14:30:21 -0700174 private static final int MAX_CACHE_SIZE = 4;
Collin Fijalkovich4ffdedf2019-12-10 09:52:14 -0800175
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700176 private static class VoidPropertyInvalidatedCache<T>
Hall Liu29b1874f2020-04-07 18:23:09 -0700177 extends PropertyInvalidatedCache<Void, T> {
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700178 private final FunctionalUtils.ThrowingFunction<ISub, T> mInterfaceMethod;
Hall Liu29b1874f2020-04-07 18:23:09 -0700179 private final String mCacheKeyProperty;
180 private final T mDefaultValue;
Collin Fijalkovich4ffdedf2019-12-10 09:52:14 -0800181
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700182 VoidPropertyInvalidatedCache(
Hall Liu29b1874f2020-04-07 18:23:09 -0700183 FunctionalUtils.ThrowingFunction<ISub, T> subscriptionInterfaceMethod,
184 String cacheKeyProperty,
185 T defaultValue) {
186 super(MAX_CACHE_SIZE, cacheKeyProperty);
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700187 mInterfaceMethod = subscriptionInterfaceMethod;
Hall Liu29b1874f2020-04-07 18:23:09 -0700188 mCacheKeyProperty = cacheKeyProperty;
189 mDefaultValue = defaultValue;
190 }
191
192 @Override
Lee Shombert0d9ec2f2022-07-29 07:39:36 -0700193 public T recompute(Void query) {
194 // This always throws on any error. The exceptions must be handled outside
195 // the cache.
196 try {
197 return mInterfaceMethod.applyOrThrow(TelephonyManager.getSubscriptionService());
198 } catch (Exception re) {
199 throw new RuntimeException(re);
200 }
201 }
202
203 @Override
204 public T query(Void query) {
Hall Liu29b1874f2020-04-07 18:23:09 -0700205 T result = mDefaultValue;
206
207 try {
208 ISub iSub = TelephonyManager.getSubscriptionService();
209 if (iSub != null) {
Lee Shombert0d9ec2f2022-07-29 07:39:36 -0700210 result = super.query(query);
Hall Liu29b1874f2020-04-07 18:23:09 -0700211 }
212 } catch (Exception ex) {
213 Rlog.w(LOG_TAG, "Failed to recompute cache key for " + mCacheKeyProperty);
214 }
215
216 if (VDBG) logd("recomputing " + mCacheKeyProperty + ", result = " + result);
217 return result;
218 }
219 }
220
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700221 private static class IntegerPropertyInvalidatedCache<T>
222 extends PropertyInvalidatedCache<Integer, T> {
223 private final FunctionalUtils.ThrowingBiFunction<ISub, Integer, T> mInterfaceMethod;
224 private final String mCacheKeyProperty;
225 private final T mDefaultValue;
226
227 IntegerPropertyInvalidatedCache(
228 FunctionalUtils.ThrowingBiFunction<ISub, Integer, T> subscriptionInterfaceMethod,
229 String cacheKeyProperty,
230 T defaultValue) {
231 super(MAX_CACHE_SIZE, cacheKeyProperty);
232 mInterfaceMethod = subscriptionInterfaceMethod;
233 mCacheKeyProperty = cacheKeyProperty;
234 mDefaultValue = defaultValue;
235 }
236
237 @Override
Lee Shombert0cece382022-01-04 08:10:15 -0800238 public T recompute(Integer query) {
Lee Shombert0d9ec2f2022-07-29 07:39:36 -0700239 // This always throws on any error. The exceptions must be handled outside
240 // the cache.
241 try {
242 return mInterfaceMethod.applyOrThrow(
243 TelephonyManager.getSubscriptionService(), query);
244 } catch (Exception re) {
245 throw new RuntimeException(re);
246 }
247 }
248
249 @Override
250 public T query(Integer query) {
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700251 T result = mDefaultValue;
252
253 try {
254 ISub iSub = TelephonyManager.getSubscriptionService();
255 if (iSub != null) {
Lee Shombert0d9ec2f2022-07-29 07:39:36 -0700256 result = super.query(query);
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700257 }
258 } catch (Exception ex) {
259 Rlog.w(LOG_TAG, "Failed to recompute cache key for " + mCacheKeyProperty);
260 }
261
262 if (VDBG) logd("recomputing " + mCacheKeyProperty + ", result = " + result);
263 return result;
264 }
265 }
266
267 private static VoidPropertyInvalidatedCache<Integer> sDefaultSubIdCache =
268 new VoidPropertyInvalidatedCache<>(ISub::getDefaultSubId,
Hall Liu29b1874f2020-04-07 18:23:09 -0700269 CACHE_KEY_DEFAULT_SUB_ID_PROPERTY,
270 INVALID_SUBSCRIPTION_ID);
271
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700272 private static VoidPropertyInvalidatedCache<Integer> sDefaultDataSubIdCache =
273 new VoidPropertyInvalidatedCache<>(ISub::getDefaultDataSubId,
Hall Liu29b1874f2020-04-07 18:23:09 -0700274 CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY,
275 INVALID_SUBSCRIPTION_ID);
Collin Fijalkovich4ffdedf2019-12-10 09:52:14 -0800276
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700277 private static VoidPropertyInvalidatedCache<Integer> sDefaultSmsSubIdCache =
278 new VoidPropertyInvalidatedCache<>(ISub::getDefaultSmsSubId,
Collin Fijalkovich02e5c592020-04-06 10:54:28 -0700279 CACHE_KEY_DEFAULT_SMS_SUB_ID_PROPERTY,
280 INVALID_SUBSCRIPTION_ID);
281
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700282 private static VoidPropertyInvalidatedCache<Integer> sActiveDataSubIdCache =
283 new VoidPropertyInvalidatedCache<>(ISub::getActiveDataSubscriptionId,
Collin Fijalkovich02e5c592020-04-06 10:54:28 -0700284 CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY,
285 INVALID_SUBSCRIPTION_ID);
Collin Fijalkovich7d7ce512020-04-02 13:32:32 -0700286
Collin Fijalkovich41f94622020-04-10 14:01:42 -0700287 private static IntegerPropertyInvalidatedCache<Integer> sSlotIndexCache =
288 new IntegerPropertyInvalidatedCache<>(ISub::getSlotIndex,
289 CACHE_KEY_SLOT_INDEX_PROPERTY,
290 INVALID_SIM_SLOT_INDEX);
291
292 /** Cache depends on getDefaultSubId, so we use the defaultSubId cache key */
293 private static IntegerPropertyInvalidatedCache<Integer> sPhoneIdCache =
294 new IntegerPropertyInvalidatedCache<>(ISub::getPhoneId,
295 CACHE_KEY_DEFAULT_SUB_ID_PROPERTY,
296 INVALID_PHONE_INDEX);
297
chen xua0007492018-10-02 19:34:10 -0700298 /**
299 * Generates a content {@link Uri} used to receive updates on simInfo change
300 * on the given subscriptionId
301 * @param subscriptionId the subscriptionId to receive updates on
302 * @return the Uri used to observe carrier identity changes
303 * @hide
304 */
305 public static Uri getUriForSubscriptionId(int subscriptionId) {
306 return Uri.withAppendedPath(CONTENT_URI, String.valueOf(subscriptionId));
307 }
308
309 /**
310 * A content {@link Uri} used to receive updates on wfc enabled user setting.
311 * <p>
312 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
chen xubf38b062018-11-01 00:08:37 -0700313 * subscription wfc enabled {@link ImsMmTelManager#isVoWiFiSettingEnabled()}
Makoto Onuki2da26292019-08-07 08:59:39 -0700314 * while your app is running. You can also use a {@link android.app.job.JobService}
315 * to ensure your app
chen xua0007492018-10-02 19:34:10 -0700316 * is notified of changes to the {@link Uri} even when it is not running.
Makoto Onuki2da26292019-08-07 08:59:39 -0700317 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
318 * delivery of updates to the {@link Uri}.
chen xua0007492018-10-02 19:34:10 -0700319 * To be notified of changes to a specific subId, append subId to the URI
320 * {@link Uri#withAppendedPath(Uri, String)}.
321 * @hide
322 */
chen xu81653862019-02-28 10:44:54 -0800323 @NonNull
chen xua0007492018-10-02 19:34:10 -0700324 @SystemApi
325 public static final Uri WFC_ENABLED_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc");
326
327 /**
chen xu83a8fb52018-11-27 23:00:50 -0800328 * A content {@link Uri} used to receive updates on advanced calling user setting
329 * @see ImsMmTelManager#isAdvancedCallingSettingEnabled().
chen xua0007492018-10-02 19:34:10 -0700330 * <p>
331 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
chen xubf38b062018-11-01 00:08:37 -0700332 * subscription advanced calling enabled
333 * {@link ImsMmTelManager#isAdvancedCallingSettingEnabled()} while your app is running.
Makoto Onuki2da26292019-08-07 08:59:39 -0700334 * You can also use a {@link android.app.job.JobService} to ensure your app is notified of
335 * changes to the {@link Uri} even when it is not running.
336 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
337 * delivery of updates to the {@link Uri}.
chen xubf38b062018-11-01 00:08:37 -0700338 * To be notified of changes to a specific subId, append subId to the URI
339 * {@link Uri#withAppendedPath(Uri, String)}.
340 * @hide
341 */
chen xu81653862019-02-28 10:44:54 -0800342 @NonNull
chen xubf38b062018-11-01 00:08:37 -0700343 @SystemApi
344 public static final Uri ADVANCED_CALLING_ENABLED_CONTENT_URI = Uri.withAppendedPath(
345 CONTENT_URI, "advanced_calling");
346
347 /**
348 * A content {@link Uri} used to receive updates on wfc mode setting.
349 * <p>
350 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
351 * subscription wfc mode {@link ImsMmTelManager#getVoWiFiModeSetting()}
Makoto Onuki2da26292019-08-07 08:59:39 -0700352 * while your app is running. You can also use a {@link android.app.job.JobService} to ensure
353 * your app is notified of changes to the {@link Uri} even when it is not running.
354 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
355 * delivery of updates to the {@link Uri}.
chen xua0007492018-10-02 19:34:10 -0700356 * To be notified of changes to a specific subId, append subId to the URI
357 * {@link Uri#withAppendedPath(Uri, String)}.
358 * @hide
359 */
chen xu81653862019-02-28 10:44:54 -0800360 @NonNull
chen xua0007492018-10-02 19:34:10 -0700361 @SystemApi
chen xubf38b062018-11-01 00:08:37 -0700362 public static final Uri WFC_MODE_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc_mode");
chen xua0007492018-10-02 19:34:10 -0700363
chen xubf38b062018-11-01 00:08:37 -0700364 /**
365 * A content {@link Uri} used to receive updates on wfc roaming mode setting.
366 * <p>
367 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
368 * subscription wfc roaming mode {@link ImsMmTelManager#getVoWiFiRoamingModeSetting()}
Makoto Onuki2da26292019-08-07 08:59:39 -0700369 * while your app is running. You can also use a {@link android.app.job.JobService}
370 * to ensure your app is notified of changes to the {@link Uri} even when it is not running.
371 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
372 * delivery of updates to the {@link Uri}.
chen xubf38b062018-11-01 00:08:37 -0700373 * To be notified of changes to a specific subId, append subId to the URI
374 * {@link Uri#withAppendedPath(Uri, String)}.
375 * @hide
376 */
chen xu81653862019-02-28 10:44:54 -0800377 @NonNull
chen xubf38b062018-11-01 00:08:37 -0700378 @SystemApi
379 public static final Uri WFC_ROAMING_MODE_CONTENT_URI = Uri.withAppendedPath(
380 CONTENT_URI, "wfc_roaming_mode");
381
382 /**
383 * A content {@link Uri} used to receive updates on vt(video telephony over IMS) enabled
384 * setting.
385 * <p>
386 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
387 * subscription vt enabled {@link ImsMmTelManager#isVtSettingEnabled()}
Makoto Onuki2da26292019-08-07 08:59:39 -0700388 * while your app is running. You can also use a {@link android.app.job.JobService} to ensure
389 * your app is notified of changes to the {@link Uri} even when it is not running.
390 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
391 * delivery of updates to the {@link Uri}.
chen xubf38b062018-11-01 00:08:37 -0700392 * To be notified of changes to a specific subId, append subId to the URI
393 * {@link Uri#withAppendedPath(Uri, String)}.
394 * @hide
395 */
chen xu81653862019-02-28 10:44:54 -0800396 @NonNull
chen xubf38b062018-11-01 00:08:37 -0700397 @SystemApi
398 public static final Uri VT_ENABLED_CONTENT_URI = Uri.withAppendedPath(
399 CONTENT_URI, "vt_enabled");
400
401 /**
402 * A content {@link Uri} used to receive updates on wfc roaming enabled setting.
403 * <p>
404 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
405 * subscription wfc roaming enabled {@link ImsMmTelManager#isVoWiFiRoamingSettingEnabled()}
Makoto Onuki2da26292019-08-07 08:59:39 -0700406 * while your app is running. You can also use a {@link android.app.job.JobService} to ensure
407 * your app is notified of changes to the {@link Uri} even when it is not running.
408 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
409 * delivery of updates to the {@link Uri}.
chen xubf38b062018-11-01 00:08:37 -0700410 * To be notified of changes to a specific subId, append subId to the URI
411 * {@link Uri#withAppendedPath(Uri, String)}.
412 * @hide
413 */
chen xu81653862019-02-28 10:44:54 -0800414 @NonNull
chen xubf38b062018-11-01 00:08:37 -0700415 @SystemApi
416 public static final Uri WFC_ROAMING_ENABLED_CONTENT_URI = Uri.withAppendedPath(
417 CONTENT_URI, "wfc_roaming_enabled");
chen xua0007492018-10-02 19:34:10 -0700418
Jack Nudelmane2ea4282021-01-13 18:46:57 -0800419
420 /**
421 * A content {@link uri} used to call the appropriate backup or restore method for sim-specific
422 * settings
423 * <p>
424 * See {@link #GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME} and {@link
425 * #RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME} for information on what method to call.
426 * @hide
427 */
428 @NonNull
429 public static final Uri SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI = Uri.withAppendedPath(
430 CONTENT_URI, "backup_and_restore");
431
432 /**
433 * A content {@link uri} used to notify contentobservers listening to siminfo restore during
434 * SuW.
435 * @hide
436 */
437 @NonNull
438 public static final Uri SIM_INFO_SUW_RESTORE_CONTENT_URI = Uri.withAppendedPath(
439 SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI, "suw_restore");
440
Wink Savillefb40dd42014-06-12 17:02:31 -0700441 /**
Sooraj Sasindrand1610872020-11-23 19:33:52 -0800442 * A content {@link Uri} used to receive updates on cross sim enabled user setting.
443 * <p>
444 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
445 * subscription cross sim calling enabled
Sooraj Sasindran1bf22692021-03-10 16:45:27 -0800446 * {@link ImsMmTelManager#isCrossSimCallingEnabled()}
Sooraj Sasindrand1610872020-11-23 19:33:52 -0800447 * while your app is running. You can also use a {@link android.app.job.JobService}
448 * to ensure your app
449 * is notified of changes to the {@link Uri} even when it is not running.
450 * Note, however, that using a {@link android.app.job.JobService} does not guarantee timely
451 * delivery of updates to the {@link Uri}.
452 * To be notified of changes to a specific subId, append subId to the URI
453 * {@link Uri#withAppendedPath(Uri, String)}.
454 * @hide
455 */
456 @NonNull
457 @SystemApi
458 public static final Uri CROSS_SIM_ENABLED_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI,
459 SimInfo.COLUMN_CROSS_SIM_CALLING_ENABLED);
460
461 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -0800462 * TelephonyProvider unique key column name is the subscription id.
463 * <P>Type: TEXT (String)</P>
464 */
465 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800466 public static final String UNIQUE_KEY_SUBSCRIPTION_ID =
467 SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800468
469 /**
Vasu Noriaea03912018-09-04 11:19:59 -0700470 * TelephonyProvider column name for a unique identifier for the subscription within the
471 * specific subscription type. For example, it contains SIM ICC Identifier subscriptions
472 * on Local SIMs. and Mac-address for Remote-SIM Subscriptions for Bluetooth devices.
Wink Savillefb40dd42014-06-12 17:02:31 -0700473 * <P>Type: TEXT (String)</P>
474 */
Wink Savillef5bca082014-09-03 15:13:33 -0700475 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800476 public static final String ICC_ID = SimInfo.COLUMN_ICC_ID;
Wink Savillefb40dd42014-06-12 17:02:31 -0700477
478 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -0800479 * TelephonyProvider column name for user SIM_SlOT_INDEX
Wink Savillefb40dd42014-06-12 17:02:31 -0700480 * <P>Type: INTEGER (int)</P>
481 */
Wink Savillef5bca082014-09-03 15:13:33 -0700482 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800483 public static final String SIM_SLOT_INDEX = SimInfo.COLUMN_SIM_SLOT_INDEX;
Wink Saville905bb542014-09-04 17:10:23 -0700484
485 /** SIM is not inserted */
Wink Savillea374c3d2014-11-11 11:48:04 -0800486 /** @hide */
Peter Wang78af57d2019-11-25 16:50:50 -0800487 public static final int SIM_NOT_INSERTED = SimInfo.SIM_NOT_INSERTED;
Wink Savillefb40dd42014-06-12 17:02:31 -0700488
489 /**
Vasu Noriaea03912018-09-04 11:19:59 -0700490 * The slot-index for Bluetooth Remote-SIM subscriptions
491 * @hide
492 */
493 public static final int SLOT_INDEX_FOR_REMOTE_SIM_SUB = INVALID_SIM_SLOT_INDEX;
494
495 /**
496 * TelephonyProvider column name Subscription-type.
497 * <P>Type: INTEGER (int)</P> {@link #SUBSCRIPTION_TYPE_LOCAL_SIM} for Local-SIM Subscriptions,
498 * {@link #SUBSCRIPTION_TYPE_REMOTE_SIM} for Remote-SIM Subscriptions.
499 * Default value is 0.
500 */
501 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800502 public static final String SUBSCRIPTION_TYPE = SimInfo.COLUMN_SUBSCRIPTION_TYPE;
Malcolm Chen7611d692019-04-09 19:27:57 -0700503
504 /**
Ramya Manoharane88f8482022-04-21 05:02:14 +0000505 * TelephonyProvider column name for last used TP - message Reference
506 * <P>Type: INTEGER (int)</P> with -1 as default value
507 * TP - Message Reference valid range [0 - 255]
508 * @hide
509 */
510 public static final String TP_MESSAGE_REF = SimInfo.COLUMN_TP_MESSAGE_REF;
511
512 /**
Ling Ma640da902022-09-16 14:03:52 -0700513 * TelephonyProvider column name enabled_mobile_data_policies.
514 * A list of mobile data policies, each of which represented by an integer and joint by ",".
Jack Yua726a482019-05-23 16:37:35 -0700515 *
516 * Default value is empty string.
Jack Yua726a482019-05-23 16:37:35 -0700517 * @hide
518 */
Ling Ma640da902022-09-16 14:03:52 -0700519 public static final String ENABLED_MOBILE_DATA_POLICIES =
520 SimInfo.COLUMN_ENABLED_MOBILE_DATA_POLICIES;
Peter Wang78af57d2019-11-25 16:50:50 -0800521
522 /** @hide */
523 @Retention(RetentionPolicy.SOURCE)
524 @IntDef(prefix = {"SUBSCRIPTION_TYPE_"},
525 value = {
526 SUBSCRIPTION_TYPE_LOCAL_SIM,
527 SUBSCRIPTION_TYPE_REMOTE_SIM})
528 public @interface SubscriptionType {}
Jack Yua726a482019-05-23 16:37:35 -0700529
530 /**
Vasu Noriaea03912018-09-04 11:19:59 -0700531 * This constant is to designate a subscription as a Local-SIM Subscription.
532 * <p> A Local-SIM can be a physical SIM inserted into a sim-slot in the device, or eSIM on the
533 * device.
534 * </p>
535 */
Peter Wang78af57d2019-11-25 16:50:50 -0800536 public static final int SUBSCRIPTION_TYPE_LOCAL_SIM = SimInfo.SUBSCRIPTION_TYPE_LOCAL_SIM;
Vasu Noriaea03912018-09-04 11:19:59 -0700537
538 /**
539 * This constant is to designate a subscription as a Remote-SIM Subscription.
540 * <p>
541 * A Remote-SIM subscription is for a SIM on a phone connected to this device via some
542 * connectivity mechanism, for example bluetooth. Similar to Local SIM, this subscription can
543 * be used for SMS, Voice and data by proxying data through the connected device.
544 * Certain data of the SIM, such as IMEI, are not accessible for Remote SIMs.
545 * </p>
546 *
547 * <p>
548 * A Remote-SIM is available only as long the phone stays connected to this device.
549 * When the phone disconnects, Remote-SIM subscription is removed from this device and is
550 * no longer known. All data associated with the subscription, such as stored SMS, call logs,
551 * contacts etc, are removed from this device.
552 * </p>
553 *
554 * <p>
555 * If the phone re-connects to this device, a new Remote-SIM subscription is created for
556 * the phone. The Subscription Id associated with the new subscription is different from
557 * the Subscription Id of the previous Remote-SIM subscription created (and removed) for the
558 * phone; i.e., new Remote-SIM subscription treats the reconnected phone as a Remote-SIM that
559 * was never seen before.
560 * </p>
561 */
Peter Wang78af57d2019-11-25 16:50:50 -0800562 public static final int SUBSCRIPTION_TYPE_REMOTE_SIM = SimInfo.SUBSCRIPTION_TYPE_REMOTE_SIM;
Vasu Noriaea03912018-09-04 11:19:59 -0700563
564 /**
Wink Saville905bb542014-09-04 17:10:23 -0700565 * TelephonyProvider column name for user displayed name.
Wink Savillefb40dd42014-06-12 17:02:31 -0700566 * <P>Type: TEXT (String)</P>
567 */
Wink Savillef5bca082014-09-03 15:13:33 -0700568 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800569 public static final String DISPLAY_NAME = SimInfo.COLUMN_DISPLAY_NAME;
Wink Savillefb40dd42014-06-12 17:02:31 -0700570
Wink Saville905bb542014-09-04 17:10:23 -0700571 /**
Sanket Padawee1013f92014-11-07 11:37:29 -0800572 * TelephonyProvider column name for the service provider name for the SIM.
573 * <P>Type: TEXT (String)</P>
574 */
575 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800576 public static final String CARRIER_NAME = SimInfo.COLUMN_CARRIER_NAME;
Sanket Padawee1013f92014-11-07 11:37:29 -0800577
578 /**
Wink Saville905bb542014-09-04 17:10:23 -0700579 * Default name resource
580 * @hide
581 */
Wink Savillefb40dd42014-06-12 17:02:31 -0700582 public static final int DEFAULT_NAME_RES = com.android.internal.R.string.unknownName;
583
584 /**
Wink Saville905bb542014-09-04 17:10:23 -0700585 * TelephonyProvider column name for source of the user displayed name.
586 * <P>Type: INT (int)</P> with one of the NAME_SOURCE_XXXX values below
587 *
588 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -0700589 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800590 public static final String NAME_SOURCE = SimInfo.COLUMN_NAME_SOURCE;
Wink Savillefb40dd42014-06-12 17:02:31 -0700591
Wink Saville905bb542014-09-04 17:10:23 -0700592 /**
Jack Yu59ca6fc2022-10-07 23:06:20 -0700593 * The name_source is unknown. (for initialization)
594 * @hide
595 */
596 public static final int NAME_SOURCE_UNKNOWN = SimInfo.NAME_SOURCE_UNKNOWN;
597
598 /**
Peter Wang0ddf4402020-01-31 18:46:26 -0800599 * The name_source is from the carrier id.
Wink Saville905bb542014-09-04 17:10:23 -0700600 * @hide
601 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800602 public static final int NAME_SOURCE_CARRIER_ID = SimInfo.NAME_SOURCE_CARRIER_ID;
Wink Savillefb40dd42014-06-12 17:02:31 -0700603
Wink Saville905bb542014-09-04 17:10:23 -0700604 /**
Jack Yu5c6eb0e2019-10-16 09:16:54 -0700605 * The name_source is from SIM EF_SPN.
Wink Saville905bb542014-09-04 17:10:23 -0700606 * @hide
607 */
Peter Wang78af57d2019-11-25 16:50:50 -0800608 public static final int NAME_SOURCE_SIM_SPN = SimInfo.NAME_SOURCE_SIM_SPN;
Wink Savillec650e0b2014-09-02 22:37:08 -0700609
Wink Saville905bb542014-09-04 17:10:23 -0700610 /**
Jack Yu5c6eb0e2019-10-16 09:16:54 -0700611 * The name_source is from user input
Wink Saville905bb542014-09-04 17:10:23 -0700612 * @hide
613 */
Mathew Inwood45d2c252018-09-14 12:35:36 +0100614 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Peter Wang78af57d2019-11-25 16:50:50 -0800615 public static final int NAME_SOURCE_USER_INPUT = SimInfo.NAME_SOURCE_USER_INPUT;
Wink Savillefb40dd42014-06-12 17:02:31 -0700616
617 /**
Amit Mahajanecdf8c52019-05-14 10:36:15 -0700618 * The name_source is carrier (carrier app, carrier config, etc.)
619 * @hide
620 */
Peter Wang78af57d2019-11-25 16:50:50 -0800621 public static final int NAME_SOURCE_CARRIER = SimInfo.NAME_SOURCE_CARRIER;
Amit Mahajanecdf8c52019-05-14 10:36:15 -0700622
623 /**
Jack Yu5c6eb0e2019-10-16 09:16:54 -0700624 * The name_source is from SIM EF_PNN.
625 * @hide
626 */
Peter Wang78af57d2019-11-25 16:50:50 -0800627 public static final int NAME_SOURCE_SIM_PNN = SimInfo.NAME_SOURCE_SIM_PNN;
Jack Yu5c6eb0e2019-10-16 09:16:54 -0700628
629 /** @hide */
630 @Retention(RetentionPolicy.SOURCE)
631 @IntDef(prefix = {"NAME_SOURCE_"},
632 value = {
Jack Yu59ca6fc2022-10-07 23:06:20 -0700633 NAME_SOURCE_UNKNOWN,
Peter Wang0ddf4402020-01-31 18:46:26 -0800634 NAME_SOURCE_CARRIER_ID,
Jack Yu5c6eb0e2019-10-16 09:16:54 -0700635 NAME_SOURCE_SIM_SPN,
636 NAME_SOURCE_USER_INPUT,
637 NAME_SOURCE_CARRIER,
638 NAME_SOURCE_SIM_PNN
639 })
640 public @interface SimDisplayNameSource {}
641
642 /**
Grace Jiab53cb662021-02-12 15:29:29 -0800643 * Device status is not shared to a remote party.
644 */
645 public static final int D2D_SHARING_DISABLED = 0;
646
647 /**
648 * Device status is shared with all numbers in the user's contacts.
649 */
650 public static final int D2D_SHARING_ALL_CONTACTS = 1;
651
652 /**
Grace Jia2bd23cf2021-03-18 14:47:31 -0700653 * Device status is shared with all selected contacts.
Grace Jiab53cb662021-02-12 15:29:29 -0800654 */
Grace Jia2bd23cf2021-03-18 14:47:31 -0700655 public static final int D2D_SHARING_SELECTED_CONTACTS = 2;
Grace Jiab53cb662021-02-12 15:29:29 -0800656
657 /**
658 * Device status is shared whenever possible.
659 */
660 public static final int D2D_SHARING_ALL = 3;
661
662 /** @hide */
663 @Retention(RetentionPolicy.SOURCE)
664 @IntDef(prefix = {"D2D_SHARING_"},
665 value = {
666 D2D_SHARING_DISABLED,
667 D2D_SHARING_ALL_CONTACTS,
Grace Jia2bd23cf2021-03-18 14:47:31 -0700668 D2D_SHARING_SELECTED_CONTACTS,
Grace Jiab53cb662021-02-12 15:29:29 -0800669 D2D_SHARING_ALL
670 })
Grace Jiaaeea4ec2021-03-10 14:00:43 -0800671 public @interface DeviceToDeviceStatusSharingPreference {}
Grace Jiab53cb662021-02-12 15:29:29 -0800672
673 /**
674 * TelephonyProvider column name for device to device sharing status.
675 * <P>Type: INTEGER (int)</P>
676 */
677 public static final String D2D_STATUS_SHARING = SimInfo.COLUMN_D2D_STATUS_SHARING;
678
679 /**
Grace Jia2bd23cf2021-03-18 14:47:31 -0700680 * TelephonyProvider column name for contacts information that allow device to device sharing.
681 * <P>Type: TEXT (String)</P>
682 */
683 public static final String D2D_STATUS_SHARING_SELECTED_CONTACTS =
684 SimInfo.COLUMN_D2D_STATUS_SHARING_SELECTED_CONTACTS;
685
686 /**
Wink Saville905bb542014-09-04 17:10:23 -0700687 * TelephonyProvider column name for the color of a SIM.
Wink Savillefb40dd42014-06-12 17:02:31 -0700688 * <P>Type: INTEGER (int)</P>
689 */
Wink Savillef5bca082014-09-03 15:13:33 -0700690 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800691 public static final String HUE = SimInfo.COLUMN_COLOR;
Wink Savillefb40dd42014-06-12 17:02:31 -0700692
693 /**
Wink Saville905bb542014-09-04 17:10:23 -0700694 * TelephonyProvider column name for the phone number of a SIM.
Wink Savillefb40dd42014-06-12 17:02:31 -0700695 * <P>Type: TEXT (String)</P>
696 */
Wink Savillef5bca082014-09-03 15:13:33 -0700697 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800698 public static final String NUMBER = SimInfo.COLUMN_NUMBER;
Wink Savillefb40dd42014-06-12 17:02:31 -0700699
700 /**
Peter Wang78af57d2019-11-25 16:50:50 -0800701 * TelephonyProvider column name for whether data roaming is enabled.
Wink Savillefb40dd42014-06-12 17:02:31 -0700702 * <P>Type: INTEGER (int)</P>
703 */
Wink Savillef5bca082014-09-03 15:13:33 -0700704 /** @hide */
Peter Wang0ddf4402020-01-31 18:46:26 -0800705 public static final String DATA_ROAMING = SimInfo.COLUMN_DATA_ROAMING;
Wink Savillefb40dd42014-06-12 17:02:31 -0700706
Stuart Scott400a3f62015-01-14 10:49:49 -0800707 /** Indicates that data roaming is enabled for a subscription */
Peter Wang78af57d2019-11-25 16:50:50 -0800708 public static final int DATA_ROAMING_ENABLE = SimInfo.DATA_ROAMING_ENABLE;
Wink Savillefb40dd42014-06-12 17:02:31 -0700709
Stuart Scott400a3f62015-01-14 10:49:49 -0800710 /** Indicates that data roaming is disabled for a subscription */
Peter Wang78af57d2019-11-25 16:50:50 -0800711 public static final int DATA_ROAMING_DISABLE = SimInfo.DATA_ROAMING_DISABLE;
Wink Savillefb40dd42014-06-12 17:02:31 -0700712
Tom Taylor7a962072014-09-04 14:05:20 -0700713 /**
chen xu64e81db2018-12-14 00:14:06 -0800714 * TelephonyProvider column name for subscription carrier id.
715 * @see TelephonyManager#getSimCarrierId()
716 * <p>Type: INTEGER (int) </p>
717 * @hide
718 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800719 public static final String CARRIER_ID = SimInfo.COLUMN_CARRIER_ID;
chen xu64e81db2018-12-14 00:14:06 -0800720
721 /**
Hall Liue0ac1f72019-04-11 15:28:20 -0700722 * @hide A comma-separated list of EHPLMNs associated with the subscription
723 * <P>Type: TEXT (String)</P>
724 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800725 public static final String EHPLMNS = SimInfo.COLUMN_EHPLMNS;
Hall Liue0ac1f72019-04-11 15:28:20 -0700726
727 /**
728 * @hide A comma-separated list of HPLMNs associated with the subscription
729 * <P>Type: TEXT (String)</P>
730 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800731 public static final String HPLMNS = SimInfo.COLUMN_HPLMNS;
Hall Liue0ac1f72019-04-11 15:28:20 -0700732
733 /**
Hall Liu0c149bd2018-06-08 18:14:21 -0700734 * TelephonyProvider column name for the MCC associated with a SIM, stored as a string.
735 * <P>Type: TEXT (String)</P>
736 * @hide
737 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800738 public static final String MCC_STRING = SimInfo.COLUMN_MCC_STRING;
Hall Liu0c149bd2018-06-08 18:14:21 -0700739
740 /**
741 * TelephonyProvider column name for the MNC associated with a SIM, stored as a string.
742 * <P>Type: TEXT (String)</P>
743 * @hide
744 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800745 public static final String MNC_STRING = SimInfo.COLUMN_MNC_STRING;
Hall Liu0c149bd2018-06-08 18:14:21 -0700746
747 /**
Wink Saville905bb542014-09-04 17:10:23 -0700748 * TelephonyProvider column name for the MCC associated with a SIM.
Tom Taylor7a962072014-09-04 14:05:20 -0700749 * <P>Type: INTEGER (int)</P>
Wink Savillea374c3d2014-11-11 11:48:04 -0800750 * @hide
Tom Taylor7a962072014-09-04 14:05:20 -0700751 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800752 public static final String MCC = SimInfo.COLUMN_MCC;
Tom Taylor7a962072014-09-04 14:05:20 -0700753
754 /**
Wink Saville905bb542014-09-04 17:10:23 -0700755 * TelephonyProvider column name for the MNC associated with a SIM.
Tom Taylor7a962072014-09-04 14:05:20 -0700756 * <P>Type: INTEGER (int)</P>
Wink Savillea374c3d2014-11-11 11:48:04 -0800757 * @hide
Tom Taylor7a962072014-09-04 14:05:20 -0700758 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800759 public static final String MNC = SimInfo.COLUMN_MNC;
Tom Taylor7a962072014-09-04 14:05:20 -0700760
Wink Savillec650e0b2014-09-02 22:37:08 -0700761 /**
chen xua2618622018-12-02 14:14:15 -0800762 * TelephonyProvider column name for the iso country code associated with a SIM.
763 * <P>Type: TEXT (String)</P>
764 * @hide
765 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800766 public static final String ISO_COUNTRY_CODE = SimInfo.COLUMN_ISO_COUNTRY_CODE;
chen xua2618622018-12-02 14:14:15 -0800767
768 /**
Jeff Davidsond02731f2017-04-09 14:31:09 -0700769 * TelephonyProvider column name for whether a subscription is embedded (that is, present on an
770 * eSIM).
771 * <p>Type: INTEGER (int), 1 for embedded or 0 for non-embedded.
772 * @hide
773 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800774 public static final String IS_EMBEDDED = SimInfo.COLUMN_IS_EMBEDDED;
Jeff Davidsond02731f2017-04-09 14:31:09 -0700775
776 /**
yinxu921daf92018-01-05 11:15:24 -0800777 * TelephonyProvider column name for SIM card identifier. For UICC card it is the ICCID of the
778 * current enabled profile on the card, while for eUICC card it is the EID of the card.
779 * <P>Type: TEXT (String)</P>
780 * @hide
781 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800782 public static final String CARD_ID = SimInfo.COLUMN_CARD_ID;
yinxu921daf92018-01-05 11:15:24 -0800783
784 /**
Jeff Davidsond02731f2017-04-09 14:31:09 -0700785 * TelephonyProvider column name for the encoded {@link UiccAccessRule}s from
786 * {@link UiccAccessRule#encodeRules}. Only present if {@link #IS_EMBEDDED} is 1.
787 * <p>TYPE: BLOB
788 * @hide
789 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800790 public static final String ACCESS_RULES = SimInfo.COLUMN_ACCESS_RULES;
Jeff Davidsond02731f2017-04-09 14:31:09 -0700791
792 /**
Nazanin Bakhshi693cec22019-08-02 16:43:44 -0700793 * TelephonyProvider column name for the encoded {@link UiccAccessRule}s from
794 * {@link UiccAccessRule#encodeRules} but for the rules that come from CarrierConfigs.
795 * Only present if there are access rules in CarrierConfigs
796 * <p>TYPE: BLOB
797 * @hide
798 */
799 public static final String ACCESS_RULES_FROM_CARRIER_CONFIGS =
Peter Wang0ddf4402020-01-31 18:46:26 -0800800 SimInfo.COLUMN_ACCESS_RULES_FROM_CARRIER_CONFIGS;
Nazanin Bakhshi693cec22019-08-02 16:43:44 -0700801
802 /**
Jeff Davidsond02731f2017-04-09 14:31:09 -0700803 * TelephonyProvider column name identifying whether an embedded subscription is on a removable
804 * card. Such subscriptions are marked inaccessible as soon as the current card is removed.
805 * Otherwise, they will remain accessible unless explicitly deleted. Only present if
806 * {@link #IS_EMBEDDED} is 1.
807 * <p>TYPE: INTEGER (int), 1 for removable or 0 for non-removable.
808 * @hide
809 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800810 public static final String IS_REMOVABLE = SimInfo.COLUMN_IS_REMOVABLE;
Jeff Davidsond02731f2017-04-09 14:31:09 -0700811
812 /**
Sanket Padawedc493092015-07-14 14:21:43 -0700813 * TelephonyProvider column name for extreme threat in CB settings
814 * @hide
815 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800816 public static final String CB_EXTREME_THREAT_ALERT =
817 SimInfo.COLUMN_CB_EXTREME_THREAT_ALERT;
Sanket Padawedc493092015-07-14 14:21:43 -0700818
819 /**
820 * TelephonyProvider column name for severe threat in CB settings
821 *@hide
822 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800823 public static final String CB_SEVERE_THREAT_ALERT = SimInfo.COLUMN_CB_SEVERE_THREAT_ALERT;
Sanket Padawedc493092015-07-14 14:21:43 -0700824
825 /**
826 * TelephonyProvider column name for amber alert in CB settings
827 *@hide
828 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800829 public static final String CB_AMBER_ALERT = SimInfo.COLUMN_CB_AMBER_ALERT;
Sanket Padawedc493092015-07-14 14:21:43 -0700830
831 /**
832 * TelephonyProvider column name for emergency alert in CB settings
833 *@hide
834 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800835 public static final String CB_EMERGENCY_ALERT = SimInfo.COLUMN_CB_EMERGENCY_ALERT;
Sanket Padawedc493092015-07-14 14:21:43 -0700836
837 /**
838 * TelephonyProvider column name for alert sound duration in CB settings
839 *@hide
840 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800841 public static final String CB_ALERT_SOUND_DURATION =
842 SimInfo.COLUMN_CB_ALERT_SOUND_DURATION;
Sanket Padawedc493092015-07-14 14:21:43 -0700843
844 /**
845 * TelephonyProvider column name for alert reminder interval in CB settings
846 *@hide
847 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800848 public static final String CB_ALERT_REMINDER_INTERVAL =
849 SimInfo.COLUMN_CB_ALERT_REMINDER_INTERVAL;
Sanket Padawedc493092015-07-14 14:21:43 -0700850
851 /**
852 * TelephonyProvider column name for enabling vibrate in CB settings
853 *@hide
854 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800855 public static final String CB_ALERT_VIBRATE = SimInfo.COLUMN_CB_ALERT_VIBRATE;
Sanket Padawedc493092015-07-14 14:21:43 -0700856
857 /**
858 * TelephonyProvider column name for enabling alert speech in CB settings
859 *@hide
860 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800861 public static final String CB_ALERT_SPEECH = SimInfo.COLUMN_CB_ALERT_SPEECH;
Sanket Padawedc493092015-07-14 14:21:43 -0700862
863 /**
864 * TelephonyProvider column name for ETWS test alert in CB settings
865 *@hide
866 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800867 public static final String CB_ETWS_TEST_ALERT = SimInfo.COLUMN_CB_ETWS_TEST_ALERT;
Sanket Padawedc493092015-07-14 14:21:43 -0700868
869 /**
870 * TelephonyProvider column name for enable channel50 alert in CB settings
871 *@hide
872 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800873 public static final String CB_CHANNEL_50_ALERT = SimInfo.COLUMN_CB_CHANNEL_50_ALERT;
Sanket Padawedc493092015-07-14 14:21:43 -0700874
875 /**
876 * TelephonyProvider column name for CMAS test alert in CB settings
877 *@hide
878 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800879 public static final String CB_CMAS_TEST_ALERT = SimInfo.COLUMN_CB_CMAS_TEST_ALERT;
Sanket Padawedc493092015-07-14 14:21:43 -0700880
881 /**
882 * TelephonyProvider column name for Opt out dialog in CB settings
883 *@hide
884 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800885 public static final String CB_OPT_OUT_DIALOG = SimInfo.COLUMN_CB_OPT_OUT_DIALOG;
Sanket Padawedc493092015-07-14 14:21:43 -0700886
887 /**
Malcolm Chenc66dee92017-09-26 14:45:40 -0700888 * TelephonyProvider column name for enable Volte.
Jordan Liud6350112017-11-14 13:45:19 -0800889 *
890 * If this setting is not initialized (set to -1) then we use the Carrier Config value
891 * {@link CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL}.
Malcolm Chenc66dee92017-09-26 14:45:40 -0700892 *@hide
893 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800894 public static final String ENHANCED_4G_MODE_ENABLED =
895 SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED;
Malcolm Chenc66dee92017-09-26 14:45:40 -0700896
897 /**
898 * TelephonyProvider column name for enable VT (Video Telephony over IMS)
899 *@hide
900 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800901 public static final String VT_IMS_ENABLED = SimInfo.COLUMN_VT_IMS_ENABLED;
Malcolm Chenc66dee92017-09-26 14:45:40 -0700902
903 /**
904 * TelephonyProvider column name for enable Wifi calling
905 *@hide
906 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800907 public static final String WFC_IMS_ENABLED = SimInfo.COLUMN_WFC_IMS_ENABLED;
Malcolm Chenc66dee92017-09-26 14:45:40 -0700908
909 /**
910 * TelephonyProvider column name for Wifi calling mode
911 *@hide
912 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800913 public static final String WFC_IMS_MODE = SimInfo.COLUMN_WFC_IMS_MODE;
Malcolm Chenc66dee92017-09-26 14:45:40 -0700914
915 /**
916 * TelephonyProvider column name for Wifi calling mode in roaming
917 *@hide
918 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800919 public static final String WFC_IMS_ROAMING_MODE = SimInfo.COLUMN_WFC_IMS_ROAMING_MODE;
Malcolm Chenc66dee92017-09-26 14:45:40 -0700920
921 /**
922 * TelephonyProvider column name for enable Wifi calling in roaming
923 *@hide
924 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800925 public static final String WFC_IMS_ROAMING_ENABLED = SimInfo.COLUMN_WFC_IMS_ROAMING_ENABLED;
Malcolm Chenc66dee92017-09-26 14:45:40 -0700926
927 /**
Brad Ebinger41c232c2020-01-22 16:09:57 -0800928 * Determines if the user has enabled IMS RCS User Capability Exchange (UCE) for this
929 * subscription.
930 * @hide
931 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800932 public static final String IMS_RCS_UCE_ENABLED = SimInfo.COLUMN_IMS_RCS_UCE_ENABLED;
Brad Ebinger41c232c2020-01-22 16:09:57 -0800933
934 /**
Jack Yuea905072020-11-17 19:48:31 -0800935 * Determines if the user has enabled cross SIM calling for this subscription.
936 *
937 * @hide
938 */
939 public static final String CROSS_SIM_CALLING_ENABLED = SimInfo.COLUMN_CROSS_SIM_CALLING_ENABLED;
940
941 /**
Malcolm Chen0ac24ef2018-08-07 15:03:32 -0700942 * TelephonyProvider column name for whether a subscription is opportunistic, that is,
943 * whether the network it connects to is limited in functionality or coverage.
944 * For example, CBRS.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -0700945 * <p>Type: INTEGER (int), 1 for opportunistic or 0 for non-opportunistic.
946 * @hide
947 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800948 public static final String IS_OPPORTUNISTIC = SimInfo.COLUMN_IS_OPPORTUNISTIC;
Malcolm Chen52f6dff2018-11-28 11:15:57 -0800949
Malcolm Chen0ac24ef2018-08-07 15:03:32 -0700950 /**
Malcolm Chenaea9b022018-10-31 20:18:02 -0700951 * TelephonyProvider column name for group ID. Subscriptions with same group ID
952 * are considered bundled together, and should behave as a single subscription at
953 * certain scenarios.
954 *
955 * @hide
956 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800957 public static final String GROUP_UUID = SimInfo.COLUMN_GROUP_UUID;
Malcolm Chen52f6dff2018-11-28 11:15:57 -0800958
Nazanin Bakhshib9b87be2018-11-21 16:32:05 -0800959 /**
Malcolm Chen0b9b81b2019-03-29 17:13:08 -0700960 * TelephonyProvider column name for group owner. It's the package name who created
961 * the subscription group.
962 *
963 * @hide
964 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800965 public static final String GROUP_OWNER = SimInfo.COLUMN_GROUP_OWNER;
Malcolm Chen52f6dff2018-11-28 11:15:57 -0800966
Malcolm Chenaea9b022018-10-31 20:18:02 -0700967 /**
Grace Chen5be6e9c2018-12-20 22:50:18 -0800968 * TelephonyProvider column name for the profile class of a subscription
969 * Only present if {@link #IS_EMBEDDED} is 1.
970 * <P>Type: INTEGER (int)</P>
971 * @hide
972 */
Peter Wang0ddf4402020-01-31 18:46:26 -0800973 public static final String PROFILE_CLASS = SimInfo.COLUMN_PROFILE_CLASS;
Grace Chen5be6e9c2018-12-20 22:50:18 -0800974
975 /**
Muralidhar Reddy090a67a2021-12-10 21:11:28 +0000976 * TelephonyProvider column name for the port index of the active UICC port.
977 * <P>Type: INTEGER (int)</P>
978 * @hide
979 */
980 public static final String PORT_INDEX = SimInfo.COLUMN_PORT_INDEX;
981
982 /**
Jayachandran Chinnakkannu2cdad9f2021-02-18 20:55:44 +0800983 * TelephonyProvider column name for VoIMS opt-in status.
984 *
985 * <P>Type: INTEGER (int)</P>
986 * @hide
987 */
988 public static final String VOIMS_OPT_IN_STATUS = SimInfo.COLUMN_VOIMS_OPT_IN_STATUS;
989
990 /**
Gary Jian204ec2a2021-10-13 13:09:54 +0800991 * TelephonyProvider column name for NR Advanced calling
992 * Determines if the user has enabled VoNR settings for this subscription.
993 *
994 * @hide
995 */
996 public static final String NR_ADVANCED_CALLING_ENABLED =
997 SimInfo.COLUMN_NR_ADVANCED_CALLING_ENABLED;
998
999 /**
Grace Chen5be6e9c2018-12-20 22:50:18 -08001000 * Profile class of the subscription
1001 * @hide
1002 */
1003 @Retention(RetentionPolicy.SOURCE)
1004 @IntDef(prefix = { "PROFILE_CLASS_" }, value = {
Peter Wang78af57d2019-11-25 16:50:50 -08001005 SimInfo.PROFILE_CLASS_TESTING,
1006 SimInfo.PROFILE_CLASS_PROVISIONING,
1007 SimInfo.PROFILE_CLASS_OPERATIONAL,
1008 SimInfo.PROFILE_CLASS_UNSET,
Grace Chen5be6e9c2018-12-20 22:50:18 -08001009 })
1010 public @interface ProfileClass {}
1011
1012 /**
1013 * A testing profile can be pre-loaded or downloaded onto
1014 * the eUICC and provides connectivity to test equipment
1015 * for the purpose of testing the device and the eUICC. It
1016 * is not intended to store any operator credentials.
1017 * @hide
1018 */
1019 @SystemApi
Peter Wang78af57d2019-11-25 16:50:50 -08001020 public static final int PROFILE_CLASS_TESTING = SimInfo.PROFILE_CLASS_TESTING;
Grace Chen5be6e9c2018-12-20 22:50:18 -08001021
1022 /**
1023 * A provisioning profile is pre-loaded onto the eUICC and
1024 * provides connectivity to a mobile network solely for the
1025 * purpose of provisioning profiles.
1026 * @hide
1027 */
1028 @SystemApi
Peter Wang78af57d2019-11-25 16:50:50 -08001029 public static final int PROFILE_CLASS_PROVISIONING = SimInfo.PROFILE_CLASS_PROVISIONING;
Grace Chen5be6e9c2018-12-20 22:50:18 -08001030
1031 /**
1032 * An operational profile can be pre-loaded or downloaded
1033 * onto the eUICC and provides services provided by the
1034 * operator.
1035 * @hide
1036 */
1037 @SystemApi
Peter Wang78af57d2019-11-25 16:50:50 -08001038 public static final int PROFILE_CLASS_OPERATIONAL = SimInfo.PROFILE_CLASS_OPERATIONAL;
Grace Chen5be6e9c2018-12-20 22:50:18 -08001039
1040 /**
1041 * The profile class is unset. This occurs when profile class
1042 * info is not available. The subscription either has no profile
1043 * metadata or the profile metadata did not encode profile class.
1044 * @hide
1045 */
1046 @SystemApi
Peter Wang78af57d2019-11-25 16:50:50 -08001047 public static final int PROFILE_CLASS_UNSET = SimInfo.PROFILE_CLASS_UNSET;
Grace Chen5be6e9c2018-12-20 22:50:18 -08001048
1049 /**
1050 * Default profile class
1051 * @hide
1052 */
1053 @SystemApi
Peter Wang0ddf4402020-01-31 18:46:26 -08001054 @Deprecated
1055 public static final int PROFILE_CLASS_DEFAULT = SimInfo.PROFILE_CLASS_UNSET;
Grace Chen5be6e9c2018-12-20 22:50:18 -08001056
1057 /**
Nazanin Bakhshi1eaf7a82019-05-31 16:34:10 -07001058 * IMSI (International Mobile Subscriber Identity).
1059 * <P>Type: TEXT </P>
1060 * @hide
1061 */
1062 //TODO: add @SystemApi
Peter Wang0ddf4402020-01-31 18:46:26 -08001063 public static final String IMSI = SimInfo.COLUMN_IMSI;
Nazanin Bakhshi1eaf7a82019-05-31 16:34:10 -07001064
1065 /**
Malcolm Chenb7c6ee382019-12-04 19:07:56 -08001066 * Whether uicc applications is set to be enabled or disabled. By default it's enabled.
1067 * @hide
1068 */
Peter Wang0ddf4402020-01-31 18:46:26 -08001069 public static final String UICC_APPLICATIONS_ENABLED = SimInfo.COLUMN_UICC_APPLICATIONS_ENABLED;
Malcolm Chenb7c6ee382019-12-04 19:07:56 -08001070
1071 /**
Nathan Haroldbd5f0d92021-11-02 19:20:56 -07001072 * Indicate which network type is allowed.
calvinpand77e0bd2020-01-14 20:37:31 +08001073 * @hide
1074 */
SongFerngWang7d951852020-12-21 16:24:25 +08001075 public static final String ALLOWED_NETWORK_TYPES =
1076 SimInfo.COLUMN_ALLOWED_NETWORK_TYPES_FOR_REASONS;
calvinpand77e0bd2020-01-14 20:37:31 +08001077
Aishwarya Mallampati747cef72022-09-20 22:51:48 +00001078 /**
1079 * TelephonyProvider column name for user handle associated with a sim.
1080 * <P>Type: INTEGER (int)</P>
1081 * @hide
1082 */
1083 public static final String USER_HANDLE = SimInfo.COLUMN_USER_HANDLE;
1084
Nathan Harold7e2d58a2021-11-02 16:32:06 -07001085 /** @hide */
1086 @Retention(RetentionPolicy.SOURCE)
1087 @IntDef(prefix = {"USAGE_SETTING_"},
1088 value = {
1089 USAGE_SETTING_UNKNOWN,
1090 USAGE_SETTING_DEFAULT,
1091 USAGE_SETTING_VOICE_CENTRIC,
1092 USAGE_SETTING_DATA_CENTRIC})
1093 public @interface UsageSetting {}
1094
1095 /**
1096 * The usage setting is unknown.
1097 *
1098 * This will be the usage setting returned on devices that do not support querying the
1099 * or setting the usage setting.
1100 *
1101 * It may also be provided by a carrier that wishes to provide a value to avoid making any
1102 * settings changes.
Nathan Harold7e2d58a2021-11-02 16:32:06 -07001103 */
1104 public static final int USAGE_SETTING_UNKNOWN = -1;
1105
1106 /**
1107 * Subscription uses the default setting.
1108 *
1109 * The value is based upon device capability and the other properties of the subscription.
1110 *
1111 * Most subscriptions will default to voice-centric when in a phone.
1112 *
1113 * An opportunistic subscription will default to data-centric.
1114 *
1115 * {@see SubscriptionInfo#isOpportunistic}
Nathan Harold7e2d58a2021-11-02 16:32:06 -07001116 */
1117 public static final int USAGE_SETTING_DEFAULT = 0;
1118
1119 /**
1120 * This subscription is forced to voice-centric mode
1121 *
Nathan Harolddff34b32021-12-15 16:38:25 -08001122 * <p>Refer to voice-centric mode in 3gpp 24.301 sec 4.3 and 3gpp 24.501 sec 4.3.
1123 * Also refer to "UE's usage setting" as defined in 3gpp 24.301 section 3.1 and 3gpp 23.221
1124 * Annex A.
Nathan Haroldb36dcb02022-03-25 13:51:55 -07001125 *
1126 * <p>Devices that support {@link PackageManager#FEATURE_TELEPHONY_CALLING} and support usage
1127 * setting configuration must support setting this value via
1128 * {@link CarrierConfigManager#KEY_CELLULAR_USAGE_SETTING_INT}.
Nathan Harold7e2d58a2021-11-02 16:32:06 -07001129 */
1130 public static final int USAGE_SETTING_VOICE_CENTRIC = 1;
1131
1132 /**
1133 * This subscription is forced to data-centric mode
1134 *
Nathan Harolddff34b32021-12-15 16:38:25 -08001135 * <p>Refer to data-centric mode in 3gpp 24.301 sec 4.3 and 3gpp 24.501 sec 4.3.
1136 * Also refer to "UE's usage setting" as defined in 3gpp 24.301 section 3.1 and 3gpp 23.221
1137 * Annex A.
Nathan Haroldb36dcb02022-03-25 13:51:55 -07001138 *
1139 * <p>Devices that support {@link PackageManager#FEATURE_TELEPHONY_DATA} and support usage
1140 * setting configuration must support setting this value via.
1141 * {@link CarrierConfigManager#KEY_CELLULAR_USAGE_SETTING_INT}.
Nathan Harold7e2d58a2021-11-02 16:32:06 -07001142 */
1143 public static final int USAGE_SETTING_DATA_CENTRIC = 2;
1144
calvinpand77e0bd2020-01-14 20:37:31 +08001145 /**
Nathan Haroldbd5f0d92021-11-02 19:20:56 -07001146 * Indicate the preferred usage setting for the subscription.
1147 *
1148 * 0 - Default - If the value has not been explicitly set, it will be "default"
1149 * 1 - Voice-centric
1150 * 2 - Data-centric
1151 *
1152 * @hide
1153 */
1154 public static final String USAGE_SETTING = SimInfo.COLUMN_USAGE_SETTING;
1155
1156 /**
Wink Savillec650e0b2014-09-02 22:37:08 -07001157 * Broadcast Action: The user has changed one of the default subs related to
1158 * data, phone calls, or sms</p>
Wink Savilled09c4ca2014-11-22 10:08:16 -08001159 *
1160 * TODO: Change to a listener
Wink Savillef5bca082014-09-03 15:13:33 -07001161 * @hide
Wink Savillec650e0b2014-09-02 22:37:08 -07001162 */
1163 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1164 public static final String SUB_DEFAULT_CHANGED_ACTION =
Rajeev Kumarc8ac4f3b2017-07-26 15:59:08 -07001165 "android.intent.action.SUB_DEFAULT_CHANGED";
Wink Savillefb40dd42014-06-12 17:02:31 -07001166
Malcolm Chen598d24c2017-04-24 18:37:29 -07001167 /**
1168 * Broadcast Action: The default subscription has changed. This has the following
1169 * extra values:</p>
1170 * The {@link #EXTRA_SUBSCRIPTION_INDEX} extra indicates the current default subscription index
1171 */
1172 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1173 public static final String ACTION_DEFAULT_SUBSCRIPTION_CHANGED
1174 = "android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED";
1175
1176 /**
1177 * Broadcast Action: The default sms subscription has changed. This has the following
1178 * extra values:</p>
1179 * {@link #EXTRA_SUBSCRIPTION_INDEX} extra indicates the current default sms
1180 * subscription index
1181 */
1182 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1183 public static final String ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED
1184 = "android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED";
1185
1186 /**
Jeff Sharkey717f52f2018-01-04 16:04:11 -07001187 * Activity Action: Display UI for managing the billing relationship plans
1188 * between a carrier and a specific subscriber.
1189 * <p>
1190 * Carrier apps are encouraged to implement this activity, and the OS will
1191 * provide an affordance to quickly enter this activity, typically via
1192 * Settings. This affordance will only be shown when the carrier app is
1193 * actively providing subscription plan information via
1194 * {@link #setSubscriptionPlans(int, List)}.
1195 * <p>
1196 * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
1197 * the user is interested in.
Jeff Sharkey717f52f2018-01-04 16:04:11 -07001198 */
1199 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
Jeff Sharkey717f52f2018-01-04 16:04:11 -07001200 public static final String ACTION_MANAGE_SUBSCRIPTION_PLANS
1201 = "android.telephony.action.MANAGE_SUBSCRIPTION_PLANS";
1202
1203 /**
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07001204 * Broadcast Action: Request a refresh of the billing relationship plans
1205 * between a carrier and a specific subscriber.
1206 * <p>
1207 * Carrier apps are encouraged to implement this receiver, and the OS will
1208 * provide an affordance to request a refresh. This affordance will only be
1209 * shown when the carrier app is actively providing subscription plan
1210 * information via {@link #setSubscriptionPlans(int, List)}.
1211 * <p>
1212 * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
1213 * the user is interested in.
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06001214 * <p>
1215 * Receivers should protect themselves by checking that the sender holds the
1216 * {@code android.permission.MANAGE_SUBSCRIPTION_PLANS} permission.
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07001217 */
1218 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07001219 public static final String ACTION_REFRESH_SUBSCRIPTION_PLANS
1220 = "android.telephony.action.REFRESH_SUBSCRIPTION_PLANS";
1221
1222 /**
1223 * Broadcast Action: The billing relationship plans between a carrier and a
1224 * specific subscriber has changed.
1225 * <p>
1226 * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
1227 * changed.
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07001228 * @hide
1229 */
Daniel Bright10aa8e72019-12-17 16:52:03 -08001230 @SystemApi
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07001231 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1232 @RequiresPermission(android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS)
1233 public static final String ACTION_SUBSCRIPTION_PLANS_CHANGED
1234 = "android.telephony.action.SUBSCRIPTION_PLANS_CHANGED";
1235
1236 /**
Malcolm Chen598d24c2017-04-24 18:37:29 -07001237 * Integer extra used with {@link #ACTION_DEFAULT_SUBSCRIPTION_CHANGED} and
1238 * {@link #ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED} to indicate the subscription
1239 * which has changed.
1240 */
1241 public static final String EXTRA_SUBSCRIPTION_INDEX = "android.telephony.extra.SUBSCRIPTION_INDEX";
1242
Jack Yud8104ec2019-09-18 09:31:28 -07001243 /**
1244 * Integer extra to specify SIM slot index.
1245 */
1246 public static final String EXTRA_SLOT_INDEX = "android.telephony.extra.SLOT_INDEX";
1247
Meng Wang0594b4f2021-10-26 13:12:47 -07001248 /**
1249 * A source of phone number: the EF-MSISDN (see 3GPP TS 31.102),
1250 * or EF-MDN for CDMA (see 3GPP2 C.P0065-B), from UICC application.
1251 *
1252 * <p>The availability and a of the number depends on the carrier.
1253 * The number may be updated by over-the-air update to UICC applications
1254 * from the carrier, or by other means with physical access to the SIM.
1255 */
1256 public static final int PHONE_NUMBER_SOURCE_UICC = 1;
1257
1258 /**
1259 * A source of phone number: provided by an app that has carrier privilege.
1260 *
1261 * <p>The number is intended to be set by a carrier app knowing the correct number
1262 * which is, for example, different from the number in {@link #PHONE_NUMBER_SOURCE_UICC UICC}
1263 * for some reason.
1264 * The number is not available until a carrier app sets one via
1265 * {@link #setCarrierPhoneNumber(int, String)}.
1266 * The app can update the number with the same API should the number change.
1267 */
1268 public static final int PHONE_NUMBER_SOURCE_CARRIER = 2;
1269
1270 /**
1271 * A source of phone number: provided by IMS (IP Multimedia Subsystem) implementation.
1272 * When IMS service is registered (as indicated by
1273 * {@link android.telephony.ims.RegistrationManager.RegistrationCallback#onRegistered(int)})
1274 * the IMS implementation may return P-Associated-Uri SIP headers (RFC 3455). The URIs
1275 * are the user’s public user identities known to the network (see 3GPP TS 24.229 5.4.1.2),
1276 * and the phone number is typically one of them (see “global number” in 3GPP TS 23.003 13.4).
1277 *
1278 * <p>This source provides the phone number from the last IMS registration.
1279 * IMS registration may happen on every device reboot or other network condition changes.
1280 * The number will be updated should the associated URI change after an IMS registration.
1281 */
1282 public static final int PHONE_NUMBER_SOURCE_IMS = 3;
1283
1284 /** @hide */
1285 @Retention(RetentionPolicy.SOURCE)
1286 @IntDef(prefix = {"PHONE_NUMBER_SOURCE"},
1287 value = {
1288 PHONE_NUMBER_SOURCE_UICC,
1289 PHONE_NUMBER_SOURCE_CARRIER,
1290 PHONE_NUMBER_SOURCE_IMS,
1291 })
1292 public @interface PhoneNumberSource {}
1293
Wink Savilled09c4ca2014-11-22 10:08:16 -08001294 private final Context mContext;
1295
Torbjorn Eklundf8899f02019-11-20 10:59:59 +01001296 // Cache of Resource that has been created in getResourcesForSubId. Key is a Pair containing
1297 // the Context and subId.
1298 private static final Map<Pair<Context, Integer>, Resources> sResourcesCache =
1299 new ConcurrentHashMap<>();
1300
Wink Savilled09c4ca2014-11-22 10:08:16 -08001301 /**
1302 * A listener class for monitoring changes to {@link SubscriptionInfo} records.
1303 * <p>
1304 * Override the onSubscriptionsChanged method in the object that extends this
Wink Saville071743f2015-01-12 17:11:04 -08001305 * class and pass it to {@link #addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener)}
Wink Savilled09c4ca2014-11-22 10:08:16 -08001306 * to register your listener and to unregister invoke
Wink Saville071743f2015-01-12 17:11:04 -08001307 * {@link #removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener)}
Wink Savilled09c4ca2014-11-22 10:08:16 -08001308 * <p>
1309 * Permissions android.Manifest.permission.READ_PHONE_STATE is required
1310 * for #onSubscriptionsChanged to be invoked.
1311 */
1312 public static class OnSubscriptionsChangedListener {
Jack He9fc75742017-11-16 15:54:14 -08001313 private class OnSubscriptionsChangedListenerHandler extends Handler {
1314 OnSubscriptionsChangedListenerHandler() {
1315 super();
1316 }
1317
1318 OnSubscriptionsChangedListenerHandler(Looper looper) {
1319 super(looper);
1320 }
Jack He9fc75742017-11-16 15:54:14 -08001321 }
1322
Chen Xu8eb62f92019-10-13 17:30:32 -07001323 /**
1324 * Posted executor callback on the handler associated with a given looper.
1325 * The looper can be the calling thread's looper or the looper passed from the
1326 * constructor {@link #OnSubscriptionsChangedListener(Looper)}.
1327 */
1328 private final HandlerExecutor mExecutor;
1329
1330 /**
1331 * @hide
1332 */
1333 public HandlerExecutor getHandlerExecutor() {
1334 return mExecutor;
1335 }
Jack He9fc75742017-11-16 15:54:14 -08001336
1337 public OnSubscriptionsChangedListener() {
Chen Xu8eb62f92019-10-13 17:30:32 -07001338 mExecutor = new HandlerExecutor(new OnSubscriptionsChangedListenerHandler());
Jack He9fc75742017-11-16 15:54:14 -08001339 }
1340
1341 /**
1342 * Allow a listener to be created with a custom looper
1343 * @param looper the looper that the underlining handler should run on
1344 * @hide
1345 */
1346 public OnSubscriptionsChangedListener(Looper looper) {
Chen Xu8eb62f92019-10-13 17:30:32 -07001347 mExecutor = new HandlerExecutor(new OnSubscriptionsChangedListenerHandler(looper));
Jack He9fc75742017-11-16 15:54:14 -08001348 }
Wink Savilled09c4ca2014-11-22 10:08:16 -08001349
1350 /**
Jordan Liu45da5052019-02-12 10:29:24 -08001351 * Callback invoked when there is any change to any SubscriptionInfo, as well as once on
1352 * registering for changes with {@link #addOnSubscriptionsChangedListener}. Typically
Wink Savilled09c4ca2014-11-22 10:08:16 -08001353 * this method would invoke {@link #getActiveSubscriptionInfoList}
1354 */
1355 public void onSubscriptionsChanged() {
1356 if (DBG) log("onSubscriptionsChanged: NOT OVERRIDDEN");
1357 }
1358
Tyler Gunn76ab5fb2020-03-25 17:49:35 -07001359 /**
1360 * Callback invoked when {@link SubscriptionManager#addOnSubscriptionsChangedListener(
1361 * Executor, OnSubscriptionsChangedListener)} or
1362 * {@link SubscriptionManager#addOnSubscriptionsChangedListener(
1363 * OnSubscriptionsChangedListener)} fails to complete due to the
1364 * {@link Context#TELEPHONY_REGISTRY_SERVICE} being unavailable.
1365 * @hide
1366 */
1367 public void onAddListenerFailed() {
1368 Rlog.w(LOG_TAG, "onAddListenerFailed not overridden");
1369 }
1370
Wink Savilled09c4ca2014-11-22 10:08:16 -08001371 private void log(String s) {
1372 Rlog.d(LOG_TAG, s);
1373 }
1374 }
1375
Wink Savillef5bca082014-09-03 15:13:33 -07001376 /** @hide */
Mathew Inwooda8382062018-08-16 17:01:12 +01001377 @UnsupportedAppUsage
Robin Leeeaf46802018-01-18 14:34:20 +01001378 public SubscriptionManager(Context context) {
Wink Savillefb40dd42014-06-12 17:02:31 -07001379 if (DBG) logd("SubscriptionManager created");
Wink Savilled09c4ca2014-11-22 10:08:16 -08001380 mContext = context;
Wink Savillefb40dd42014-06-12 17:02:31 -07001381 }
1382
Aaron Huang21089442020-01-16 23:31:02 +08001383 private NetworkPolicyManager getNetworkPolicyManager() {
1384 return (NetworkPolicyManager) mContext
1385 .getSystemService(Context.NETWORK_POLICY_SERVICE);
1386 }
1387
Wink Savillefb40dd42014-06-12 17:02:31 -07001388 /**
Jeff Sharkey717f52f2018-01-04 16:04:11 -07001389 * @deprecated developers should always obtain references directly from
1390 * {@link Context#getSystemService(Class)}.
Wink Savillefb40dd42014-06-12 17:02:31 -07001391 */
Jeff Sharkey717f52f2018-01-04 16:04:11 -07001392 @Deprecated
Wink Savilled09c4ca2014-11-22 10:08:16 -08001393 public static SubscriptionManager from(Context context) {
Jeff Sharkeyddf21642018-01-08 13:38:43 -07001394 return (SubscriptionManager) context
1395 .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Wink Savilled09c4ca2014-11-22 10:08:16 -08001396 }
1397
1398 /**
1399 * Register for changes to the list of active {@link SubscriptionInfo} records or to the
1400 * individual records themselves. When a change occurs the onSubscriptionsChanged method of
Jordan Liu45da5052019-02-12 10:29:24 -08001401 * the listener will be invoked immediately if there has been a notification. The
1402 * onSubscriptionChanged method will also be triggered once initially when calling this
Zongheng Wangeb56d062020-02-20 18:19:10 -08001403 * function. The callback will be invoked on the looper specified in the listener's constructor.
Wink Savilled09c4ca2014-11-22 10:08:16 -08001404 *
1405 * @param listener an instance of {@link OnSubscriptionsChangedListener} with
1406 * onSubscriptionsChanged overridden.
Zongheng Wangeb56d062020-02-20 18:19:10 -08001407 *
1408 * @deprecated Will get exception if the parameter listener is not initialized with a Looper.
1409 * Use {@link #addOnSubscriptionsChangedListener(Executor, OnSubscriptionsChangedListener)}.
Wink Savilled09c4ca2014-11-22 10:08:16 -08001410 */
Zongheng Wangeb56d062020-02-20 18:19:10 -08001411 @Deprecated
Wink Saville071743f2015-01-12 17:11:04 -08001412 public void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
Chen Xu8eb62f92019-10-13 17:30:32 -07001413 if (listener == null) return;
Zongheng Wang5d39bd12020-01-07 13:46:13 +08001414 addOnSubscriptionsChangedListener(listener.mExecutor, listener);
1415 }
1416
1417 /**
1418 * Register for changes to the list of active {@link SubscriptionInfo} records or to the
1419 * individual records themselves. When a change occurs the onSubscriptionsChanged method of
1420 * the listener will be invoked immediately if there has been a notification. The
1421 * onSubscriptionChanged method will also be triggered once initially when calling this
1422 * function.
1423 *
1424 * @param listener an instance of {@link OnSubscriptionsChangedListener} with
1425 * onSubscriptionsChanged overridden.
1426 * @param executor the executor that will execute callbacks.
1427 */
1428 public void addOnSubscriptionsChangedListener(
1429 @NonNull @CallbackExecutor Executor executor,
1430 @NonNull OnSubscriptionsChangedListener listener) {
Hall Liu5fb337f2017-11-22 17:38:15 -08001431 String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>";
Wink Savillea374c3d2014-11-11 11:48:04 -08001432 if (DBG) {
Hall Liu5fb337f2017-11-22 17:38:15 -08001433 logd("register OnSubscriptionsChangedListener pkgName=" + pkgName
Wink Savilled09c4ca2014-11-22 10:08:16 -08001434 + " listener=" + listener);
Wink Savillea374c3d2014-11-11 11:48:04 -08001435 }
Chen Xu8eb62f92019-10-13 17:30:32 -07001436 // We use the TelephonyRegistry as it runs in the system and thus is always
1437 // available. Where as SubscriptionController could crash and not be available
1438 TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
1439 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
1440 if (telephonyRegistryManager != null) {
1441 telephonyRegistryManager.addOnSubscriptionsChangedListener(listener,
Zongheng Wang5d39bd12020-01-07 13:46:13 +08001442 executor);
Tyler Gunn76ab5fb2020-03-25 17:49:35 -07001443 } else {
1444 // If the telephony registry isn't available, we will inform the caller on their
1445 // listener that it failed so they can try to re-register.
1446 loge("addOnSubscriptionsChangedListener: pkgname=" + pkgName + " failed to be added "
1447 + " due to TELEPHONY_REGISTRY_SERVICE being unavailable.");
1448 executor.execute(() -> listener.onAddListenerFailed());
Wink Savillea374c3d2014-11-11 11:48:04 -08001449 }
1450 }
1451
1452 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -08001453 * Unregister the {@link OnSubscriptionsChangedListener}. This is not strictly necessary
1454 * as the listener will automatically be unregistered if an attempt to invoke the listener
1455 * fails.
Wink Savillea374c3d2014-11-11 11:48:04 -08001456 *
Wink Savilled09c4ca2014-11-22 10:08:16 -08001457 * @param listener that is to be unregistered.
Wink Savillea374c3d2014-11-11 11:48:04 -08001458 */
Wink Saville071743f2015-01-12 17:11:04 -08001459 public void removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
Chen Xu8eb62f92019-10-13 17:30:32 -07001460 if (listener == null) return;
Robert Greenwalt278b8f92015-07-01 14:34:17 -07001461 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
Wink Savillea374c3d2014-11-11 11:48:04 -08001462 if (DBG) {
Wink Savilled09c4ca2014-11-22 10:08:16 -08001463 logd("unregister OnSubscriptionsChangedListener pkgForDebug=" + pkgForDebug
Wink Savillea374c3d2014-11-11 11:48:04 -08001464 + " listener=" + listener);
1465 }
Chen Xu8eb62f92019-10-13 17:30:32 -07001466 // We use the TelephonyRegistry as it runs in the system and thus is always
1467 // available where as SubscriptionController could crash and not be available
1468 TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
1469 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
1470 if (telephonyRegistryManager != null) {
1471 telephonyRegistryManager.removeOnSubscriptionsChangedListener(listener);
Malcolm Chen27829e22018-09-04 22:12:31 -07001472 }
1473 }
1474
1475 /**
1476 * A listener class for monitoring changes to {@link SubscriptionInfo} records of opportunistic
1477 * subscriptions.
1478 * <p>
1479 * Override the onOpportunisticSubscriptionsChanged method in the object that extends this
1480 * or {@link #addOnOpportunisticSubscriptionsChangedListener(
1481 * Executor, OnOpportunisticSubscriptionsChangedListener)}
1482 * to register your listener and to unregister invoke
1483 * {@link #removeOnOpportunisticSubscriptionsChangedListener(
1484 * OnOpportunisticSubscriptionsChangedListener)}
1485 * <p>
1486 * Permissions android.Manifest.permission.READ_PHONE_STATE is required
1487 * for #onOpportunisticSubscriptionsChanged to be invoked.
1488 */
1489 public static class OnOpportunisticSubscriptionsChangedListener {
Malcolm Chen27829e22018-09-04 22:12:31 -07001490 /**
1491 * Callback invoked when there is any change to any SubscriptionInfo. Typically
1492 * this method would invoke {@link #getActiveSubscriptionInfoList}
1493 */
1494 public void onOpportunisticSubscriptionsChanged() {
1495 if (DBG) log("onOpportunisticSubscriptionsChanged: NOT OVERRIDDEN");
1496 }
1497
Malcolm Chen27829e22018-09-04 22:12:31 -07001498 private void log(String s) {
1499 Rlog.d(LOG_TAG, s);
1500 }
1501 }
1502
1503 /**
1504 * Register for changes to the list of opportunistic subscription records or to the
1505 * individual records themselves. When a change occurs the onOpportunisticSubscriptionsChanged
1506 * method of the listener will be invoked immediately if there has been a notification.
1507 *
1508 * @param listener an instance of {@link OnOpportunisticSubscriptionsChangedListener} with
1509 * onOpportunisticSubscriptionsChanged overridden.
1510 */
1511 public void addOnOpportunisticSubscriptionsChangedListener(
1512 @NonNull @CallbackExecutor Executor executor,
1513 @NonNull OnOpportunisticSubscriptionsChangedListener listener) {
1514 if (executor == null || listener == null) {
1515 return;
1516 }
1517
1518 String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>";
1519 if (DBG) {
1520 logd("register addOnOpportunisticSubscriptionsChangedListener pkgName=" + pkgName
1521 + " listener=" + listener);
1522 }
1523
Chen Xu8eb62f92019-10-13 17:30:32 -07001524 // We use the TelephonyRegistry as it runs in the system and thus is always
1525 // available where as SubscriptionController could crash and not be available
1526 TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
1527 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
1528 if (telephonyRegistryManager != null) {
1529 telephonyRegistryManager.addOnOpportunisticSubscriptionsChangedListener(
1530 listener, executor);
Malcolm Chen27829e22018-09-04 22:12:31 -07001531 }
1532 }
1533
1534 /**
1535 * Unregister the {@link OnOpportunisticSubscriptionsChangedListener} that is currently
1536 * listening opportunistic subscriptions change. This is not strictly necessary
1537 * as the listener will automatically be unregistered if an attempt to invoke the listener
1538 * fails.
1539 *
1540 * @param listener that is to be unregistered.
1541 */
1542 public void removeOnOpportunisticSubscriptionsChangedListener(
Malcolm Chen80e1e5c2019-02-27 15:16:05 -08001543 @NonNull OnOpportunisticSubscriptionsChangedListener listener) {
1544 Preconditions.checkNotNull(listener, "listener cannot be null");
Malcolm Chen27829e22018-09-04 22:12:31 -07001545 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
1546 if (DBG) {
1547 logd("unregister OnOpportunisticSubscriptionsChangedListener pkgForDebug="
1548 + pkgForDebug + " listener=" + listener);
1549 }
Chen Xu8eb62f92019-10-13 17:30:32 -07001550 TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
1551 mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
1552 if (telephonyRegistryManager != null) {
1553 telephonyRegistryManager.removeOnOpportunisticSubscriptionsChangedListener(listener);
Wink Savillea374c3d2014-11-11 11:48:04 -08001554 }
1555 }
1556
1557 /**
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001558 * Get the active SubscriptionInfo with the input subId.
1559 *
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001560 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1561 * or that the calling app has carrier privileges (see
1562 * {@link TelephonyManager#hasCarrierPrivileges}).
1563 *
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001564 * @param subId The unique SubscriptionInfo key in database.
Wink Savilled09c4ca2014-11-22 10:08:16 -08001565 * @return SubscriptionInfo, maybe null if its not active.
Wink Savillea374c3d2014-11-11 11:48:04 -08001566 */
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001567 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
1568 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
Wink Savilled09c4ca2014-11-22 10:08:16 -08001569 public SubscriptionInfo getActiveSubscriptionInfo(int subId) {
1570 if (VDBG) logd("[getActiveSubscriptionInfo]+ subId=" + subId);
Wink Savillea54bf652014-12-11 13:37:50 -08001571 if (!isValidSubscriptionId(subId)) {
Sanket Padawe28964eb2015-06-05 16:13:51 -07001572 if (DBG) {
1573 logd("[getActiveSubscriptionInfo]- invalid subId");
1574 }
Wink Savillefb40dd42014-06-12 17:02:31 -07001575 return null;
1576 }
1577
Wink Savillea374c3d2014-11-11 11:48:04 -08001578 SubscriptionInfo subInfo = null;
Wink Savillefb40dd42014-06-12 17:02:31 -07001579
1580 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001581 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07001582 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08001583 subInfo = iSub.getActiveSubscriptionInfo(subId, mContext.getOpPackageName(),
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08001584 mContext.getAttributionTag());
Wink Savillefb40dd42014-06-12 17:02:31 -07001585 }
1586 } catch (RemoteException ex) {
1587 // ignore it
1588 }
1589
1590 return subInfo;
Wink Savillefb40dd42014-06-12 17:02:31 -07001591 }
1592
1593 /**
sqianff8dfe72020-01-07 13:45:07 -08001594 * Gets an active SubscriptionInfo {@link SubscriptionInfo} associated with the Sim IccId.
1595 *
Wink Savillefb40dd42014-06-12 17:02:31 -07001596 * @param iccId the IccId of SIM card
Wink Savilled09c4ca2014-11-22 10:08:16 -08001597 * @return SubscriptionInfo, maybe null if its not active
sqianff8dfe72020-01-07 13:45:07 -08001598 *
Wink Savillef5bca082014-09-03 15:13:33 -07001599 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07001600 */
sqianff8dfe72020-01-07 13:45:07 -08001601 @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
1602 @Nullable
1603 @SystemApi
1604 public SubscriptionInfo getActiveSubscriptionInfoForIcc(@NonNull String iccId) {
Wink Savilled09c4ca2014-11-22 10:08:16 -08001605 if (VDBG) logd("[getActiveSubscriptionInfoForIccIndex]+ iccId=" + iccId);
Wink Savillefb40dd42014-06-12 17:02:31 -07001606 if (iccId == null) {
Wink Savilled09c4ca2014-11-22 10:08:16 -08001607 logd("[getActiveSubscriptionInfoForIccIndex]- null iccid");
Wink Savillefb40dd42014-06-12 17:02:31 -07001608 return null;
1609 }
1610
Wink Savilled09c4ca2014-11-22 10:08:16 -08001611 SubscriptionInfo result = null;
Wink Savillefb40dd42014-06-12 17:02:31 -07001612
1613 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001614 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07001615 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08001616 result = iSub.getActiveSubscriptionInfoForIccId(iccId, mContext.getOpPackageName(),
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08001617 mContext.getAttributionTag());
Wink Savillefb40dd42014-06-12 17:02:31 -07001618 }
1619 } catch (RemoteException ex) {
1620 // ignore it
1621 }
1622
1623 return result;
1624 }
1625
1626 /**
Sanket Padawe7e460252017-03-10 16:18:20 -08001627 * Get the active SubscriptionInfo associated with the slotIndex
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001628 *
1629 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1630 * or that the calling app has carrier privileges (see
1631 * {@link TelephonyManager#hasCarrierPrivileges}).
1632 *
Sanket Padawe7e460252017-03-10 16:18:20 -08001633 * @param slotIndex the slot which the subscription is inserted
Wink Savilled09c4ca2014-11-22 10:08:16 -08001634 * @return SubscriptionInfo, maybe null if its not active
Wink Savillefb40dd42014-06-12 17:02:31 -07001635 */
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001636 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
1637 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
Sanket Padawe7e460252017-03-10 16:18:20 -08001638 public SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex) {
1639 if (VDBG) logd("[getActiveSubscriptionInfoForSimSlotIndex]+ slotIndex=" + slotIndex);
1640 if (!isValidSlotIndex(slotIndex)) {
1641 logd("[getActiveSubscriptionInfoForSimSlotIndex]- invalid slotIndex");
Wink Savillefb40dd42014-06-12 17:02:31 -07001642 return null;
1643 }
1644
Wink Savilled09c4ca2014-11-22 10:08:16 -08001645 SubscriptionInfo result = null;
Wink Savillefb40dd42014-06-12 17:02:31 -07001646
1647 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001648 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07001649 if (iSub != null) {
Sanket Padawe7e460252017-03-10 16:18:20 -08001650 result = iSub.getActiveSubscriptionInfoForSimSlotIndex(slotIndex,
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08001651 mContext.getOpPackageName(), mContext.getAttributionTag());
Wink Savillefb40dd42014-06-12 17:02:31 -07001652 }
1653 } catch (RemoteException ex) {
1654 // ignore it
1655 }
1656
1657 return result;
1658 }
1659
1660 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -08001661 * @return List of all SubscriptionInfo records in database,
1662 * include those that were inserted before, maybe empty but not null.
Wink Savillef5bca082014-09-03 15:13:33 -07001663 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07001664 */
Benedict Wong061b2f72020-11-02 17:52:06 -08001665 @NonNull
Mathew Inwooda8382062018-08-16 17:01:12 +01001666 @UnsupportedAppUsage
Wink Savilled09c4ca2014-11-22 10:08:16 -08001667 public List<SubscriptionInfo> getAllSubscriptionInfoList() {
Wink Savillea374c3d2014-11-11 11:48:04 -08001668 if (VDBG) logd("[getAllSubscriptionInfoList]+");
Wink Savillefb40dd42014-06-12 17:02:31 -07001669
Wink Savillea374c3d2014-11-11 11:48:04 -08001670 List<SubscriptionInfo> result = null;
Wink Savillefb40dd42014-06-12 17:02:31 -07001671
1672 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001673 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07001674 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08001675 result = iSub.getAllSubInfoList(mContext.getOpPackageName(),
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08001676 mContext.getAttributionTag());
Wink Savillefb40dd42014-06-12 17:02:31 -07001677 }
1678 } catch (RemoteException ex) {
1679 // ignore it
1680 }
1681
Wink Saville905bb542014-09-04 17:10:23 -07001682 if (result == null) {
Benedict Wong061b2f72020-11-02 17:52:06 -08001683 result = Collections.emptyList();
Wink Saville905bb542014-09-04 17:10:23 -07001684 }
Wink Savillefb40dd42014-06-12 17:02:31 -07001685 return result;
1686 }
1687
1688 /**
Vasu Noriaea03912018-09-04 11:19:59 -07001689 * Get the SubscriptionInfo(s) of the currently active SIM(s). The records will be sorted
Wink Savilled09c4ca2014-11-22 10:08:16 -08001690 * by {@link SubscriptionInfo#getSimSlotIndex} then by {@link SubscriptionInfo#getSubscriptionId}.
1691 *
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001692 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1693 * or that the calling app has carrier privileges (see
1694 * {@link TelephonyManager#hasCarrierPrivileges}). In the latter case, only records accessible
1695 * to the calling app are returned.
1696 *
Wink Savilled09c4ca2014-11-22 10:08:16 -08001697 * @return Sorted list of the currently {@link SubscriptionInfo} records available on the device.
1698 * <ul>
1699 * <li>
1700 * If null is returned the current state is unknown but if a {@link OnSubscriptionsChangedListener}
1701 * has been registered {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be
1702 * invoked in the future.
1703 * </li>
1704 * <li>
1705 * If the list is empty then there are no {@link SubscriptionInfo} records currently available.
1706 * </li>
1707 * <li>
1708 * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
1709 * then by {@link SubscriptionInfo#getSubscriptionId}.
1710 * </li>
1711 * </ul>
Wink Savillefb40dd42014-06-12 17:02:31 -07001712 */
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001713 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
1714 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
Wink Savilled09c4ca2014-11-22 10:08:16 -08001715 public List<SubscriptionInfo> getActiveSubscriptionInfoList() {
Malcolm Chen31071852019-02-12 17:29:59 -08001716 return getActiveSubscriptionInfoList(/* userVisibleonly */true);
Malcolm Chenc3d7de02018-12-21 17:00:30 -08001717 }
1718
1719 /**
Sooraj Sasindrane5ac4da2019-11-07 18:32:37 -08001720 * Get both hidden and visible SubscriptionInfo(s) of the currently active SIM(s).
1721 * The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex}
1722 * then by {@link SubscriptionInfo#getSubscriptionId}.
Malcolm Chenc3d7de02018-12-21 17:00:30 -08001723 *
Peter Wang01d128c2019-12-17 19:11:23 -08001724 * Hidden subscriptions refer to those are not meant visible to the users.
1725 * For example, an opportunistic subscription that is grouped with other
1726 * subscriptions should remain invisible to users as they are only functionally
1727 * supplementary to primary ones.
1728 *
Sooraj Sasindrane5ac4da2019-11-07 18:32:37 -08001729 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1730 * or that the calling app has carrier privileges (see
1731 * {@link TelephonyManager#hasCarrierPrivileges}). In the latter case, only records accessible
1732 * to the calling app are returned.
1733 *
1734 * @return Sorted list of the currently available {@link SubscriptionInfo}
1735 * records on the device.
1736 * This is similar to {@link #getActiveSubscriptionInfoList} except that it will return
1737 * both active and hidden SubscriptionInfos.
1738 *
Malcolm Chenc3d7de02018-12-21 17:00:30 -08001739 */
Sooraj Sasindran40468062020-01-06 19:10:50 -08001740 public @NonNull List<SubscriptionInfo> getCompleteActiveSubscriptionInfoList() {
1741 List<SubscriptionInfo> completeList = getActiveSubscriptionInfoList(
1742 /* userVisibleonly */false);
1743 if (completeList == null) {
1744 completeList = new ArrayList<>();
1745 }
1746 return completeList;
Sooraj Sasindrane5ac4da2019-11-07 18:32:37 -08001747 }
1748
1749 /**
1750 * This is similar to {@link #getActiveSubscriptionInfoList()}, but if userVisibleOnly
1751 * is true, it will filter out the hidden subscriptions.
1752 *
1753 * @hide
1754 */
1755 public @Nullable List<SubscriptionInfo> getActiveSubscriptionInfoList(boolean userVisibleOnly) {
Malcolm Chenc3d7de02018-12-21 17:00:30 -08001756 List<SubscriptionInfo> activeList = null;
Wink Savillefb40dd42014-06-12 17:02:31 -07001757
1758 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001759 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07001760 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08001761 activeList = iSub.getActiveSubscriptionInfoList(mContext.getOpPackageName(),
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08001762 mContext.getAttributionTag());
Wink Savillefb40dd42014-06-12 17:02:31 -07001763 }
1764 } catch (RemoteException ex) {
1765 // ignore it
1766 }
Malcolm Chenc3d7de02018-12-21 17:00:30 -08001767
1768 if (!userVisibleOnly || activeList == null) {
1769 return activeList;
1770 } else {
Malcolm Chend1b4a812019-02-28 14:07:59 -08001771 return activeList.stream().filter(subInfo -> isSubscriptionVisible(subInfo))
Malcolm Chenc3d7de02018-12-21 17:00:30 -08001772 .collect(Collectors.toList());
1773 }
Wink Savillefb40dd42014-06-12 17:02:31 -07001774 }
1775
1776 /**
Jeff Davidsond02731f2017-04-09 14:31:09 -07001777 * Gets the SubscriptionInfo(s) of all available subscriptions, if any.
1778 *
1779 * <p>Available subscriptions include active ones (those with a non-negative
1780 * {@link SubscriptionInfo#getSimSlotIndex()}) as well as inactive but installed embedded
1781 * subscriptions.
1782 *
1783 * <p>The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by
1784 * {@link SubscriptionInfo#getSubscriptionId}.
1785 *
1786 * @return Sorted list of the current {@link SubscriptionInfo} records available on the
1787 * device.
1788 * <ul>
1789 * <li>
1790 * If null is returned the current state is unknown but if a
1791 * {@link OnSubscriptionsChangedListener} has been registered
1792 * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be invoked in the future.
1793 * <li>
1794 * If the list is empty then there are no {@link SubscriptionInfo} records currently available.
1795 * <li>
1796 * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
1797 * then by {@link SubscriptionInfo#getSubscriptionId}.
1798 * </ul>
Jiuyu Sund3bb4ae2018-02-08 16:38:26 +00001799 *
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08001800 * <p>
1801 * Permissions android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE is required
1802 * for #getAvailableSubscriptionInfoList to be invoked.
1803 * @hide
Jeff Davidsond02731f2017-04-09 14:31:09 -07001804 */
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08001805 @SystemApi
Jeff Davidsond02731f2017-04-09 14:31:09 -07001806 public List<SubscriptionInfo> getAvailableSubscriptionInfoList() {
1807 List<SubscriptionInfo> result = null;
1808
1809 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001810 ISub iSub = TelephonyManager.getSubscriptionService();
Jeff Davidsond02731f2017-04-09 14:31:09 -07001811 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08001812 result = iSub.getAvailableSubscriptionInfoList(mContext.getOpPackageName(),
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08001813 mContext.getAttributionTag());
Jeff Davidsond02731f2017-04-09 14:31:09 -07001814 }
1815 } catch (RemoteException ex) {
1816 // ignore it
1817 }
1818 return result;
1819 }
1820
1821 /**
1822 * Gets the SubscriptionInfo(s) of all embedded subscriptions accessible to the calling app, if
1823 * any.
1824 *
1825 * <p>Only those subscriptions for which the calling app has carrier privileges per the
1826 * subscription metadata, if any, will be included in the returned list.
1827 *
1828 * <p>The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by
1829 * {@link SubscriptionInfo#getSubscriptionId}.
1830 *
1831 * @return Sorted list of the current embedded {@link SubscriptionInfo} records available on the
1832 * device which are accessible to the caller.
1833 * <ul>
1834 * <li>
1835 * If null is returned the current state is unknown but if a
1836 * {@link OnSubscriptionsChangedListener} has been registered
1837 * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be invoked in the future.
1838 * <li>
1839 * If the list is empty then there are no {@link SubscriptionInfo} records currently available.
1840 * <li>
1841 * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
1842 * then by {@link SubscriptionInfo#getSubscriptionId}.
1843 * </ul>
Jeff Davidsond02731f2017-04-09 14:31:09 -07001844 */
1845 public List<SubscriptionInfo> getAccessibleSubscriptionInfoList() {
1846 List<SubscriptionInfo> result = null;
1847
1848 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001849 ISub iSub = TelephonyManager.getSubscriptionService();
Jeff Davidsond02731f2017-04-09 14:31:09 -07001850 if (iSub != null) {
1851 result = iSub.getAccessibleSubscriptionInfoList(mContext.getOpPackageName());
1852 }
1853 } catch (RemoteException ex) {
1854 // ignore it
1855 }
1856 return result;
1857 }
1858
1859 /**
Pengquan Mengeb7ac732018-11-29 18:33:17 -08001860 * Request a refresh of the platform cache of profile information for the eUICC which
1861 * corresponds to the card ID returned by {@link TelephonyManager#getCardIdForDefaultEuicc()}.
Jeff Davidsond02731f2017-04-09 14:31:09 -07001862 *
1863 * <p>Should be called by the EuiccService implementation whenever this information changes due
1864 * to an operation done outside the scope of a request initiated by the platform to the
1865 * EuiccService. There is no need to refresh for downloads, deletes, or other operations that
1866 * were made through the EuiccService.
1867 *
1868 * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
Pengquan Mengeb7ac732018-11-29 18:33:17 -08001869 *
1870 * @see {@link TelephonyManager#getCardIdForDefaultEuicc()} for more information on the card ID.
1871 *
Jeff Davidsond02731f2017-04-09 14:31:09 -07001872 * @hide
Jeff Davidsond02731f2017-04-09 14:31:09 -07001873 */
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08001874 @SystemApi
Jeff Davidsond02731f2017-04-09 14:31:09 -07001875 public void requestEmbeddedSubscriptionInfoListRefresh() {
Pengquan Mengeb7ac732018-11-29 18:33:17 -08001876 int cardId = TelephonyManager.from(mContext).getCardIdForDefaultEuicc();
Jeff Davidsond02731f2017-04-09 14:31:09 -07001877 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001878 ISub iSub = TelephonyManager.getSubscriptionService();
Jeff Davidsond02731f2017-04-09 14:31:09 -07001879 if (iSub != null) {
Pengquan Mengeb7ac732018-11-29 18:33:17 -08001880 iSub.requestEmbeddedSubscriptionInfoListRefresh(cardId);
Jeff Davidsond02731f2017-04-09 14:31:09 -07001881 }
1882 } catch (RemoteException ex) {
Pengquan Mengeb7ac732018-11-29 18:33:17 -08001883 logd("requestEmbeddedSubscriptionInfoListFresh for card = " + cardId + " failed.");
1884 }
1885 }
1886
1887 /**
1888 * Request a refresh of the platform cache of profile information for the eUICC with the given
1889 * {@code cardId}.
1890 *
1891 * <p>Should be called by the EuiccService implementation whenever this information changes due
1892 * to an operation done outside the scope of a request initiated by the platform to the
1893 * EuiccService. There is no need to refresh for downloads, deletes, or other operations that
1894 * were made through the EuiccService.
1895 *
1896 * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
1897 *
1898 * @param cardId the card ID of the eUICC.
1899 *
1900 * @see {@link TelephonyManager#getCardIdForDefaultEuicc()} for more information on the card ID.
1901 *
1902 * @hide
1903 */
1904 @SystemApi
1905 public void requestEmbeddedSubscriptionInfoListRefresh(int cardId) {
1906 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001907 ISub iSub = TelephonyManager.getSubscriptionService();
Pengquan Mengeb7ac732018-11-29 18:33:17 -08001908 if (iSub != null) {
1909 iSub.requestEmbeddedSubscriptionInfoListRefresh(cardId);
1910 }
1911 } catch (RemoteException ex) {
1912 logd("requestEmbeddedSubscriptionInfoListFresh for card = " + cardId + " failed.");
Jeff Davidsond02731f2017-04-09 14:31:09 -07001913 }
1914 }
1915
1916 /**
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001917 *
1918 * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1919 * or that the calling app has carrier privileges (see
1920 * {@link TelephonyManager#hasCarrierPrivileges}). In the latter case, the count will include
1921 * only those subscriptions accessible to the caller.
1922 *
Wink Savilled09c4ca2014-11-22 10:08:16 -08001923 * @return the current number of active subscriptions. There is no guarantee the value
1924 * returned by this method will be the same as the length of the list returned by
1925 * {@link #getActiveSubscriptionInfoList}.
Wink Savillec650e0b2014-09-02 22:37:08 -07001926 */
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001927 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
1928 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
Wink Savilled09c4ca2014-11-22 10:08:16 -08001929 public int getActiveSubscriptionInfoCount() {
Wink Savillec650e0b2014-09-02 22:37:08 -07001930 int result = 0;
1931
1932 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001933 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillec650e0b2014-09-02 22:37:08 -07001934 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08001935 result = iSub.getActiveSubInfoCount(mContext.getOpPackageName(),
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08001936 mContext.getAttributionTag());
Wink Savillec650e0b2014-09-02 22:37:08 -07001937 }
1938 } catch (RemoteException ex) {
1939 // ignore it
1940 }
1941
1942 return result;
1943 }
1944
1945 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -08001946 * @return the maximum number of active subscriptions that will be returned by
1947 * {@link #getActiveSubscriptionInfoList} and the value returned by
1948 * {@link #getActiveSubscriptionInfoCount}.
1949 */
1950 public int getActiveSubscriptionInfoCountMax() {
1951 int result = 0;
1952
1953 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07001954 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savilled09c4ca2014-11-22 10:08:16 -08001955 if (iSub != null) {
1956 result = iSub.getActiveSubInfoCountMax();
1957 }
1958 } catch (RemoteException ex) {
1959 // ignore it
1960 }
1961
1962 return result;
1963 }
1964
1965 /**
1966 * Add a new SubscriptionInfo to SubscriptionInfo database if needed
Wink Savillefb40dd42014-06-12 17:02:31 -07001967 * @param iccId the IccId of the SIM card
Sanket Padawe7e460252017-03-10 16:18:20 -08001968 * @param slotIndex the slot which the SIM is inserted
Wink Savillefb40dd42014-06-12 17:02:31 -07001969 * @return the URL of the newly created row or the updated row
Wink Savillef5bca082014-09-03 15:13:33 -07001970 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07001971 */
Sanket Padawe7e460252017-03-10 16:18:20 -08001972 public Uri addSubscriptionInfoRecord(String iccId, int slotIndex) {
1973 if (VDBG) logd("[addSubscriptionInfoRecord]+ iccId:" + iccId + " slotIndex:" + slotIndex);
Wink Savillefb40dd42014-06-12 17:02:31 -07001974 if (iccId == null) {
Wink Savillea374c3d2014-11-11 11:48:04 -08001975 logd("[addSubscriptionInfoRecord]- null iccId");
Wink Savillefb40dd42014-06-12 17:02:31 -07001976 }
Sanket Padawe7e460252017-03-10 16:18:20 -08001977 if (!isValidSlotIndex(slotIndex)) {
1978 logd("[addSubscriptionInfoRecord]- invalid slotIndex");
Wink Savillec650e0b2014-09-02 22:37:08 -07001979 }
Wink Savillefb40dd42014-06-12 17:02:31 -07001980
Vasu Noriaea03912018-09-04 11:19:59 -07001981 addSubscriptionInfoRecord(iccId, null, slotIndex, SUBSCRIPTION_TYPE_LOCAL_SIM);
Wink Savillefb40dd42014-06-12 17:02:31 -07001982
1983 // FIXME: Always returns null?
1984 return null;
1985
1986 }
1987
1988 /**
Vasu Noriaea03912018-09-04 11:19:59 -07001989 * Add a new SubscriptionInfo to SubscriptionInfo database if needed
1990 * @param uniqueId This is the unique identifier for the subscription within the
1991 * specific subscription type.
1992 * @param displayName human-readable name of the device the subscription corresponds to.
1993 * @param slotIndex the slot assigned to this subscription. It is ignored for subscriptionType
1994 * of {@link #SUBSCRIPTION_TYPE_REMOTE_SIM}.
1995 * @param subscriptionType the {@link #SUBSCRIPTION_TYPE}
1996 * @hide
1997 */
Etienne Ruffieux6a646db2021-07-27 10:06:27 +00001998 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
1999 public void addSubscriptionInfoRecord(@NonNull String uniqueId, @Nullable String displayName,
Etienne Ruffieux036f3012022-02-24 10:33:04 +00002000 int slotIndex, @SubscriptionType int subscriptionType) {
Vasu Noriaea03912018-09-04 11:19:59 -07002001 if (VDBG) {
2002 logd("[addSubscriptionInfoRecord]+ uniqueId:" + uniqueId
2003 + ", displayName:" + displayName + ", slotIndex:" + slotIndex
2004 + ", subscriptionType: " + subscriptionType);
2005 }
2006 if (uniqueId == null) {
2007 Log.e(LOG_TAG, "[addSubscriptionInfoRecord]- uniqueId is null");
2008 return;
2009 }
2010
2011 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002012 ISub iSub = TelephonyManager.getSubscriptionService();
Vasu Noriaea03912018-09-04 11:19:59 -07002013 if (iSub == null) {
2014 Log.e(LOG_TAG, "[addSubscriptionInfoRecord]- ISub service is null");
2015 return;
2016 }
2017 int result = iSub.addSubInfo(uniqueId, displayName, slotIndex, subscriptionType);
2018 if (result < 0) {
2019 Log.e(LOG_TAG, "Adding of subscription didn't succeed: error = " + result);
2020 } else {
2021 logd("successfully added new subscription");
2022 }
2023 } catch (RemoteException ex) {
2024 // ignore it
2025 }
2026 }
2027
2028 /**
2029 * Remove SubscriptionInfo record from the SubscriptionInfo database
2030 * @param uniqueId This is the unique identifier for the subscription within the specific
2031 * subscription type.
2032 * @param subscriptionType the {@link #SUBSCRIPTION_TYPE}
2033 * @hide
2034 */
Etienne Ruffieux6a646db2021-07-27 10:06:27 +00002035 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
Etienne Ruffieux036f3012022-02-24 10:33:04 +00002036 public void removeSubscriptionInfoRecord(@NonNull String uniqueId,
2037 @SubscriptionType int subscriptionType) {
Vasu Noriaea03912018-09-04 11:19:59 -07002038 if (VDBG) {
2039 logd("[removeSubscriptionInfoRecord]+ uniqueId:" + uniqueId
2040 + ", subscriptionType: " + subscriptionType);
2041 }
2042 if (uniqueId == null) {
2043 Log.e(LOG_TAG, "[addSubscriptionInfoRecord]- uniqueId is null");
2044 return;
2045 }
2046
2047 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002048 ISub iSub = TelephonyManager.getSubscriptionService();
Vasu Noriaea03912018-09-04 11:19:59 -07002049 if (iSub == null) {
2050 Log.e(LOG_TAG, "[removeSubscriptionInfoRecord]- ISub service is null");
2051 return;
2052 }
2053 int result = iSub.removeSubInfo(uniqueId, subscriptionType);
2054 if (result < 0) {
2055 Log.e(LOG_TAG, "Removal of subscription didn't succeed: error = " + result);
2056 } else {
2057 logd("successfully removed subscription");
2058 }
2059 } catch (RemoteException ex) {
2060 // ignore it
2061 }
2062 }
2063
2064 /**
changbetty23eee52e2019-12-18 18:09:56 +08002065 * Set SIM icon tint color for subscription ID
Wink Savilled09c4ca2014-11-22 10:08:16 -08002066 * @param tint the RGB value of icon tint color of the SIM
changbetty23eee52e2019-12-18 18:09:56 +08002067 * @param subId the unique Subscritpion ID in database
Wink Savillefb40dd42014-06-12 17:02:31 -07002068 * @return the number of records updated
Wink Savillef5bca082014-09-03 15:13:33 -07002069 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07002070 */
changbetty23eee52e2019-12-18 18:09:56 +08002071 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
2072 public int setIconTint(@ColorInt int tint, int subId) {
Stuart Scottab45ec12014-10-28 09:29:01 -07002073 if (VDBG) logd("[setIconTint]+ tint:" + tint + " subId:" + subId);
Malcolm Chenbd4ae762018-08-03 17:24:07 -07002074 return setSubscriptionPropertyHelper(subId, "setIconTint",
2075 (iSub)-> iSub.setIconTint(tint, subId)
2076 );
Wink Savillefb40dd42014-06-12 17:02:31 -07002077 }
2078
2079 /**
changbetty23eee52e2019-12-18 18:09:56 +08002080 * Set the display name for a subscription ID
Wink Savillefb40dd42014-06-12 17:02:31 -07002081 * @param displayName the display name of SIM card
changbetty23eee52e2019-12-18 18:09:56 +08002082 * @param subId the unique Subscritpion ID in database
Jack Yu5c6eb0e2019-10-16 09:16:54 -07002083 * @param nameSource SIM display name source
Wink Saville98513d72014-12-08 12:44:16 -08002084 * @return the number of records updated or < 0 if invalid subId
Wink Savillef5bca082014-09-03 15:13:33 -07002085 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07002086 */
changbetty23eee52e2019-12-18 18:09:56 +08002087 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
2088 public int setDisplayName(@Nullable String displayName, int subId,
2089 @SimDisplayNameSource int nameSource) {
Wink Savillec650e0b2014-09-02 22:37:08 -07002090 if (VDBG) {
2091 logd("[setDisplayName]+ displayName:" + displayName + " subId:" + subId
2092 + " nameSource:" + nameSource);
2093 }
Malcolm Chenbd4ae762018-08-03 17:24:07 -07002094 return setSubscriptionPropertyHelper(subId, "setDisplayName",
2095 (iSub)-> iSub.setDisplayNameUsingSrc(displayName, subId, nameSource)
2096 );
Wink Savillefb40dd42014-06-12 17:02:31 -07002097 }
2098
2099 /**
2100 * Set phone number by subId
Wink Savillefb40dd42014-06-12 17:02:31 -07002101 * @param number the phone number of the SIM
Wink Savillea374c3d2014-11-11 11:48:04 -08002102 * @param subId the unique SubscriptionInfo index in database
Wink Savillefb40dd42014-06-12 17:02:31 -07002103 * @return the number of records updated
Wink Savillef5bca082014-09-03 15:13:33 -07002104 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07002105 */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +00002106 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Wink Savilled09c4ca2014-11-22 10:08:16 -08002107 public int setDisplayNumber(String number, int subId) {
Malcolm Chenbd4ae762018-08-03 17:24:07 -07002108 if (number == null) {
Wink Savillec650e0b2014-09-02 22:37:08 -07002109 logd("[setDisplayNumber]- fail");
Wink Savillefb40dd42014-06-12 17:02:31 -07002110 return -1;
2111 }
Malcolm Chenbd4ae762018-08-03 17:24:07 -07002112 return setSubscriptionPropertyHelper(subId, "setDisplayNumber",
2113 (iSub)-> iSub.setDisplayNumber(number, subId)
2114 );
Wink Savillefb40dd42014-06-12 17:02:31 -07002115 }
2116
2117 /**
Wink Savillefb40dd42014-06-12 17:02:31 -07002118 * Set data roaming by simInfo index
Wink Savillefb40dd42014-06-12 17:02:31 -07002119 * @param roaming 0:Don't allow data when roaming, 1:Allow data when roaming
Wink Savillea374c3d2014-11-11 11:48:04 -08002120 * @param subId the unique SubscriptionInfo index in database
Wink Savillefb40dd42014-06-12 17:02:31 -07002121 * @return the number of records updated
Wink Savillef5bca082014-09-03 15:13:33 -07002122 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07002123 */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +00002124 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Wink Savilled09c4ca2014-11-22 10:08:16 -08002125 public int setDataRoaming(int roaming, int subId) {
Wink Savillefb40dd42014-06-12 17:02:31 -07002126 if (VDBG) logd("[setDataRoaming]+ roaming:" + roaming + " subId:" + subId);
Malcolm Chenbd4ae762018-08-03 17:24:07 -07002127 return setSubscriptionPropertyHelper(subId, "setDataRoaming",
2128 (iSub)->iSub.setDataRoaming(roaming, subId)
2129 );
Wink Savillefb40dd42014-06-12 17:02:31 -07002130 }
2131
Wink Saville905bb542014-09-04 17:10:23 -07002132 /**
Sanket Padawe7e460252017-03-10 16:18:20 -08002133 * Get slotIndex associated with the subscription.
sqian996a3182018-10-12 18:41:19 -07002134 *
2135 * @param subscriptionId the unique SubscriptionInfo index in database
2136 * @return slotIndex as a positive integer or {@link #INVALID_SIM_SLOT_INDEX} if the supplied
2137 * subscriptionId doesn't have an associated slot index.
Wink Saville905bb542014-09-04 17:10:23 -07002138 */
sqian996a3182018-10-12 18:41:19 -07002139 public static int getSlotIndex(int subscriptionId) {
Collin Fijalkovich41f94622020-04-10 14:01:42 -07002140 return sSlotIndexCache.query(subscriptionId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002141 }
2142
sqiancd4dafb2018-08-29 13:58:49 -07002143 /**
2144 * Get an array of Subscription Ids for specified slot Index.
sqian91412858b2018-11-09 14:52:25 -08002145 * @param slotIndex the slot index.
2146 * @return subscription Ids or null if the given slot Index is not valid or there are no active
2147 * subscriptions in the slot.
sqiancd4dafb2018-08-29 13:58:49 -07002148 */
sqianf8ace212018-10-19 19:01:42 -07002149 @Nullable
sqiand8c30b92018-10-30 16:58:20 -07002150 public int[] getSubscriptionIds(int slotIndex) {
sqiancd4dafb2018-08-29 13:58:49 -07002151 return getSubId(slotIndex);
2152 }
2153
Wink Savillef5bca082014-09-03 15:13:33 -07002154 /** @hide */
Mathew Inwooda8382062018-08-16 17:01:12 +01002155 @UnsupportedAppUsage
Sanket Padawe7e460252017-03-10 16:18:20 -08002156 public static int[] getSubId(int slotIndex) {
2157 if (!isValidSlotIndex(slotIndex)) {
Wink Savillec650e0b2014-09-02 22:37:08 -07002158 logd("[getSubId]- fail");
2159 return null;
2160 }
Wink Savillefb40dd42014-06-12 17:02:31 -07002161
Wink Saville63f03dd2014-10-23 10:44:45 -07002162 int[] subId = null;
Wink Savillefb40dd42014-06-12 17:02:31 -07002163
2164 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002165 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07002166 if (iSub != null) {
Sanket Padawe7e460252017-03-10 16:18:20 -08002167 subId = iSub.getSubId(slotIndex);
Wink Savillefb40dd42014-06-12 17:02:31 -07002168 }
2169 } catch (RemoteException ex) {
2170 // ignore it
2171 }
2172
2173 return subId;
2174 }
2175
Wink Savillef5bca082014-09-03 15:13:33 -07002176 /** @hide */
Chen Xu4c0b06d2018-10-22 16:54:39 +00002177 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
Wink Saville63f03dd2014-10-23 10:44:45 -07002178 public static int getPhoneId(int subId) {
Collin Fijalkovich41f94622020-04-10 14:01:42 -07002179 return sPhoneIdCache.query(subId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002180 }
2181
Wink Savillefb40dd42014-06-12 17:02:31 -07002182 private static void logd(String msg) {
Wink Savilled09c4ca2014-11-22 10:08:16 -08002183 Rlog.d(LOG_TAG, msg);
Wink Savillefb40dd42014-06-12 17:02:31 -07002184 }
2185
Malcolm Chen4674a792019-03-20 20:32:27 -07002186 private static void loge(String msg) {
2187 Rlog.e(LOG_TAG, msg);
2188 }
2189
Wink Savillefb40dd42014-06-12 17:02:31 -07002190 /**
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002191 * Returns the system's default subscription id.
2192 *
2193 * For a voice capable device, it will return getDefaultVoiceSubscriptionId.
2194 * For a data only device, it will return the getDefaultDataSubscriptionId.
2195 * May return an INVALID_SUBSCRIPTION_ID on error.
2196 *
2197 * @return the "system" default subscription id.
Wink Savillefb40dd42014-06-12 17:02:31 -07002198 */
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002199 public static int getDefaultSubscriptionId() {
Collin Fijalkovich4ffdedf2019-12-10 09:52:14 -08002200 return sDefaultSubIdCache.query(null);
Wink Savillefb40dd42014-06-12 17:02:31 -07002201 }
2202
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002203 /**
2204 * Returns the system's default voice subscription id.
2205 *
2206 * On a data only device or on error, will return INVALID_SUBSCRIPTION_ID.
2207 *
2208 * @return the default voice subscription Id.
2209 */
2210 public static int getDefaultVoiceSubscriptionId() {
Wink Savilled09c4ca2014-11-22 10:08:16 -08002211 int subId = INVALID_SUBSCRIPTION_ID;
Wink Savillefb40dd42014-06-12 17:02:31 -07002212
2213 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002214 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07002215 if (iSub != null) {
2216 subId = iSub.getDefaultVoiceSubId();
2217 }
2218 } catch (RemoteException ex) {
2219 // ignore it
2220 }
2221
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002222 if (VDBG) logd("getDefaultVoiceSubscriptionId, sub id = " + subId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002223 return subId;
2224 }
2225
Hall Liud2f962a2019-10-31 15:17:58 -07002226 /**
2227 * Sets the system's default voice subscription id.
2228 *
2229 * On a data-only device, this is a no-op.
2230 *
2231 * May throw a {@link RuntimeException} if the provided subscription id is equal to
2232 * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}
2233 *
2234 * @param subscriptionId A valid subscription ID to set as the system default, or
2235 * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}
2236 * @hide
2237 */
2238 @SystemApi
Hall Liud2f962a2019-10-31 15:17:58 -07002239 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
2240 public void setDefaultVoiceSubscriptionId(int subscriptionId) {
2241 if (VDBG) logd("setDefaultVoiceSubId sub id = " + subscriptionId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002242 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002243 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07002244 if (iSub != null) {
Hall Liud2f962a2019-10-31 15:17:58 -07002245 iSub.setDefaultVoiceSubId(subscriptionId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002246 }
2247 } catch (RemoteException ex) {
Wink Savillec650e0b2014-09-02 22:37:08 -07002248 // ignore it
Wink Savillefb40dd42014-06-12 17:02:31 -07002249 }
2250 }
2251
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002252 /**
Hall Liud2f962a2019-10-31 15:17:58 -07002253 * Same as {@link #setDefaultVoiceSubscriptionId(int)}, but preserved for backwards
2254 * compatibility.
2255 * @hide
2256 */
2257 public void setDefaultVoiceSubId(int subId) {
2258 setDefaultVoiceSubscriptionId(subId);
2259 }
2260
2261 /**
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002262 * Return the SubscriptionInfo for default voice subscription.
2263 *
2264 * Will return null on data only devices, or on error.
2265 *
2266 * @return the SubscriptionInfo for the default voice subscription.
2267 * @hide
2268 */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +00002269 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Wink Savilled09c4ca2014-11-22 10:08:16 -08002270 public SubscriptionInfo getDefaultVoiceSubscriptionInfo() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002271 return getActiveSubscriptionInfo(getDefaultVoiceSubscriptionId());
Wink Savillefb40dd42014-06-12 17:02:31 -07002272 }
2273
Wink Savillef5bca082014-09-03 15:13:33 -07002274 /** @hide */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +00002275 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Wink Savillec650e0b2014-09-02 22:37:08 -07002276 public static int getDefaultVoicePhoneId() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002277 return getPhoneId(getDefaultVoiceSubscriptionId());
Wink Savillefb40dd42014-06-12 17:02:31 -07002278 }
2279
Wink Saville905bb542014-09-04 17:10:23 -07002280 /**
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002281 * Returns the system's default SMS subscription id.
Wink Savilled09c4ca2014-11-22 10:08:16 -08002282 *
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002283 * On a data only device or on error, will return INVALID_SUBSCRIPTION_ID.
2284 *
2285 * @return the default SMS subscription Id.
Wink Saville905bb542014-09-04 17:10:23 -07002286 */
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002287 public static int getDefaultSmsSubscriptionId() {
Collin Fijalkovich02e5c592020-04-06 10:54:28 -07002288 return sDefaultSmsSubIdCache.query(null);
Wink Savillec650e0b2014-09-02 22:37:08 -07002289 }
2290
sqiandb496412018-11-12 18:14:18 -08002291 /**
2292 * Set the subscription which will be used by default for SMS, with the subscription which
2293 * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied
2294 * subscription ID is not usable (check with {@link #isUsableSubscriptionId(int)}).
2295 *
2296 * @param subscriptionId the supplied subscription ID
2297 *
2298 * @hide
2299 */
2300 @SystemApi
2301 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
2302 public void setDefaultSmsSubId(int subscriptionId) {
2303 if (VDBG) logd("setDefaultSmsSubId sub id = " + subscriptionId);
Wink Savillec650e0b2014-09-02 22:37:08 -07002304 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002305 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillec650e0b2014-09-02 22:37:08 -07002306 if (iSub != null) {
sqiandb496412018-11-12 18:14:18 -08002307 iSub.setDefaultSmsSubId(subscriptionId);
Wink Savillec650e0b2014-09-02 22:37:08 -07002308 }
2309 } catch (RemoteException ex) {
sqiana31ef442019-02-13 14:41:44 -08002310 ex.rethrowFromSystemServer();
Wink Savillec650e0b2014-09-02 22:37:08 -07002311 }
2312 }
2313
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002314 /**
2315 * Returns the system's default data subscription id.
2316 *
2317 * On a voice only device or on error, will return INVALID_SUBSCRIPTION_ID.
2318 *
2319 * @return the default data subscription Id.
2320 */
2321 public static int getDefaultDataSubscriptionId() {
Collin Fijalkovichce43a592020-03-25 14:30:21 -07002322 return sDefaultDataSubIdCache.query(null);
Wink Savillefb40dd42014-06-12 17:02:31 -07002323 }
2324
sqiandb496412018-11-12 18:14:18 -08002325 /**
2326 * Set the subscription which will be used by default for data, with the subscription which
2327 * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied
2328 * subscription ID is not usable (check with {@link #isUsableSubscriptionId(int)}).
2329 *
2330 * @param subscriptionId the supplied subscription ID
2331 *
2332 * @hide
2333 */
2334 @SystemApi
2335 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
2336 public void setDefaultDataSubId(int subscriptionId) {
2337 if (VDBG) logd("setDataSubscription sub id = " + subscriptionId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002338 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002339 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07002340 if (iSub != null) {
sqiandb496412018-11-12 18:14:18 -08002341 iSub.setDefaultDataSubId(subscriptionId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002342 }
2343 } catch (RemoteException ex) {
Wink Savillec650e0b2014-09-02 22:37:08 -07002344 // ignore it
Wink Savillefb40dd42014-06-12 17:02:31 -07002345 }
2346 }
2347
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002348 /**
2349 * Return the SubscriptionInfo for default data subscription.
2350 *
2351 * Will return null on voice only devices, or on error.
2352 *
2353 * @return the SubscriptionInfo for the default data subscription.
2354 * @hide
2355 */
Mathew Inwooda8382062018-08-16 17:01:12 +01002356 @UnsupportedAppUsage
Wink Savilled09c4ca2014-11-22 10:08:16 -08002357 public SubscriptionInfo getDefaultDataSubscriptionInfo() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08002358 return getActiveSubscriptionInfo(getDefaultDataSubscriptionId());
Wink Savillec650e0b2014-09-02 22:37:08 -07002359 }
Wink Savillefb40dd42014-06-12 17:02:31 -07002360
Wink Savillef5bca082014-09-03 15:13:33 -07002361 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -08002362 public void clearSubscriptionInfo() {
Wink Savillefb40dd42014-06-12 17:02:31 -07002363 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002364 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillefb40dd42014-06-12 17:02:31 -07002365 if (iSub != null) {
Robert Greenwalt278b8f92015-07-01 14:34:17 -07002366 iSub.clearSubInfo();
Wink Savillefb40dd42014-06-12 17:02:31 -07002367 }
2368 } catch (RemoteException ex) {
2369 // ignore it
2370 }
2371
2372 return;
2373 }
2374
Wink Savillec650e0b2014-09-02 22:37:08 -07002375 /**
sqian0bcdd6c2018-10-30 13:55:23 -07002376 * Check if the supplied subscription ID is valid.
2377 *
2378 * <p>A valid subscription ID is not necessarily an active subscription ID
2379 * (see {@link #isActiveSubscriptionId(int)}) or an usable subscription ID
2380 * (see {@link #isUsableSubscriptionId(int)}). Unless specifically noted, subscription
2381 * APIs work with a valid subscription ID.
sqian00dae7e02018-08-30 11:53:14 -07002382 *
2383 * @param subscriptionId The subscription ID.
sqian0bcdd6c2018-10-30 13:55:23 -07002384 * @return {@code true} if the supplied subscriptionId is valid; {@code false} otherwise.
Wink Saville905bb542014-09-04 17:10:23 -07002385 */
sqian00dae7e02018-08-30 11:53:14 -07002386 public static boolean isValidSubscriptionId(int subscriptionId) {
2387 return subscriptionId > INVALID_SUBSCRIPTION_ID;
Wink Savillec650e0b2014-09-02 22:37:08 -07002388 }
2389
Wink Saville8eab2b62014-09-23 14:20:58 -07002390 /**
sqian0bcdd6c2018-10-30 13:55:23 -07002391 * Check if the supplied subscription ID is usable.
sqian798da562018-09-12 16:31:17 -07002392 *
sqian0bcdd6c2018-10-30 13:55:23 -07002393 * <p>A usable subscription ID is a valid subscription ID, but not necessarily an active
2394 * subscription ID (see {@link #isActiveSubscriptionId(int)}). Some subscription APIs
2395 * require a usable subscription ID, and this is noted in their documentation; otherwise, a
2396 * subscription ID does not need to be usable for subscription functions, only valid.
sqian798da562018-09-12 16:31:17 -07002397 *
2398 * @param subscriptionId the subscription ID
2399 * @return {@code true} if the subscription ID is usable; {@code false} otherwise.
2400 */
2401 public static boolean isUsableSubscriptionId(int subscriptionId) {
2402 return isUsableSubIdValue(subscriptionId);
2403 }
2404
2405 /**
Wink Saville8eab2b62014-09-23 14:20:58 -07002406 * @return true if subId is an usable subId value else false. A
Wink Saville98513d72014-12-08 12:44:16 -08002407 * usable subId means its neither a INVALID_SUBSCRIPTION_ID nor a DEFAULT_SUB_ID.
Wink Saville8eab2b62014-09-23 14:20:58 -07002408 * @hide
2409 */
Chen Xu4c0b06d2018-10-22 16:54:39 +00002410 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
Wink Saville63f03dd2014-10-23 10:44:45 -07002411 public static boolean isUsableSubIdValue(int subId) {
Wink Savilled09c4ca2014-11-22 10:08:16 -08002412 return subId >= MIN_SUBSCRIPTION_ID_VALUE && subId <= MAX_SUBSCRIPTION_ID_VALUE;
Wink Saville8eab2b62014-09-23 14:20:58 -07002413 }
2414
Wink Savillef5bca082014-09-03 15:13:33 -07002415 /** @hide */
Mathew Inwood45d2c252018-09-14 12:35:36 +01002416 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Sanket Padawe7e460252017-03-10 16:18:20 -08002417 public static boolean isValidSlotIndex(int slotIndex) {
Malcolm Chena43e23f2019-10-21 14:22:18 -07002418 return slotIndex >= 0 && slotIndex < TelephonyManager.getDefault().getActiveModemCount();
Wink Savillec650e0b2014-09-02 22:37:08 -07002419 }
2420
Wink Savillef5bca082014-09-03 15:13:33 -07002421 /** @hide */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +00002422 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Wink Savillec650e0b2014-09-02 22:37:08 -07002423 public static boolean isValidPhoneId(int phoneId) {
Malcolm Chena43e23f2019-10-21 14:22:18 -07002424 return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getActiveModemCount();
Malcolm Chenf87292f2019-09-23 14:06:19 -07002425 }
2426
Wink Savillef5bca082014-09-03 15:13:33 -07002427 /** @hide */
Chen Xu4c0b06d2018-10-22 16:54:39 +00002428 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
Wink Savillefb40dd42014-06-12 17:02:31 -07002429 public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId) {
Wink Saville63f03dd2014-10-23 10:44:45 -07002430 int[] subIds = SubscriptionManager.getSubId(phoneId);
Wink Savillec650e0b2014-09-02 22:37:08 -07002431 if (subIds != null && subIds.length > 0) {
2432 putPhoneIdAndSubIdExtra(intent, phoneId, subIds[0]);
Wink Savillefb40dd42014-06-12 17:02:31 -07002433 } else {
2434 logd("putPhoneIdAndSubIdExtra: no valid subs");
Amit Mahajanba71c5f2019-02-07 12:29:55 -08002435 intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
Daniel Bright71d3dac2020-01-15 12:10:53 -08002436 intent.putExtra(EXTRA_SLOT_INDEX, phoneId);
Wink Savillefb40dd42014-06-12 17:02:31 -07002437 }
2438 }
Wink Savilleeeacf932014-06-18 01:07:10 -07002439
Wink Savillef5bca082014-09-03 15:13:33 -07002440 /** @hide */
Mathew Inwood5f0edaa2020-11-02 10:29:35 +00002441 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Wink Saville63f03dd2014-10-23 10:44:45 -07002442 public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId, int subId) {
Wink Savilleeeacf932014-06-18 01:07:10 -07002443 if (VDBG) logd("putPhoneIdAndSubIdExtra: phoneId=" + phoneId + " subId=" + subId);
Jack Yud8104ec2019-09-18 09:31:28 -07002444 intent.putExtra(EXTRA_SLOT_INDEX, phoneId);
Wink Savillec650e0b2014-09-02 22:37:08 -07002445 intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
Daniel Bright0b5d2852020-01-09 21:58:16 -08002446 putSubscriptionIdExtra(intent, subId);
Wink Savillec650e0b2014-09-02 22:37:08 -07002447 }
2448
2449 /**
Peter Wang01d128c2019-12-17 19:11:23 -08002450 * Get visible subscription Id(s) of the currently active SIM(s).
Hunter Knepshieldb26cbbd2019-07-03 14:22:32 -07002451 *
Wink Saville8a38a202014-09-03 12:22:54 -07002452 * @return the list of subId's that are active,
Peter Wang01d128c2019-12-17 19:11:23 -08002453 * is never null but the length may be 0.
Wink Savillef5bca082014-09-03 15:13:33 -07002454 * @hide
Wink Savillec650e0b2014-09-02 22:37:08 -07002455 */
Peter Wang01d128c2019-12-17 19:11:23 -08002456 @SystemApi
Peter Wangc061cdf2020-03-16 04:45:23 -07002457 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
Jeff Sharkey32566012014-12-02 18:30:14 -08002458 public @NonNull int[] getActiveSubscriptionIdList() {
Hunter Knepshieldb26cbbd2019-07-03 14:22:32 -07002459 return getActiveSubscriptionIdList(/* visibleOnly */ true);
2460 }
Wink Savillec650e0b2014-09-02 22:37:08 -07002461
Hunter Knepshieldb26cbbd2019-07-03 14:22:32 -07002462 /**
Peter Wang01d128c2019-12-17 19:11:23 -08002463 * Get both hidden and visible subscription Id(s) of the currently active SIM(s).
Hunter Knepshieldb26cbbd2019-07-03 14:22:32 -07002464 *
Peter Wang01d128c2019-12-17 19:11:23 -08002465 * Hidden subscriptions refer to those are not meant visible to the users.
2466 * For example, an opportunistic subscription that is grouped with other
2467 * subscriptions should remain invisible to users as they are only functionally
2468 * supplementary to primary ones.
2469 *
2470 * @return the list of subId's that are active,
2471 * is never null but the length may be 0.
2472 * @hide
2473 */
2474 @SystemApi
Peter Wangc061cdf2020-03-16 04:45:23 -07002475 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
2476 public @NonNull int[] getCompleteActiveSubscriptionIdList() {
Peter Wang01d128c2019-12-17 19:11:23 -08002477 return getActiveSubscriptionIdList(/* visibleOnly */false);
2478 }
2479
2480 /**
Hunter Knepshieldb26cbbd2019-07-03 14:22:32 -07002481 * @return a non-null list of subId's that are active.
2482 *
2483 * @hide
2484 */
2485 public @NonNull int[] getActiveSubscriptionIdList(boolean visibleOnly) {
Wink Savillec650e0b2014-09-02 22:37:08 -07002486 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002487 ISub iSub = TelephonyManager.getSubscriptionService();
Wink Savillec650e0b2014-09-02 22:37:08 -07002488 if (iSub != null) {
Hunter Knepshieldb26cbbd2019-07-03 14:22:32 -07002489 int[] subId = iSub.getActiveSubIdList(visibleOnly);
2490 if (subId != null) return subId;
Wink Savillec650e0b2014-09-02 22:37:08 -07002491 }
2492 } catch (RemoteException ex) {
2493 // ignore it
2494 }
2495
Hunter Knepshieldb26cbbd2019-07-03 14:22:32 -07002496 return new int[0];
Wink Savilleeeacf932014-06-18 01:07:10 -07002497 }
Wink Savilled09c4ca2014-11-22 10:08:16 -08002498
2499 /**
2500 * Returns true if the device is considered roaming on the current
2501 * network for a subscription.
2502 * <p>
2503 * Availability: Only when user registered to a network.
2504 *
2505 * @param subId The subscription ID
2506 * @return true if the network for the subscription is roaming, false otherwise
2507 */
2508 public boolean isNetworkRoaming(int subId) {
2509 final int phoneId = getPhoneId(subId);
2510 if (phoneId < 0) {
2511 // What else can we do?
2512 return false;
2513 }
Legler Wu85973dc2015-01-29 15:07:39 +08002514 return TelephonyManager.getDefault().isNetworkRoaming(subId);
Wink Savilled09c4ca2014-11-22 10:08:16 -08002515 }
Wink Saville47920fa2014-12-02 17:08:14 -08002516
2517 /**
Sanket Padawe7e460252017-03-10 16:18:20 -08002518 * Returns a constant indicating the state of sim for the slot index.
Wink Saville47920fa2014-12-02 17:08:14 -08002519 *
Sanket Padawe7e460252017-03-10 16:18:20 -08002520 * @param slotIndex
Wink Saville47920fa2014-12-02 17:08:14 -08002521 *
2522 * {@See TelephonyManager#SIM_STATE_UNKNOWN}
2523 * {@See TelephonyManager#SIM_STATE_ABSENT}
2524 * {@See TelephonyManager#SIM_STATE_PIN_REQUIRED}
2525 * {@See TelephonyManager#SIM_STATE_PUK_REQUIRED}
2526 * {@See TelephonyManager#SIM_STATE_NETWORK_LOCKED}
2527 * {@See TelephonyManager#SIM_STATE_READY}
2528 * {@See TelephonyManager#SIM_STATE_NOT_READY}
2529 * {@See TelephonyManager#SIM_STATE_PERM_DISABLED}
2530 * {@See TelephonyManager#SIM_STATE_CARD_IO_ERROR}
2531 *
2532 * {@hide}
2533 */
Sanket Padawe7e460252017-03-10 16:18:20 -08002534 public static int getSimStateForSlotIndex(int slotIndex) {
Sanket Padawe330dcac2015-06-18 12:08:01 -07002535 int simState = TelephonyManager.SIM_STATE_UNKNOWN;
Wink Saville47920fa2014-12-02 17:08:14 -08002536
2537 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002538 ISub iSub = TelephonyManager.getSubscriptionService();
Sanket Padawe330dcac2015-06-18 12:08:01 -07002539 if (iSub != null) {
Sanket Padawe7e460252017-03-10 16:18:20 -08002540 simState = iSub.getSimStateForSlotIndex(slotIndex);
Sanket Padawe330dcac2015-06-18 12:08:01 -07002541 }
Wink Saville47920fa2014-12-02 17:08:14 -08002542 } catch (RemoteException ex) {
Wink Saville47920fa2014-12-02 17:08:14 -08002543 }
Jack Yud2cf0ce2015-12-30 12:06:01 -08002544
Wink Saville47920fa2014-12-02 17:08:14 -08002545 return simState;
2546 }
Shishir Agrawal0ced7922014-12-10 10:20:39 -08002547
2548 /**
Sanket Padawedc493092015-07-14 14:21:43 -07002549 * Store properties associated with SubscriptionInfo in database
2550 * @param subId Subscription Id of Subscription
2551 * @param propKey Column name in database associated with SubscriptionInfo
2552 * @param propValue Value to store in DB for particular subId & column name
2553 * @hide
2554 */
2555 public static void setSubscriptionProperty(int subId, String propKey, String propValue) {
2556 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002557 ISub iSub = TelephonyManager.getSubscriptionService();
Sanket Padawedc493092015-07-14 14:21:43 -07002558 if (iSub != null) {
2559 iSub.setSubscriptionProperty(subId, propKey, propValue);
2560 }
2561 } catch (RemoteException ex) {
2562 // ignore it
2563 }
2564 }
2565
2566 /**
Grace Jia2bd23cf2021-03-18 14:47:31 -07002567 * Serialize list of contacts uri to string
2568 * @hide
2569 */
2570 public static String serializeUriLists(List<Uri> uris) {
2571 List<String> contacts = new ArrayList<>();
2572 for (Uri uri : uris) {
2573 contacts.add(uri.toString());
2574 }
2575 try {
2576 ByteArrayOutputStream bos = new ByteArrayOutputStream();
2577 ObjectOutputStream oos = new ObjectOutputStream(bos);
2578 oos.writeObject(contacts);
2579 oos.flush();
2580 return Base64.encodeToString(bos.toByteArray(), Base64.DEFAULT);
2581 } catch (IOException e) {
2582 logd("serializeUriLists IO exception");
2583 }
2584 return "";
2585 }
2586
2587 /**
2588 * Return list of contacts uri corresponding to query result.
2589 * @param subId Subscription Id of Subscription
2590 * @param propKey Column name in SubscriptionInfo database
2591 * @return list of contacts uri to be returned
2592 * @hide
2593 */
2594 private static List<Uri> getContactsFromSubscriptionProperty(int subId, String propKey,
2595 Context context) {
2596 String result = getSubscriptionProperty(subId, propKey, context);
2597 if (result != null) {
2598 try {
2599 byte[] b = Base64.decode(result, Base64.DEFAULT);
2600 ByteArrayInputStream bis = new ByteArrayInputStream(b);
2601 ObjectInputStream ois = new ObjectInputStream(bis);
2602 List<String> contacts = ArrayList.class.cast(ois.readObject());
2603 List<Uri> uris = new ArrayList<>();
2604 for (String contact : contacts) {
2605 uris.add(Uri.parse(contact));
2606 }
2607 return uris;
2608 } catch (IOException e) {
2609 logd("getContactsFromSubscriptionProperty IO exception");
2610 } catch (ClassNotFoundException e) {
2611 logd("getContactsFromSubscriptionProperty ClassNotFound exception");
2612 }
2613 }
2614 return new ArrayList<>();
2615 }
2616
2617 /**
Sanket Padawedc493092015-07-14 14:21:43 -07002618 * Store properties associated with SubscriptionInfo in database
2619 * @param subId Subscription Id of Subscription
2620 * @param propKey Column name in SubscriptionInfo database
2621 * @return Value associated with subId and propKey column in database
2622 * @hide
2623 */
2624 private static String getSubscriptionProperty(int subId, String propKey,
2625 Context context) {
2626 String resultValue = null;
2627 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002628 ISub iSub = TelephonyManager.getSubscriptionService();
Sanket Padawedc493092015-07-14 14:21:43 -07002629 if (iSub != null) {
Rajeev Kumarc8ac4f3b2017-07-26 15:59:08 -07002630 resultValue = iSub.getSubscriptionProperty(subId, propKey,
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08002631 context.getOpPackageName(), context.getAttributionTag());
Sanket Padawedc493092015-07-14 14:21:43 -07002632 }
2633 } catch (RemoteException ex) {
2634 // ignore it
2635 }
2636 return resultValue;
2637 }
2638
2639 /**
2640 * Returns boolean value corresponding to query result.
2641 * @param subId Subscription Id of Subscription
2642 * @param propKey Column name in SubscriptionInfo database
2643 * @param defValue Default boolean value to be returned
2644 * @return boolean result value to be returned
2645 * @hide
2646 */
2647 public static boolean getBooleanSubscriptionProperty(int subId, String propKey,
2648 boolean defValue, Context context) {
2649 String result = getSubscriptionProperty(subId, propKey, context);
2650 if (result != null) {
2651 try {
2652 return Integer.parseInt(result) == 1;
2653 } catch (NumberFormatException err) {
2654 logd("getBooleanSubscriptionProperty NumberFormat exception");
2655 }
2656 }
2657 return defValue;
2658 }
2659
2660 /**
2661 * Returns integer value corresponding to query result.
2662 * @param subId Subscription Id of Subscription
2663 * @param propKey Column name in SubscriptionInfo database
2664 * @param defValue Default integer value to be returned
2665 * @return integer result value to be returned
2666 * @hide
2667 */
2668 public static int getIntegerSubscriptionProperty(int subId, String propKey, int defValue,
2669 Context context) {
2670 String result = getSubscriptionProperty(subId, propKey, context);
2671 if (result != null) {
2672 try {
2673 return Integer.parseInt(result);
2674 } catch (NumberFormatException err) {
calvinpand77e0bd2020-01-14 20:37:31 +08002675 logd("getIntegerSubscriptionProperty NumberFormat exception");
2676 }
2677 }
2678 return defValue;
2679 }
2680
2681 /**
2682 * Returns long value corresponding to query result.
2683 * @param subId Subscription Id of Subscription
2684 * @param propKey Column name in SubscriptionInfo database
2685 * @param defValue Default long value to be returned
2686 * @return long result value to be returned
2687 * @hide
2688 */
2689 public static long getLongSubscriptionProperty(int subId, String propKey, long defValue,
2690 Context context) {
2691 String result = getSubscriptionProperty(subId, propKey, context);
2692 if (result != null) {
2693 try {
2694 return Long.parseLong(result);
2695 } catch (NumberFormatException err) {
2696 logd("getLongSubscriptionProperty NumberFormat exception");
Sanket Padawedc493092015-07-14 14:21:43 -07002697 }
2698 }
2699 return defValue;
2700 }
2701
2702 /**
Jordan Liue4141f02019-08-16 14:07:03 -07002703 * Returns the {@link Resources} from the given {@link Context} for the MCC/MNC associated with
2704 * the subscription. If the subscription ID is invalid, the base resources are returned instead.
2705 *
2706 * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
2707 *
Sanket Padawedc493092015-07-14 14:21:43 -07002708 * @param context Context object
Jordan Liue4141f02019-08-16 14:07:03 -07002709 * @param subId Subscription Id of Subscription whose resources are required
Sanket Padawedc493092015-07-14 14:21:43 -07002710 * @return Resources associated with Subscription.
2711 * @hide
2712 */
Jordan Liue4141f02019-08-16 14:07:03 -07002713 @NonNull
2714 @SystemApi
2715 public static Resources getResourcesForSubId(@NonNull Context context, int subId) {
Torbjorn Eklund99c11d82018-08-21 16:06:47 +02002716 return getResourcesForSubId(context, subId, false);
2717 }
2718
2719 /**
2720 * Returns the resources associated with Subscription.
2721 * @param context Context object
2722 * @param subId Subscription Id of Subscription who's resources are required
2723 * @param useRootLocale if root locale should be used. Localized locale is used if false.
2724 * @return Resources associated with Subscription.
2725 * @hide
2726 */
Torbjorn Eklundf8899f02019-11-20 10:59:59 +01002727 @NonNull
Torbjorn Eklund99c11d82018-08-21 16:06:47 +02002728 public static Resources getResourcesForSubId(Context context, int subId,
2729 boolean useRootLocale) {
Torbjorn Eklundf8899f02019-11-20 10:59:59 +01002730 // Check if resources for this context and subId already exist in the resource cache.
2731 // Resources that use the root locale are not cached.
2732 Pair<Context, Integer> cacheKey = null;
2733 if (isValidSubscriptionId(subId) && !useRootLocale) {
2734 cacheKey = Pair.create(context, subId);
2735 if (sResourcesCache.containsKey(cacheKey)) {
2736 // Cache hit. Use cached Resources.
2737 return sResourcesCache.get(cacheKey);
2738 }
2739 }
2740
Sanket Padawedc493092015-07-14 14:21:43 -07002741 final SubscriptionInfo subInfo =
2742 SubscriptionManager.from(context).getActiveSubscriptionInfo(subId);
2743
Jordan Liu0e161082020-01-21 10:55:08 -08002744 Configuration overrideConfig = new Configuration();
Sanket Padawedc493092015-07-14 14:21:43 -07002745 if (subInfo != null) {
Jordan Liu0e161082020-01-21 10:55:08 -08002746 overrideConfig.mcc = subInfo.getMcc();
2747 overrideConfig.mnc = subInfo.getMnc();
Willy Hu138b89d2021-03-22 11:36:54 +08002748 if (overrideConfig.mnc == 0) {
2749 overrideConfig.mnc = Configuration.MNC_ZERO;
2750 cacheKey = null;
2751 }
Hui Wang00e633c2022-03-15 21:53:49 +00002752 } else {
2753 cacheKey = null;
Sanket Padawedc493092015-07-14 14:21:43 -07002754 }
Torbjorn Eklund99c11d82018-08-21 16:06:47 +02002755
2756 if (useRootLocale) {
Jordan Liu0e161082020-01-21 10:55:08 -08002757 overrideConfig.setLocale(Locale.ROOT);
Torbjorn Eklund99c11d82018-08-21 16:06:47 +02002758 }
2759
Jordan Liu0e161082020-01-21 10:55:08 -08002760 // Create new context with new configuration so that we can avoid modifying the passed in
2761 // context.
2762 // Note that if the original context configuration changes, the resources here will also
2763 // change for all values except those overridden by newConfig (e.g. if the device has an
2764 // orientation change).
2765 Context newContext = context.createConfigurationContext(overrideConfig);
2766 Resources res = newContext.getResources();
Torbjorn Eklundf8899f02019-11-20 10:59:59 +01002767
2768 if (cacheKey != null) {
2769 // Save the newly created Resources in the resource cache.
2770 sResourcesCache.put(cacheKey, res);
2771 }
2772 return res;
Sanket Padawedc493092015-07-14 14:21:43 -07002773 }
2774
2775 /**
sqian0bcdd6c2018-10-30 13:55:23 -07002776 * Checks if the supplied subscription ID corresponds to a subscription which is actively in
2777 * use on the device. An active subscription ID is a valid and usable subscription ID.
sqianec149462018-09-10 19:05:51 -07002778 *
2779 * @param subscriptionId the subscription ID.
2780 * @return {@code true} if the supplied subscription ID corresponds to an active subscription;
2781 * {@code false} if it does not correspond to an active subscription; or throw a
2782 * SecurityException if the caller hasn't got the right permission.
2783 */
2784 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
2785 public boolean isActiveSubscriptionId(int subscriptionId) {
2786 return isActiveSubId(subscriptionId);
2787 }
2788
2789 /**
Shishir Agrawal0ced7922014-12-10 10:20:39 -08002790 * @return true if the sub ID is active. i.e. The sub ID corresponds to a known subscription
2791 * and the SIM providing the subscription is present in a slot and in "LOADED" state.
2792 * @hide
2793 */
Mathew Inwooda8382062018-08-16 17:01:12 +01002794 @UnsupportedAppUsage
Shishir Agrawal0ced7922014-12-10 10:20:39 -08002795 public boolean isActiveSubId(int subId) {
2796 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002797 ISub iSub = TelephonyManager.getSubscriptionService();
Sanket Padawe330dcac2015-06-18 12:08:01 -07002798 if (iSub != null) {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08002799 return iSub.isActiveSubId(subId, mContext.getOpPackageName(),
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08002800 mContext.getAttributionTag());
Sanket Padawe330dcac2015-06-18 12:08:01 -07002801 }
Shishir Agrawal0ced7922014-12-10 10:20:39 -08002802 } catch (RemoteException ex) {
2803 }
2804 return false;
2805 }
Jeff Sharkey53313d72017-07-13 16:47:32 -06002806
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002807 /**
2808 * Get the description of the billing relationship plan between a carrier
2809 * and a specific subscriber.
2810 * <p>
2811 * This method is only accessible to the following narrow set of apps:
2812 * <ul>
2813 * <li>The carrier app for this subscriberId, as determined by
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07002814 * {@link TelephonyManager#hasCarrierPrivileges()}.
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002815 * <li>The carrier app explicitly delegated access through
2816 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2817 * </ul>
2818 *
2819 * @param subId the subscriber this relationship applies to
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06002820 * @throws SecurityException if the caller doesn't meet the requirements
2821 * outlined above.
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002822 */
Jeff Sharkey53313d72017-07-13 16:47:32 -06002823 public @NonNull List<SubscriptionPlan> getSubscriptionPlans(int subId) {
Aaron Huang21089442020-01-16 23:31:02 +08002824 SubscriptionPlan[] subscriptionPlans =
2825 getNetworkPolicyManager().getSubscriptionPlans(subId, mContext.getOpPackageName());
2826 return subscriptionPlans == null
2827 ? Collections.emptyList() : Arrays.asList(subscriptionPlans);
Jeff Sharkey53313d72017-07-13 16:47:32 -06002828 }
2829
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002830 /**
2831 * Set the description of the billing relationship plan between a carrier
2832 * and a specific subscriber.
2833 * <p>
2834 * This method is only accessible to the following narrow set of apps:
2835 * <ul>
2836 * <li>The carrier app for this subscriberId, as determined by
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07002837 * {@link TelephonyManager#hasCarrierPrivileges()}.
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002838 * <li>The carrier app explicitly delegated access through
2839 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2840 * </ul>
2841 *
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06002842 * @param subId the subscriber this relationship applies to. An empty list
2843 * may be sent to clear any existing plans.
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002844 * @param plans the list of plans. The first plan is always the primary and
2845 * most important plan. Any additional plans are secondary and
2846 * may not be displayed or used by decision making logic.
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06002847 * @throws SecurityException if the caller doesn't meet the requirements
2848 * outlined above.
Sarah Chin80b73b92019-09-26 11:37:13 -07002849 * @throws IllegalArgumentException if plans don't meet the requirements
Sarah Chinc9e48d92019-10-29 15:30:24 -07002850 * defined in {@link SubscriptionPlan}.
Sarah Chine6f17fe2022-01-31 19:10:14 -08002851 * @deprecated use {@link #setSubscriptionPlans(int, List, long)} instead.
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002852 */
Sarah Chine6f17fe2022-01-31 19:10:14 -08002853 @Deprecated
Jeff Sharkey53313d72017-07-13 16:47:32 -06002854 public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans) {
Sarah Chine6f17fe2022-01-31 19:10:14 -08002855 setSubscriptionPlans(subId, plans, 0);
2856 }
2857
2858 /**
2859 * Set the description of the billing relationship plan between a carrier
2860 * and a specific subscriber.
2861 * <p>
2862 * This method is only accessible to the following narrow set of apps:
2863 * <ul>
2864 * <li>The carrier app for this subscriberId, as determined by
2865 * {@link TelephonyManager#hasCarrierPrivileges()}.
2866 * <li>The carrier app explicitly delegated access through
2867 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2868 * </ul>
2869 *
2870 * @param subId the subscriber this relationship applies to. An empty list
2871 * may be sent to clear any existing plans.
2872 * @param plans the list of plans. The first plan is always the primary and
2873 * most important plan. Any additional plans are secondary and
2874 * may not be displayed or used by decision making logic.
2875 * @param expirationDurationMillis the duration after which the subscription plans
2876 * will be automatically cleared, or {@code 0} to leave the plans until
2877 * explicitly cleared, or the next reboot, whichever happens first.
2878 * @throws SecurityException if the caller doesn't meet the requirements
2879 * outlined above.
2880 * @throws IllegalArgumentException if plans don't meet the requirements
2881 * defined in {@link SubscriptionPlan}.
2882 */
2883 public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans,
2884 @DurationMillisLong long expirationDurationMillis) {
Aaron Huang21089442020-01-16 23:31:02 +08002885 getNetworkPolicyManager().setSubscriptionPlans(subId,
Sarah Chine6f17fe2022-01-31 19:10:14 -08002886 plans.toArray(new SubscriptionPlan[0]), expirationDurationMillis,
2887 mContext.getOpPackageName());
Jeff Sharkey53313d72017-07-13 16:47:32 -06002888 }
Jeff Sharkey717f52f2018-01-04 16:04:11 -07002889
Jeff Sharkey717f52f2018-01-04 16:04:11 -07002890 /**
Jeff Sharkey9252b342018-01-19 07:58:35 +09002891 * Temporarily override the billing relationship plan between a carrier and
2892 * a specific subscriber to be considered unmetered. This will be reflected
2893 * to apps via {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED}.
2894 * <p>
2895 * This method is only accessible to the following narrow set of apps:
2896 * <ul>
2897 * <li>The carrier app for this subscriberId, as determined by
2898 * {@link TelephonyManager#hasCarrierPrivileges()}.
2899 * <li>The carrier app explicitly delegated access through
2900 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2901 * </ul>
2902 *
2903 * @param subId the subscriber this override applies to.
2904 * @param overrideUnmetered set if the billing relationship should be
2905 * considered unmetered.
Sarah Chine6f17fe2022-01-31 19:10:14 -08002906 * @param expirationDurationMillis the duration after which the requested override
2907 * will be automatically cleared, or {@code 0} to leave in the
Jeff Sharkey9252b342018-01-19 07:58:35 +09002908 * requested state until explicitly cleared, or the next reboot,
2909 * whichever happens first.
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06002910 * @throws SecurityException if the caller doesn't meet the requirements
Sarah Chinb321fb52021-01-07 16:40:16 -08002911 * outlined above.
Jeff Sharkey9252b342018-01-19 07:58:35 +09002912 */
Jeff Sharkey9252b342018-01-19 07:58:35 +09002913 public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered,
Sarah Chine6f17fe2022-01-31 19:10:14 -08002914 @DurationMillisLong long expirationDurationMillis) {
Sarah Chinb321fb52021-01-07 16:40:16 -08002915 setSubscriptionOverrideUnmetered(subId, overrideUnmetered,
Sarah Chine6f17fe2022-01-31 19:10:14 -08002916 TelephonyManager.getAllNetworkTypes(), expirationDurationMillis);
Sarah Chinb321fb52021-01-07 16:40:16 -08002917 }
Aaron Huang21089442020-01-16 23:31:02 +08002918
Sarah Chinb321fb52021-01-07 16:40:16 -08002919 /**
2920 * Temporarily override the billing relationship plan between a carrier and
2921 * a specific subscriber to be considered unmetered. This will be reflected
2922 * to apps via {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED}.
2923 * <p>
2924 * This method is only accessible to the following narrow set of apps:
2925 * <ul>
2926 * <li>The carrier app for this subscriberId, as determined by
2927 * {@link TelephonyManager#hasCarrierPrivileges()}.
2928 * <li>The carrier app explicitly delegated access through
2929 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2930 * </ul>
2931 *
2932 * @param subId the subscriber this override applies to.
2933 * @param overrideUnmetered set if the billing relationship should be
2934 * considered unmetered.
Sarah Chinf7e9c832021-04-15 19:40:25 -07002935 * @param networkTypes the network types this override applies to. If no
2936 * network types are specified, override values will be ignored.
Sarah Chinb321fb52021-01-07 16:40:16 -08002937 * {@see TelephonyManager#getAllNetworkTypes()}
Sarah Chine6f17fe2022-01-31 19:10:14 -08002938 * @param expirationDurationMillis the duration after which the requested override
2939 * will be automatically cleared, or {@code 0} to leave in the
Sarah Chinb321fb52021-01-07 16:40:16 -08002940 * requested state until explicitly cleared, or the next reboot,
2941 * whichever happens first.
2942 * @throws SecurityException if the caller doesn't meet the requirements
2943 * outlined above.
2944 */
2945 public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered,
2946 @NonNull @Annotation.NetworkType int[] networkTypes,
Sarah Chine6f17fe2022-01-31 19:10:14 -08002947 @DurationMillisLong long expirationDurationMillis) {
Aaron Huang21089442020-01-16 23:31:02 +08002948 final int overrideValue = overrideUnmetered ? SUBSCRIPTION_OVERRIDE_UNMETERED : 0;
2949 getNetworkPolicyManager().setSubscriptionOverride(subId, SUBSCRIPTION_OVERRIDE_UNMETERED,
Sarah Chine6f17fe2022-01-31 19:10:14 -08002950 overrideValue, networkTypes, expirationDurationMillis, mContext.getOpPackageName());
Jeff Sharkey9252b342018-01-19 07:58:35 +09002951 }
2952
2953 /**
2954 * Temporarily override the billing relationship plan between a carrier and
2955 * a specific subscriber to be considered congested. This will cause the
2956 * device to delay certain network requests when possible, such as developer
2957 * jobs that are willing to run in a flexible time window.
2958 * <p>
2959 * This method is only accessible to the following narrow set of apps:
2960 * <ul>
2961 * <li>The carrier app for this subscriberId, as determined by
2962 * {@link TelephonyManager#hasCarrierPrivileges()}.
2963 * <li>The carrier app explicitly delegated access through
2964 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2965 * </ul>
2966 *
2967 * @param subId the subscriber this override applies to.
2968 * @param overrideCongested set if the subscription should be considered
2969 * congested.
Sarah Chine6f17fe2022-01-31 19:10:14 -08002970 * @param expirationDurationMillis the duration after which the requested override
2971 * will be automatically cleared, or {@code 0} to leave in the
Jeff Sharkey9252b342018-01-19 07:58:35 +09002972 * requested state until explicitly cleared, or the next reboot,
2973 * whichever happens first.
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06002974 * @throws SecurityException if the caller doesn't meet the requirements
Sarah Chinb321fb52021-01-07 16:40:16 -08002975 * outlined above.
Jeff Sharkey9252b342018-01-19 07:58:35 +09002976 */
Jeff Sharkey9252b342018-01-19 07:58:35 +09002977 public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested,
Sarah Chine6f17fe2022-01-31 19:10:14 -08002978 @DurationMillisLong long expirationDurationMillis) {
Sarah Chinb321fb52021-01-07 16:40:16 -08002979 setSubscriptionOverrideCongested(subId, overrideCongested,
Sarah Chine6f17fe2022-01-31 19:10:14 -08002980 TelephonyManager.getAllNetworkTypes(), expirationDurationMillis);
Sarah Chinb321fb52021-01-07 16:40:16 -08002981 }
2982
2983 /**
2984 * Temporarily override the billing relationship plan between a carrier and
2985 * a specific subscriber to be considered congested. This will cause the
2986 * device to delay certain network requests when possible, such as developer
2987 * jobs that are willing to run in a flexible time window.
2988 * <p>
2989 * This method is only accessible to the following narrow set of apps:
2990 * <ul>
2991 * <li>The carrier app for this subscriberId, as determined by
2992 * {@link TelephonyManager#hasCarrierPrivileges()}.
2993 * <li>The carrier app explicitly delegated access through
2994 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2995 * </ul>
2996 *
2997 * @param subId the subscriber this override applies to.
2998 * @param overrideCongested set if the subscription should be considered
2999 * congested.
Sarah Chinf7e9c832021-04-15 19:40:25 -07003000 * @param networkTypes the network types this override applies to. If no
3001 * network types are specified, override values will be ignored.
Sarah Chinb321fb52021-01-07 16:40:16 -08003002 * {@see TelephonyManager#getAllNetworkTypes()}
Sarah Chine6f17fe2022-01-31 19:10:14 -08003003 * @param expirationDurationMillis the duration after which the requested override
3004 * will be automatically cleared, or {@code 0} to leave in the
Sarah Chinb321fb52021-01-07 16:40:16 -08003005 * requested state until explicitly cleared, or the next reboot,
3006 * whichever happens first.
3007 * @throws SecurityException if the caller doesn't meet the requirements
3008 * outlined above.
3009 */
3010 public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested,
3011 @NonNull @Annotation.NetworkType int[] networkTypes,
Sarah Chine6f17fe2022-01-31 19:10:14 -08003012 @DurationMillisLong long expirationDurationMillis) {
Aaron Huang21089442020-01-16 23:31:02 +08003013 final int overrideValue = overrideCongested ? SUBSCRIPTION_OVERRIDE_CONGESTED : 0;
3014 getNetworkPolicyManager().setSubscriptionOverride(subId, SUBSCRIPTION_OVERRIDE_CONGESTED,
Sarah Chine6f17fe2022-01-31 19:10:14 -08003015 overrideValue, networkTypes, expirationDurationMillis, mContext.getOpPackageName());
Jeff Sharkey9252b342018-01-19 07:58:35 +09003016 }
3017
3018 /**
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003019 * Checks whether the app with the given context is authorized to manage the given subscription
Malcolm Chen2619a9b2019-12-26 13:17:34 -08003020 * according to its metadata.
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003021 *
Sarah Chin172f15e2021-02-23 12:21:24 -08003022 * Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded} returns
3023 * true). To check for permissions for non-embedded subscription as well,
3024 * {@see android.telephony.TelephonyManager#hasCarrierPrivileges}.
3025 *
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003026 * @param info The subscription to check.
3027 * @return whether the app is authorized to manage this subscription per its metadata.
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003028 */
3029 public boolean canManageSubscription(SubscriptionInfo info) {
3030 return canManageSubscription(info, mContext.getPackageName());
3031 }
3032
3033 /**
Holly Jiuyu Sun59159c42018-03-15 18:06:42 -07003034 * Checks whether the given app is authorized to manage the given subscription. An app can only
3035 * be authorized if it is included in the {@link android.telephony.UiccAccessRule} of the
3036 * {@link android.telephony.SubscriptionInfo} with the access status.
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003037 *
Sarah Chin172f15e2021-02-23 12:21:24 -08003038 * Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded} returns
3039 * true). To check for permissions for non-embedded subscription as well,
3040 * {@see android.telephony.TelephonyManager#hasCarrierPrivileges}.
3041 *
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003042 * @param info The subscription to check.
3043 * @param packageName Package name of the app to check.
Holly Jiuyu Sun59159c42018-03-15 18:06:42 -07003044 * @return whether the app is authorized to manage this subscription per its access rules.
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003045 * @hide
3046 */
Malcolm Chen2619a9b2019-12-26 13:17:34 -08003047 @SystemApi
Malcolm Chen05d1ed12020-02-25 17:50:05 -08003048 public boolean canManageSubscription(@NonNull SubscriptionInfo info,
3049 @NonNull String packageName) {
Jack Yu27209092022-09-14 00:40:57 -07003050 if (info == null || info.getAccessRules() == null || packageName == null) {
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003051 return false;
3052 }
3053 PackageManager packageManager = mContext.getPackageManager();
3054 PackageInfo packageInfo;
3055 try {
Cheonho Park51586d52019-07-31 14:19:41 +09003056 packageInfo = packageManager.getPackageInfo(packageName,
3057 PackageManager.GET_SIGNING_CERTIFICATES);
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003058 } catch (PackageManager.NameNotFoundException e) {
Nazanin Bakhshi293ecad2019-08-29 16:19:12 -07003059 logd("Unknown package: " + packageName);
3060 return false;
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003061 }
Jack Yu27209092022-09-14 00:40:57 -07003062 for (UiccAccessRule rule : info.getAccessRules()) {
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08003063 if (rule.getCarrierPrivilegeStatus(packageInfo)
3064 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
3065 return true;
3066 }
3067 }
3068 return false;
3069 }
Malcolm Chenbd4ae762018-08-03 17:24:07 -07003070
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003071 /**
Malcolm Chen009f0a92018-10-22 20:03:46 -07003072 * Set which subscription is preferred for cellular data.
3073 * It's also usually the subscription we set up internet connection on.
Malcolm Chen8cf1b782018-09-24 20:00:08 -07003074 *
3075 * PreferredData overwrites user setting of default data subscription. And it's used
Malcolm Chen009f0a92018-10-22 20:03:46 -07003076 * by AlternativeNetworkService or carrier apps to switch primary and CBRS
Malcolm Chenc1873af2018-09-24 20:01:32 -07003077 * subscription dynamically in multi-SIM devices.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003078 *
Malcolm Chen009f0a92018-10-22 20:03:46 -07003079 * @param subId which subscription is preferred to for cellular data. If it's
Malcolm Chen003c8e52018-11-12 20:13:29 -08003080 * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}, it means
Malcolm Chen009f0a92018-10-22 20:03:46 -07003081 * it's unset and {@link SubscriptionManager#getDefaultDataSubscriptionId()}
3082 * is used to determine which modem is preferred.
Malcolm Chenfe577d32019-03-18 17:26:43 -07003083 * @param needValidation whether Telephony will wait until the network is validated by
3084 * connectivity service before switching data to it. More details see
3085 * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED}.
Malcolm Chenfd11df22019-02-05 17:19:48 -08003086 * @param executor The executor of where the callback will execute.
3087 * @param callback Callback will be triggered once it succeeds or failed.
Malcolm Chen9ee14732019-03-29 18:30:23 -07003088 * Pass null if don't care about the result.
Malcolm Chenfd11df22019-02-05 17:19:48 -08003089 *
Jack Yu58ac8382022-07-20 01:09:19 -07003090 * @throws IllegalStateException when subscription manager service is not available.
3091 * @throws SecurityException when clients do not have MODIFY_PHONE_STATE permission.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003092 * @hide
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003093 */
Malcolm Chenfd11df22019-02-05 17:19:48 -08003094 @SystemApi
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003095 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
Malcolm Chenfd11df22019-02-05 17:19:48 -08003096 public void setPreferredDataSubscriptionId(int subId, boolean needValidation,
Malcolm Chen9ee14732019-03-29 18:30:23 -07003097 @Nullable @CallbackExecutor Executor executor, @Nullable
3098 @TelephonyManager.SetOpportunisticSubscriptionResult Consumer<Integer> callback) {
Nazanin Bakhshie0215a72019-01-04 17:38:36 -08003099 if (VDBG) logd("[setPreferredDataSubscriptionId]+ subId:" + subId);
Malcolm Chend78dac02019-01-24 16:33:51 -08003100 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003101 ISub iSub = TelephonyManager.getSubscriptionService();
Jack Yu58ac8382022-07-20 01:09:19 -07003102 if (iSub == null) {
3103 throw new IllegalStateException("subscription manager service is null.");
3104 }
Malcolm Chenfd11df22019-02-05 17:19:48 -08003105
3106 ISetOpportunisticDataCallback callbackStub = new ISetOpportunisticDataCallback.Stub() {
3107 @Override
3108 public void onComplete(int result) {
Sooraj Sasindran3b09d712019-02-28 14:46:14 -08003109 if (executor == null || callback == null) {
3110 return;
3111 }
Sooraj Sasindrane6a2c0a2019-11-26 13:56:49 -08003112 final long identity = Binder.clearCallingIdentity();
3113 try {
3114 executor.execute(() -> {
3115 callback.accept(result);
3116 });
3117 } finally {
3118 Binder.restoreCallingIdentity(identity);
3119 }
Malcolm Chenfd11df22019-02-05 17:19:48 -08003120 }
3121 };
3122 iSub.setPreferredDataSubscriptionId(subId, needValidation, callbackStub);
Malcolm Chend78dac02019-01-24 16:33:51 -08003123 } catch (RemoteException ex) {
Jack Yu58ac8382022-07-20 01:09:19 -07003124 loge("setPreferredDataSubscriptionId RemoteException=" + ex);
3125 ex.rethrowFromSystemServer();
Malcolm Chend78dac02019-01-24 16:33:51 -08003126 }
Nazanin Bakhshie0215a72019-01-04 17:38:36 -08003127 }
3128
3129 /**
3130 * Get which subscription is preferred for cellular data.
3131 * It's also usually the subscription we set up internet connection on.
3132 *
3133 * PreferredData overwrites user setting of default data subscription. And it's used
3134 * by AlternativeNetworkService or carrier apps to switch primary and CBRS
3135 * subscription dynamically in multi-SIM devices.
3136 *
3137 * @return preferred subscription id for cellular data. {@link DEFAULT_SUBSCRIPTION_ID} if
3138 * there's no prefered subscription.
3139 *
3140 * @hide
3141 *
3142 */
3143 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
3144 public int getPreferredDataSubscriptionId() {
3145 int preferredSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
3146 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003147 ISub iSub = TelephonyManager.getSubscriptionService();
Nazanin Bakhshie0215a72019-01-04 17:38:36 -08003148 if (iSub != null) {
3149 preferredSubId = iSub.getPreferredDataSubscriptionId();
3150 }
3151 } catch (RemoteException ex) {
3152 // ignore it
3153 }
3154
3155 return preferredSubId;
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003156 }
3157
3158 /**
Malcolm Chen44137862018-10-23 18:44:03 -07003159 * Return opportunistic subscriptions that can be visible to the caller.
3160 * Opportunistic subscriptions are for opportunistic networks, which are cellular
3161 * networks with limited capabilities and coverage, for example, CBRS.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003162 *
Malcolm Chen44137862018-10-23 18:44:03 -07003163 * <p>Requires Permission:
3164 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
3165 * or that the calling app has carrier privileges (see
3166 * {@link TelephonyManager#hasCarrierPrivileges}).
3167 *
3168 * @return the list of opportunistic subscription info. If none exists, an empty list.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003169 */
Malcolm Chen44137862018-10-23 18:44:03 -07003170 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003171 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
Malcolm Chen44137862018-10-23 18:44:03 -07003172 public @NonNull List<SubscriptionInfo> getOpportunisticSubscriptions() {
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08003173 String contextPkg = mContext != null ? mContext.getOpPackageName() : "<unknown>";
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08003174 String contextAttributionTag = mContext != null ? mContext.getAttributionTag() : null;
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003175 List<SubscriptionInfo> subInfoList = null;
3176
3177 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003178 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003179 if (iSub != null) {
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08003180 subInfoList = iSub.getOpportunisticSubscriptions(contextPkg,
3181 contextAttributionTag);
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003182 }
3183 } catch (RemoteException ex) {
3184 // ignore it
3185 }
3186
3187 if (subInfoList == null) {
3188 subInfoList = new ArrayList<>();
3189 }
3190
3191 return subInfoList;
3192 }
3193
3194 /**
3195 * Switch to a certain subscription
3196 *
3197 * @param subId sub id
3198 * @param callbackIntent pending intent that will be sent after operation is done.
sandeepjsb061a762022-03-24 10:30:59 +00003199 *
3200 * to-be-deprecated this API is a duplicate of {@link EuiccManager#switchToSubscription(int,
3201 * PendingIntent)} and does not support Multiple Enabled Profile(MEP). Apps should use
3202 * {@link EuiccManager#switchToSubscription(int, PendingIntent)} or
3203 * {@link EuiccManager#switchToSubscription(int, int, PendingIntent)} instead.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003204 */
3205 @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
Malcolm Chen80e1e5c2019-02-27 15:16:05 -08003206 public void switchToSubscription(int subId, @NonNull PendingIntent callbackIntent) {
3207 Preconditions.checkNotNull(callbackIntent, "callbackIntent cannot be null");
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003208 EuiccManager euiccManager = new EuiccManager(mContext);
3209 euiccManager.switchToSubscription(subId, callbackIntent);
3210 }
3211
3212 /**
Malcolm Chend4dc4ee2018-12-11 13:56:53 -08003213 * Set whether a subscription is opportunistic, that is, whether the network it connects
3214 * to has limited coverage. For example, CBRS. Setting a subscription opportunistic has
3215 * following impacts:
3216 * 1) Even if it's active, it will be dormant most of the time. The modem will not try
3217 * to scan or camp until it knows an available network is nearby to save power.
3218 * 2) Telephony relies on system app or carrier input to notify nearby available networks.
danielwbhuanga3358802019-03-11 11:52:10 +08003219 * See {@link TelephonyManager#updateAvailableNetworks(List, Executor, Consumer)}
3220 * for more information.
Malcolm Chend4dc4ee2018-12-11 13:56:53 -08003221 * 3) In multi-SIM devices, when the network is nearby and camped, system may automatically
3222 * switch internet data between it and default data subscription, based on carrier
3223 * recommendation and its signal strength and metered-ness, etc.
3224 *
3225 *
3226 * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE} or carrier
3227 * privilege permission of the subscription.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003228 *
3229 * @param opportunistic whether it’s opportunistic subscription.
3230 * @param subId the unique SubscriptionInfo index in database
Malcolm Chend4dc4ee2018-12-11 13:56:53 -08003231 * @return {@code true} if the operation is succeed, {@code false} otherwise.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003232 */
Malcolm Chend4dc4ee2018-12-11 13:56:53 -08003233 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003234 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
Malcolm Chend4dc4ee2018-12-11 13:56:53 -08003235 public boolean setOpportunistic(boolean opportunistic, int subId) {
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003236 if (VDBG) logd("[setOpportunistic]+ opportunistic:" + opportunistic + " subId:" + subId);
3237 return setSubscriptionPropertyHelper(subId, "setOpportunistic",
Malcolm Chend4dc4ee2018-12-11 13:56:53 -08003238 (iSub)-> iSub.setOpportunistic(
3239 opportunistic, subId, mContext.getOpPackageName())) == 1;
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003240 }
3241
3242 /**
Malcolm Chenaea9b022018-10-31 20:18:02 -07003243 * Inform SubscriptionManager that subscriptions in the list are bundled
Malcolm Chen4674a792019-03-20 20:32:27 -07003244 * as a group. It can be multiple primary (non-opportunistic) subscriptions,
3245 * or one or more primary plus one or more opportunistic subscriptions.
3246 *
3247 * This API will always create a new immutable group and assign group UUID to all the
3248 * subscriptions, regardless whether they are in a group already or not.
3249 *
3250 * Grouped subscriptions will have below behaviors:
3251 * 1) They will share the same user settings.
3252 * 2) The opportunistic subscriptions in the group is considered invisible and will not
3253 * return from {@link #getActiveSubscriptionInfoList()}, unless caller has carrier
3254 * privilege permission of the subscriptions.
3255 * 3) The opportunistic subscriptions in the group can't be active by itself. If all other
3256 * non-opportunistic ones are deactivated (unplugged or disabled in Settings),
3257 * the opportunistic ones will be deactivated automatically.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003258 *
John Reckc877f582018-11-16 15:46:02 -08003259 * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003260 * permission or had carrier privilege permission on the subscriptions:
Malcolm Chen18350e42018-12-12 10:29:16 -08003261 * {@link TelephonyManager#hasCarrierPrivileges()} or
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003262 * {@link #canManageSubscription(SubscriptionInfo)}
3263 *
3264 * @throws SecurityException if the caller doesn't meet the requirements
3265 * outlined above.
Malcolm Chen3c976932019-04-03 18:39:21 -07003266 * @throws IllegalArgumentException if any of the subscriptions in the list doesn't exist.
3267 * @throws IllegalStateException if Telephony service is in bad state.
Malcolm Chenaea9b022018-10-31 20:18:02 -07003268 *
3269 * @param subIdList list of subId that will be in the same group
Malcolm Chen4674a792019-03-20 20:32:27 -07003270 * @return groupUUID a UUID assigned to the subscription group.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003271 *
3272 */
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003273 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003274 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
Malcolm Chen4674a792019-03-20 20:32:27 -07003275 public @NonNull ParcelUuid createSubscriptionGroup(@NonNull List<Integer> subIdList) {
3276 Preconditions.checkNotNull(subIdList, "can't create group for null subId list");
Malcolm Chenaea9b022018-10-31 20:18:02 -07003277 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
3278 if (VDBG) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003279 logd("[createSubscriptionGroup]");
Malcolm Chenaea9b022018-10-31 20:18:02 -07003280 }
3281
Malcolm Chen4674a792019-03-20 20:32:27 -07003282 ParcelUuid groupUuid = null;
3283 int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray();
Malcolm Chenaea9b022018-10-31 20:18:02 -07003284 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003285 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chenaea9b022018-10-31 20:18:02 -07003286 if (iSub != null) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003287 groupUuid = iSub.createSubscriptionGroup(subIdArray, pkgForDebug);
3288 } else {
3289 if (!isSystemProcess()) {
3290 throw new IllegalStateException("telephony service is null.");
3291 }
Malcolm Chenaea9b022018-10-31 20:18:02 -07003292 }
3293 } catch (RemoteException ex) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003294 loge("createSubscriptionGroup RemoteException " + ex);
3295 if (!isSystemProcess()) {
3296 ex.rethrowAsRuntimeException();
3297 }
Malcolm Chenaea9b022018-10-31 20:18:02 -07003298 }
3299
Malcolm Chen4674a792019-03-20 20:32:27 -07003300 return groupUuid;
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07003301 }
3302
Nazanin Bakhshib9b87be2018-11-21 16:32:05 -08003303 /**
Malcolm Chen4674a792019-03-20 20:32:27 -07003304 * Add a list of subscriptions into a group.
3305 * See {@link #createSubscriptionGroup(List)} for more details.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003306 *
3307 * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
3308 * permission or had carrier privilege permission on the subscriptions:
Malcolm Chen18350e42018-12-12 10:29:16 -08003309 * {@link TelephonyManager#hasCarrierPrivileges()} or
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003310 * {@link #canManageSubscription(SubscriptionInfo)}
3311 *
3312 * @throws SecurityException if the caller doesn't meet the requirements
3313 * outlined above.
Malcolm Chen710a09a2019-08-22 13:07:30 -07003314 * @throws IllegalArgumentException if the some subscriptions in the list doesn't exist.
Malcolm Chen3c976932019-04-03 18:39:21 -07003315 * @throws IllegalStateException if Telephony service is in bad state.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003316 *
Malcolm Chen4674a792019-03-20 20:32:27 -07003317 * @param subIdList list of subId that need adding into the group
3318 * @param groupUuid the groupUuid the subscriptions are being added to.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003319 *
3320 */
3321 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
3322 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
Malcolm Chen4674a792019-03-20 20:32:27 -07003323 public void addSubscriptionsIntoGroup(@NonNull List<Integer> subIdList,
3324 @NonNull ParcelUuid groupUuid) {
3325 Preconditions.checkNotNull(subIdList, "subIdList can't be null.");
3326 Preconditions.checkNotNull(groupUuid, "groupUuid can't be null.");
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003327 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
3328 if (VDBG) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003329 logd("[addSubscriptionsIntoGroup]");
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003330 }
3331
Malcolm Chen4674a792019-03-20 20:32:27 -07003332 int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray();
3333
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003334 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003335 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003336 if (iSub != null) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003337 iSub.addSubscriptionsIntoGroup(subIdArray, groupUuid, pkgForDebug);
3338 } else {
3339 if (!isSystemProcess()) {
3340 throw new IllegalStateException("telephony service is null.");
3341 }
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003342 }
3343 } catch (RemoteException ex) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003344 loge("addSubscriptionsIntoGroup RemoteException " + ex);
3345 if (!isSystemProcess()) {
3346 ex.rethrowAsRuntimeException();
3347 }
3348 }
3349 }
3350
3351 private boolean isSystemProcess() {
3352 return Process.myUid() == Process.SYSTEM_UID;
3353 }
3354
3355 /**
3356 * Remove a list of subscriptions from their subscription group.
3357 * See {@link #createSubscriptionGroup(List)} for more details.
3358 *
3359 * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
3360 * permission or had carrier privilege permission on the subscriptions:
3361 * {@link TelephonyManager#hasCarrierPrivileges()} or
3362 * {@link #canManageSubscription(SubscriptionInfo)}
3363 *
3364 * @throws SecurityException if the caller doesn't meet the requirements
3365 * outlined above.
3366 * @throws IllegalArgumentException if the some subscriptions in the list doesn't belong
3367 * the specified group.
Malcolm Chen3c976932019-04-03 18:39:21 -07003368 * @throws IllegalStateException if Telephony service is in bad state.
Malcolm Chen4674a792019-03-20 20:32:27 -07003369 *
3370 * @param subIdList list of subId that need removing from their groups.
3371 *
3372 */
3373 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
3374 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
3375 public void removeSubscriptionsFromGroup(@NonNull List<Integer> subIdList,
3376 @NonNull ParcelUuid groupUuid) {
3377 Preconditions.checkNotNull(subIdList, "subIdList can't be null.");
3378 Preconditions.checkNotNull(groupUuid, "groupUuid can't be null.");
3379 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
3380 if (VDBG) {
3381 logd("[removeSubscriptionsFromGroup]");
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003382 }
3383
Malcolm Chen4674a792019-03-20 20:32:27 -07003384 int[] subIdArray = subIdList.stream().mapToInt(i->i).toArray();
3385
3386 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003387 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chen4674a792019-03-20 20:32:27 -07003388 if (iSub != null) {
3389 iSub.removeSubscriptionsFromGroup(subIdArray, groupUuid, pkgForDebug);
3390 } else {
3391 if (!isSystemProcess()) {
3392 throw new IllegalStateException("telephony service is null.");
3393 }
3394 }
3395 } catch (RemoteException ex) {
3396 loge("removeSubscriptionsFromGroup RemoteException " + ex);
3397 if (!isSystemProcess()) {
3398 ex.rethrowAsRuntimeException();
3399 }
3400 }
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003401 }
3402
3403 /**
3404 * Get subscriptionInfo list of subscriptions that are in the same group of given subId.
Malcolm Chen4674a792019-03-20 20:32:27 -07003405 * See {@link #createSubscriptionGroup(List)} for more details.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003406 *
hyosun91934802022-04-26 13:24:27 +00003407 * Caller must have {@link android.Manifest.permission#READ_PHONE_STATE}
3408 * or carrier privilege permission on the subscription.
Malcolm Chen18350e42018-12-12 10:29:16 -08003409 * {@link TelephonyManager#hasCarrierPrivileges()}
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003410 *
hyosun91934802022-04-26 13:24:27 +00003411 * <p>Starting with API level 33, the caller also needs permission to access device identifiers
3412 * to get the list of subscriptions associated with a group UUID.
3413 * This method can be invoked if one of the following requirements is met:
3414 * <ul>
3415 * <li>If the app has carrier privilege permission.
3416 * {@link TelephonyManager#hasCarrierPrivileges()}
3417 * <li>If the app has {@link android.Manifest.permission#READ_PHONE_STATE} permission and
3418 * access to device identifiers.
3419 * </ul>
3420 *
Malcolm Chen4f609c72019-11-06 14:02:46 -08003421 * @throws IllegalStateException if Telephony service is in bad state.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003422 * @throws SecurityException if the caller doesn't meet the requirements
3423 * outlined above.
3424 *
Malcolm Chen4674a792019-03-20 20:32:27 -07003425 * @param groupUuid of which list of subInfo will be returned.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003426 * @return list of subscriptionInfo that belong to the same group, including the given
Malcolm Chen4674a792019-03-20 20:32:27 -07003427 * subscription itself. It will return an empty list if no subscription belongs to the group.
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003428 *
3429 */
3430 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
3431 @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
Malcolm Chen4674a792019-03-20 20:32:27 -07003432 public @NonNull List<SubscriptionInfo> getSubscriptionsInGroup(@NonNull ParcelUuid groupUuid) {
3433 Preconditions.checkNotNull(groupUuid, "groupUuid can't be null");
Philip P. Moltmann06b07e92020-01-07 14:53:47 -08003434 String contextPkg = mContext != null ? mContext.getOpPackageName() : "<unknown>";
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08003435 String contextAttributionTag = mContext != null ? mContext.getAttributionTag() : null;
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003436 if (VDBG) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003437 logd("[getSubscriptionsInGroup]+ groupUuid:" + groupUuid);
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003438 }
3439
3440 List<SubscriptionInfo> result = null;
3441 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003442 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003443 if (iSub != null) {
Philip P. Moltmannaea50fc2020-03-05 15:01:29 -08003444 result = iSub.getSubscriptionsInGroup(groupUuid, contextPkg,
3445 contextAttributionTag);
Malcolm Chen4674a792019-03-20 20:32:27 -07003446 } else {
3447 if (!isSystemProcess()) {
3448 throw new IllegalStateException("telephony service is null.");
3449 }
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003450 }
3451 } catch (RemoteException ex) {
Malcolm Chen4674a792019-03-20 20:32:27 -07003452 loge("removeSubscriptionsFromGroup RemoteException " + ex);
3453 if (!isSystemProcess()) {
3454 ex.rethrowAsRuntimeException();
3455 }
Malcolm Chenbe9240b2018-12-03 20:29:33 -08003456 }
3457
3458 return result;
3459 }
3460
3461 /**
Malcolm Chend1b4a812019-02-28 14:07:59 -08003462 * Whether a subscription is visible to API caller. If it's a bundled opportunistic
3463 * subscription, it should be hidden anywhere in Settings, dialer, status bar etc.
3464 * Exception is if caller owns carrier privilege, in which case they will
Malcolm Chen31071852019-02-12 17:29:59 -08003465 * want to see their own hidden subscriptions.
Malcolm Chen0db9aa12018-12-06 11:19:03 -08003466 *
3467 * @param info the subscriptionInfo to check against.
Malcolm Chend1b4a812019-02-28 14:07:59 -08003468 * @return true if this subscription should be visible to the API caller.
Malcolm Chen0db9aa12018-12-06 11:19:03 -08003469 *
Qingxi Lie0662472019-05-17 15:16:21 -07003470 * @hide
Malcolm Chen0db9aa12018-12-06 11:19:03 -08003471 */
Qingxi Lie0662472019-05-17 15:16:21 -07003472 public boolean isSubscriptionVisible(SubscriptionInfo info) {
Malcolm Chen31071852019-02-12 17:29:59 -08003473 if (info == null) return false;
Malcolm Chend1b4a812019-02-28 14:07:59 -08003474 // If subscription is NOT grouped opportunistic subscription, it's visible.
Malcolm Chen4674a792019-03-20 20:32:27 -07003475 if (info.getGroupUuid() == null || !info.isOpportunistic()) return true;
Malcolm Chen31071852019-02-12 17:29:59 -08003476
Malcolm Chend1b4a812019-02-28 14:07:59 -08003477 // If the caller is the carrier app and owns the subscription, it should be visible
3478 // to the caller.
3479 boolean hasCarrierPrivilegePermission = TelephonyManager.from(mContext)
3480 .hasCarrierPrivileges(info.getSubscriptionId())
Nazanin Bakhshi65371b22019-08-19 16:36:07 -07003481 || canManageSubscription(info);
Malcolm Chend1b4a812019-02-28 14:07:59 -08003482 return hasCarrierPrivilegePermission;
Malcolm Chen0db9aa12018-12-06 11:19:03 -08003483 }
3484
3485 /**
3486 * Return a list of subscriptions that are available and visible to the user.
3487 * Used by Settings app to show a list of subscriptions for user to pick.
3488 *
3489 * <p>
3490 * Permissions android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE is required
3491 * for getSelectableSubscriptionInfoList to be invoked.
3492 * @return list of user selectable subscriptions.
3493 *
3494 * @hide
3495 */
3496 public @Nullable List<SubscriptionInfo> getSelectableSubscriptionInfoList() {
3497 List<SubscriptionInfo> availableList = getAvailableSubscriptionInfoList();
3498 if (availableList == null) {
3499 return null;
3500 } else {
Malcolm Chenb82864c2019-02-26 16:48:40 -08003501 // Multiple subscriptions in a group should only have one representative.
3502 // It should be the current active primary subscription if any, or any
3503 // primary subscription.
3504 List<SubscriptionInfo> selectableList = new ArrayList<>();
Malcolm Chen4674a792019-03-20 20:32:27 -07003505 Map<ParcelUuid, SubscriptionInfo> groupMap = new HashMap<>();
Malcolm Chenb82864c2019-02-26 16:48:40 -08003506
3507 for (SubscriptionInfo info : availableList) {
3508 // Opportunistic subscriptions are considered invisible
3509 // to users so they should never be returned.
Malcolm Chend1b4a812019-02-28 14:07:59 -08003510 if (!isSubscriptionVisible(info)) continue;
Malcolm Chenb82864c2019-02-26 16:48:40 -08003511
Malcolm Chen4674a792019-03-20 20:32:27 -07003512 ParcelUuid groupUuid = info.getGroupUuid();
Malcolm Chenb82864c2019-02-26 16:48:40 -08003513 if (groupUuid == null) {
3514 // Doesn't belong to any group. Add in the list.
3515 selectableList.add(info);
3516 } else if (!groupMap.containsKey(groupUuid)
3517 || (groupMap.get(groupUuid).getSimSlotIndex() == INVALID_SIM_SLOT_INDEX
3518 && info.getSimSlotIndex() != INVALID_SIM_SLOT_INDEX)) {
3519 // If it belongs to a group that has never been recorded or it's the current
3520 // active subscription, add it in the list.
3521 selectableList.remove(groupMap.get(groupUuid));
3522 selectableList.add(info);
3523 groupMap.put(groupUuid, info);
3524 }
3525
3526 }
3527 return selectableList;
Malcolm Chen0db9aa12018-12-06 11:19:03 -08003528 }
3529 }
3530
Malcolm Chen77b2b552018-12-13 19:24:03 -08003531 /**
Malcolm Chen4c7c1b22019-11-19 15:27:55 -08003532 * Enables or disables a subscription. This is currently used in the settings page. It will
3533 * fail and return false if operation is not supported or failed.
3534 *
3535 * To disable an active subscription on a physical (non-Euicc) SIM,
3536 * {@link #canDisablePhysicalSubscription} needs to be true.
Malcolm Chen77b2b552018-12-13 19:24:03 -08003537 *
3538 * <p>
3539 * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
3540 *
3541 * @param enable whether user is turning it on or off.
3542 * @param subscriptionId Subscription to be enabled or disabled.
3543 * It could be a eSIM or pSIM subscription.
3544 *
3545 * @return whether the operation is successful.
3546 *
3547 * @hide
3548 */
3549 @SystemApi
3550 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
3551 public boolean setSubscriptionEnabled(int subscriptionId, boolean enable) {
3552 if (VDBG) {
3553 logd("setSubscriptionActivated subId= " + subscriptionId + " enable " + enable);
3554 }
3555 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003556 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chen77b2b552018-12-13 19:24:03 -08003557 if (iSub != null) {
3558 return iSub.setSubscriptionEnabled(enable, subscriptionId);
3559 }
3560 } catch (RemoteException ex) {
3561 // ignore it
3562 }
3563
3564 return false;
3565 }
3566
3567 /**
Malcolm Chen4ece3db2019-12-16 14:01:50 -08003568 * Set uicc applications being enabled or disabled.
3569 * The value will be remembered on the subscription and will be applied whenever it's present.
3570 * If the subscription in currently present, it will also apply the setting to modem
Jordan Liu02939242021-04-27 13:34:31 -07003571 * immediately (the setting in the modem will not change until the modem receives and responds
3572 * to the request, but typically this should only take a few seconds. The user visible setting
3573 * available from SubscriptionInfo.areUiccApplicationsEnabled() will be updated
3574 * immediately.)
Malcolm Chen4ece3db2019-12-16 14:01:50 -08003575 *
3576 * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
3577 *
Malcolm Chen4ece3db2019-12-16 14:01:50 -08003578 * @param subscriptionId which subscription to operate on.
Malcolm Chen91056a42020-02-21 17:11:57 -08003579 * @param enabled whether uicc applications are enabled or disabled.
Malcolm Chen4ece3db2019-12-16 14:01:50 -08003580 * @hide
3581 */
3582 @SystemApi
3583 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
Malcolm Chen91056a42020-02-21 17:11:57 -08003584 public void setUiccApplicationsEnabled(int subscriptionId, boolean enabled) {
Malcolm Chen4ece3db2019-12-16 14:01:50 -08003585 if (VDBG) {
3586 logd("setUiccApplicationsEnabled subId= " + subscriptionId + " enable " + enabled);
3587 }
3588 try {
Peter Wangd9eebca2019-12-30 16:14:01 -08003589 ISub iSub = ISub.Stub.asInterface(
3590 TelephonyFrameworkInitializer
3591 .getTelephonyServiceManager()
3592 .getSubscriptionServiceRegisterer()
3593 .get());
Malcolm Chen4ece3db2019-12-16 14:01:50 -08003594 if (iSub != null) {
3595 iSub.setUiccApplicationsEnabled(enabled, subscriptionId);
3596 }
3597 } catch (RemoteException ex) {
3598 // ignore it
3599 }
3600 }
3601
3602 /**
Malcolm Chen4c7c1b22019-11-19 15:27:55 -08003603 * Whether it's supported to disable / re-enable a subscription on a physical (non-euicc) SIM.
3604 *
3605 * Physical SIM refers non-euicc, or aka non-programmable SIM.
3606 *
3607 * It provides whether a physical SIM card can be disabled without taking it out, which is done
3608 * via {@link #setSubscriptionEnabled(int, boolean)} API.
3609 *
3610 * Requires Permission: READ_PRIVILEGED_PHONE_STATE.
3611 *
3612 * @return whether can disable subscriptions on physical SIMs.
3613 *
3614 * @hide
3615 */
3616 @SystemApi
3617 @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
3618 public boolean canDisablePhysicalSubscription() {
3619 if (VDBG) {
3620 logd("canDisablePhysicalSubscription");
3621 }
3622 try {
Peter Wangd9eebca2019-12-30 16:14:01 -08003623 ISub iSub = ISub.Stub.asInterface(
3624 TelephonyFrameworkInitializer
3625 .getTelephonyServiceManager()
3626 .getSubscriptionServiceRegisterer()
3627 .get());
Malcolm Chen4c7c1b22019-11-19 15:27:55 -08003628 if (iSub != null) {
3629 return iSub.canDisablePhysicalSubscription();
3630 }
3631 } catch (RemoteException ex) {
3632 // ignore it
3633 }
3634
3635 return false;
3636 }
3637
3638 /**
Malcolm Chendcc97e12019-06-18 13:57:03 -07003639 * DO NOT USE.
3640 * This API is designed for features that are not finished at this point. Do not call this API.
Malcolm Chen77b2b552018-12-13 19:24:03 -08003641 * @hide
Malcolm Chendcc97e12019-06-18 13:57:03 -07003642 * TODO b/135547512: further clean up
Malcolm Chen77b2b552018-12-13 19:24:03 -08003643 */
3644 @SystemApi
3645 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
3646 public boolean isSubscriptionEnabled(int subscriptionId) {
3647 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003648 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chen77b2b552018-12-13 19:24:03 -08003649 if (iSub != null) {
3650 return iSub.isSubscriptionEnabled(subscriptionId);
3651 }
3652 } catch (RemoteException ex) {
3653 // ignore it
3654 }
3655
3656 return false;
3657 }
3658
3659 /**
Grace Jiab53cb662021-02-12 15:29:29 -08003660 * Set the device to device status sharing user preference for a subscription ID. The setting
3661 * app uses this method to indicate with whom they wish to share device to device status
3662 * information.
3663 * @param sharing the status sharing preference
Grace Jiaaeea4ec2021-03-10 14:00:43 -08003664 * @param subscriptionId the unique Subscription ID in database
Grace Jiab53cb662021-02-12 15:29:29 -08003665 */
3666 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
Grace Jia25a8bdb2021-03-29 22:56:57 -07003667 public void setDeviceToDeviceStatusSharingPreference(int subscriptionId,
3668 @DeviceToDeviceStatusSharingPreference int sharing) {
Grace Jiab53cb662021-02-12 15:29:29 -08003669 if (VDBG) {
Grace Jiaaeea4ec2021-03-10 14:00:43 -08003670 logd("[setDeviceToDeviceStatusSharing] + sharing: " + sharing + " subId: "
3671 + subscriptionId);
Grace Jiab53cb662021-02-12 15:29:29 -08003672 }
Grace Jiaaeea4ec2021-03-10 14:00:43 -08003673 setSubscriptionPropertyHelper(subscriptionId, "setDeviceToDeviceSharingStatus",
3674 (iSub)->iSub.setDeviceToDeviceStatusSharing(sharing, subscriptionId));
Grace Jiab53cb662021-02-12 15:29:29 -08003675 }
3676
3677 /**
3678 * Returns the user-chosen device to device status sharing preference
Grace Jiaaeea4ec2021-03-10 14:00:43 -08003679 * @param subscriptionId Subscription id of subscription
Grace Jiab53cb662021-02-12 15:29:29 -08003680 * @return The device to device status sharing preference
3681 */
Grace Jiaaeea4ec2021-03-10 14:00:43 -08003682 public @DeviceToDeviceStatusSharingPreference int getDeviceToDeviceStatusSharingPreference(
3683 int subscriptionId) {
Grace Jiab53cb662021-02-12 15:29:29 -08003684 if (VDBG) {
Grace Jiaaeea4ec2021-03-10 14:00:43 -08003685 logd("[getDeviceToDeviceStatusSharing] + subId: " + subscriptionId);
Grace Jiab53cb662021-02-12 15:29:29 -08003686 }
Grace Jiaaeea4ec2021-03-10 14:00:43 -08003687 return getIntegerSubscriptionProperty(subscriptionId, D2D_STATUS_SHARING,
3688 D2D_SHARING_DISABLED, mContext);
Grace Jiab53cb662021-02-12 15:29:29 -08003689 }
3690
3691 /**
Grace Jia2bd23cf2021-03-18 14:47:31 -07003692 * Set the list of contacts that allow device to device status sharing for a subscription ID.
3693 * The setting app uses this method to indicate with whom they wish to share device to device
3694 * status information.
3695 * @param contacts The list of contacts that allow device to device status sharing
3696 * @param subscriptionId The unique Subscription ID in database
3697 */
3698 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
Grace Jia25a8bdb2021-03-29 22:56:57 -07003699 public void setDeviceToDeviceStatusSharingContacts(int subscriptionId,
3700 @NonNull List<Uri> contacts) {
Grace Jia2bd23cf2021-03-18 14:47:31 -07003701 String contactString = serializeUriLists(contacts);
3702 if (VDBG) {
3703 logd("[setDeviceToDeviceStatusSharingContacts] + contacts: " + contactString
3704 + " subId: " + subscriptionId);
3705 }
3706 setSubscriptionPropertyHelper(subscriptionId, "setDeviceToDeviceSharingStatus",
3707 (iSub)->iSub.setDeviceToDeviceStatusSharingContacts(serializeUriLists(contacts),
3708 subscriptionId));
3709 }
3710
3711 /**
3712 * Returns the list of contacts that allow device to device status sharing.
3713 * @param subscriptionId Subscription id of subscription
3714 * @return The list of contacts that allow device to device status sharing
3715 */
3716 public @NonNull List<Uri> getDeviceToDeviceStatusSharingContacts(
3717 int subscriptionId) {
3718 if (VDBG) {
3719 logd("[getDeviceToDeviceStatusSharingContacts] + subId: " + subscriptionId);
3720 }
3721 return getContactsFromSubscriptionProperty(subscriptionId,
3722 D2D_STATUS_SHARING_SELECTED_CONTACTS, mContext);
3723 }
3724
3725 /**
Malcolm Chendcc97e12019-06-18 13:57:03 -07003726 * DO NOT USE.
3727 * This API is designed for features that are not finished at this point. Do not call this API.
Malcolm Chen77b2b552018-12-13 19:24:03 -08003728 * @hide
Malcolm Chendcc97e12019-06-18 13:57:03 -07003729 * TODO b/135547512: further clean up
Malcolm Chen77b2b552018-12-13 19:24:03 -08003730 */
3731 @SystemApi
3732 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
3733 public int getEnabledSubscriptionId(int slotIndex) {
3734 int subId = INVALID_SUBSCRIPTION_ID;
3735
3736 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003737 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chen77b2b552018-12-13 19:24:03 -08003738 if (iSub != null) {
3739 subId = iSub.getEnabledSubscriptionId(slotIndex);
3740 }
3741 } catch (RemoteException ex) {
3742 // ignore it
3743 }
3744
3745 if (VDBG) logd("getEnabledSubscriptionId, subId = " + subId);
3746 return subId;
3747 }
3748
Malcolm Chenbd4ae762018-08-03 17:24:07 -07003749 private interface CallISubMethodHelper {
3750 int callMethod(ISub iSub) throws RemoteException;
3751 }
3752
3753 private int setSubscriptionPropertyHelper(int subId, String methodName,
3754 CallISubMethodHelper helper) {
3755 if (!isValidSubscriptionId(subId)) {
3756 logd("[" + methodName + "]" + "- fail");
3757 return -1;
3758 }
3759
3760 int result = 0;
3761
3762 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07003763 ISub iSub = TelephonyManager.getSubscriptionService();
Malcolm Chenbd4ae762018-08-03 17:24:07 -07003764 if (iSub != null) {
3765 result = helper.callMethod(iSub);
3766 }
3767 } catch (RemoteException ex) {
3768 // ignore it
3769 }
3770
3771 return result;
3772 }
Jack Yu807a82b2019-06-06 17:13:06 -07003773
3774 /**
Jayachandran C9ecb50e2019-11-08 00:47:34 -08003775 * Get active data subscription id. Active data subscription refers to the subscription
3776 * currently chosen to provide cellular internet connection to the user. This may be
3777 * different from getDefaultDataSubscriptionId(). Eg. Opportunistics data
3778 *
Jack Yu807a82b2019-06-06 17:13:06 -07003779 * See {@link PhoneStateListener#onActiveDataSubscriptionIdChanged(int)} for the details.
3780 *
Jayachandran C9ecb50e2019-11-08 00:47:34 -08003781 * @return Active data subscription id if any is chosen, or
3782 * SubscriptionManager.INVALID_SUBSCRIPTION_ID if not.
Jack Yu807a82b2019-06-06 17:13:06 -07003783 */
3784 public static int getActiveDataSubscriptionId() {
Collin Fijalkovich7d7ce512020-04-02 13:32:32 -07003785 return sActiveDataSubIdCache.query(null);
Jack Yu807a82b2019-06-06 17:13:06 -07003786 }
Daniel Bright0b5d2852020-01-09 21:58:16 -08003787
3788 /**
3789 * Helper method that puts a subscription id on an intent with the constants:
3790 * PhoneConstant.SUBSCRIPTION_KEY and SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX.
3791 * Both constants are used to support backwards compatibility. Once we know we got all places,
3792 * we can remove PhoneConstants.SUBSCRIPTION_KEY.
3793 * @param intent Intent to put sub id on.
3794 * @param subId SubscriptionId to put on intent.
3795 *
3796 * @hide
3797 */
3798 public static void putSubscriptionIdExtra(Intent intent, int subId) {
3799 intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
3800 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
3801 }
Collin Fijalkovich4ffdedf2019-12-10 09:52:14 -08003802
3803 /** @hide */
3804 public static void invalidateDefaultSubIdCaches() {
3805 PropertyInvalidatedCache.invalidateCache(CACHE_KEY_DEFAULT_SUB_ID_PROPERTY);
3806 }
3807
Collin Fijalkovichce43a592020-03-25 14:30:21 -07003808 /** @hide */
3809 public static void invalidateDefaultDataSubIdCaches() {
3810 PropertyInvalidatedCache.invalidateCache(CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY);
3811 }
3812
Collin Fijalkovich7d7ce512020-04-02 13:32:32 -07003813 /** @hide */
Collin Fijalkovich02e5c592020-04-06 10:54:28 -07003814 public static void invalidateDefaultSmsSubIdCaches() {
3815 PropertyInvalidatedCache.invalidateCache(CACHE_KEY_DEFAULT_SMS_SUB_ID_PROPERTY);
3816 }
3817
3818 /** @hide */
Collin Fijalkovich7d7ce512020-04-02 13:32:32 -07003819 public static void invalidateActiveDataSubIdCaches() {
3820 PropertyInvalidatedCache.invalidateCache(CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY);
3821 }
3822
Collin Fijalkovich41f94622020-04-10 14:01:42 -07003823 /** @hide */
3824 public static void invalidateSlotIndexCaches() {
3825 PropertyInvalidatedCache.invalidateCache(CACHE_KEY_SLOT_INDEX_PROPERTY);
Collin Fijalkovich7d7ce512020-04-02 13:32:32 -07003826 }
3827
3828 /**
3829 * Allows a test process to disable client-side caching operations.
3830 *
3831 * @hide
3832 */
3833 public static void disableCaching() {
3834 sDefaultSubIdCache.disableLocal();
3835 sDefaultDataSubIdCache.disableLocal();
3836 sActiveDataSubIdCache.disableLocal();
Collin Fijalkovich02e5c592020-04-06 10:54:28 -07003837 sDefaultSmsSubIdCache.disableLocal();
Collin Fijalkovich41f94622020-04-10 14:01:42 -07003838 sSlotIndexCache.disableLocal();
3839 sPhoneIdCache.disableLocal();
3840 }
3841
3842 /**
3843 * Clears all process-local binder caches.
3844 *
3845 * @hide */
3846 public static void clearCaches() {
3847 sDefaultSubIdCache.clear();
3848 sDefaultDataSubIdCache.clear();
3849 sActiveDataSubIdCache.clear();
3850 sDefaultSmsSubIdCache.clear();
3851 sSlotIndexCache.clear();
3852 sPhoneIdCache.clear();
Collin Fijalkovich4ffdedf2019-12-10 09:52:14 -08003853 }
Jack Nudelmane2ea4282021-01-13 18:46:57 -08003854
3855 /**
3856 * Called to retrieve SIM-specific settings data to be backed up.
3857 *
3858 * @return data in byte[] to be backed up.
3859 *
3860 * @hide
3861 */
3862 @NonNull
3863 @SystemApi
3864 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
3865 public byte[] getAllSimSpecificSettingsForBackup() {
3866 Bundle bundle = mContext.getContentResolver().call(
3867 SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
3868 GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME, null, null);
3869 return bundle.getByteArray(SubscriptionManager.KEY_SIM_SPECIFIC_SETTINGS_DATA);
3870 }
3871
3872 /**
3873 * Called to attempt to restore the backed up sim-specific configs to device for specific sim.
3874 * This will try to restore the data that was stored internally when {@link
3875 * #restoreAllSimSpecificSettingsFromBackup(byte[] data)} was called during setup wizard.
3876 * End result is SimInfoDB is modified to match any backed up configs for the requested
3877 * inserted sim.
3878 *
3879 * <p>
3880 * The {@link Uri} {@link #SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI} is notified if any SimInfoDB
3881 * entry is updated as the result of this method call.
3882 *
3883 * @param iccId of the sim that a restore is requested for.
3884 *
3885 * @hide
3886 */
3887 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
3888 public void restoreSimSpecificSettingsForIccIdFromBackup(@NonNull String iccId) {
3889 mContext.getContentResolver().call(
3890 SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
3891 RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME,
3892 iccId, null);
3893 }
3894
3895 /**
3896 * Called during setup wizard restore flow to attempt to restore the backed up sim-specific
3897 * configs to device for all existing SIMs in SimInfoDB. Internally, it will store the backup
3898 * data in an internal file. This file will persist on device for device's lifetime and will be
3899 * used later on when a SIM is inserted to restore that specific SIM's settings by calling
3900 * {@link #restoreSimSpecificSettingsForIccIdFromBackup(String iccId)}. End result is
3901 * SimInfoDB is modified to match any backed up configs for the appropriate inserted SIMs.
3902 *
3903 * <p>
3904 * The {@link Uri} {@link #SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI} is notified if any SimInfoDB
3905 * entry is updated as the result of this method call.
3906 *
3907 * @param data with the sim specific configs to be backed up.
3908 *
3909 * @hide
3910 */
3911 @SystemApi
3912 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
3913 public void restoreAllSimSpecificSettingsFromBackup(@NonNull byte[] data) {
3914 Bundle bundle = new Bundle();
3915 bundle.putByteArray(KEY_SIM_SPECIFIC_SETTINGS_DATA, data);
3916 mContext.getContentResolver().call(
3917 SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
3918 RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME,
3919 null, bundle);
3920 }
Meng Wang0594b4f2021-10-26 13:12:47 -07003921
3922 /**
Meng Wangbbb01fc2021-11-17 13:43:02 -08003923 * Returns the phone number for the given {@code subscriptionId} and {@code source},
Meng Wang0594b4f2021-10-26 13:12:47 -07003924 * or an empty string if not available.
3925 *
Meng Wangbbb01fc2021-11-17 13:43:02 -08003926 * <p>General apps that need to know the phone number should use {@link #getPhoneNumber(int)}
3927 * instead. This API may be suitable specific apps that needs to know the phone number from
3928 * a specific source. For example, a carrier app needs to know exactly what's on
3929 * {@link #PHONE_NUMBER_SOURCE_UICC UICC} and decide if the previously set phone number
3930 * of source {@link #PHONE_NUMBER_SOURCE_CARRIER carrier} should be updated.
3931 *
Meng Wang355b2542022-01-13 22:36:59 +00003932 * <p>The API provides no guarantees of what format the number is in: the format can vary
3933 * depending on the {@code source} and the network etc. Programmatic parsing should be done
3934 * cautiously, for example, after formatting the number to a consistent format with
3935 * {@link android.telephony.PhoneNumberUtils#formatNumberToE164(String, String)}.
3936 *
Meng Wangbbb01fc2021-11-17 13:43:02 -08003937 * <p>Note the assumption is that one subscription (which usually means one SIM) has
3938 * only one phone number. The multiple sources backup each other so hopefully at least one
3939 * is availavle. For example, for a carrier that doesn't typically set phone numbers
3940 * on {@link #PHONE_NUMBER_SOURCE_UICC UICC}, the source {@link #PHONE_NUMBER_SOURCE_IMS IMS}
3941 * may provide one. Or, a carrier may decide to provide the phone number via source
3942 * {@link #PHONE_NUMBER_SOURCE_CARRIER carrier} if neither source UICC nor IMS is available.
Meng Wang0594b4f2021-10-26 13:12:47 -07003943 *
3944 * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID}
3945 * for the default one.
3946 * @param source the source of the phone number, one of the PHONE_NUMBER_SOURCE_* constants.
3947 * @return the phone number, or an empty string if not available.
3948 * @throws IllegalArgumentException if {@code source} is invalid.
3949 * @throws IllegalStateException if the telephony process is not currently available.
3950 * @throws SecurityException if the caller doesn't have permissions required.
3951 * @see #PHONE_NUMBER_SOURCE_UICC
3952 * @see #PHONE_NUMBER_SOURCE_CARRIER
3953 * @see #PHONE_NUMBER_SOURCE_IMS
3954 */
Meng Wang0594b4f2021-10-26 13:12:47 -07003955 @RequiresPermission(anyOf = {
3956 android.Manifest.permission.READ_PHONE_NUMBERS,
3957 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
Meng Wangbbb01fc2021-11-17 13:43:02 -08003958 "carrier privileges",
Meng Wang0594b4f2021-10-26 13:12:47 -07003959 })
3960 @NonNull
3961 public String getPhoneNumber(int subscriptionId, @PhoneNumberSource int source) {
3962 if (subscriptionId == DEFAULT_SUBSCRIPTION_ID) {
3963 subscriptionId = getDefaultSubscriptionId();
3964 }
3965 if (source != PHONE_NUMBER_SOURCE_UICC
3966 && source != PHONE_NUMBER_SOURCE_CARRIER
3967 && source != PHONE_NUMBER_SOURCE_IMS) {
3968 throw new IllegalArgumentException("invalid source " + source);
3969 }
3970 try {
3971 ISub iSub = TelephonyManager.getSubscriptionService();
3972 if (iSub != null) {
3973 return iSub.getPhoneNumber(subscriptionId, source,
3974 mContext.getOpPackageName(), mContext.getAttributionTag());
3975 } else {
3976 throw new IllegalStateException("subscription service unavailable.");
3977 }
3978 } catch (RemoteException ex) {
3979 throw ex.rethrowAsRuntimeException();
3980 }
3981 }
3982
3983 /**
3984 * Returns the phone number for the given {@code subId}, or an empty string if
3985 * not available.
3986 *
Meng Wangbbb01fc2021-11-17 13:43:02 -08003987 * <p>This API is suitable for general apps that needs to know the phone number.
3988 * For specific apps that needs to know the phone number provided by a specific source,
3989 * {@link #getPhoneNumber(int, int)} may be suitable.
3990 *
Meng Wang0594b4f2021-10-26 13:12:47 -07003991 * <p>This API is built up on {@link #getPhoneNumber(int, int)}, but picks
3992 * from available sources in the following order: {@link #PHONE_NUMBER_SOURCE_CARRIER}
3993 * > {@link #PHONE_NUMBER_SOURCE_UICC} > {@link #PHONE_NUMBER_SOURCE_IMS}.
3994 *
Meng Wang355b2542022-01-13 22:36:59 +00003995 * <p>The API provides no guarantees of what format the number is in: the format can vary
3996 * depending on the underlying source and the network etc. Programmatic parsing should be done
3997 * cautiously, for example, after formatting the number to a consistent format with
3998 * {@link android.telephony.PhoneNumberUtils#formatNumberToE164(String, String)}.
3999 *
Meng Wang0594b4f2021-10-26 13:12:47 -07004000 * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID}
4001 * for the default one.
4002 * @return the phone number, or an empty string if not available.
4003 * @throws IllegalStateException if the telephony process is not currently available.
4004 * @throws SecurityException if the caller doesn't have permissions required.
4005 * @see #getPhoneNumber(int, int)
4006 */
Meng Wang0594b4f2021-10-26 13:12:47 -07004007 @RequiresPermission(anyOf = {
4008 android.Manifest.permission.READ_PHONE_NUMBERS,
4009 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
Meng Wangbbb01fc2021-11-17 13:43:02 -08004010 "carrier privileges",
Meng Wang0594b4f2021-10-26 13:12:47 -07004011 })
4012 @NonNull
4013 public String getPhoneNumber(int subscriptionId) {
4014 if (subscriptionId == DEFAULT_SUBSCRIPTION_ID) {
4015 subscriptionId = getDefaultSubscriptionId();
4016 }
4017 try {
4018 ISub iSub = TelephonyManager.getSubscriptionService();
4019 if (iSub != null) {
4020 return iSub.getPhoneNumberFromFirstAvailableSource(subscriptionId,
4021 mContext.getOpPackageName(), mContext.getAttributionTag());
4022 } else {
4023 throw new IllegalStateException("subscription service unavailable.");
4024 }
4025 } catch (RemoteException ex) {
4026 throw ex.rethrowAsRuntimeException();
4027 }
4028 }
4029
4030 /**
4031 * Sets the phone number for the given {@code subId} for source
4032 * {@link #PHONE_NUMBER_SOURCE_CARRIER carrier}.
4033 * Sets an empty string to remove the previously set phone number.
4034 *
Meng Wangbbb01fc2021-11-17 13:43:02 -08004035 * <p>The API is suitable for carrier apps to provide a phone number, for example when
4036 * it's not possible to update {@link #PHONE_NUMBER_SOURCE_UICC UICC} directly.
Meng Wang0594b4f2021-10-26 13:12:47 -07004037 *
Meng Wang355b2542022-01-13 22:36:59 +00004038 * <p>It's recommended that the phone number is formatted to well-known formats,
4039 * for example, by {@link PhoneNumberUtils} {@code formatNumber*} methods.
4040 *
Meng Wang0594b4f2021-10-26 13:12:47 -07004041 * @param subscriptionId the subscription ID, or {@link #DEFAULT_SUBSCRIPTION_ID}
4042 * for the default one.
4043 * @param number the phone number, or an empty string to remove the previously set number.
4044 * @throws IllegalStateException if the telephony process is not currently available.
4045 * @throws NullPointerException if {@code number} is {@code null}.
4046 * @throws SecurityException if the caller doesn't have permissions required.
4047 */
Meng Wangbbb01fc2021-11-17 13:43:02 -08004048 @RequiresPermission("carrier privileges")
Meng Wang0594b4f2021-10-26 13:12:47 -07004049 public void setCarrierPhoneNumber(int subscriptionId, @NonNull String number) {
4050 if (subscriptionId == DEFAULT_SUBSCRIPTION_ID) {
4051 subscriptionId = getDefaultSubscriptionId();
4052 }
4053 if (number == null) {
4054 throw new NullPointerException("invalid number null");
4055 }
4056 try {
4057 ISub iSub = TelephonyManager.getSubscriptionService();
4058 if (iSub != null) {
4059 iSub.setPhoneNumber(subscriptionId, PHONE_NUMBER_SOURCE_CARRIER, number,
4060 mContext.getOpPackageName(), mContext.getAttributionTag());
4061 } else {
4062 throw new IllegalStateException("subscription service unavailable.");
4063 }
4064 } catch (RemoteException ex) {
4065 throw ex.rethrowAsRuntimeException();
4066 }
4067 }
Nathan Harolde93321c2021-11-03 15:56:27 -07004068
4069 /**
4070 * Set the preferred usage setting.
4071 *
4072 * The cellular usage setting is a switch which controls the mode of operation for the cellular
4073 * radio to either require or not require voice service. It is not managed via Android’s
4074 * Settings.
4075 *
4076 * @param subscriptionId the subId of the subscription.
4077 * @param usageSetting the requested usage setting.
4078 *
4079 * @throws IllegalStateException if a specific mode or setting the mode is not supported on a
4080 * particular device.
4081 *
4082 * <p>Requires {@link android.Manifest.permission#MODIFY_PHONE_STATE}
4083 * or that the calling app has CarrierPrivileges for the given subscription.
4084 *
4085 * Note: This method will not allow the setting of USAGE_SETTING_UNKNOWN.
4086 *
4087 * @hide
4088 */
4089 @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
4090 void setUsageSetting(int subscriptionId, @UsageSetting int usageSetting) {
4091 if (VDBG) logd("[setUsageSetting]+ setting:" + usageSetting + " subId:" + subscriptionId);
4092 setSubscriptionPropertyHelper(subscriptionId, "setUsageSetting",
4093 (iSub)-> iSub.setUsageSetting(
4094 usageSetting, subscriptionId, mContext.getOpPackageName()));
4095 }
Jack Yuc8b8a4e2022-10-13 01:59:43 -07004096
4097 /**
4098 * Convert display name source to string.
4099 *
4100 * @param source The display name source.
4101 * @return The display name source in string format.
4102 *
4103 * @hide
4104 */
4105 @NonNull
4106 public static String displayNameSourceToString(
4107 @SubscriptionManager.SimDisplayNameSource int source) {
4108 switch (source) {
4109 case SubscriptionManager.NAME_SOURCE_UNKNOWN: return "UNKNOWN";
4110 case SubscriptionManager.NAME_SOURCE_CARRIER_ID: return "CARRIER_ID";
4111 case SubscriptionManager.NAME_SOURCE_SIM_SPN: return "SIM_SPN";
4112 case SubscriptionManager.NAME_SOURCE_USER_INPUT: return "USER_INPUT";
4113 case SubscriptionManager.NAME_SOURCE_CARRIER: return "CARRIER";
4114 case SubscriptionManager.NAME_SOURCE_SIM_PNN: return "SIM_PNN";
4115 default:
4116 return "UNKNOWN(" + source + ")";
4117 }
4118 }
4119
4120 /**
4121 * Convert subscription type to string.
4122 *
4123 * @param type The subscription type.
4124 * @return The subscription type in string format.
4125 *
4126 * @hide
4127 */
4128 @NonNull
4129 public static String subscriptionTypeToString(@SubscriptionManager.SubscriptionType int type) {
4130 switch (type) {
4131 case SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM: return "LOCAL_SIM";
4132 case SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM: return "REMOTE_SIM";
4133 default:
4134 return "UNKNOWN(" + type + ")";
4135 }
4136 }
4137
4138 /**
4139 * Convert usage setting to string.
4140 *
4141 * @param usageSetting Usage setting.
4142 * @return The usage setting in string format.
4143 *
4144 * @hide
4145 */
4146 @NonNull
4147 public static String usageSettingToString(@SubscriptionManager.UsageSetting int usageSetting) {
4148 switch (usageSetting) {
4149 case SubscriptionManager.USAGE_SETTING_UNKNOWN: return "UNKNOWN";
4150 case SubscriptionManager.USAGE_SETTING_DEFAULT: return "DEFAULT";
4151 case SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC: return "VOICE_CENTRIC";
4152 case SubscriptionManager.USAGE_SETTING_DATA_CENTRIC: return "DATA_CENTRIC";
4153 default:
4154 return "UNKNOWN(" + usageSetting + ")";
4155 }
4156 }
Aishwarya Mallampati4f838952022-09-22 22:21:41 +00004157
4158 /**
4159 * Set userHandle for a subscription.
4160 *
4161 * Used to set an association between a subscription and a user on the device so that voice
4162 * calling and SMS from that subscription can be associated with that user.
4163 * Data services are always shared between users on the device.
4164 *
4165 * @param subscriptionId the subId of the subscription.
4166 * @param userHandle the userHandle associated with the subscription.
4167 * Pass {@code null} user handle to clear the association.
4168 *
4169 * @throws IllegalArgumentException if subscription is invalid.
4170 * @throws SecurityException if the caller doesn't have permissions required.
4171 * @throws IllegalStateException if subscription service is not available.
4172 *
4173 * @hide
4174 */
4175 @SystemApi
4176 @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION)
4177 public void setUserHandle(int subscriptionId, @Nullable UserHandle userHandle) {
4178 if (!isValidSubscriptionId(subscriptionId)) {
4179 throw new IllegalArgumentException("[setUserHandle]: Invalid subscriptionId: "
4180 + subscriptionId);
4181 }
4182
4183 try {
4184 ISub iSub = TelephonyManager.getSubscriptionService();
4185 if (iSub != null) {
4186 iSub.setUserHandle(userHandle, subscriptionId, mContext.getOpPackageName());
4187 } else {
4188 throw new IllegalStateException("[setUserHandle]: "
4189 + "subscription service unavailable");
4190 }
4191 } catch (RemoteException ex) {
4192 ex.rethrowAsRuntimeException();
4193 }
4194 }
4195
4196 /**
4197 * Get UserHandle of this subscription.
4198 *
4199 * Used to get user handle associated with this subscription.
4200 *
4201 * @param subscriptionId the subId of the subscription.
4202 * @return userHandle associated with this subscription
4203 * or {@code null} if subscription is not associated with any user.
4204 *
4205 * @throws IllegalArgumentException if subscription is invalid.
4206 * @throws SecurityException if the caller doesn't have permissions required.
4207 * @throws IllegalStateException if subscription service is not available.
4208 *
4209 * @hide
4210 */
4211 @SystemApi
4212 @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION)
4213 public @Nullable UserHandle getUserHandle(int subscriptionId) {
4214 if (!isValidSubscriptionId(subscriptionId)) {
4215 throw new IllegalArgumentException("[getUserHandle]: Invalid subscriptionId: "
4216 + subscriptionId);
4217 }
4218
4219 try {
4220 ISub iSub = TelephonyManager.getSubscriptionService();
4221 if (iSub != null) {
4222 return iSub.getUserHandle(subscriptionId, mContext.getOpPackageName());
4223 } else {
4224 throw new IllegalStateException("[getUserHandle]: "
4225 + "subscription service unavailable");
4226 }
4227 } catch (RemoteException ex) {
4228 ex.rethrowAsRuntimeException();
4229 }
4230 return null;
4231 }
Wink Savillefb40dd42014-06-12 17:02:31 -07004232}