blob: 80ee9b393f4dfd14b427e8333bcd34c5175dd258 [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
Jeff Sharkey9252b342018-01-19 07:58:35 +090019import static android.net.NetworkPolicyManager.OVERRIDE_CONGESTED;
20import static android.net.NetworkPolicyManager.OVERRIDE_UNMETERED;
21
Malcolm Chen27829e22018-09-04 22:12:31 -070022import android.annotation.CallbackExecutor;
Jeff Sharkey9252b342018-01-19 07:58:35 +090023import android.annotation.DurationMillisLong;
Jeff Sharkey32566012014-12-02 18:30:14 -080024import android.annotation.NonNull;
Jeff Sharkey717f52f2018-01-04 16:04:11 -070025import android.annotation.Nullable;
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -070026import android.annotation.RequiresPermission;
Wink Savillec650e0b2014-09-02 22:37:08 -070027import android.annotation.SdkConstant;
28import android.annotation.SdkConstant.SdkConstantType;
Jeff Davidson3c0415a2018-02-23 15:27:46 -080029import android.annotation.SuppressAutoDoc;
Jeff Sharkey717f52f2018-01-04 16:04:11 -070030import android.annotation.SystemApi;
Jeff Sharkey17bebd22017-07-19 21:00:38 -060031import android.annotation.SystemService;
Mathew Inwooda8382062018-08-16 17:01:12 +010032import android.annotation.UnsupportedAppUsage;
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -070033import android.app.BroadcastOptions;
Malcolm Chen0ac24ef2018-08-07 15:03:32 -070034import android.app.PendingIntent;
chen xua0007492018-10-02 19:34:10 -070035import android.app.job.JobService;
Wink Savillea374c3d2014-11-11 11:48:04 -080036import android.content.Context;
Wink Savillefb40dd42014-06-12 17:02:31 -070037import android.content.Intent;
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -080038import android.content.pm.PackageInfo;
Jeff Sharkey717f52f2018-01-04 16:04:11 -070039import android.content.pm.PackageManager;
Sanket Padawedc493092015-07-14 14:21:43 -070040import android.content.res.Configuration;
41import android.content.res.Resources;
chen xua0007492018-10-02 19:34:10 -070042import android.database.ContentObserver;
Jeff Sharkey53313d72017-07-13 16:47:32 -060043import android.net.INetworkPolicyManager;
Jeff Sharkey9252b342018-01-19 07:58:35 +090044import android.net.NetworkCapabilities;
Wink Savillefb40dd42014-06-12 17:02:31 -070045import android.net.Uri;
Mathew Inwood45d2c252018-09-14 12:35:36 +010046import android.os.Build;
Wink Savilled09c4ca2014-11-22 10:08:16 -080047import android.os.Handler;
Jack He9fc75742017-11-16 15:54:14 -080048import android.os.Looper;
Wink Savilled09c4ca2014-11-22 10:08:16 -080049import android.os.Message;
Wink Savillefb40dd42014-06-12 17:02:31 -070050import android.os.RemoteException;
Jeff Davidsond02731f2017-04-09 14:31:09 -070051import android.os.ServiceManager;
Malcolm Chen0ac24ef2018-08-07 15:03:32 -070052import android.telephony.euicc.EuiccManager;
chen xubf38b062018-11-01 00:08:37 -070053import android.telephony.ims.ImsMmTelManager;
Sanket Padawedc493092015-07-14 14:21:43 -070054import android.util.DisplayMetrics;
Malcolm Chen27829e22018-09-04 22:12:31 -070055import android.util.Log;
Jeff Sharkey717f52f2018-01-04 16:04:11 -070056
Wink Savilled09c4ca2014-11-22 10:08:16 -080057import com.android.internal.telephony.IOnSubscriptionsChangedListener;
Jeff Davidsond02731f2017-04-09 14:31:09 -070058import com.android.internal.telephony.ISub;
Wink Savillea374c3d2014-11-11 11:48:04 -080059import com.android.internal.telephony.ITelephonyRegistry;
Wink Savillefb40dd42014-06-12 17:02:31 -070060import com.android.internal.telephony.PhoneConstants;
Jeff Sharkey717f52f2018-01-04 16:04:11 -070061
Wink Saville905bb542014-09-04 17:10:23 -070062import java.util.ArrayList;
Jeff Sharkey53313d72017-07-13 16:47:32 -060063import java.util.Arrays;
Rajeev Kumarc8ac4f3b2017-07-26 15:59:08 -070064import java.util.Collections;
Wink Savillefb40dd42014-06-12 17:02:31 -070065import java.util.List;
Torbjorn Eklund99c11d82018-08-21 16:06:47 +020066import java.util.Locale;
Malcolm Chen27829e22018-09-04 22:12:31 -070067import java.util.concurrent.Executor;
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -070068import java.util.concurrent.TimeUnit;
Wink Savillefb40dd42014-06-12 17:02:31 -070069
70/**
Wink Savillef5bca082014-09-03 15:13:33 -070071 * SubscriptionManager is the application interface to SubscriptionController
72 * and provides information about the current Telephony Subscriptions.
Wink Savillefb40dd42014-06-12 17:02:31 -070073 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060074@SystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)
Wink Savilled09c4ca2014-11-22 10:08:16 -080075public class SubscriptionManager {
76 private static final String LOG_TAG = "SubscriptionManager";
77 private static final boolean DBG = false;
Wink Savillefb40dd42014-06-12 17:02:31 -070078 private static final boolean VDBG = false;
79
Wink Savillea374c3d2014-11-11 11:48:04 -080080 /** An invalid subscription identifier */
Wink Savilled09c4ca2014-11-22 10:08:16 -080081 public static final int INVALID_SUBSCRIPTION_ID = -1;
82
83 /** Base value for Dummy SUBSCRIPTION_ID's. */
84 /** FIXME: Remove DummySubId's, but for now have them map just below INVALID_SUBSCRIPTION_ID
Rajeev Kumarc8ac4f3b2017-07-26 15:59:08 -070085 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -080086 public static final int DUMMY_SUBSCRIPTION_ID_BASE = INVALID_SUBSCRIPTION_ID - 1;
Wink Savillefb40dd42014-06-12 17:02:31 -070087
Wink Savillea374c3d2014-11-11 11:48:04 -080088 /** An invalid phone identifier */
89 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -080090 public static final int INVALID_PHONE_INDEX = -1;
Wink Savillec650e0b2014-09-02 22:37:08 -070091
sqian996a3182018-10-12 18:41:19 -070092 /** Indicates invalid sim slot. This can be returned by {@link #getSlotIndex(int)}. */
Wink Savilled09c4ca2014-11-22 10:08:16 -080093 public static final int INVALID_SIM_SLOT_INDEX = -1;
Wink Savillea374c3d2014-11-11 11:48:04 -080094
sqian798da562018-09-12 16:31:17 -070095 /** Indicates the default subscription ID in Telephony. */
Wink Savilled09c4ca2014-11-22 10:08:16 -080096 public static final int DEFAULT_SUBSCRIPTION_ID = Integer.MAX_VALUE;
Wink Savillea374c3d2014-11-11 11:48:04 -080097
Wink Savilled09c4ca2014-11-22 10:08:16 -080098 /**
99 * Indicates the caller wants the default phone id.
Jack Yu67140302015-12-10 12:27:58 -0800100 * Used in SubscriptionController and Phone but do we really need it???
Wink Savilled09c4ca2014-11-22 10:08:16 -0800101 * @hide
102 */
103 public static final int DEFAULT_PHONE_INDEX = Integer.MAX_VALUE;
Wink Saville2d1ee982014-11-20 20:29:51 +0000104
Wink Savilled09c4ca2014-11-22 10:08:16 -0800105 /** Indicates the caller wants the default slot id. NOT used remove? */
Wink Saville2d1ee982014-11-20 20:29:51 +0000106 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800107 public static final int DEFAULT_SIM_SLOT_INDEX = Integer.MAX_VALUE;
Wink Savillec650e0b2014-09-02 22:37:08 -0700108
Wink Saville8eab2b62014-09-23 14:20:58 -0700109 /** Minimum possible subid that represents a subscription */
110 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800111 public static final int MIN_SUBSCRIPTION_ID_VALUE = 0;
Wink Saville8eab2b62014-09-23 14:20:58 -0700112
113 /** Maximum possible subid that represents a subscription */
114 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800115 public static final int MAX_SUBSCRIPTION_ID_VALUE = DEFAULT_SUBSCRIPTION_ID - 1;
Wink Saville8eab2b62014-09-23 14:20:58 -0700116
Wink Savillef5bca082014-09-03 15:13:33 -0700117 /** @hide */
Mathew Inwooda8382062018-08-16 17:01:12 +0100118 @UnsupportedAppUsage
Wink Savillefb40dd42014-06-12 17:02:31 -0700119 public static final Uri CONTENT_URI = Uri.parse("content://telephony/siminfo");
120
chen xua0007492018-10-02 19:34:10 -0700121
122 /**
123 * Generates a content {@link Uri} used to receive updates on simInfo change
124 * on the given subscriptionId
125 * @param subscriptionId the subscriptionId to receive updates on
126 * @return the Uri used to observe carrier identity changes
127 * @hide
128 */
129 public static Uri getUriForSubscriptionId(int subscriptionId) {
130 return Uri.withAppendedPath(CONTENT_URI, String.valueOf(subscriptionId));
131 }
132
133 /**
134 * A content {@link Uri} used to receive updates on wfc enabled user setting.
135 * <p>
136 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
chen xubf38b062018-11-01 00:08:37 -0700137 * subscription wfc enabled {@link ImsMmTelManager#isVoWiFiSettingEnabled()}
chen xua0007492018-10-02 19:34:10 -0700138 * while your app is running. You can also use a {@link JobService} to ensure your app
139 * is notified of changes to the {@link Uri} even when it is not running.
140 * Note, however, that using a {@link JobService} does not guarantee timely delivery of
141 * updates to the {@link Uri}.
142 * To be notified of changes to a specific subId, append subId to the URI
143 * {@link Uri#withAppendedPath(Uri, String)}.
144 * @hide
145 */
146 @SystemApi
147 public static final Uri WFC_ENABLED_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc");
148
149 /**
chen xubf38b062018-11-01 00:08:37 -0700150 * A content {@link Uri} used to receive updates on advanced calling user setting.
chen xua0007492018-10-02 19:34:10 -0700151 * <p>
152 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
chen xubf38b062018-11-01 00:08:37 -0700153 * subscription advanced calling enabled
154 * {@link ImsMmTelManager#isAdvancedCallingSettingEnabled()} while your app is running.
155 * You can also use a {@link JobService} to ensure your app is notified of changes to the
156 * {@link Uri} even when it is not running.
157 * Note, however, that using a {@link JobService} does not guarantee timely delivery of
158 * updates to the {@link Uri}.
159 * To be notified of changes to a specific subId, append subId to the URI
160 * {@link Uri#withAppendedPath(Uri, String)}.
161 * @hide
162 */
163 @SystemApi
164 public static final Uri ADVANCED_CALLING_ENABLED_CONTENT_URI = Uri.withAppendedPath(
165 CONTENT_URI, "advanced_calling");
166
167 /**
168 * A content {@link Uri} used to receive updates on wfc mode setting.
169 * <p>
170 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
171 * subscription wfc mode {@link ImsMmTelManager#getVoWiFiModeSetting()}
chen xua0007492018-10-02 19:34:10 -0700172 * while your app is running. You can also use a {@link JobService} to ensure your app
173 * is notified of changes to the {@link Uri} even when it is not running.
174 * Note, however, that using a {@link JobService} does not guarantee timely delivery of
175 * updates to the {@link Uri}.
176 * To be notified of changes to a specific subId, append subId to the URI
177 * {@link Uri#withAppendedPath(Uri, String)}.
178 * @hide
179 */
180 @SystemApi
chen xubf38b062018-11-01 00:08:37 -0700181 public static final Uri WFC_MODE_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc_mode");
chen xua0007492018-10-02 19:34:10 -0700182
chen xubf38b062018-11-01 00:08:37 -0700183 /**
184 * A content {@link Uri} used to receive updates on wfc roaming mode setting.
185 * <p>
186 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
187 * subscription wfc roaming mode {@link ImsMmTelManager#getVoWiFiRoamingModeSetting()}
188 * while your app is running. You can also use a {@link JobService} to ensure your app
189 * is notified of changes to the {@link Uri} even when it is not running.
190 * Note, however, that using a {@link JobService} does not guarantee timely delivery of
191 * updates to the {@link Uri}.
192 * To be notified of changes to a specific subId, append subId to the URI
193 * {@link Uri#withAppendedPath(Uri, String)}.
194 * @hide
195 */
196 @SystemApi
197 public static final Uri WFC_ROAMING_MODE_CONTENT_URI = Uri.withAppendedPath(
198 CONTENT_URI, "wfc_roaming_mode");
199
200 /**
201 * A content {@link Uri} used to receive updates on vt(video telephony over IMS) enabled
202 * setting.
203 * <p>
204 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
205 * subscription vt enabled {@link ImsMmTelManager#isVtSettingEnabled()}
206 * while your app is running. You can also use a {@link JobService} to ensure your app
207 * is notified of changes to the {@link Uri} even when it is not running.
208 * Note, however, that using a {@link JobService} does not guarantee timely delivery of
209 * updates to the {@link Uri}.
210 * To be notified of changes to a specific subId, append subId to the URI
211 * {@link Uri#withAppendedPath(Uri, String)}.
212 * @hide
213 */
214 @SystemApi
215 public static final Uri VT_ENABLED_CONTENT_URI = Uri.withAppendedPath(
216 CONTENT_URI, "vt_enabled");
217
218 /**
219 * A content {@link Uri} used to receive updates on wfc roaming enabled setting.
220 * <p>
221 * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
222 * subscription wfc roaming enabled {@link ImsMmTelManager#isVoWiFiRoamingSettingEnabled()}
223 * while your app is running. You can also use a {@link JobService} to ensure your app
224 * is notified of changes to the {@link Uri} even when it is not running.
225 * Note, however, that using a {@link JobService} does not guarantee timely delivery of
226 * updates to the {@link Uri}.
227 * To be notified of changes to a specific subId, append subId to the URI
228 * {@link Uri#withAppendedPath(Uri, String)}.
229 * @hide
230 */
231 @SystemApi
232 public static final Uri WFC_ROAMING_ENABLED_CONTENT_URI = Uri.withAppendedPath(
233 CONTENT_URI, "wfc_roaming_enabled");
chen xua0007492018-10-02 19:34:10 -0700234
Wink Savillefb40dd42014-06-12 17:02:31 -0700235 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -0800236 * TelephonyProvider unique key column name is the subscription id.
237 * <P>Type: TEXT (String)</P>
238 */
239 /** @hide */
240 public static final String UNIQUE_KEY_SUBSCRIPTION_ID = "_id";
241
242 /**
243 * TelephonyProvider column name for SIM ICC Identifier
Wink Savillefb40dd42014-06-12 17:02:31 -0700244 * <P>Type: TEXT (String)</P>
245 */
Wink Savillef5bca082014-09-03 15:13:33 -0700246 /** @hide */
Wink Savillefb40dd42014-06-12 17:02:31 -0700247 public static final String ICC_ID = "icc_id";
248
249 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -0800250 * TelephonyProvider column name for user SIM_SlOT_INDEX
Wink Savillefb40dd42014-06-12 17:02:31 -0700251 * <P>Type: INTEGER (int)</P>
252 */
Wink Savillef5bca082014-09-03 15:13:33 -0700253 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800254 public static final String SIM_SLOT_INDEX = "sim_id";
Wink Saville905bb542014-09-04 17:10:23 -0700255
256 /** SIM is not inserted */
Wink Savillea374c3d2014-11-11 11:48:04 -0800257 /** @hide */
Wink Savillefb40dd42014-06-12 17:02:31 -0700258 public static final int SIM_NOT_INSERTED = -1;
259
260 /**
Wink Saville905bb542014-09-04 17:10:23 -0700261 * TelephonyProvider column name for user displayed name.
Wink Savillefb40dd42014-06-12 17:02:31 -0700262 * <P>Type: TEXT (String)</P>
263 */
Wink Savillef5bca082014-09-03 15:13:33 -0700264 /** @hide */
Wink Savillefb40dd42014-06-12 17:02:31 -0700265 public static final String DISPLAY_NAME = "display_name";
266
Wink Saville905bb542014-09-04 17:10:23 -0700267 /**
Sanket Padawee1013f92014-11-07 11:37:29 -0800268 * TelephonyProvider column name for the service provider name for the SIM.
269 * <P>Type: TEXT (String)</P>
270 */
271 /** @hide */
272 public static final String CARRIER_NAME = "carrier_name";
273
274 /**
Wink Saville905bb542014-09-04 17:10:23 -0700275 * Default name resource
276 * @hide
277 */
Wink Savillefb40dd42014-06-12 17:02:31 -0700278 public static final int DEFAULT_NAME_RES = com.android.internal.R.string.unknownName;
279
280 /**
Wink Saville905bb542014-09-04 17:10:23 -0700281 * TelephonyProvider column name for source of the user displayed name.
282 * <P>Type: INT (int)</P> with one of the NAME_SOURCE_XXXX values below
283 *
284 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -0700285 */
286 public static final String NAME_SOURCE = "name_source";
287
Wink Saville905bb542014-09-04 17:10:23 -0700288 /**
289 * The name_source is undefined
290 * @hide
291 */
Wink Savillec650e0b2014-09-02 22:37:08 -0700292 public static final int NAME_SOURCE_UNDEFINDED = -1;
Wink Savillefb40dd42014-06-12 17:02:31 -0700293
Wink Saville905bb542014-09-04 17:10:23 -0700294 /**
295 * The name_source is the default
296 * @hide
297 */
Wink Savillec650e0b2014-09-02 22:37:08 -0700298 public static final int NAME_SOURCE_DEFAULT_SOURCE = 0;
Wink Savillefb40dd42014-06-12 17:02:31 -0700299
Wink Saville905bb542014-09-04 17:10:23 -0700300 /**
301 * The name_source is from the SIM
302 * @hide
303 */
Wink Savillec650e0b2014-09-02 22:37:08 -0700304 public static final int NAME_SOURCE_SIM_SOURCE = 1;
305
Wink Saville905bb542014-09-04 17:10:23 -0700306 /**
307 * The name_source is from the user
308 * @hide
309 */
Mathew Inwood45d2c252018-09-14 12:35:36 +0100310 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Wink Savillec650e0b2014-09-02 22:37:08 -0700311 public static final int NAME_SOURCE_USER_INPUT = 2;
Wink Savillefb40dd42014-06-12 17:02:31 -0700312
313 /**
Wink Saville905bb542014-09-04 17:10:23 -0700314 * TelephonyProvider column name for the color of a SIM.
Wink Savillefb40dd42014-06-12 17:02:31 -0700315 * <P>Type: INTEGER (int)</P>
316 */
Wink Savillef5bca082014-09-03 15:13:33 -0700317 /** @hide */
Wink Savillefb40dd42014-06-12 17:02:31 -0700318 public static final String COLOR = "color";
319
Wink Savillef5bca082014-09-03 15:13:33 -0700320 /** @hide */
Wink Savillefb40dd42014-06-12 17:02:31 -0700321 public static final int COLOR_1 = 0;
322
Wink Savillef5bca082014-09-03 15:13:33 -0700323 /** @hide */
Wink Savillefb40dd42014-06-12 17:02:31 -0700324 public static final int COLOR_2 = 1;
325
Wink Savillef5bca082014-09-03 15:13:33 -0700326 /** @hide */
Wink Savillefb40dd42014-06-12 17:02:31 -0700327 public static final int COLOR_3 = 2;
328
Wink Savillef5bca082014-09-03 15:13:33 -0700329 /** @hide */
Wink Savillefb40dd42014-06-12 17:02:31 -0700330 public static final int COLOR_4 = 3;
331
Wink Savillef5bca082014-09-03 15:13:33 -0700332 /** @hide */
Wink Savillefb40dd42014-06-12 17:02:31 -0700333 public static final int COLOR_DEFAULT = COLOR_1;
334
335 /**
Wink Saville905bb542014-09-04 17:10:23 -0700336 * TelephonyProvider column name for the phone number of a SIM.
Wink Savillefb40dd42014-06-12 17:02:31 -0700337 * <P>Type: TEXT (String)</P>
338 */
Wink Savillef5bca082014-09-03 15:13:33 -0700339 /** @hide */
Wink Savillefb40dd42014-06-12 17:02:31 -0700340 public static final String NUMBER = "number";
341
342 /**
Wink Saville905bb542014-09-04 17:10:23 -0700343 * TelephonyProvider column name for the number display format of a SIM.
Wink Savillefb40dd42014-06-12 17:02:31 -0700344 * <P>Type: INTEGER (int)</P>
345 */
Wink Savillef5bca082014-09-03 15:13:33 -0700346 /** @hide */
Wink Savillefb40dd42014-06-12 17:02:31 -0700347 public static final String DISPLAY_NUMBER_FORMAT = "display_number_format";
348
Wink Savillef5bca082014-09-03 15:13:33 -0700349 /** @hide */
Wink Savillec650e0b2014-09-02 22:37:08 -0700350 public static final int DISPLAY_NUMBER_NONE = 0;
Wink Savillefb40dd42014-06-12 17:02:31 -0700351
Wink Savillef5bca082014-09-03 15:13:33 -0700352 /** @hide */
Wink Savillefb40dd42014-06-12 17:02:31 -0700353 public static final int DISPLAY_NUMBER_FIRST = 1;
354
Wink Savillef5bca082014-09-03 15:13:33 -0700355 /** @hide */
Wink Savillefb40dd42014-06-12 17:02:31 -0700356 public static final int DISPLAY_NUMBER_LAST = 2;
357
Wink Savillef5bca082014-09-03 15:13:33 -0700358 /** @hide */
Stuart Scott95fc99b2014-10-29 16:58:19 -0700359 public static final int DISPLAY_NUMBER_DEFAULT = DISPLAY_NUMBER_FIRST;
Wink Savillefb40dd42014-06-12 17:02:31 -0700360
361 /**
Wink Saville905bb542014-09-04 17:10:23 -0700362 * TelephonyProvider column name for permission for data roaming of a SIM.
Wink Savillefb40dd42014-06-12 17:02:31 -0700363 * <P>Type: INTEGER (int)</P>
364 */
Wink Savillef5bca082014-09-03 15:13:33 -0700365 /** @hide */
Wink Savillefb40dd42014-06-12 17:02:31 -0700366 public static final String DATA_ROAMING = "data_roaming";
367
Stuart Scott400a3f62015-01-14 10:49:49 -0800368 /** Indicates that data roaming is enabled for a subscription */
Wink Savillefb40dd42014-06-12 17:02:31 -0700369 public static final int DATA_ROAMING_ENABLE = 1;
370
Stuart Scott400a3f62015-01-14 10:49:49 -0800371 /** Indicates that data roaming is disabled for a subscription */
Wink Savillefb40dd42014-06-12 17:02:31 -0700372 public static final int DATA_ROAMING_DISABLE = 0;
373
Wink Savillef5bca082014-09-03 15:13:33 -0700374 /** @hide */
Wink Savillefb40dd42014-06-12 17:02:31 -0700375 public static final int DATA_ROAMING_DEFAULT = DATA_ROAMING_DISABLE;
376
fionaxu1bf6ec22016-05-23 16:33:16 -0700377 /** @hide */
378 public static final int SIM_PROVISIONED = 0;
379
Tom Taylor7a962072014-09-04 14:05:20 -0700380 /**
Hall Liu0c149bd2018-06-08 18:14:21 -0700381 * TelephonyProvider column name for the MCC associated with a SIM, stored as a string.
382 * <P>Type: TEXT (String)</P>
383 * @hide
384 */
385 public static final String MCC_STRING = "mcc_string";
386
387 /**
388 * TelephonyProvider column name for the MNC associated with a SIM, stored as a string.
389 * <P>Type: TEXT (String)</P>
390 * @hide
391 */
392 public static final String MNC_STRING = "mnc_string";
393
394 /**
Wink Saville905bb542014-09-04 17:10:23 -0700395 * TelephonyProvider column name for the MCC associated with a SIM.
Tom Taylor7a962072014-09-04 14:05:20 -0700396 * <P>Type: INTEGER (int)</P>
Wink Savillea374c3d2014-11-11 11:48:04 -0800397 * @hide
Tom Taylor7a962072014-09-04 14:05:20 -0700398 */
399 public static final String MCC = "mcc";
400
401 /**
Wink Saville905bb542014-09-04 17:10:23 -0700402 * TelephonyProvider column name for the MNC associated with a SIM.
Tom Taylor7a962072014-09-04 14:05:20 -0700403 * <P>Type: INTEGER (int)</P>
Wink Savillea374c3d2014-11-11 11:48:04 -0800404 * @hide
Tom Taylor7a962072014-09-04 14:05:20 -0700405 */
406 public static final String MNC = "mnc";
407
Wink Savillec650e0b2014-09-02 22:37:08 -0700408 /**
fionaxub5592dc2016-04-08 13:19:31 -0700409 * TelephonyProvider column name for the sim provisioning status associated with a SIM.
410 * <P>Type: INTEGER (int)</P>
411 * @hide
412 */
413 public static final String SIM_PROVISIONING_STATUS = "sim_provisioning_status";
414
415 /**
Jeff Davidsond02731f2017-04-09 14:31:09 -0700416 * TelephonyProvider column name for whether a subscription is embedded (that is, present on an
417 * eSIM).
418 * <p>Type: INTEGER (int), 1 for embedded or 0 for non-embedded.
419 * @hide
420 */
421 public static final String IS_EMBEDDED = "is_embedded";
422
423 /**
yinxu921daf92018-01-05 11:15:24 -0800424 * TelephonyProvider column name for SIM card identifier. For UICC card it is the ICCID of the
425 * current enabled profile on the card, while for eUICC card it is the EID of the card.
426 * <P>Type: TEXT (String)</P>
427 * @hide
428 */
Malcolm Chenbd4ae762018-08-03 17:24:07 -0700429 public static final String CARD_ID = "card_id";
yinxu921daf92018-01-05 11:15:24 -0800430
431 /**
Jeff Davidsond02731f2017-04-09 14:31:09 -0700432 * TelephonyProvider column name for the encoded {@link UiccAccessRule}s from
433 * {@link UiccAccessRule#encodeRules}. Only present if {@link #IS_EMBEDDED} is 1.
434 * <p>TYPE: BLOB
435 * @hide
436 */
437 public static final String ACCESS_RULES = "access_rules";
438
439 /**
440 * TelephonyProvider column name identifying whether an embedded subscription is on a removable
441 * card. Such subscriptions are marked inaccessible as soon as the current card is removed.
442 * Otherwise, they will remain accessible unless explicitly deleted. Only present if
443 * {@link #IS_EMBEDDED} is 1.
444 * <p>TYPE: INTEGER (int), 1 for removable or 0 for non-removable.
445 * @hide
446 */
447 public static final String IS_REMOVABLE = "is_removable";
448
449 /**
Sanket Padawedc493092015-07-14 14:21:43 -0700450 * TelephonyProvider column name for extreme threat in CB settings
451 * @hide
452 */
453 public static final String CB_EXTREME_THREAT_ALERT = "enable_cmas_extreme_threat_alerts";
454
455 /**
456 * TelephonyProvider column name for severe threat in CB settings
457 *@hide
458 */
459 public static final String CB_SEVERE_THREAT_ALERT = "enable_cmas_severe_threat_alerts";
460
461 /**
462 * TelephonyProvider column name for amber alert in CB settings
463 *@hide
464 */
465 public static final String CB_AMBER_ALERT = "enable_cmas_amber_alerts";
466
467 /**
468 * TelephonyProvider column name for emergency alert in CB settings
469 *@hide
470 */
471 public static final String CB_EMERGENCY_ALERT = "enable_emergency_alerts";
472
473 /**
474 * TelephonyProvider column name for alert sound duration in CB settings
475 *@hide
476 */
477 public static final String CB_ALERT_SOUND_DURATION = "alert_sound_duration";
478
479 /**
480 * TelephonyProvider column name for alert reminder interval in CB settings
481 *@hide
482 */
483 public static final String CB_ALERT_REMINDER_INTERVAL = "alert_reminder_interval";
484
485 /**
486 * TelephonyProvider column name for enabling vibrate in CB settings
487 *@hide
488 */
489 public static final String CB_ALERT_VIBRATE = "enable_alert_vibrate";
490
491 /**
492 * TelephonyProvider column name for enabling alert speech in CB settings
493 *@hide
494 */
495 public static final String CB_ALERT_SPEECH = "enable_alert_speech";
496
497 /**
498 * TelephonyProvider column name for ETWS test alert in CB settings
499 *@hide
500 */
501 public static final String CB_ETWS_TEST_ALERT = "enable_etws_test_alerts";
502
503 /**
504 * TelephonyProvider column name for enable channel50 alert in CB settings
505 *@hide
506 */
507 public static final String CB_CHANNEL_50_ALERT = "enable_channel_50_alerts";
508
509 /**
510 * TelephonyProvider column name for CMAS test alert in CB settings
511 *@hide
512 */
513 public static final String CB_CMAS_TEST_ALERT= "enable_cmas_test_alerts";
514
515 /**
516 * TelephonyProvider column name for Opt out dialog in CB settings
517 *@hide
518 */
519 public static final String CB_OPT_OUT_DIALOG = "show_cmas_opt_out_dialog";
520
521 /**
Malcolm Chenc66dee92017-09-26 14:45:40 -0700522 * TelephonyProvider column name for enable Volte.
Jordan Liud6350112017-11-14 13:45:19 -0800523 *
524 * If this setting is not initialized (set to -1) then we use the Carrier Config value
525 * {@link CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL}.
Malcolm Chenc66dee92017-09-26 14:45:40 -0700526 *@hide
527 */
528 public static final String ENHANCED_4G_MODE_ENABLED = "volte_vt_enabled";
529
530 /**
531 * TelephonyProvider column name for enable VT (Video Telephony over IMS)
532 *@hide
533 */
534 public static final String VT_IMS_ENABLED = "vt_ims_enabled";
535
536 /**
537 * TelephonyProvider column name for enable Wifi calling
538 *@hide
539 */
540 public static final String WFC_IMS_ENABLED = "wfc_ims_enabled";
541
542 /**
543 * TelephonyProvider column name for Wifi calling mode
544 *@hide
545 */
546 public static final String WFC_IMS_MODE = "wfc_ims_mode";
547
548 /**
549 * TelephonyProvider column name for Wifi calling mode in roaming
550 *@hide
551 */
552 public static final String WFC_IMS_ROAMING_MODE = "wfc_ims_roaming_mode";
553
554 /**
555 * TelephonyProvider column name for enable Wifi calling in roaming
556 *@hide
557 */
558 public static final String WFC_IMS_ROAMING_ENABLED = "wfc_ims_roaming_enabled";
559
560 /**
Malcolm Chen0ac24ef2018-08-07 15:03:32 -0700561 * TelephonyProvider column name for whether a subscription is opportunistic, that is,
562 * whether the network it connects to is limited in functionality or coverage.
563 * For example, CBRS.
564 * IS_EMBEDDED should always be true.
565 * <p>Type: INTEGER (int), 1 for opportunistic or 0 for non-opportunistic.
566 * @hide
567 */
568 public static final String IS_OPPORTUNISTIC = "is_opportunistic";
569
570 /**
571 * TelephonyProvider column name for subId of parent subscription of an opportunistic
572 * subscription.
573 * if the parent sub id is valid, then is_opportunistic should always to true.
574 * @hide
575 */
576 public static final String PARENT_SUB_ID = "parent_sub_id";
577
578 /**
Wink Savillec650e0b2014-09-02 22:37:08 -0700579 * Broadcast Action: The user has changed one of the default subs related to
580 * data, phone calls, or sms</p>
Wink Savilled09c4ca2014-11-22 10:08:16 -0800581 *
582 * TODO: Change to a listener
Wink Savillef5bca082014-09-03 15:13:33 -0700583 * @hide
Wink Savillec650e0b2014-09-02 22:37:08 -0700584 */
585 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
586 public static final String SUB_DEFAULT_CHANGED_ACTION =
Rajeev Kumarc8ac4f3b2017-07-26 15:59:08 -0700587 "android.intent.action.SUB_DEFAULT_CHANGED";
Wink Savillefb40dd42014-06-12 17:02:31 -0700588
Malcolm Chen598d24c2017-04-24 18:37:29 -0700589 /**
590 * Broadcast Action: The default subscription has changed. This has the following
591 * extra values:</p>
592 * The {@link #EXTRA_SUBSCRIPTION_INDEX} extra indicates the current default subscription index
593 */
594 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
595 public static final String ACTION_DEFAULT_SUBSCRIPTION_CHANGED
596 = "android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED";
597
598 /**
599 * Broadcast Action: The default sms subscription has changed. This has the following
600 * extra values:</p>
601 * {@link #EXTRA_SUBSCRIPTION_INDEX} extra indicates the current default sms
602 * subscription index
603 */
604 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
605 public static final String ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED
606 = "android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED";
607
608 /**
Jeff Sharkey717f52f2018-01-04 16:04:11 -0700609 * Activity Action: Display UI for managing the billing relationship plans
610 * between a carrier and a specific subscriber.
611 * <p>
612 * Carrier apps are encouraged to implement this activity, and the OS will
613 * provide an affordance to quickly enter this activity, typically via
614 * Settings. This affordance will only be shown when the carrier app is
615 * actively providing subscription plan information via
616 * {@link #setSubscriptionPlans(int, List)}.
617 * <p>
618 * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
619 * the user is interested in.
Jeff Sharkey717f52f2018-01-04 16:04:11 -0700620 */
621 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
622 @SystemApi
623 public static final String ACTION_MANAGE_SUBSCRIPTION_PLANS
624 = "android.telephony.action.MANAGE_SUBSCRIPTION_PLANS";
625
626 /**
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -0700627 * Broadcast Action: Request a refresh of the billing relationship plans
628 * between a carrier and a specific subscriber.
629 * <p>
630 * Carrier apps are encouraged to implement this receiver, and the OS will
631 * provide an affordance to request a refresh. This affordance will only be
632 * shown when the carrier app is actively providing subscription plan
633 * information via {@link #setSubscriptionPlans(int, List)}.
634 * <p>
635 * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
636 * the user is interested in.
Jeff Sharkey0fc6d032018-03-30 16:25:11 -0600637 * <p>
638 * Receivers should protect themselves by checking that the sender holds the
639 * {@code android.permission.MANAGE_SUBSCRIPTION_PLANS} permission.
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -0700640 */
641 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
642 @SystemApi
643 public static final String ACTION_REFRESH_SUBSCRIPTION_PLANS
644 = "android.telephony.action.REFRESH_SUBSCRIPTION_PLANS";
645
646 /**
647 * Broadcast Action: The billing relationship plans between a carrier and a
648 * specific subscriber has changed.
649 * <p>
650 * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
651 * changed.
652 *
653 * @hide
654 */
655 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
656 @RequiresPermission(android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS)
657 public static final String ACTION_SUBSCRIPTION_PLANS_CHANGED
658 = "android.telephony.action.SUBSCRIPTION_PLANS_CHANGED";
659
660 /**
Malcolm Chen598d24c2017-04-24 18:37:29 -0700661 * Integer extra used with {@link #ACTION_DEFAULT_SUBSCRIPTION_CHANGED} and
662 * {@link #ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED} to indicate the subscription
663 * which has changed.
664 */
665 public static final String EXTRA_SUBSCRIPTION_INDEX = "android.telephony.extra.SUBSCRIPTION_INDEX";
666
Wink Savilled09c4ca2014-11-22 10:08:16 -0800667 private final Context mContext;
Jeff Sharkeya435ab52018-03-30 13:25:18 -0600668 private volatile INetworkPolicyManager mNetworkPolicy;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800669
670 /**
671 * A listener class for monitoring changes to {@link SubscriptionInfo} records.
672 * <p>
673 * Override the onSubscriptionsChanged method in the object that extends this
Wink Saville071743f2015-01-12 17:11:04 -0800674 * class and pass it to {@link #addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener)}
Wink Savilled09c4ca2014-11-22 10:08:16 -0800675 * to register your listener and to unregister invoke
Wink Saville071743f2015-01-12 17:11:04 -0800676 * {@link #removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener)}
Wink Savilled09c4ca2014-11-22 10:08:16 -0800677 * <p>
678 * Permissions android.Manifest.permission.READ_PHONE_STATE is required
679 * for #onSubscriptionsChanged to be invoked.
680 */
681 public static class OnSubscriptionsChangedListener {
Jack He9fc75742017-11-16 15:54:14 -0800682 private class OnSubscriptionsChangedListenerHandler extends Handler {
683 OnSubscriptionsChangedListenerHandler() {
684 super();
685 }
686
687 OnSubscriptionsChangedListenerHandler(Looper looper) {
688 super(looper);
689 }
690
Wink Savilled09c4ca2014-11-22 10:08:16 -0800691 @Override
692 public void handleMessage(Message msg) {
693 if (DBG) {
694 log("handleMessage: invoke the overriden onSubscriptionsChanged()");
695 }
696 OnSubscriptionsChangedListener.this.onSubscriptionsChanged();
697 }
Jack He9fc75742017-11-16 15:54:14 -0800698 }
699
700 private final Handler mHandler;
701
702 public OnSubscriptionsChangedListener() {
703 mHandler = new OnSubscriptionsChangedListenerHandler();
704 }
705
706 /**
707 * Allow a listener to be created with a custom looper
708 * @param looper the looper that the underlining handler should run on
709 * @hide
710 */
711 public OnSubscriptionsChangedListener(Looper looper) {
712 mHandler = new OnSubscriptionsChangedListenerHandler(looper);
713 }
Wink Savilled09c4ca2014-11-22 10:08:16 -0800714
715 /**
716 * Callback invoked when there is any change to any SubscriptionInfo. Typically
717 * this method would invoke {@link #getActiveSubscriptionInfoList}
718 */
719 public void onSubscriptionsChanged() {
720 if (DBG) log("onSubscriptionsChanged: NOT OVERRIDDEN");
721 }
722
723 /**
724 * The callback methods need to be called on the handler thread where
725 * this object was created. If the binder did that for us it'd be nice.
726 */
727 IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() {
728 @Override
729 public void onSubscriptionsChanged() {
730 if (DBG) log("callback: received, sendEmptyMessage(0) to handler");
731 mHandler.sendEmptyMessage(0);
732 }
733 };
734
735 private void log(String s) {
736 Rlog.d(LOG_TAG, s);
737 }
738 }
739
Wink Savillef5bca082014-09-03 15:13:33 -0700740 /** @hide */
Mathew Inwooda8382062018-08-16 17:01:12 +0100741 @UnsupportedAppUsage
Robin Leeeaf46802018-01-18 14:34:20 +0100742 public SubscriptionManager(Context context) {
Wink Savillefb40dd42014-06-12 17:02:31 -0700743 if (DBG) logd("SubscriptionManager created");
Wink Savilled09c4ca2014-11-22 10:08:16 -0800744 mContext = context;
Wink Savillefb40dd42014-06-12 17:02:31 -0700745 }
746
747 /**
Jeff Sharkey717f52f2018-01-04 16:04:11 -0700748 * @deprecated developers should always obtain references directly from
749 * {@link Context#getSystemService(Class)}.
Wink Savillefb40dd42014-06-12 17:02:31 -0700750 */
Jeff Sharkey717f52f2018-01-04 16:04:11 -0700751 @Deprecated
Wink Savilled09c4ca2014-11-22 10:08:16 -0800752 public static SubscriptionManager from(Context context) {
Jeff Sharkeyddf21642018-01-08 13:38:43 -0700753 return (SubscriptionManager) context
754 .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Wink Savilled09c4ca2014-11-22 10:08:16 -0800755 }
756
Robin Leeeaf46802018-01-18 14:34:20 +0100757 private final INetworkPolicyManager getNetworkPolicy() {
758 if (mNetworkPolicy == null) {
759 mNetworkPolicy = INetworkPolicyManager.Stub
760 .asInterface(ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
761 }
762 return mNetworkPolicy;
763 }
764
Wink Savilled09c4ca2014-11-22 10:08:16 -0800765 /**
766 * Register for changes to the list of active {@link SubscriptionInfo} records or to the
767 * individual records themselves. When a change occurs the onSubscriptionsChanged method of
768 * the listener will be invoked immediately if there has been a notification.
769 *
770 * @param listener an instance of {@link OnSubscriptionsChangedListener} with
771 * onSubscriptionsChanged overridden.
772 */
Wink Saville071743f2015-01-12 17:11:04 -0800773 public void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
Hall Liu5fb337f2017-11-22 17:38:15 -0800774 String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>";
Wink Savillea374c3d2014-11-11 11:48:04 -0800775 if (DBG) {
Hall Liu5fb337f2017-11-22 17:38:15 -0800776 logd("register OnSubscriptionsChangedListener pkgName=" + pkgName
Wink Savilled09c4ca2014-11-22 10:08:16 -0800777 + " listener=" + listener);
Wink Savillea374c3d2014-11-11 11:48:04 -0800778 }
779 try {
Wink Savilled09c4ca2014-11-22 10:08:16 -0800780 // We use the TelephonyRegistry as it runs in the system and thus is always
781 // available. Where as SubscriptionController could crash and not be available
Wink Savillea374c3d2014-11-11 11:48:04 -0800782 ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
783 "telephony.registry"));
784 if (tr != null) {
Hall Liu5fb337f2017-11-22 17:38:15 -0800785 tr.addOnSubscriptionsChangedListener(pkgName, listener.callback);
Wink Savillea374c3d2014-11-11 11:48:04 -0800786 }
787 } catch (RemoteException ex) {
Malcolm Chen27829e22018-09-04 22:12:31 -0700788 Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex);
Wink Savillea374c3d2014-11-11 11:48:04 -0800789 }
790 }
791
792 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -0800793 * Unregister the {@link OnSubscriptionsChangedListener}. This is not strictly necessary
794 * as the listener will automatically be unregistered if an attempt to invoke the listener
795 * fails.
Wink Savillea374c3d2014-11-11 11:48:04 -0800796 *
Wink Savilled09c4ca2014-11-22 10:08:16 -0800797 * @param listener that is to be unregistered.
Wink Savillea374c3d2014-11-11 11:48:04 -0800798 */
Wink Saville071743f2015-01-12 17:11:04 -0800799 public void removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
Robert Greenwalt278b8f92015-07-01 14:34:17 -0700800 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
Wink Savillea374c3d2014-11-11 11:48:04 -0800801 if (DBG) {
Wink Savilled09c4ca2014-11-22 10:08:16 -0800802 logd("unregister OnSubscriptionsChangedListener pkgForDebug=" + pkgForDebug
Wink Savillea374c3d2014-11-11 11:48:04 -0800803 + " listener=" + listener);
804 }
805 try {
Malcolm Chen27829e22018-09-04 22:12:31 -0700806 // We use the TelephonyRegistry as it runs in the system and thus is always
Wink Savillea374c3d2014-11-11 11:48:04 -0800807 // available where as SubscriptionController could crash and not be available
808 ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
809 "telephony.registry"));
810 if (tr != null) {
Wink Saville071743f2015-01-12 17:11:04 -0800811 tr.removeOnSubscriptionsChangedListener(pkgForDebug, listener.callback);
Wink Savillea374c3d2014-11-11 11:48:04 -0800812 }
813 } catch (RemoteException ex) {
Malcolm Chen27829e22018-09-04 22:12:31 -0700814 Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex);
815 }
816 }
817
818 /**
819 * A listener class for monitoring changes to {@link SubscriptionInfo} records of opportunistic
820 * subscriptions.
821 * <p>
822 * Override the onOpportunisticSubscriptionsChanged method in the object that extends this
823 * or {@link #addOnOpportunisticSubscriptionsChangedListener(
824 * Executor, OnOpportunisticSubscriptionsChangedListener)}
825 * to register your listener and to unregister invoke
826 * {@link #removeOnOpportunisticSubscriptionsChangedListener(
827 * OnOpportunisticSubscriptionsChangedListener)}
828 * <p>
829 * Permissions android.Manifest.permission.READ_PHONE_STATE is required
830 * for #onOpportunisticSubscriptionsChanged to be invoked.
831 */
832 public static class OnOpportunisticSubscriptionsChangedListener {
833 private Executor mExecutor;
834 /**
835 * Callback invoked when there is any change to any SubscriptionInfo. Typically
836 * this method would invoke {@link #getActiveSubscriptionInfoList}
837 */
838 public void onOpportunisticSubscriptionsChanged() {
839 if (DBG) log("onOpportunisticSubscriptionsChanged: NOT OVERRIDDEN");
840 }
841
842 private void setExecutor(Executor executor) {
843 mExecutor = executor;
844 }
845
846 /**
847 * The callback methods need to be called on the handler thread where
848 * this object was created. If the binder did that for us it'd be nice.
849 */
850 IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() {
851 @Override
852 public void onSubscriptionsChanged() {
853 if (DBG) log("onOpportunisticSubscriptionsChanged callback received.");
854 mExecutor.execute(() -> onOpportunisticSubscriptionsChanged());
855 }
856 };
857
858 private void log(String s) {
859 Rlog.d(LOG_TAG, s);
860 }
861 }
862
863 /**
864 * Register for changes to the list of opportunistic subscription records or to the
865 * individual records themselves. When a change occurs the onOpportunisticSubscriptionsChanged
866 * method of the listener will be invoked immediately if there has been a notification.
867 *
868 * @param listener an instance of {@link OnOpportunisticSubscriptionsChangedListener} with
869 * onOpportunisticSubscriptionsChanged overridden.
870 */
871 public void addOnOpportunisticSubscriptionsChangedListener(
872 @NonNull @CallbackExecutor Executor executor,
873 @NonNull OnOpportunisticSubscriptionsChangedListener listener) {
874 if (executor == null || listener == null) {
875 return;
876 }
877
878 String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>";
879 if (DBG) {
880 logd("register addOnOpportunisticSubscriptionsChangedListener pkgName=" + pkgName
881 + " listener=" + listener);
882 }
883
884 listener.setExecutor(executor);
885
886 try {
887 // We use the TelephonyRegistry as it runs in the system and thus is always
888 // available. Where as SubscriptionController could crash and not be available
889 ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
890 "telephony.registry"));
891 if (tr != null) {
892 tr.addOnOpportunisticSubscriptionsChangedListener(pkgName, listener.callback);
893 }
894 } catch (RemoteException ex) {
895 Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex);
896 }
897 }
898
899 /**
900 * Unregister the {@link OnOpportunisticSubscriptionsChangedListener} that is currently
901 * listening opportunistic subscriptions change. This is not strictly necessary
902 * as the listener will automatically be unregistered if an attempt to invoke the listener
903 * fails.
904 *
905 * @param listener that is to be unregistered.
906 */
907 public void removeOnOpportunisticSubscriptionsChangedListener(
908 OnOpportunisticSubscriptionsChangedListener listener) {
909 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
910 if (DBG) {
911 logd("unregister OnOpportunisticSubscriptionsChangedListener pkgForDebug="
912 + pkgForDebug + " listener=" + listener);
913 }
914 try {
915 // We use the TelephonyRegistry as it runs in the system and thus is always
916 // available where as SubscriptionController could crash and not be available
917 ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
918 "telephony.registry"));
919 if (tr != null) {
920 tr.removeOnSubscriptionsChangedListener(pkgForDebug, listener.callback);
921 }
922 } catch (RemoteException ex) {
923 Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex);
Wink Savillea374c3d2014-11-11 11:48:04 -0800924 }
925 }
926
927 /**
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -0800928 * Get the active SubscriptionInfo with the input subId.
929 *
Jeff Davidson3c0415a2018-02-23 15:27:46 -0800930 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
931 * or that the calling app has carrier privileges (see
932 * {@link TelephonyManager#hasCarrierPrivileges}).
933 *
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -0800934 * @param subId The unique SubscriptionInfo key in database.
Wink Savilled09c4ca2014-11-22 10:08:16 -0800935 * @return SubscriptionInfo, maybe null if its not active.
Wink Savillea374c3d2014-11-11 11:48:04 -0800936 */
Jeff Davidson3c0415a2018-02-23 15:27:46 -0800937 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
938 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
Wink Savilled09c4ca2014-11-22 10:08:16 -0800939 public SubscriptionInfo getActiveSubscriptionInfo(int subId) {
940 if (VDBG) logd("[getActiveSubscriptionInfo]+ subId=" + subId);
Wink Savillea54bf652014-12-11 13:37:50 -0800941 if (!isValidSubscriptionId(subId)) {
Sanket Padawe28964eb2015-06-05 16:13:51 -0700942 if (DBG) {
943 logd("[getActiveSubscriptionInfo]- invalid subId");
944 }
Wink Savillefb40dd42014-06-12 17:02:31 -0700945 return null;
946 }
947
Wink Savillea374c3d2014-11-11 11:48:04 -0800948 SubscriptionInfo subInfo = null;
Wink Savillefb40dd42014-06-12 17:02:31 -0700949
950 try {
951 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
952 if (iSub != null) {
Svet Ganov21301f62015-04-18 22:10:13 -0700953 subInfo = iSub.getActiveSubscriptionInfo(subId, mContext.getOpPackageName());
Wink Savillefb40dd42014-06-12 17:02:31 -0700954 }
955 } catch (RemoteException ex) {
956 // ignore it
957 }
958
959 return subInfo;
960
961 }
962
963 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -0800964 * Get the active SubscriptionInfo associated with the iccId
Wink Savillefb40dd42014-06-12 17:02:31 -0700965 * @param iccId the IccId of SIM card
Wink Savilled09c4ca2014-11-22 10:08:16 -0800966 * @return SubscriptionInfo, maybe null if its not active
Wink Savillef5bca082014-09-03 15:13:33 -0700967 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -0700968 */
Wink Savilled09c4ca2014-11-22 10:08:16 -0800969 public SubscriptionInfo getActiveSubscriptionInfoForIccIndex(String iccId) {
970 if (VDBG) logd("[getActiveSubscriptionInfoForIccIndex]+ iccId=" + iccId);
Wink Savillefb40dd42014-06-12 17:02:31 -0700971 if (iccId == null) {
Wink Savilled09c4ca2014-11-22 10:08:16 -0800972 logd("[getActiveSubscriptionInfoForIccIndex]- null iccid");
Wink Savillefb40dd42014-06-12 17:02:31 -0700973 return null;
974 }
975
Wink Savilled09c4ca2014-11-22 10:08:16 -0800976 SubscriptionInfo result = null;
Wink Savillefb40dd42014-06-12 17:02:31 -0700977
978 try {
979 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
980 if (iSub != null) {
Svet Ganov21301f62015-04-18 22:10:13 -0700981 result = iSub.getActiveSubscriptionInfoForIccId(iccId, mContext.getOpPackageName());
Wink Savillefb40dd42014-06-12 17:02:31 -0700982 }
983 } catch (RemoteException ex) {
984 // ignore it
985 }
986
987 return result;
988 }
989
990 /**
Sanket Padawe7e460252017-03-10 16:18:20 -0800991 * Get the active SubscriptionInfo associated with the slotIndex
Jeff Davidson3c0415a2018-02-23 15:27:46 -0800992 *
993 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
994 * or that the calling app has carrier privileges (see
995 * {@link TelephonyManager#hasCarrierPrivileges}).
996 *
Sanket Padawe7e460252017-03-10 16:18:20 -0800997 * @param slotIndex the slot which the subscription is inserted
Wink Savilled09c4ca2014-11-22 10:08:16 -0800998 * @return SubscriptionInfo, maybe null if its not active
Wink Savillefb40dd42014-06-12 17:02:31 -0700999 */
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001000 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
1001 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
Sanket Padawe7e460252017-03-10 16:18:20 -08001002 public SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex) {
1003 if (VDBG) logd("[getActiveSubscriptionInfoForSimSlotIndex]+ slotIndex=" + slotIndex);
1004 if (!isValidSlotIndex(slotIndex)) {
1005 logd("[getActiveSubscriptionInfoForSimSlotIndex]- invalid slotIndex");
Wink Savillefb40dd42014-06-12 17:02:31 -07001006 return null;
1007 }
1008
Wink Savilled09c4ca2014-11-22 10:08:16 -08001009 SubscriptionInfo result = null;
Wink Savillefb40dd42014-06-12 17:02:31 -07001010
1011 try {
1012 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1013 if (iSub != null) {
Sanket Padawe7e460252017-03-10 16:18:20 -08001014 result = iSub.getActiveSubscriptionInfoForSimSlotIndex(slotIndex,
Svet Ganov21301f62015-04-18 22:10:13 -07001015 mContext.getOpPackageName());
Wink Savillefb40dd42014-06-12 17:02:31 -07001016 }
1017 } catch (RemoteException ex) {
1018 // ignore it
1019 }
1020
1021 return result;
1022 }
1023
1024 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -08001025 * @return List of all SubscriptionInfo records in database,
1026 * include those that were inserted before, maybe empty but not null.
Wink Savillef5bca082014-09-03 15:13:33 -07001027 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07001028 */
Mathew Inwooda8382062018-08-16 17:01:12 +01001029 @UnsupportedAppUsage
Wink Savilled09c4ca2014-11-22 10:08:16 -08001030 public List<SubscriptionInfo> getAllSubscriptionInfoList() {
Wink Savillea374c3d2014-11-11 11:48:04 -08001031 if (VDBG) logd("[getAllSubscriptionInfoList]+");
Wink Savillefb40dd42014-06-12 17:02:31 -07001032
Wink Savillea374c3d2014-11-11 11:48:04 -08001033 List<SubscriptionInfo> result = null;
Wink Savillefb40dd42014-06-12 17:02:31 -07001034
1035 try {
1036 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1037 if (iSub != null) {
Svet Ganov21301f62015-04-18 22:10:13 -07001038 result = iSub.getAllSubInfoList(mContext.getOpPackageName());
Wink Savillefb40dd42014-06-12 17:02:31 -07001039 }
1040 } catch (RemoteException ex) {
1041 // ignore it
1042 }
1043
Wink Saville905bb542014-09-04 17:10:23 -07001044 if (result == null) {
Rajeev Kumarc8ac4f3b2017-07-26 15:59:08 -07001045 result = new ArrayList<>();
Wink Saville905bb542014-09-04 17:10:23 -07001046 }
Wink Savillefb40dd42014-06-12 17:02:31 -07001047 return result;
1048 }
1049
1050 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -08001051 * Get the SubscriptionInfo(s) of the currently inserted SIM(s). The records will be sorted
1052 * by {@link SubscriptionInfo#getSimSlotIndex} then by {@link SubscriptionInfo#getSubscriptionId}.
1053 *
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001054 * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1055 * or that the calling app has carrier privileges (see
1056 * {@link TelephonyManager#hasCarrierPrivileges}). In the latter case, only records accessible
1057 * to the calling app are returned.
1058 *
Wink Savilled09c4ca2014-11-22 10:08:16 -08001059 * @return Sorted list of the currently {@link SubscriptionInfo} records available on the device.
1060 * <ul>
1061 * <li>
1062 * If null is returned the current state is unknown but if a {@link OnSubscriptionsChangedListener}
1063 * has been registered {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be
1064 * invoked in the future.
1065 * </li>
1066 * <li>
1067 * If the list is empty then there are no {@link SubscriptionInfo} records currently available.
1068 * </li>
1069 * <li>
1070 * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
1071 * then by {@link SubscriptionInfo#getSubscriptionId}.
1072 * </li>
1073 * </ul>
Wink Savillefb40dd42014-06-12 17:02:31 -07001074 */
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001075 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
1076 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
Wink Savilled09c4ca2014-11-22 10:08:16 -08001077 public List<SubscriptionInfo> getActiveSubscriptionInfoList() {
Wink Savillea374c3d2014-11-11 11:48:04 -08001078 List<SubscriptionInfo> result = null;
Wink Savillefb40dd42014-06-12 17:02:31 -07001079
1080 try {
1081 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1082 if (iSub != null) {
Svet Ganov21301f62015-04-18 22:10:13 -07001083 result = iSub.getActiveSubscriptionInfoList(mContext.getOpPackageName());
Wink Savillefb40dd42014-06-12 17:02:31 -07001084 }
1085 } catch (RemoteException ex) {
1086 // ignore it
1087 }
Wink Savillefb40dd42014-06-12 17:02:31 -07001088 return result;
1089 }
1090
1091 /**
Jeff Davidsond02731f2017-04-09 14:31:09 -07001092 * Gets the SubscriptionInfo(s) of all available subscriptions, if any.
1093 *
1094 * <p>Available subscriptions include active ones (those with a non-negative
1095 * {@link SubscriptionInfo#getSimSlotIndex()}) as well as inactive but installed embedded
1096 * subscriptions.
1097 *
1098 * <p>The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by
1099 * {@link SubscriptionInfo#getSubscriptionId}.
1100 *
1101 * @return Sorted list of the current {@link SubscriptionInfo} records available on the
1102 * device.
1103 * <ul>
1104 * <li>
1105 * If null is returned the current state is unknown but if a
1106 * {@link OnSubscriptionsChangedListener} has been registered
1107 * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be invoked in the future.
1108 * <li>
1109 * If the list is empty then there are no {@link SubscriptionInfo} records currently available.
1110 * <li>
1111 * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
1112 * then by {@link SubscriptionInfo#getSubscriptionId}.
1113 * </ul>
Jiuyu Sund3bb4ae2018-02-08 16:38:26 +00001114 *
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08001115 * <p>
1116 * Permissions android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE is required
1117 * for #getAvailableSubscriptionInfoList to be invoked.
1118 * @hide
Jeff Davidsond02731f2017-04-09 14:31:09 -07001119 */
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08001120 @SystemApi
Jeff Davidsond02731f2017-04-09 14:31:09 -07001121 public List<SubscriptionInfo> getAvailableSubscriptionInfoList() {
1122 List<SubscriptionInfo> result = null;
1123
1124 try {
1125 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1126 if (iSub != null) {
1127 result = iSub.getAvailableSubscriptionInfoList(mContext.getOpPackageName());
1128 }
1129 } catch (RemoteException ex) {
1130 // ignore it
1131 }
1132 return result;
1133 }
1134
1135 /**
1136 * Gets the SubscriptionInfo(s) of all embedded subscriptions accessible to the calling app, if
1137 * any.
1138 *
1139 * <p>Only those subscriptions for which the calling app has carrier privileges per the
1140 * subscription metadata, if any, will be included in the returned list.
1141 *
1142 * <p>The records will be sorted by {@link SubscriptionInfo#getSimSlotIndex} then by
1143 * {@link SubscriptionInfo#getSubscriptionId}.
1144 *
1145 * @return Sorted list of the current embedded {@link SubscriptionInfo} records available on the
1146 * device which are accessible to the caller.
1147 * <ul>
1148 * <li>
1149 * If null is returned the current state is unknown but if a
1150 * {@link OnSubscriptionsChangedListener} has been registered
1151 * {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be invoked in the future.
1152 * <li>
1153 * If the list is empty then there are no {@link SubscriptionInfo} records currently available.
1154 * <li>
1155 * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
1156 * then by {@link SubscriptionInfo#getSubscriptionId}.
1157 * </ul>
Jeff Davidsond02731f2017-04-09 14:31:09 -07001158 */
1159 public List<SubscriptionInfo> getAccessibleSubscriptionInfoList() {
1160 List<SubscriptionInfo> result = null;
1161
1162 try {
1163 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1164 if (iSub != null) {
1165 result = iSub.getAccessibleSubscriptionInfoList(mContext.getOpPackageName());
1166 }
1167 } catch (RemoteException ex) {
1168 // ignore it
1169 }
1170 return result;
1171 }
1172
1173 /**
1174 * Request a refresh of the platform cache of profile information.
1175 *
1176 * <p>Should be called by the EuiccService implementation whenever this information changes due
1177 * to an operation done outside the scope of a request initiated by the platform to the
1178 * EuiccService. There is no need to refresh for downloads, deletes, or other operations that
1179 * were made through the EuiccService.
1180 *
1181 * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
1182 * @hide
Jeff Davidsond02731f2017-04-09 14:31:09 -07001183 */
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08001184 @SystemApi
Jeff Davidsond02731f2017-04-09 14:31:09 -07001185 public void requestEmbeddedSubscriptionInfoListRefresh() {
1186 try {
1187 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1188 if (iSub != null) {
1189 iSub.requestEmbeddedSubscriptionInfoListRefresh();
1190 }
1191 } catch (RemoteException ex) {
1192 // ignore it
1193 }
1194 }
1195
1196 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -08001197 * @return the count of all subscriptions in the database, this includes
1198 * all subscriptions that have been seen.
Wink Savillef5bca082014-09-03 15:13:33 -07001199 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07001200 */
Mathew Inwooda8382062018-08-16 17:01:12 +01001201 @UnsupportedAppUsage
Wink Savilled09c4ca2014-11-22 10:08:16 -08001202 public int getAllSubscriptionInfoCount() {
Wink Savillea374c3d2014-11-11 11:48:04 -08001203 if (VDBG) logd("[getAllSubscriptionInfoCount]+");
Wink Savillefb40dd42014-06-12 17:02:31 -07001204
1205 int result = 0;
1206
1207 try {
1208 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1209 if (iSub != null) {
Svet Ganov21301f62015-04-18 22:10:13 -07001210 result = iSub.getAllSubInfoCount(mContext.getOpPackageName());
Wink Savillefb40dd42014-06-12 17:02:31 -07001211 }
1212 } catch (RemoteException ex) {
1213 // ignore it
1214 }
1215
1216 return result;
1217 }
1218
1219 /**
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001220 *
1221 * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1222 * or that the calling app has carrier privileges (see
1223 * {@link TelephonyManager#hasCarrierPrivileges}). In the latter case, the count will include
1224 * only those subscriptions accessible to the caller.
1225 *
Wink Savilled09c4ca2014-11-22 10:08:16 -08001226 * @return the current number of active subscriptions. There is no guarantee the value
1227 * returned by this method will be the same as the length of the list returned by
1228 * {@link #getActiveSubscriptionInfoList}.
Wink Savillec650e0b2014-09-02 22:37:08 -07001229 */
Jeff Davidson3c0415a2018-02-23 15:27:46 -08001230 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
1231 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
Wink Savilled09c4ca2014-11-22 10:08:16 -08001232 public int getActiveSubscriptionInfoCount() {
Wink Savillec650e0b2014-09-02 22:37:08 -07001233 int result = 0;
1234
1235 try {
1236 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1237 if (iSub != null) {
Svet Ganov21301f62015-04-18 22:10:13 -07001238 result = iSub.getActiveSubInfoCount(mContext.getOpPackageName());
Wink Savillec650e0b2014-09-02 22:37:08 -07001239 }
1240 } catch (RemoteException ex) {
1241 // ignore it
1242 }
1243
1244 return result;
1245 }
1246
1247 /**
Wink Savilled09c4ca2014-11-22 10:08:16 -08001248 * @return the maximum number of active subscriptions that will be returned by
1249 * {@link #getActiveSubscriptionInfoList} and the value returned by
1250 * {@link #getActiveSubscriptionInfoCount}.
1251 */
1252 public int getActiveSubscriptionInfoCountMax() {
1253 int result = 0;
1254
1255 try {
1256 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1257 if (iSub != null) {
1258 result = iSub.getActiveSubInfoCountMax();
1259 }
1260 } catch (RemoteException ex) {
1261 // ignore it
1262 }
1263
1264 return result;
1265 }
1266
1267 /**
1268 * Add a new SubscriptionInfo to SubscriptionInfo database if needed
Wink Savillefb40dd42014-06-12 17:02:31 -07001269 * @param iccId the IccId of the SIM card
Sanket Padawe7e460252017-03-10 16:18:20 -08001270 * @param slotIndex the slot which the SIM is inserted
Wink Savillefb40dd42014-06-12 17:02:31 -07001271 * @return the URL of the newly created row or the updated row
Wink Savillef5bca082014-09-03 15:13:33 -07001272 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07001273 */
Sanket Padawe7e460252017-03-10 16:18:20 -08001274 public Uri addSubscriptionInfoRecord(String iccId, int slotIndex) {
1275 if (VDBG) logd("[addSubscriptionInfoRecord]+ iccId:" + iccId + " slotIndex:" + slotIndex);
Wink Savillefb40dd42014-06-12 17:02:31 -07001276 if (iccId == null) {
Wink Savillea374c3d2014-11-11 11:48:04 -08001277 logd("[addSubscriptionInfoRecord]- null iccId");
Wink Savillefb40dd42014-06-12 17:02:31 -07001278 }
Sanket Padawe7e460252017-03-10 16:18:20 -08001279 if (!isValidSlotIndex(slotIndex)) {
1280 logd("[addSubscriptionInfoRecord]- invalid slotIndex");
Wink Savillec650e0b2014-09-02 22:37:08 -07001281 }
Wink Savillefb40dd42014-06-12 17:02:31 -07001282
1283 try {
1284 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1285 if (iSub != null) {
1286 // FIXME: This returns 1 on success, 0 on error should should we return it?
Sanket Padawe7e460252017-03-10 16:18:20 -08001287 iSub.addSubInfoRecord(iccId, slotIndex);
sqiana77d9d72018-05-08 14:11:11 -07001288 } else {
1289 logd("[addSubscriptionInfoRecord]- ISub service is null");
Wink Savillefb40dd42014-06-12 17:02:31 -07001290 }
1291 } catch (RemoteException ex) {
1292 // ignore it
1293 }
1294
1295 // FIXME: Always returns null?
1296 return null;
1297
1298 }
1299
1300 /**
Stuart Scottab45ec12014-10-28 09:29:01 -07001301 * Set SIM icon tint color by simInfo index
Wink Savilled09c4ca2014-11-22 10:08:16 -08001302 * @param tint the RGB value of icon tint color of the SIM
Wink Savillefb40dd42014-06-12 17:02:31 -07001303 * @param subId the unique SubInfoRecord index in database
1304 * @return the number of records updated
Wink Savillef5bca082014-09-03 15:13:33 -07001305 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07001306 */
Mathew Inwooda8382062018-08-16 17:01:12 +01001307 @UnsupportedAppUsage
Wink Savilled09c4ca2014-11-22 10:08:16 -08001308 public int setIconTint(int tint, int subId) {
Stuart Scottab45ec12014-10-28 09:29:01 -07001309 if (VDBG) logd("[setIconTint]+ tint:" + tint + " subId:" + subId);
Malcolm Chenbd4ae762018-08-03 17:24:07 -07001310 return setSubscriptionPropertyHelper(subId, "setIconTint",
1311 (iSub)-> iSub.setIconTint(tint, subId)
1312 );
Wink Savillefb40dd42014-06-12 17:02:31 -07001313 }
1314
1315 /**
1316 * Set display name by simInfo index
Wink Savillefb40dd42014-06-12 17:02:31 -07001317 * @param displayName the display name of SIM card
Wink Savillea374c3d2014-11-11 11:48:04 -08001318 * @param subId the unique SubscriptionInfo index in database
Wink Savillefb40dd42014-06-12 17:02:31 -07001319 * @return the number of records updated
Wink Savillef5bca082014-09-03 15:13:33 -07001320 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07001321 */
Wink Savilled09c4ca2014-11-22 10:08:16 -08001322 public int setDisplayName(String displayName, int subId) {
Wink Savillec650e0b2014-09-02 22:37:08 -07001323 return setDisplayName(displayName, subId, NAME_SOURCE_UNDEFINDED);
Wink Savillefb40dd42014-06-12 17:02:31 -07001324 }
1325
1326 /**
1327 * Set display name by simInfo index with name source
Wink Savillefb40dd42014-06-12 17:02:31 -07001328 * @param displayName the display name of SIM card
Wink Savillea374c3d2014-11-11 11:48:04 -08001329 * @param subId the unique SubscriptionInfo index in database
Wink Savillec650e0b2014-09-02 22:37:08 -07001330 * @param nameSource 0: NAME_SOURCE_DEFAULT_SOURCE, 1: NAME_SOURCE_SIM_SOURCE,
1331 * 2: NAME_SOURCE_USER_INPUT, -1 NAME_SOURCE_UNDEFINED
Wink Saville98513d72014-12-08 12:44:16 -08001332 * @return the number of records updated or < 0 if invalid subId
Wink Savillef5bca082014-09-03 15:13:33 -07001333 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07001334 */
Mathew Inwooda8382062018-08-16 17:01:12 +01001335 @UnsupportedAppUsage
Wink Savilled09c4ca2014-11-22 10:08:16 -08001336 public int setDisplayName(String displayName, int subId, long nameSource) {
Wink Savillec650e0b2014-09-02 22:37:08 -07001337 if (VDBG) {
1338 logd("[setDisplayName]+ displayName:" + displayName + " subId:" + subId
1339 + " nameSource:" + nameSource);
1340 }
Malcolm Chenbd4ae762018-08-03 17:24:07 -07001341 return setSubscriptionPropertyHelper(subId, "setDisplayName",
1342 (iSub)-> iSub.setDisplayNameUsingSrc(displayName, subId, nameSource)
1343 );
Wink Savillefb40dd42014-06-12 17:02:31 -07001344 }
1345
1346 /**
1347 * Set phone number by subId
Wink Savillefb40dd42014-06-12 17:02:31 -07001348 * @param number the phone number of the SIM
Wink Savillea374c3d2014-11-11 11:48:04 -08001349 * @param subId the unique SubscriptionInfo index in database
Wink Savillefb40dd42014-06-12 17:02:31 -07001350 * @return the number of records updated
Wink Savillef5bca082014-09-03 15:13:33 -07001351 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07001352 */
Mathew Inwooda8382062018-08-16 17:01:12 +01001353 @UnsupportedAppUsage
Wink Savilled09c4ca2014-11-22 10:08:16 -08001354 public int setDisplayNumber(String number, int subId) {
Malcolm Chenbd4ae762018-08-03 17:24:07 -07001355 if (number == null) {
Wink Savillec650e0b2014-09-02 22:37:08 -07001356 logd("[setDisplayNumber]- fail");
Wink Savillefb40dd42014-06-12 17:02:31 -07001357 return -1;
1358 }
Malcolm Chenbd4ae762018-08-03 17:24:07 -07001359 return setSubscriptionPropertyHelper(subId, "setDisplayNumber",
1360 (iSub)-> iSub.setDisplayNumber(number, subId)
1361 );
Wink Savillefb40dd42014-06-12 17:02:31 -07001362 }
1363
1364 /**
Wink Savillefb40dd42014-06-12 17:02:31 -07001365 * Set data roaming by simInfo index
Wink Savillefb40dd42014-06-12 17:02:31 -07001366 * @param roaming 0:Don't allow data when roaming, 1:Allow data when roaming
Wink Savillea374c3d2014-11-11 11:48:04 -08001367 * @param subId the unique SubscriptionInfo index in database
Wink Savillefb40dd42014-06-12 17:02:31 -07001368 * @return the number of records updated
Wink Savillef5bca082014-09-03 15:13:33 -07001369 * @hide
Wink Savillefb40dd42014-06-12 17:02:31 -07001370 */
Mathew Inwooda8382062018-08-16 17:01:12 +01001371 @UnsupportedAppUsage
Wink Savilled09c4ca2014-11-22 10:08:16 -08001372 public int setDataRoaming(int roaming, int subId) {
Wink Savillefb40dd42014-06-12 17:02:31 -07001373 if (VDBG) logd("[setDataRoaming]+ roaming:" + roaming + " subId:" + subId);
Malcolm Chenbd4ae762018-08-03 17:24:07 -07001374 return setSubscriptionPropertyHelper(subId, "setDataRoaming",
1375 (iSub)->iSub.setDataRoaming(roaming, subId)
1376 );
Wink Savillefb40dd42014-06-12 17:02:31 -07001377 }
1378
Wink Saville905bb542014-09-04 17:10:23 -07001379 /**
Sanket Padawe7e460252017-03-10 16:18:20 -08001380 * Get slotIndex associated with the subscription.
sqian996a3182018-10-12 18:41:19 -07001381 *
1382 * @param subscriptionId the unique SubscriptionInfo index in database
1383 * @return slotIndex as a positive integer or {@link #INVALID_SIM_SLOT_INDEX} if the supplied
1384 * subscriptionId doesn't have an associated slot index.
Wink Saville905bb542014-09-04 17:10:23 -07001385 */
sqian996a3182018-10-12 18:41:19 -07001386 public static int getSlotIndex(int subscriptionId) {
1387 if (!isValidSubscriptionId(subscriptionId)) {
Sanket Padawe28964eb2015-06-05 16:13:51 -07001388 if (DBG) {
sqian996a3182018-10-12 18:41:19 -07001389 logd("[getSlotIndex]- supplied subscriptionId is invalid.");
Sanket Padawe28964eb2015-06-05 16:13:51 -07001390 }
Wink Savillec650e0b2014-09-02 22:37:08 -07001391 }
Wink Savillefb40dd42014-06-12 17:02:31 -07001392
Wink Savilled09c4ca2014-11-22 10:08:16 -08001393 int result = INVALID_SIM_SLOT_INDEX;
Wink Savillefb40dd42014-06-12 17:02:31 -07001394
1395 try {
1396 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1397 if (iSub != null) {
sqian996a3182018-10-12 18:41:19 -07001398 result = iSub.getSlotIndex(subscriptionId);
Wink Savillefb40dd42014-06-12 17:02:31 -07001399 }
1400 } catch (RemoteException ex) {
1401 // ignore it
1402 }
1403
1404 return result;
1405
1406 }
1407
sqiancd4dafb2018-08-29 13:58:49 -07001408 /**
1409 * Get an array of Subscription Ids for specified slot Index.
1410 * @param slotIndex the slot Index.
1411 * @return subscription Ids or null if the given slot Index is not valid.
1412 */
sqianf8ace212018-10-19 19:01:42 -07001413 @Nullable
sqiancd4dafb2018-08-29 13:58:49 -07001414 public static int[] getSubscriptionIds(int slotIndex) {
1415 return getSubId(slotIndex);
1416 }
1417
Wink Savillef5bca082014-09-03 15:13:33 -07001418 /** @hide */
Mathew Inwooda8382062018-08-16 17:01:12 +01001419 @UnsupportedAppUsage
Sanket Padawe7e460252017-03-10 16:18:20 -08001420 public static int[] getSubId(int slotIndex) {
1421 if (!isValidSlotIndex(slotIndex)) {
Wink Savillec650e0b2014-09-02 22:37:08 -07001422 logd("[getSubId]- fail");
1423 return null;
1424 }
Wink Savillefb40dd42014-06-12 17:02:31 -07001425
Wink Saville63f03dd2014-10-23 10:44:45 -07001426 int[] subId = null;
Wink Savillefb40dd42014-06-12 17:02:31 -07001427
1428 try {
1429 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1430 if (iSub != null) {
Sanket Padawe7e460252017-03-10 16:18:20 -08001431 subId = iSub.getSubId(slotIndex);
Wink Savillefb40dd42014-06-12 17:02:31 -07001432 }
1433 } catch (RemoteException ex) {
1434 // ignore it
1435 }
1436
1437 return subId;
1438 }
1439
Wink Savillef5bca082014-09-03 15:13:33 -07001440 /** @hide */
Chen Xu4c0b06d2018-10-22 16:54:39 +00001441 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
Wink Saville63f03dd2014-10-23 10:44:45 -07001442 public static int getPhoneId(int subId) {
Wink Savillea54bf652014-12-11 13:37:50 -08001443 if (!isValidSubscriptionId(subId)) {
Sanket Padawe28964eb2015-06-05 16:13:51 -07001444 if (DBG) {
1445 logd("[getPhoneId]- fail");
1446 }
Wink Savilled09c4ca2014-11-22 10:08:16 -08001447 return INVALID_PHONE_INDEX;
Wink Savillec650e0b2014-09-02 22:37:08 -07001448 }
Wink Savillefb40dd42014-06-12 17:02:31 -07001449
Wink Savilled09c4ca2014-11-22 10:08:16 -08001450 int result = INVALID_PHONE_INDEX;
Wink Savillefb40dd42014-06-12 17:02:31 -07001451
1452 try {
1453 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1454 if (iSub != null) {
1455 result = iSub.getPhoneId(subId);
1456 }
1457 } catch (RemoteException ex) {
1458 // ignore it
1459 }
1460
Wink Savillec650e0b2014-09-02 22:37:08 -07001461 if (VDBG) logd("[getPhoneId]- phoneId=" + result);
Wink Savillefb40dd42014-06-12 17:02:31 -07001462 return result;
1463
1464 }
1465
Wink Savillefb40dd42014-06-12 17:02:31 -07001466 private static void logd(String msg) {
Wink Savilled09c4ca2014-11-22 10:08:16 -08001467 Rlog.d(LOG_TAG, msg);
Wink Savillefb40dd42014-06-12 17:02:31 -07001468 }
1469
Wink Savillefb40dd42014-06-12 17:02:31 -07001470 /**
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001471 * Returns the system's default subscription id.
1472 *
1473 * For a voice capable device, it will return getDefaultVoiceSubscriptionId.
1474 * For a data only device, it will return the getDefaultDataSubscriptionId.
1475 * May return an INVALID_SUBSCRIPTION_ID on error.
1476 *
1477 * @return the "system" default subscription id.
Wink Savillefb40dd42014-06-12 17:02:31 -07001478 */
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001479 public static int getDefaultSubscriptionId() {
Wink Savilled09c4ca2014-11-22 10:08:16 -08001480 int subId = INVALID_SUBSCRIPTION_ID;
Wink Savillefb40dd42014-06-12 17:02:31 -07001481
1482 try {
1483 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1484 if (iSub != null) {
1485 subId = iSub.getDefaultSubId();
1486 }
1487 } catch (RemoteException ex) {
1488 // ignore it
1489 }
1490
1491 if (VDBG) logd("getDefaultSubId=" + subId);
1492 return subId;
1493 }
1494
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001495 /**
1496 * Returns the system's default voice subscription id.
1497 *
1498 * On a data only device or on error, will return INVALID_SUBSCRIPTION_ID.
1499 *
1500 * @return the default voice subscription Id.
1501 */
1502 public static int getDefaultVoiceSubscriptionId() {
Wink Savilled09c4ca2014-11-22 10:08:16 -08001503 int subId = INVALID_SUBSCRIPTION_ID;
Wink Savillefb40dd42014-06-12 17:02:31 -07001504
1505 try {
1506 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1507 if (iSub != null) {
1508 subId = iSub.getDefaultVoiceSubId();
1509 }
1510 } catch (RemoteException ex) {
1511 // ignore it
1512 }
1513
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001514 if (VDBG) logd("getDefaultVoiceSubscriptionId, sub id = " + subId);
Wink Savillefb40dd42014-06-12 17:02:31 -07001515 return subId;
1516 }
1517
Wink Savillef5bca082014-09-03 15:13:33 -07001518 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -08001519 public void setDefaultVoiceSubId(int subId) {
Wink Savillefb40dd42014-06-12 17:02:31 -07001520 if (VDBG) logd("setDefaultVoiceSubId sub id = " + subId);
1521 try {
1522 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1523 if (iSub != null) {
1524 iSub.setDefaultVoiceSubId(subId);
1525 }
1526 } catch (RemoteException ex) {
Wink Savillec650e0b2014-09-02 22:37:08 -07001527 // ignore it
Wink Savillefb40dd42014-06-12 17:02:31 -07001528 }
1529 }
1530
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001531 /**
1532 * Return the SubscriptionInfo for default voice subscription.
1533 *
1534 * Will return null on data only devices, or on error.
1535 *
1536 * @return the SubscriptionInfo for the default voice subscription.
1537 * @hide
1538 */
Mathew Inwooda8382062018-08-16 17:01:12 +01001539 @UnsupportedAppUsage
Wink Savilled09c4ca2014-11-22 10:08:16 -08001540 public SubscriptionInfo getDefaultVoiceSubscriptionInfo() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001541 return getActiveSubscriptionInfo(getDefaultVoiceSubscriptionId());
Wink Savillefb40dd42014-06-12 17:02:31 -07001542 }
1543
Wink Savillef5bca082014-09-03 15:13:33 -07001544 /** @hide */
Mathew Inwooda8382062018-08-16 17:01:12 +01001545 @UnsupportedAppUsage
Wink Savillec650e0b2014-09-02 22:37:08 -07001546 public static int getDefaultVoicePhoneId() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001547 return getPhoneId(getDefaultVoiceSubscriptionId());
Wink Savillefb40dd42014-06-12 17:02:31 -07001548 }
1549
Wink Saville905bb542014-09-04 17:10:23 -07001550 /**
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001551 * Returns the system's default SMS subscription id.
Wink Savilled09c4ca2014-11-22 10:08:16 -08001552 *
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001553 * On a data only device or on error, will return INVALID_SUBSCRIPTION_ID.
1554 *
1555 * @return the default SMS subscription Id.
Wink Saville905bb542014-09-04 17:10:23 -07001556 */
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001557 public static int getDefaultSmsSubscriptionId() {
Wink Savilled09c4ca2014-11-22 10:08:16 -08001558 int subId = INVALID_SUBSCRIPTION_ID;
Wink Savillefb40dd42014-06-12 17:02:31 -07001559
1560 try {
1561 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1562 if (iSub != null) {
Wink Savillec650e0b2014-09-02 22:37:08 -07001563 subId = iSub.getDefaultSmsSubId();
Wink Savillefb40dd42014-06-12 17:02:31 -07001564 }
1565 } catch (RemoteException ex) {
Wink Savillec650e0b2014-09-02 22:37:08 -07001566 // ignore it
Wink Savillefb40dd42014-06-12 17:02:31 -07001567 }
Wink Savillec650e0b2014-09-02 22:37:08 -07001568
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001569 if (VDBG) logd("getDefaultSmsSubscriptionId, sub id = " + subId);
Wink Savillec650e0b2014-09-02 22:37:08 -07001570 return subId;
1571 }
1572
Wink Savillef5bca082014-09-03 15:13:33 -07001573 /** @hide */
Mathew Inwooda8382062018-08-16 17:01:12 +01001574 @UnsupportedAppUsage
Wink Savilled09c4ca2014-11-22 10:08:16 -08001575 public void setDefaultSmsSubId(int subId) {
Wink Savillec650e0b2014-09-02 22:37:08 -07001576 if (VDBG) logd("setDefaultSmsSubId sub id = " + subId);
1577 try {
1578 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1579 if (iSub != null) {
1580 iSub.setDefaultSmsSubId(subId);
1581 }
1582 } catch (RemoteException ex) {
1583 // ignore it
1584 }
1585 }
1586
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001587 /**
1588 * Return the SubscriptionInfo for default voice subscription.
1589 *
1590 * Will return null on data only devices, or on error.
1591 *
1592 * @return the SubscriptionInfo for the default SMS subscription.
1593 * @hide
1594 */
Wink Savilled09c4ca2014-11-22 10:08:16 -08001595 public SubscriptionInfo getDefaultSmsSubscriptionInfo() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001596 return getActiveSubscriptionInfo(getDefaultSmsSubscriptionId());
Wink Savillec650e0b2014-09-02 22:37:08 -07001597 }
1598
Wink Savillef5bca082014-09-03 15:13:33 -07001599 /** @hide */
Mathew Inwooda8382062018-08-16 17:01:12 +01001600 @UnsupportedAppUsage
Wink Savilled09c4ca2014-11-22 10:08:16 -08001601 public int getDefaultSmsPhoneId() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001602 return getPhoneId(getDefaultSmsSubscriptionId());
Wink Savillec650e0b2014-09-02 22:37:08 -07001603 }
1604
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001605 /**
1606 * Returns the system's default data subscription id.
1607 *
1608 * On a voice only device or on error, will return INVALID_SUBSCRIPTION_ID.
1609 *
1610 * @return the default data subscription Id.
1611 */
1612 public static int getDefaultDataSubscriptionId() {
Wink Savilled09c4ca2014-11-22 10:08:16 -08001613 int subId = INVALID_SUBSCRIPTION_ID;
Wink Savillec650e0b2014-09-02 22:37:08 -07001614
1615 try {
1616 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1617 if (iSub != null) {
1618 subId = iSub.getDefaultDataSubId();
1619 }
1620 } catch (RemoteException ex) {
1621 // ignore it
1622 }
1623
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001624 if (VDBG) logd("getDefaultDataSubscriptionId, sub id = " + subId);
Wink Savillec650e0b2014-09-02 22:37:08 -07001625 return subId;
Wink Savillefb40dd42014-06-12 17:02:31 -07001626 }
1627
Wink Savillef5bca082014-09-03 15:13:33 -07001628 /** @hide */
Mathew Inwooda8382062018-08-16 17:01:12 +01001629 @UnsupportedAppUsage
Wink Savilled09c4ca2014-11-22 10:08:16 -08001630 public void setDefaultDataSubId(int subId) {
Wink Savillefb40dd42014-06-12 17:02:31 -07001631 if (VDBG) logd("setDataSubscription sub id = " + subId);
1632 try {
1633 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1634 if (iSub != null) {
1635 iSub.setDefaultDataSubId(subId);
1636 }
1637 } catch (RemoteException ex) {
Wink Savillec650e0b2014-09-02 22:37:08 -07001638 // ignore it
Wink Savillefb40dd42014-06-12 17:02:31 -07001639 }
1640 }
1641
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001642 /**
1643 * Return the SubscriptionInfo for default data subscription.
1644 *
1645 * Will return null on voice only devices, or on error.
1646 *
1647 * @return the SubscriptionInfo for the default data subscription.
1648 * @hide
1649 */
Mathew Inwooda8382062018-08-16 17:01:12 +01001650 @UnsupportedAppUsage
Wink Savilled09c4ca2014-11-22 10:08:16 -08001651 public SubscriptionInfo getDefaultDataSubscriptionInfo() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001652 return getActiveSubscriptionInfo(getDefaultDataSubscriptionId());
Wink Savillec650e0b2014-09-02 22:37:08 -07001653 }
Wink Savillefb40dd42014-06-12 17:02:31 -07001654
Wink Savillef5bca082014-09-03 15:13:33 -07001655 /** @hide */
Mathew Inwooda8382062018-08-16 17:01:12 +01001656 @UnsupportedAppUsage
Wink Savilled09c4ca2014-11-22 10:08:16 -08001657 public int getDefaultDataPhoneId() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001658 return getPhoneId(getDefaultDataSubscriptionId());
Wink Savillec650e0b2014-09-02 22:37:08 -07001659 }
1660
Wink Savillef5bca082014-09-03 15:13:33 -07001661 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -08001662 public void clearSubscriptionInfo() {
Wink Savillefb40dd42014-06-12 17:02:31 -07001663 try {
1664 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1665 if (iSub != null) {
Robert Greenwalt278b8f92015-07-01 14:34:17 -07001666 iSub.clearSubInfo();
Wink Savillefb40dd42014-06-12 17:02:31 -07001667 }
1668 } catch (RemoteException ex) {
1669 // ignore it
1670 }
1671
1672 return;
1673 }
1674
Wink Savillec650e0b2014-09-02 22:37:08 -07001675 //FIXME this is vulnerable to race conditions
Wink Savillef5bca082014-09-03 15:13:33 -07001676 /** @hide */
Wink Savilled09c4ca2014-11-22 10:08:16 -08001677 public boolean allDefaultsSelected() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001678 if (!isValidSubscriptionId(getDefaultDataSubscriptionId())) {
Wink Savillec650e0b2014-09-02 22:37:08 -07001679 return false;
1680 }
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001681 if (!isValidSubscriptionId(getDefaultSmsSubscriptionId())) {
Wink Savillec650e0b2014-09-02 22:37:08 -07001682 return false;
1683 }
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001684 if (!isValidSubscriptionId(getDefaultVoiceSubscriptionId())) {
Wink Savillec650e0b2014-09-02 22:37:08 -07001685 return false;
1686 }
1687 return true;
1688 }
1689
1690 /**
1691 * If a default is set to subscription which is not active, this will reset that default back to
Wink Saville98513d72014-12-08 12:44:16 -08001692 * an invalid subscription id, i.e. < 0.
Wink Savillef5bca082014-09-03 15:13:33 -07001693 * @hide
Wink Savillec650e0b2014-09-02 22:37:08 -07001694 */
Mathew Inwooda8382062018-08-16 17:01:12 +01001695 @UnsupportedAppUsage
Wink Savilled09c4ca2014-11-22 10:08:16 -08001696 public void clearDefaultsForInactiveSubIds() {
Wink Savillec650e0b2014-09-02 22:37:08 -07001697 if (VDBG) logd("clearDefaultsForInactiveSubIds");
1698 try {
1699 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1700 if (iSub != null) {
Robert Greenwalt278b8f92015-07-01 14:34:17 -07001701 iSub.clearDefaultsForInactiveSubIds();
Wink Savillec650e0b2014-09-02 22:37:08 -07001702 }
1703 } catch (RemoteException ex) {
1704 // ignore it
1705 }
1706 }
1707
Wink Saville905bb542014-09-04 17:10:23 -07001708 /**
sqian00dae7e02018-08-30 11:53:14 -07001709 * Checks if the supplied subscription ID is valid.
1710 * Note: a valid subscription ID does not necessarily correspond to an active subscription.
1711 *
1712 * @param subscriptionId The subscription ID.
1713 * @return true if the supplied subscriptionId is valid; false otherwise.
Wink Saville905bb542014-09-04 17:10:23 -07001714 */
sqian00dae7e02018-08-30 11:53:14 -07001715 public static boolean isValidSubscriptionId(int subscriptionId) {
1716 return subscriptionId > INVALID_SUBSCRIPTION_ID;
Wink Savillec650e0b2014-09-02 22:37:08 -07001717 }
1718
Wink Saville8eab2b62014-09-23 14:20:58 -07001719 /**
sqian798da562018-09-12 16:31:17 -07001720 * Check if the subscription ID is usable.
1721 *
1722 * A usable subscription ID has a valid value except some special values such as
Nan Zhang6c288ef2018-10-11 16:44:28 -07001723 * {@link #DEFAULT_SUBSCRIPTION_ID}. It can be used for subscription functions.
sqian798da562018-09-12 16:31:17 -07001724 *
1725 * @param subscriptionId the subscription ID
1726 * @return {@code true} if the subscription ID is usable; {@code false} otherwise.
1727 */
1728 public static boolean isUsableSubscriptionId(int subscriptionId) {
1729 return isUsableSubIdValue(subscriptionId);
1730 }
1731
1732 /**
Wink Saville8eab2b62014-09-23 14:20:58 -07001733 * @return true if subId is an usable subId value else false. A
Wink Saville98513d72014-12-08 12:44:16 -08001734 * usable subId means its neither a INVALID_SUBSCRIPTION_ID nor a DEFAULT_SUB_ID.
Wink Saville8eab2b62014-09-23 14:20:58 -07001735 * @hide
1736 */
Chen Xu4c0b06d2018-10-22 16:54:39 +00001737 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
Wink Saville63f03dd2014-10-23 10:44:45 -07001738 public static boolean isUsableSubIdValue(int subId) {
Wink Savilled09c4ca2014-11-22 10:08:16 -08001739 return subId >= MIN_SUBSCRIPTION_ID_VALUE && subId <= MAX_SUBSCRIPTION_ID_VALUE;
Wink Saville8eab2b62014-09-23 14:20:58 -07001740 }
1741
Wink Savillef5bca082014-09-03 15:13:33 -07001742 /** @hide */
Mathew Inwood45d2c252018-09-14 12:35:36 +01001743 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Sanket Padawe7e460252017-03-10 16:18:20 -08001744 public static boolean isValidSlotIndex(int slotIndex) {
1745 return slotIndex >= 0 && slotIndex < TelephonyManager.getDefault().getSimCount();
Wink Savillec650e0b2014-09-02 22:37:08 -07001746 }
1747
Wink Savillef5bca082014-09-03 15:13:33 -07001748 /** @hide */
Mathew Inwooda8382062018-08-16 17:01:12 +01001749 @UnsupportedAppUsage
Wink Savillec650e0b2014-09-02 22:37:08 -07001750 public static boolean isValidPhoneId(int phoneId) {
Wink Savilled09c4ca2014-11-22 10:08:16 -08001751 return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getPhoneCount();
Wink Savillec650e0b2014-09-02 22:37:08 -07001752 }
1753
Wink Savillef5bca082014-09-03 15:13:33 -07001754 /** @hide */
Chen Xu4c0b06d2018-10-22 16:54:39 +00001755 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
Wink Savillefb40dd42014-06-12 17:02:31 -07001756 public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId) {
Wink Saville63f03dd2014-10-23 10:44:45 -07001757 int[] subIds = SubscriptionManager.getSubId(phoneId);
Wink Savillec650e0b2014-09-02 22:37:08 -07001758 if (subIds != null && subIds.length > 0) {
1759 putPhoneIdAndSubIdExtra(intent, phoneId, subIds[0]);
Wink Savillefb40dd42014-06-12 17:02:31 -07001760 } else {
1761 logd("putPhoneIdAndSubIdExtra: no valid subs");
1762 }
1763 }
Wink Savilleeeacf932014-06-18 01:07:10 -07001764
Wink Savillef5bca082014-09-03 15:13:33 -07001765 /** @hide */
Mathew Inwooda8382062018-08-16 17:01:12 +01001766 @UnsupportedAppUsage
Wink Saville63f03dd2014-10-23 10:44:45 -07001767 public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId, int subId) {
Wink Savilleeeacf932014-06-18 01:07:10 -07001768 if (VDBG) logd("putPhoneIdAndSubIdExtra: phoneId=" + phoneId + " subId=" + subId);
Wink Savilleeeacf932014-06-18 01:07:10 -07001769 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
Malcolm Chen598d24c2017-04-24 18:37:29 -07001770 intent.putExtra(EXTRA_SUBSCRIPTION_INDEX, subId);
Wink Savillec650e0b2014-09-02 22:37:08 -07001771 intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
Sanket Padawe7e460252017-03-10 16:18:20 -08001772 //FIXME this is using phoneId and slotIndex interchangeably
Wink Savillec650e0b2014-09-02 22:37:08 -07001773 //Eventually, this should be removed as it is not the slot id
1774 intent.putExtra(PhoneConstants.SLOT_KEY, phoneId);
1775 }
1776
1777 /**
Wink Saville8a38a202014-09-03 12:22:54 -07001778 * @return the list of subId's that are active,
Wink Savillec650e0b2014-09-02 22:37:08 -07001779 * is never null but the length maybe 0.
Wink Savillef5bca082014-09-03 15:13:33 -07001780 * @hide
Wink Savillec650e0b2014-09-02 22:37:08 -07001781 */
Mathew Inwooda8382062018-08-16 17:01:12 +01001782 @UnsupportedAppUsage
Jeff Sharkey32566012014-12-02 18:30:14 -08001783 public @NonNull int[] getActiveSubscriptionIdList() {
Wink Saville63f03dd2014-10-23 10:44:45 -07001784 int[] subId = null;
Wink Savillec650e0b2014-09-02 22:37:08 -07001785
1786 try {
1787 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1788 if (iSub != null) {
Wink Saville8a38a202014-09-03 12:22:54 -07001789 subId = iSub.getActiveSubIdList();
Wink Savillec650e0b2014-09-02 22:37:08 -07001790 }
1791 } catch (RemoteException ex) {
1792 // ignore it
1793 }
1794
1795 if (subId == null) {
Wink Saville63f03dd2014-10-23 10:44:45 -07001796 subId = new int[0];
Wink Savillec650e0b2014-09-02 22:37:08 -07001797 }
1798
1799 return subId;
Wink Saville2d1ee982014-11-20 20:29:51 +00001800
Wink Savilleeeacf932014-06-18 01:07:10 -07001801 }
Wink Savilled09c4ca2014-11-22 10:08:16 -08001802
1803 /**
1804 * Returns true if the device is considered roaming on the current
1805 * network for a subscription.
1806 * <p>
1807 * Availability: Only when user registered to a network.
1808 *
1809 * @param subId The subscription ID
1810 * @return true if the network for the subscription is roaming, false otherwise
1811 */
1812 public boolean isNetworkRoaming(int subId) {
1813 final int phoneId = getPhoneId(subId);
1814 if (phoneId < 0) {
1815 // What else can we do?
1816 return false;
1817 }
Legler Wu85973dc2015-01-29 15:07:39 +08001818 return TelephonyManager.getDefault().isNetworkRoaming(subId);
Wink Savilled09c4ca2014-11-22 10:08:16 -08001819 }
Wink Saville47920fa2014-12-02 17:08:14 -08001820
1821 /**
Sanket Padawe7e460252017-03-10 16:18:20 -08001822 * Returns a constant indicating the state of sim for the slot index.
Wink Saville47920fa2014-12-02 17:08:14 -08001823 *
Sanket Padawe7e460252017-03-10 16:18:20 -08001824 * @param slotIndex
Wink Saville47920fa2014-12-02 17:08:14 -08001825 *
1826 * {@See TelephonyManager#SIM_STATE_UNKNOWN}
1827 * {@See TelephonyManager#SIM_STATE_ABSENT}
1828 * {@See TelephonyManager#SIM_STATE_PIN_REQUIRED}
1829 * {@See TelephonyManager#SIM_STATE_PUK_REQUIRED}
1830 * {@See TelephonyManager#SIM_STATE_NETWORK_LOCKED}
1831 * {@See TelephonyManager#SIM_STATE_READY}
1832 * {@See TelephonyManager#SIM_STATE_NOT_READY}
1833 * {@See TelephonyManager#SIM_STATE_PERM_DISABLED}
1834 * {@See TelephonyManager#SIM_STATE_CARD_IO_ERROR}
1835 *
1836 * {@hide}
1837 */
Sanket Padawe7e460252017-03-10 16:18:20 -08001838 public static int getSimStateForSlotIndex(int slotIndex) {
Sanket Padawe330dcac2015-06-18 12:08:01 -07001839 int simState = TelephonyManager.SIM_STATE_UNKNOWN;
Wink Saville47920fa2014-12-02 17:08:14 -08001840
1841 try {
1842 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
Sanket Padawe330dcac2015-06-18 12:08:01 -07001843 if (iSub != null) {
Sanket Padawe7e460252017-03-10 16:18:20 -08001844 simState = iSub.getSimStateForSlotIndex(slotIndex);
Sanket Padawe330dcac2015-06-18 12:08:01 -07001845 }
Wink Saville47920fa2014-12-02 17:08:14 -08001846 } catch (RemoteException ex) {
Wink Saville47920fa2014-12-02 17:08:14 -08001847 }
Jack Yud2cf0ce2015-12-30 12:06:01 -08001848
Wink Saville47920fa2014-12-02 17:08:14 -08001849 return simState;
1850 }
Shishir Agrawal0ced7922014-12-10 10:20:39 -08001851
1852 /**
Sanket Padawedc493092015-07-14 14:21:43 -07001853 * Store properties associated with SubscriptionInfo in database
1854 * @param subId Subscription Id of Subscription
1855 * @param propKey Column name in database associated with SubscriptionInfo
1856 * @param propValue Value to store in DB for particular subId & column name
1857 * @hide
1858 */
1859 public static void setSubscriptionProperty(int subId, String propKey, String propValue) {
1860 try {
1861 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1862 if (iSub != null) {
1863 iSub.setSubscriptionProperty(subId, propKey, propValue);
1864 }
1865 } catch (RemoteException ex) {
1866 // ignore it
1867 }
1868 }
1869
1870 /**
1871 * Store properties associated with SubscriptionInfo in database
1872 * @param subId Subscription Id of Subscription
1873 * @param propKey Column name in SubscriptionInfo database
1874 * @return Value associated with subId and propKey column in database
1875 * @hide
1876 */
1877 private static String getSubscriptionProperty(int subId, String propKey,
1878 Context context) {
1879 String resultValue = null;
1880 try {
1881 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
1882 if (iSub != null) {
Rajeev Kumarc8ac4f3b2017-07-26 15:59:08 -07001883 resultValue = iSub.getSubscriptionProperty(subId, propKey,
1884 context.getOpPackageName());
Sanket Padawedc493092015-07-14 14:21:43 -07001885 }
1886 } catch (RemoteException ex) {
1887 // ignore it
1888 }
1889 return resultValue;
1890 }
1891
1892 /**
1893 * Returns boolean value corresponding to query result.
1894 * @param subId Subscription Id of Subscription
1895 * @param propKey Column name in SubscriptionInfo database
1896 * @param defValue Default boolean value to be returned
1897 * @return boolean result value to be returned
1898 * @hide
1899 */
1900 public static boolean getBooleanSubscriptionProperty(int subId, String propKey,
1901 boolean defValue, Context context) {
1902 String result = getSubscriptionProperty(subId, propKey, context);
1903 if (result != null) {
1904 try {
1905 return Integer.parseInt(result) == 1;
1906 } catch (NumberFormatException err) {
1907 logd("getBooleanSubscriptionProperty NumberFormat exception");
1908 }
1909 }
1910 return defValue;
1911 }
1912
1913 /**
1914 * Returns integer value corresponding to query result.
1915 * @param subId Subscription Id of Subscription
1916 * @param propKey Column name in SubscriptionInfo database
1917 * @param defValue Default integer value to be returned
1918 * @return integer result value to be returned
1919 * @hide
1920 */
1921 public static int getIntegerSubscriptionProperty(int subId, String propKey, int defValue,
1922 Context context) {
1923 String result = getSubscriptionProperty(subId, propKey, context);
1924 if (result != null) {
1925 try {
1926 return Integer.parseInt(result);
1927 } catch (NumberFormatException err) {
1928 logd("getBooleanSubscriptionProperty NumberFormat exception");
1929 }
1930 }
1931 return defValue;
1932 }
1933
1934 /**
1935 * Returns the resources associated with Subscription.
1936 * @param context Context object
1937 * @param subId Subscription Id of Subscription who's resources are required
1938 * @return Resources associated with Subscription.
1939 * @hide
1940 */
Mathew Inwooda8382062018-08-16 17:01:12 +01001941 @UnsupportedAppUsage
Sanket Padawedc493092015-07-14 14:21:43 -07001942 public static Resources getResourcesForSubId(Context context, int subId) {
Torbjorn Eklund99c11d82018-08-21 16:06:47 +02001943 return getResourcesForSubId(context, subId, false);
1944 }
1945
1946 /**
1947 * Returns the resources associated with Subscription.
1948 * @param context Context object
1949 * @param subId Subscription Id of Subscription who's resources are required
1950 * @param useRootLocale if root locale should be used. Localized locale is used if false.
1951 * @return Resources associated with Subscription.
1952 * @hide
1953 */
1954 public static Resources getResourcesForSubId(Context context, int subId,
1955 boolean useRootLocale) {
Sanket Padawedc493092015-07-14 14:21:43 -07001956 final SubscriptionInfo subInfo =
1957 SubscriptionManager.from(context).getActiveSubscriptionInfo(subId);
1958
1959 Configuration config = context.getResources().getConfiguration();
1960 Configuration newConfig = new Configuration();
1961 newConfig.setTo(config);
1962 if (subInfo != null) {
1963 newConfig.mcc = subInfo.getMcc();
1964 newConfig.mnc = subInfo.getMnc();
Sandeep Guttae1da5a32016-03-07 13:24:56 +05301965 if (newConfig.mnc == 0) newConfig.mnc = Configuration.MNC_ZERO;
Sanket Padawedc493092015-07-14 14:21:43 -07001966 }
Torbjorn Eklund99c11d82018-08-21 16:06:47 +02001967
1968 if (useRootLocale) {
1969 newConfig.setLocale(Locale.ROOT);
1970 }
1971
Sanket Padawedc493092015-07-14 14:21:43 -07001972 DisplayMetrics metrics = context.getResources().getDisplayMetrics();
1973 DisplayMetrics newMetrics = new DisplayMetrics();
1974 newMetrics.setTo(metrics);
1975 return new Resources(context.getResources().getAssets(), newMetrics, newConfig);
1976 }
1977
1978 /**
sqianec149462018-09-10 19:05:51 -07001979 * Checks if the supplied subscription ID corresponds to an active subscription.
1980 *
1981 * @param subscriptionId the subscription ID.
1982 * @return {@code true} if the supplied subscription ID corresponds to an active subscription;
1983 * {@code false} if it does not correspond to an active subscription; or throw a
1984 * SecurityException if the caller hasn't got the right permission.
1985 */
1986 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
1987 public boolean isActiveSubscriptionId(int subscriptionId) {
1988 return isActiveSubId(subscriptionId);
1989 }
1990
1991 /**
Shishir Agrawal0ced7922014-12-10 10:20:39 -08001992 * @return true if the sub ID is active. i.e. The sub ID corresponds to a known subscription
1993 * and the SIM providing the subscription is present in a slot and in "LOADED" state.
1994 * @hide
1995 */
Mathew Inwooda8382062018-08-16 17:01:12 +01001996 @UnsupportedAppUsage
Shishir Agrawal0ced7922014-12-10 10:20:39 -08001997 public boolean isActiveSubId(int subId) {
1998 try {
1999 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
Sanket Padawe330dcac2015-06-18 12:08:01 -07002000 if (iSub != null) {
sqianec149462018-09-10 19:05:51 -07002001 return iSub.isActiveSubId(subId, mContext.getOpPackageName());
Sanket Padawe330dcac2015-06-18 12:08:01 -07002002 }
Shishir Agrawal0ced7922014-12-10 10:20:39 -08002003 } catch (RemoteException ex) {
2004 }
2005 return false;
2006 }
Jeff Sharkey53313d72017-07-13 16:47:32 -06002007
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002008 /**
2009 * Get the description of the billing relationship plan between a carrier
2010 * and a specific subscriber.
2011 * <p>
2012 * This method is only accessible to the following narrow set of apps:
2013 * <ul>
2014 * <li>The carrier app for this subscriberId, as determined by
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07002015 * {@link TelephonyManager#hasCarrierPrivileges()}.
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002016 * <li>The carrier app explicitly delegated access through
2017 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2018 * </ul>
2019 *
2020 * @param subId the subscriber this relationship applies to
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06002021 * @throws SecurityException if the caller doesn't meet the requirements
2022 * outlined above.
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002023 */
Jeff Sharkeyb74799882017-07-28 16:55:41 -06002024 @SystemApi
Jeff Sharkey53313d72017-07-13 16:47:32 -06002025 public @NonNull List<SubscriptionPlan> getSubscriptionPlans(int subId) {
Jeff Sharkey53313d72017-07-13 16:47:32 -06002026 try {
Rajeev Kumarc8ac4f3b2017-07-26 15:59:08 -07002027 SubscriptionPlan[] subscriptionPlans =
Robin Leeeaf46802018-01-18 14:34:20 +01002028 getNetworkPolicy().getSubscriptionPlans(subId, mContext.getOpPackageName());
Rajeev Kumarc8ac4f3b2017-07-26 15:59:08 -07002029 return subscriptionPlans == null
2030 ? Collections.emptyList() : Arrays.asList(subscriptionPlans);
Jeff Sharkey53313d72017-07-13 16:47:32 -06002031 } catch (RemoteException e) {
2032 throw e.rethrowFromSystemServer();
2033 }
2034 }
2035
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002036 /**
2037 * Set the description of the billing relationship plan between a carrier
2038 * and a specific subscriber.
2039 * <p>
2040 * This method is only accessible to the following narrow set of apps:
2041 * <ul>
2042 * <li>The carrier app for this subscriberId, as determined by
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07002043 * {@link TelephonyManager#hasCarrierPrivileges()}.
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002044 * <li>The carrier app explicitly delegated access through
2045 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2046 * </ul>
2047 *
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06002048 * @param subId the subscriber this relationship applies to. An empty list
2049 * may be sent to clear any existing plans.
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002050 * @param plans the list of plans. The first plan is always the primary and
2051 * most important plan. Any additional plans are secondary and
2052 * may not be displayed or used by decision making logic.
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06002053 * @throws SecurityException if the caller doesn't meet the requirements
2054 * outlined above.
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002055 */
Jeff Sharkeyb74799882017-07-28 16:55:41 -06002056 @SystemApi
Jeff Sharkey53313d72017-07-13 16:47:32 -06002057 public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans) {
Jeff Sharkey53313d72017-07-13 16:47:32 -06002058 try {
Robin Leeeaf46802018-01-18 14:34:20 +01002059 getNetworkPolicy().setSubscriptionPlans(subId,
Jeff Sharkey717f52f2018-01-04 16:04:11 -07002060 plans.toArray(new SubscriptionPlan[plans.size()]), mContext.getOpPackageName());
Jeff Sharkey53313d72017-07-13 16:47:32 -06002061 } catch (RemoteException e) {
2062 throw e.rethrowFromSystemServer();
2063 }
2064 }
Jeff Sharkey717f52f2018-01-04 16:04:11 -07002065
2066 /** @hide */
2067 private String getSubscriptionPlansOwner(int subId) {
2068 try {
Robin Leeeaf46802018-01-18 14:34:20 +01002069 return getNetworkPolicy().getSubscriptionPlansOwner(subId);
Jeff Sharkey717f52f2018-01-04 16:04:11 -07002070 } catch (RemoteException e) {
2071 throw e.rethrowFromSystemServer();
2072 }
2073 }
2074
2075 /**
Jeff Sharkey9252b342018-01-19 07:58:35 +09002076 * Temporarily override the billing relationship plan between a carrier and
2077 * a specific subscriber to be considered unmetered. This will be reflected
2078 * to apps via {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED}.
2079 * <p>
2080 * This method is only accessible to the following narrow set of apps:
2081 * <ul>
2082 * <li>The carrier app for this subscriberId, as determined by
2083 * {@link TelephonyManager#hasCarrierPrivileges()}.
2084 * <li>The carrier app explicitly delegated access through
2085 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2086 * </ul>
2087 *
2088 * @param subId the subscriber this override applies to.
2089 * @param overrideUnmetered set if the billing relationship should be
2090 * considered unmetered.
2091 * @param timeoutMillis the timeout after which the requested override will
2092 * be automatically cleared, or {@code 0} to leave in the
2093 * requested state until explicitly cleared, or the next reboot,
2094 * whichever happens first.
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06002095 * @throws SecurityException if the caller doesn't meet the requirements
2096 * outlined above.
Jeff Sharkey9252b342018-01-19 07:58:35 +09002097 */
2098 @SystemApi
2099 public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered,
2100 @DurationMillisLong long timeoutMillis) {
2101 try {
2102 final int overrideValue = overrideUnmetered ? OVERRIDE_UNMETERED : 0;
Jeff Sharkeya435ab52018-03-30 13:25:18 -06002103 getNetworkPolicy().setSubscriptionOverride(subId, OVERRIDE_UNMETERED, overrideValue,
Jeff Sharkey9252b342018-01-19 07:58:35 +09002104 timeoutMillis, mContext.getOpPackageName());
2105 } catch (RemoteException e) {
2106 throw e.rethrowFromSystemServer();
2107 }
2108 }
2109
2110 /**
2111 * Temporarily override the billing relationship plan between a carrier and
2112 * a specific subscriber to be considered congested. This will cause the
2113 * device to delay certain network requests when possible, such as developer
2114 * jobs that are willing to run in a flexible time window.
2115 * <p>
2116 * This method is only accessible to the following narrow set of apps:
2117 * <ul>
2118 * <li>The carrier app for this subscriberId, as determined by
2119 * {@link TelephonyManager#hasCarrierPrivileges()}.
2120 * <li>The carrier app explicitly delegated access through
2121 * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
2122 * </ul>
2123 *
2124 * @param subId the subscriber this override applies to.
2125 * @param overrideCongested set if the subscription should be considered
2126 * congested.
2127 * @param timeoutMillis the timeout after which the requested override will
2128 * be automatically cleared, or {@code 0} to leave in the
2129 * requested state until explicitly cleared, or the next reboot,
2130 * whichever happens first.
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06002131 * @throws SecurityException if the caller doesn't meet the requirements
2132 * outlined above.
Jeff Sharkey9252b342018-01-19 07:58:35 +09002133 */
2134 @SystemApi
2135 public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested,
2136 @DurationMillisLong long timeoutMillis) {
2137 try {
2138 final int overrideValue = overrideCongested ? OVERRIDE_CONGESTED : 0;
Jeff Sharkeya435ab52018-03-30 13:25:18 -06002139 getNetworkPolicy().setSubscriptionOverride(subId, OVERRIDE_CONGESTED, overrideValue,
Jeff Sharkey9252b342018-01-19 07:58:35 +09002140 timeoutMillis, mContext.getOpPackageName());
2141 } catch (RemoteException e) {
2142 throw e.rethrowFromSystemServer();
2143 }
2144 }
2145
2146 /**
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07002147 * Create an {@link Intent} that can be launched towards the carrier app
2148 * that is currently defining the billing relationship plan through
Jeff Sharkey717f52f2018-01-04 16:04:11 -07002149 * {@link #setSubscriptionPlans(int, List)}.
2150 *
2151 * @return ready to launch Intent targeted towards the carrier app, or
2152 * {@code null} if no carrier app is defined, or if the defined
2153 * carrier app provides no management activity.
2154 * @hide
2155 */
2156 public @Nullable Intent createManageSubscriptionIntent(int subId) {
2157 // Bail if no owner
2158 final String owner = getSubscriptionPlansOwner(subId);
2159 if (owner == null) return null;
2160
2161 // Bail if no plans
2162 final List<SubscriptionPlan> plans = getSubscriptionPlans(subId);
2163 if (plans.isEmpty()) return null;
2164
2165 final Intent intent = new Intent(ACTION_MANAGE_SUBSCRIPTION_PLANS);
2166 intent.setPackage(owner);
2167 intent.putExtra(EXTRA_SUBSCRIPTION_INDEX, subId);
2168
2169 // Bail if not implemented
2170 if (mContext.getPackageManager().queryIntentActivities(intent,
2171 PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2172 return null;
2173 }
2174
2175 return intent;
2176 }
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07002177
2178 /** @hide */
2179 private @Nullable Intent createRefreshSubscriptionIntent(int subId) {
2180 // Bail if no owner
2181 final String owner = getSubscriptionPlansOwner(subId);
2182 if (owner == null) return null;
2183
2184 // Bail if no plans
2185 final List<SubscriptionPlan> plans = getSubscriptionPlans(subId);
2186 if (plans.isEmpty()) return null;
2187
2188 final Intent intent = new Intent(ACTION_REFRESH_SUBSCRIPTION_PLANS);
2189 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
2190 intent.setPackage(owner);
2191 intent.putExtra(EXTRA_SUBSCRIPTION_INDEX, subId);
2192
2193 // Bail if not implemented
2194 if (mContext.getPackageManager().queryBroadcastReceivers(intent, 0).isEmpty()) {
2195 return null;
2196 }
2197
2198 return intent;
2199 }
2200
2201 /**
2202 * Check if there is a carrier app that is currently defining the billing
2203 * relationship plan through {@link #setSubscriptionPlans(int, List)} that
2204 * supports refreshing of subscription plans.
2205 *
2206 * @hide
2207 */
2208 public boolean isSubscriptionPlansRefreshSupported(int subId) {
2209 return createRefreshSubscriptionIntent(subId) != null;
2210 }
2211
2212 /**
2213 * Request that the carrier app that is currently defining the billing
2214 * relationship plan through {@link #setSubscriptionPlans(int, List)}
2215 * refresh its subscription plans.
2216 * <p>
2217 * If the app is able to successfully update the plans, you'll expect to
2218 * receive the {@link #ACTION_SUBSCRIPTION_PLANS_CHANGED} broadcast.
2219 *
2220 * @hide
2221 */
2222 public void requestSubscriptionPlansRefresh(int subId) {
2223 final Intent intent = createRefreshSubscriptionIntent(subId);
2224 final BroadcastOptions options = BroadcastOptions.makeBasic();
2225 options.setTemporaryAppWhitelistDuration(TimeUnit.MINUTES.toMillis(1));
2226 mContext.sendBroadcast(intent, null, options.toBundle());
2227 }
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08002228
2229 /**
2230 * Checks whether the app with the given context is authorized to manage the given subscription
2231 * according to its metadata. Only supported for embedded subscriptions (if
2232 * {@code SubscriptionInfo#isEmbedded} returns true).
2233 *
2234 * @param info The subscription to check.
2235 * @return whether the app is authorized to manage this subscription per its metadata.
Holly Jiuyu Sun59159c42018-03-15 18:06:42 -07002236 * @throws IllegalArgumentException if this subscription is not embedded.
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08002237 */
2238 public boolean canManageSubscription(SubscriptionInfo info) {
2239 return canManageSubscription(info, mContext.getPackageName());
2240 }
2241
2242 /**
Holly Jiuyu Sun59159c42018-03-15 18:06:42 -07002243 * Checks whether the given app is authorized to manage the given subscription. An app can only
2244 * be authorized if it is included in the {@link android.telephony.UiccAccessRule} of the
2245 * {@link android.telephony.SubscriptionInfo} with the access status.
2246 * Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded}
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08002247 * returns true).
2248 *
2249 * @param info The subscription to check.
2250 * @param packageName Package name of the app to check.
Holly Jiuyu Sun59159c42018-03-15 18:06:42 -07002251 * @return whether the app is authorized to manage this subscription per its access rules.
2252 * @throws IllegalArgumentException if this subscription is not embedded.
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08002253 * @hide
2254 */
2255 public boolean canManageSubscription(SubscriptionInfo info, String packageName) {
2256 if (!info.isEmbedded()) {
Holly Jiuyu Sun59159c42018-03-15 18:06:42 -07002257 throw new IllegalArgumentException("Not an embedded subscription");
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -08002258 }
2259 if (info.getAccessRules() == null) {
2260 return false;
2261 }
2262 PackageManager packageManager = mContext.getPackageManager();
2263 PackageInfo packageInfo;
2264 try {
2265 packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
2266 } catch (PackageManager.NameNotFoundException e) {
2267 throw new IllegalArgumentException("Unknown package: " + packageName, e);
2268 }
2269 for (UiccAccessRule rule : info.getAccessRules()) {
2270 if (rule.getCarrierPrivilegeStatus(packageInfo)
2271 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
2272 return true;
2273 }
2274 }
2275 return false;
2276 }
Malcolm Chenbd4ae762018-08-03 17:24:07 -07002277
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07002278 /**
Malcolm Chen009f0a92018-10-22 20:03:46 -07002279 * Set which subscription is preferred for cellular data.
2280 * It's also usually the subscription we set up internet connection on.
Malcolm Chen8cf1b782018-09-24 20:00:08 -07002281 *
2282 * PreferredData overwrites user setting of default data subscription. And it's used
Malcolm Chen009f0a92018-10-22 20:03:46 -07002283 * by AlternativeNetworkService or carrier apps to switch primary and CBRS
Malcolm Chenc1873af2018-09-24 20:01:32 -07002284 * subscription dynamically in multi-SIM devices.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07002285 *
Malcolm Chen009f0a92018-10-22 20:03:46 -07002286 * @param subId which subscription is preferred to for cellular data. If it's
2287 * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}, it means
2288 * it's unset and {@link SubscriptionManager#getDefaultDataSubscriptionId()}
2289 * is used to determine which modem is preferred.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07002290 * @hide
2291 *
2292 */
2293 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
Malcolm Chen009f0a92018-10-22 20:03:46 -07002294 public void setPreferredData(int subId) {
2295 if (VDBG) logd("[setPreferredData]+ subId:" + subId);
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07002296 setSubscriptionPropertyHelper(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
Malcolm Chen009f0a92018-10-22 20:03:46 -07002297 "setPreferredData", (iSub)-> iSub.setPreferredData(subId));
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07002298 }
2299
2300 /**
Sooraj Sasindran32e446b2018-08-06 15:24:45 -07002301 * Get opportunistic data Profiles.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07002302 *
Sooraj Sasindran32e446b2018-08-06 15:24:45 -07002303 * Provide all available user downloaded profiles on phone which are used only for
2304 * opportunistic data.
2305 * @param slotIndex slot on which the profiles are queried from.
Malcolm Chen9cfff6c2018-10-09 18:15:21 -07002306 * @return the list of opportunistic subscription info. If none exists, an empty list.
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07002307 */
2308 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
Malcolm Chen9cfff6c2018-10-09 18:15:21 -07002309 public @NonNull List<SubscriptionInfo> getOpportunisticSubscriptions(int slotIndex) {
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07002310 String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
2311 List<SubscriptionInfo> subInfoList = null;
2312
2313 try {
2314 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
2315 if (iSub != null) {
Sooraj Sasindran32e446b2018-08-06 15:24:45 -07002316 subInfoList = iSub.getOpportunisticSubscriptions(slotIndex, pkgForDebug);
Malcolm Chen0ac24ef2018-08-07 15:03:32 -07002317 }
2318 } catch (RemoteException ex) {
2319 // ignore it
2320 }
2321
2322 if (subInfoList == null) {
2323 subInfoList = new ArrayList<>();
2324 }
2325
2326 return subInfoList;
2327 }
2328
2329 /**
2330 * Switch to a certain subscription
2331 *
2332 * @param subId sub id
2333 * @param callbackIntent pending intent that will be sent after operation is done.
2334 */
2335 @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
2336 public void switchToSubscription(int subId, PendingIntent callbackIntent) {
2337 EuiccManager euiccManager = new EuiccManager(mContext);
2338 euiccManager.switchToSubscription(subId, callbackIntent);
2339 }
2340
2341 /**
2342 * Set opportunistic by simInfo index
2343 *
2344 * @param opportunistic whether it’s opportunistic subscription.
2345 * @param subId the unique SubscriptionInfo index in database
2346 * @return the number of records updated
2347 * @hide
2348 */
2349 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
2350 public int setOpportunistic(boolean opportunistic, int subId) {
2351 if (VDBG) logd("[setOpportunistic]+ opportunistic:" + opportunistic + " subId:" + subId);
2352 return setSubscriptionPropertyHelper(subId, "setOpportunistic",
2353 (iSub)-> iSub.setOpportunistic(opportunistic, subId));
2354 }
2355
2356 /**
2357 * Set parent subId by simInfo index
2358 *
2359 * @param parentSubId subId of its parent subscription.
2360 * @param subId the unique SubscriptionInfo index in database
2361 * @return the number of records updated
2362 * @hide
2363 *
2364 */
2365 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
2366 public int setParentSubId(int parentSubId, int subId) {
2367 if (VDBG) logd("[setParentSubId]+ parentSubId:" + parentSubId + " subId:" + subId);
2368 return setSubscriptionPropertyHelper(subId, "parentSubId",
2369 (iSub)-> iSub.setParentSubId(parentSubId, subId));
2370 }
2371
Malcolm Chenbd4ae762018-08-03 17:24:07 -07002372 private interface CallISubMethodHelper {
2373 int callMethod(ISub iSub) throws RemoteException;
2374 }
2375
2376 private int setSubscriptionPropertyHelper(int subId, String methodName,
2377 CallISubMethodHelper helper) {
2378 if (!isValidSubscriptionId(subId)) {
2379 logd("[" + methodName + "]" + "- fail");
2380 return -1;
2381 }
2382
2383 int result = 0;
2384
2385 try {
2386 ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
2387 if (iSub != null) {
2388 result = helper.callMethod(iSub);
2389 }
2390 } catch (RemoteException ex) {
2391 // ignore it
2392 }
2393
2394 return result;
2395 }
Wink Savillefb40dd42014-06-12 17:02:31 -07002396}