blob: cd4509a9452df04a0fe46ebc534333bca2b3d54f [file] [log] [blame]
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.phone;
18
Hall Liud892bec2018-11-30 14:51:45 -080019import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20
Ta-wei Yen87c49842016-05-13 21:19:52 -070021import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
22
Ta-wei Yen30a69c82016-12-27 14:52:32 -080023import android.Manifest.permission;
Tyler Gunnf70ed162019-04-03 15:28:53 -070024import android.annotation.Nullable;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070025import android.app.AppOpsManager;
Ta-wei Yen30a69c82016-12-27 14:52:32 -080026import android.app.PendingIntent;
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -070027import android.content.ComponentName;
Amit Mahajan7dbbd822019-03-13 17:33:47 -070028import android.content.ContentResolver;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070029import android.content.Context;
30import android.content.Intent;
Derek Tan97ebb422014-09-05 16:55:38 -070031import android.content.SharedPreferences;
Nathan Harold31d7ff32018-10-15 20:20:30 -070032import android.content.pm.ApplicationInfo;
Derek Tan740e1672017-06-27 14:56:27 -070033import android.content.pm.ComponentInfo;
Amith Yamasani6e118872016-02-19 12:53:51 -080034import android.content.pm.PackageInfo;
Shishir Agrawal60f9c952014-06-23 12:00:43 -070035import android.content.pm.PackageManager;
Jack Yu84291ec2017-05-26 16:07:50 -070036import android.net.NetworkStats;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070037import android.net.Uri;
38import android.os.AsyncResult;
39import android.os.Binder;
Hall Liuf19c44f2018-11-27 14:38:17 -080040import android.os.Build;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070041import android.os.Bundle;
42import android.os.Handler;
yinxu504e1392017-04-12 16:03:22 -070043import android.os.IBinder;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070044import android.os.Looper;
45import android.os.Message;
yinxu504e1392017-04-12 16:03:22 -070046import android.os.Messenger;
Malcolm Chen6ca97372019-07-01 16:28:21 -070047import android.os.ParcelUuid;
Tyler Gunn65d45c22017-06-05 11:22:26 -070048import android.os.PersistableBundle;
Brad Ebinger5f64b052017-12-14 14:26:15 -080049import android.os.RemoteException;
Adam Lesinski903a54c2016-04-11 14:49:52 -070050import android.os.ResultReceiver;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070051import android.os.ServiceManager;
Brad Ebinger1ce9c432019-07-16 13:19:44 -070052import android.os.ServiceSpecificException;
Brad Ebingerdac2f002018-04-03 15:17:52 -070053import android.os.ShellCallback;
Pengquan Meng85728fb2018-03-12 16:31:21 -070054import android.os.SystemProperties;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070055import android.os.UserHandle;
Stuart Scott981d8582015-04-21 14:09:50 -070056import android.os.UserManager;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070057import android.os.WorkSource;
Derek Tan97ebb422014-09-05 16:55:38 -070058import android.preference.PreferenceManager;
Ihab Awadf2177b72013-11-25 13:33:23 -080059import android.provider.Settings;
Amit Mahajan7dbbd822019-03-13 17:33:47 -070060import android.provider.Telephony;
Santos Cordon7a1885b2015-02-03 11:15:19 -080061import android.telecom.PhoneAccount;
Nancy Chen31f9ba12016-01-06 11:42:12 -080062import android.telecom.PhoneAccountHandle;
Andrew Lee9431b832015-03-09 18:46:45 -070063import android.telecom.TelecomManager;
Junda Liu12f7d802015-05-01 12:06:44 -070064import android.telephony.CarrierConfigManager;
Michele Berionne482f8202018-11-27 18:57:59 -080065import android.telephony.CarrierRestrictionRules;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070066import android.telephony.CellInfo;
Nathan Haroldf180aac2018-06-01 18:43:55 -070067import android.telephony.CellInfoGsm;
68import android.telephony.CellInfoWcdma;
Nathan Harold3ff88932018-08-14 10:19:49 -070069import android.telephony.CellLocation;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070070import android.telephony.ClientRequestStats;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -070071import android.telephony.ICellInfoCallback;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -070072import android.telephony.IccOpenLogicalChannelResponse;
Hall Liu1aa510f2017-11-22 17:40:08 -080073import android.telephony.LocationAccessPolicy;
Ta-wei Yen87c49842016-05-13 21:19:52 -070074import android.telephony.ModemActivityInfo;
Jake Hambye994d462014-02-03 13:10:13 -080075import android.telephony.NeighboringCellInfo;
yinxu504e1392017-04-12 16:03:22 -070076import android.telephony.NetworkScanRequest;
Michele4245e952019-02-04 11:36:23 -080077import android.telephony.PhoneCapability;
Hall Liud892bec2018-11-30 14:51:45 -080078import android.telephony.PhoneNumberRange;
Wink Saville5d475dd2014-10-17 15:00:58 -070079import android.telephony.RadioAccessFamily;
Hall Liub2ac8ef2019-02-28 15:56:23 -080080import android.telephony.RadioAccessSpecifier;
Tyler Gunn65d45c22017-06-05 11:22:26 -070081import android.telephony.Rlog;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070082import android.telephony.ServiceState;
Nathan Harold46b42aa2017-03-10 19:38:22 -080083import android.telephony.SignalStrength;
Wink Saville0f3b5fc2014-11-11 08:40:49 -080084import android.telephony.SubscriptionInfo;
Jeff Sharkey85190e62014-12-05 09:40:12 -080085import android.telephony.SubscriptionManager;
Sanket Padawe99ef1e32016-05-18 16:12:33 -070086import android.telephony.TelephonyHistogram;
Ta-wei Yenb6929602016-05-24 15:48:27 -070087import android.telephony.TelephonyManager;
Hall Liub2ac8ef2019-02-28 15:56:23 -080088import android.telephony.TelephonyScanManager;
Jordan Liu5aa07002018-12-18 15:44:48 -080089import android.telephony.UiccCardInfo;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +000090import android.telephony.UiccSlotInfo;
Tyler Gunn65d45c22017-06-05 11:22:26 -070091import android.telephony.UssdResponse;
Ta-wei Yenb6929602016-05-24 15:48:27 -070092import android.telephony.VisualVoicemailSmsFilterSettings;
Nathan Harold3ff88932018-08-14 10:19:49 -070093import android.telephony.cdma.CdmaCellLocation;
Jack Yub5d8f642018-11-26 11:20:48 -080094import android.telephony.data.ApnSetting;
Jack Yu41407ee2019-05-13 16:54:09 -070095import android.telephony.data.ApnSetting.ApnType;
Jack Yub5d8f642018-11-26 11:20:48 -080096import android.telephony.emergency.EmergencyNumber;
Nathan Harold3ff88932018-08-14 10:19:49 -070097import android.telephony.gsm.GsmCellLocation;
Brad Ebinger1ce9c432019-07-16 13:19:44 -070098import android.telephony.ims.ImsException;
Brad Ebinger1c8542e2019-01-14 13:43:14 -080099import android.telephony.ims.ProvisioningManager;
Brad Ebinger35c841c2018-10-01 10:40:55 -0700100import android.telephony.ims.aidl.IImsCapabilityCallback;
Brad Ebinger22bc3e42018-01-16 09:39:35 -0800101import android.telephony.ims.aidl.IImsConfig;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -0700102import android.telephony.ims.aidl.IImsConfigCallback;
Brad Ebinger22bc3e42018-01-16 09:39:35 -0800103import android.telephony.ims.aidl.IImsMmTelFeature;
104import android.telephony.ims.aidl.IImsRcsFeature;
105import android.telephony.ims.aidl.IImsRegistration;
Brad Ebinger35c841c2018-10-01 10:40:55 -0700106import android.telephony.ims.aidl.IImsRegistrationCallback;
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800107import android.telephony.ims.feature.MmTelFeature;
108import android.telephony.ims.stub.ImsConfigImplBase;
Brad Ebinger1f2b5082018-02-08 16:11:32 -0800109import android.telephony.ims.stub.ImsRegistrationImplBase;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700110import android.text.TextUtils;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800111import android.util.ArraySet;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700112import android.util.Log;
Jake Hambye994d462014-02-03 13:10:13 -0800113import android.util.Pair;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800114import android.util.Slog;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800115
Andrew Lee312e8172014-10-23 17:01:36 -0700116import com.android.ims.ImsManager;
Brad Ebinger34bef922017-11-09 10:27:08 -0800117import com.android.ims.internal.IImsServiceFeatureCallback;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700118import com.android.internal.telephony.CallManager;
Tyler Gunn52dcf772017-04-26 11:30:31 -0700119import com.android.internal.telephony.CallStateException;
pkanwar79ec0542017-07-31 14:10:01 -0700120import com.android.internal.telephony.CarrierInfoManager;
chen xu651eec72018-11-11 19:03:44 -0800121import com.android.internal.telephony.CarrierResolver;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700122import com.android.internal.telephony.CellNetworkScanResult;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700123import com.android.internal.telephony.CommandException;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700124import com.android.internal.telephony.DefaultPhoneNotifier;
Nathan Harold48d6fd52019-02-06 19:01:40 -0800125import com.android.internal.telephony.HalVersion;
Brad Ebingera63db5f2019-04-23 16:31:13 -0700126import com.android.internal.telephony.IIntegerConsumer;
Hall Liud892bec2018-11-30 14:51:45 -0800127import com.android.internal.telephony.INumberVerificationCallback;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700128import com.android.internal.telephony.ITelephony;
Jake Hambye994d462014-02-03 13:10:13 -0800129import com.android.internal.telephony.IccCard;
Jack Yu5f7092c2018-04-13 14:05:37 -0700130import com.android.internal.telephony.LocaleTracker;
Narayan Kamath1c496c22015-04-16 14:40:19 +0100131import com.android.internal.telephony.MccTable;
yinxub1bed742017-04-17 11:45:04 -0700132import com.android.internal.telephony.NetworkScanRequestTracker;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700133import com.android.internal.telephony.OperatorInfo;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700134import com.android.internal.telephony.Phone;
Malcolm Chen2c63d402018-08-14 16:00:53 -0700135import com.android.internal.telephony.PhoneConfigurationManager;
Nathan Harolda667c152016-12-14 11:27:20 -0800136import com.android.internal.telephony.PhoneConstantConversions;
Ta-wei Yen87c49842016-05-13 21:19:52 -0700137import com.android.internal.telephony.PhoneConstants;
Wink Saville36469e72014-06-11 15:17:00 -0700138import com.android.internal.telephony.PhoneFactory;
Wink Saville5d475dd2014-10-17 15:00:58 -0700139import com.android.internal.telephony.ProxyController;
Sanket Padawe99ef1e32016-05-18 16:12:33 -0700140import com.android.internal.telephony.RIL;
Svet Ganovb320e182015-04-16 12:30:10 -0700141import com.android.internal.telephony.RILConstants;
Jack Yu5f7092c2018-04-13 14:05:37 -0700142import com.android.internal.telephony.ServiceStateTracker;
Makoto Onukida3bf792018-09-18 16:06:29 -0700143import com.android.internal.telephony.SmsApplication;
144import com.android.internal.telephony.SmsApplication.SmsApplicationData;
Amit Mahajandccb3f12019-05-13 13:48:32 -0700145import com.android.internal.telephony.SmsController;
Brad Ebingera63db5f2019-04-23 16:31:13 -0700146import com.android.internal.telephony.SmsPermissions;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800147import com.android.internal.telephony.SubscriptionController;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800148import com.android.internal.telephony.TelephonyPermissions;
Malcolm Chendc8c10e2019-04-10 18:25:07 -0700149import com.android.internal.telephony.dataconnection.ApnSettingUtils;
sqianf4ca7ed2019-01-15 18:32:07 -0800150import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Derek Tan740e1672017-06-27 14:56:27 -0700151import com.android.internal.telephony.euicc.EuiccConnector;
Brad Ebinger9c0eb502019-01-23 15:06:19 -0800152import com.android.internal.telephony.ims.ImsResolver;
Pengquan Meng6c2dc9f2019-02-06 11:12:53 -0800153import com.android.internal.telephony.metrics.TelephonyMetrics;
Jack Yu1e81ccd2019-09-26 11:48:33 -0700154import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700155import com.android.internal.telephony.uicc.IccIoResult;
156import com.android.internal.telephony.uicc.IccUtils;
Nathan Haroldb3014052017-01-25 15:57:32 -0800157import com.android.internal.telephony.uicc.SIMRecords;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700158import com.android.internal.telephony.uicc.UiccCard;
Nathan Haroldb3014052017-01-25 15:57:32 -0800159import com.android.internal.telephony.uicc.UiccCardApplication;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700160import com.android.internal.telephony.uicc.UiccController;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800161import com.android.internal.telephony.uicc.UiccProfile;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000162import com.android.internal.telephony.uicc.UiccSlot;
fionaxu7ed723d2017-05-30 18:58:54 -0700163import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
Jake Hambye994d462014-02-03 13:10:13 -0800164import com.android.internal.util.HexDump;
Brad Ebingera63db5f2019-04-23 16:31:13 -0700165import com.android.phone.settings.PickSmsSubscriptionActivity;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700166import com.android.phone.vvm.PhoneAccountHandleConverter;
Ta-wei Yen527a9c02017-01-06 15:29:25 -0800167import com.android.phone.vvm.RemoteVvmTaskManager;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700168import com.android.phone.vvm.VisualVoicemailSettingsUtil;
Ta-wei Yenc8905312017-03-28 11:14:45 -0700169import com.android.phone.vvm.VisualVoicemailSmsFilterConfig;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800170
Ta-wei Yenc236d6b2016-06-21 13:33:12 -0700171import java.io.FileDescriptor;
172import java.io.PrintWriter;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700173import java.util.ArrayList;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800174import java.util.Arrays;
Makoto Onukida3bf792018-09-18 16:06:29 -0700175import java.util.Collection;
sqian11b7a0e2018-12-05 18:48:28 -0800176import java.util.HashMap;
sqianf4ca7ed2019-01-15 18:32:07 -0800177import java.util.HashSet;
Jake Hambye994d462014-02-03 13:10:13 -0800178import java.util.List;
Narayan Kamath1c496c22015-04-16 14:40:19 +0100179import java.util.Locale;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800180import java.util.Map;
Nazanin Bakhshif71371d2019-04-29 17:29:44 -0700181import java.util.NoSuchElementException;
sqianf4ca7ed2019-01-15 18:32:07 -0800182import java.util.Set;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700183
184/**
185 * Implementation of the ITelephony interface.
186 */
Santos Cordon117fee72014-05-16 17:56:12 -0700187public class PhoneInterfaceManager extends ITelephony.Stub {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700188 private static final String LOG_TAG = "PhoneInterfaceManager";
189 private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
190 private static final boolean DBG_LOC = false;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800191 private static final boolean DBG_MERGE = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700192
193 // Message codes used with mMainThreadHandler
194 private static final int CMD_HANDLE_PIN_MMI = 1;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700195 private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7;
196 private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700197 private static final int CMD_OPEN_CHANNEL = 9;
198 private static final int EVENT_OPEN_CHANNEL_DONE = 10;
199 private static final int CMD_CLOSE_CHANNEL = 11;
200 private static final int EVENT_CLOSE_CHANNEL_DONE = 12;
Jake Hambye994d462014-02-03 13:10:13 -0800201 private static final int CMD_NV_READ_ITEM = 13;
202 private static final int EVENT_NV_READ_ITEM_DONE = 14;
203 private static final int CMD_NV_WRITE_ITEM = 15;
204 private static final int EVENT_NV_WRITE_ITEM_DONE = 16;
205 private static final int CMD_NV_WRITE_CDMA_PRL = 17;
206 private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18;
chen xu6dac5ab2018-10-26 17:39:23 -0700207 private static final int CMD_RESET_MODEM_CONFIG = 19;
208 private static final int EVENT_RESET_MODEM_CONFIG_DONE = 20;
Jake Hamby7c27be32014-03-03 13:25:59 -0800209 private static final int CMD_GET_PREFERRED_NETWORK_TYPE = 21;
210 private static final int EVENT_GET_PREFERRED_NETWORK_TYPE_DONE = 22;
211 private static final int CMD_SET_PREFERRED_NETWORK_TYPE = 23;
212 private static final int EVENT_SET_PREFERRED_NETWORK_TYPE_DONE = 24;
Sailesh Nepal35b59452014-03-06 09:26:56 -0800213 private static final int CMD_SEND_ENVELOPE = 25;
214 private static final int EVENT_SEND_ENVELOPE_DONE = 26;
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000215 private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27;
216 private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28;
Derek Tan6b088ee2014-09-05 14:15:18 -0700217 private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29;
218 private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30;
219 private static final int CMD_EXCHANGE_SIM_IO = 31;
220 private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800221 private static final int CMD_SET_VOICEMAIL_NUMBER = 33;
222 private static final int EVENT_SET_VOICEMAIL_NUMBER_DONE = 34;
Stuart Scott54788802015-03-30 13:18:01 -0700223 private static final int CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC = 35;
224 private static final int EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE = 36;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700225 private static final int CMD_GET_MODEM_ACTIVITY_INFO = 37;
226 private static final int EVENT_GET_MODEM_ACTIVITY_INFO_DONE = 38;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700227 private static final int CMD_PERFORM_NETWORK_SCAN = 39;
228 private static final int EVENT_PERFORM_NETWORK_SCAN_DONE = 40;
229 private static final int CMD_SET_NETWORK_SELECTION_MODE_MANUAL = 41;
230 private static final int EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE = 42;
Meng Wang1a7c35a2016-05-05 20:56:15 -0700231 private static final int CMD_SET_ALLOWED_CARRIERS = 43;
232 private static final int EVENT_SET_ALLOWED_CARRIERS_DONE = 44;
233 private static final int CMD_GET_ALLOWED_CARRIERS = 45;
234 private static final int EVENT_GET_ALLOWED_CARRIERS_DONE = 46;
pkanwar32d516d2016-10-14 19:37:38 -0700235 private static final int CMD_HANDLE_USSD_REQUEST = 47;
Nathan Haroldb3014052017-01-25 15:57:32 -0800236 private static final int CMD_GET_FORBIDDEN_PLMNS = 48;
237 private static final int EVENT_GET_FORBIDDEN_PLMNS_DONE = 49;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000238 private static final int CMD_SWITCH_SLOTS = 50;
239 private static final int EVENT_SWITCH_SLOTS_DONE = 51;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700240 private static final int CMD_GET_NETWORK_SELECTION_MODE = 52;
241 private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 53;
242 private static final int CMD_GET_CDMA_ROAMING_MODE = 54;
243 private static final int EVENT_GET_CDMA_ROAMING_MODE_DONE = 55;
244 private static final int CMD_SET_CDMA_ROAMING_MODE = 56;
245 private static final int EVENT_SET_CDMA_ROAMING_MODE_DONE = 57;
246 private static final int CMD_SET_CDMA_SUBSCRIPTION_MODE = 58;
247 private static final int EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE = 59;
Nathan Harold3ff88932018-08-14 10:19:49 -0700248 private static final int CMD_GET_ALL_CELL_INFO = 60;
249 private static final int EVENT_GET_ALL_CELL_INFO_DONE = 61;
250 private static final int CMD_GET_CELL_LOCATION = 62;
251 private static final int EVENT_GET_CELL_LOCATION_DONE = 63;
chen xu6dac5ab2018-10-26 17:39:23 -0700252 private static final int CMD_MODEM_REBOOT = 64;
253 private static final int EVENT_CMD_MODEM_REBOOT_DONE = 65;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -0700254 private static final int CMD_REQUEST_CELL_INFO_UPDATE = 66;
255 private static final int EVENT_REQUEST_CELL_INFO_UPDATE_DONE = 67;
Malcolm Chen8e4ed912019-01-15 20:22:16 -0800256 private static final int CMD_REQUEST_ENABLE_MODEM = 68;
257 private static final int EVENT_ENABLE_MODEM_DONE = 69;
Nazanin Bakhshif71371d2019-04-29 17:29:44 -0700258 private static final int CMD_GET_MODEM_STATUS = 70;
259 private static final int EVENT_GET_MODEM_STATUS_DONE = 71;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700260
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -0800261 // Parameters of select command.
262 private static final int SELECT_COMMAND = 0xA4;
263 private static final int SELECT_P1 = 0x04;
264 private static final int SELECT_P2 = 0;
265 private static final int SELECT_P3 = 0x10;
266
Pengquan Meng85728fb2018-03-12 16:31:21 -0700267 private static final String DEFAULT_NETWORK_MODE_PROPERTY_NAME = "ro.telephony.default_network";
268 private static final String DEFAULT_DATA_ROAMING_PROPERTY_NAME = "ro.com.android.dataroaming";
269 private static final String DEFAULT_MOBILE_DATA_PROPERTY_NAME = "ro.com.android.mobiledata";
270
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700271 /** The singleton instance. */
272 private static PhoneInterfaceManager sInstance;
273
Wink Saville3ab207e2014-11-20 13:07:20 -0800274 private PhoneGlobals mApp;
Wink Saville3ab207e2014-11-20 13:07:20 -0800275 private CallManager mCM;
Stuart Scott981d8582015-04-21 14:09:50 -0700276 private UserManager mUserManager;
Wink Saville3ab207e2014-11-20 13:07:20 -0800277 private AppOpsManager mAppOps;
278 private MainThreadHandler mMainThreadHandler;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800279 private SubscriptionController mSubscriptionController;
Wink Saville3ab207e2014-11-20 13:07:20 -0800280 private SharedPreferences mTelephonySharedPreferences;
Malcolm Chen2c63d402018-08-14 16:00:53 -0700281 private PhoneConfigurationManager mPhoneConfigurationManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700282
Derek Tan97ebb422014-09-05 16:55:38 -0700283 private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
284 private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
Jeff Sharkey85190e62014-12-05 09:40:12 -0800285 private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800286 private static final String PREF_PROVISION_IMS_MMTEL_PREFIX = "provision_ims_mmtel_";
Derek Tan89e89d42014-07-08 17:00:10 -0700287
Michelecea4cf22018-12-21 15:00:11 -0800288 // String to store multi SIM allowed
289 private static final String PREF_MULTI_SIM_RESTRICTED = "multisim_restricted";
290
Derek Tan740e1672017-06-27 14:56:27 -0700291 // The AID of ISD-R.
292 private static final String ISDR_AID = "A0000005591010FFFFFFFF8900000100";
293
yinxub1bed742017-04-17 11:45:04 -0700294 private NetworkScanRequestTracker mNetworkScanRequestTracker;
295
David Kelly5e06a7f2018-03-12 14:10:59 +0000296 private static final int TYPE_ALLOCATION_CODE_LENGTH = 8;
297 private static final int MANUFACTURER_CODE_LENGTH = 8;
298
Derek Tan89e89d42014-07-08 17:00:10 -0700299 /**
Shishir Agrawal566b7612013-10-28 14:41:00 -0700300 * A request object to use for transmitting data to an ICC.
301 */
302 private static final class IccAPDUArgument {
303 public int channel, cla, command, p1, p2, p3;
304 public String data;
305
306 public IccAPDUArgument(int channel, int cla, int command,
307 int p1, int p2, int p3, String data) {
308 this.channel = channel;
309 this.cla = cla;
310 this.command = command;
311 this.p1 = p1;
312 this.p2 = p2;
313 this.p3 = p3;
314 this.data = data;
315 }
316 }
317
318 /**
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700319 * A request object to use for transmitting data to an ICC.
320 */
321 private static final class ManualNetworkSelectionArgument {
322 public OperatorInfo operatorInfo;
323 public boolean persistSelection;
324
325 public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) {
326 this.operatorInfo = operatorInfo;
327 this.persistSelection = persistSelection;
328 }
329 }
330
331 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700332 * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
333 * request after sending. The main thread will notify the request when it is complete.
334 */
335 private static final class MainThreadRequest {
336 /** The argument to use for the request */
337 public Object argument;
338 /** The result of the request that is run on the main thread */
339 public Object result;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800340 // The subscriber id that this request applies to. Defaults to
341 // SubscriptionManager.INVALID_SUBSCRIPTION_ID
342 public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700343
Nathan Harold92bed182018-10-12 18:16:49 -0700344 // In cases where subId is unavailable, the caller needs to specify the phone.
345 public Phone phone;
346
vagdeviaf9a5b92018-08-15 16:01:53 -0700347 public WorkSource workSource;
348
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700349 public MainThreadRequest(Object argument) {
350 this.argument = argument;
351 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800352
Nathan Harold92bed182018-10-12 18:16:49 -0700353 MainThreadRequest(Object argument, Phone phone, WorkSource workSource) {
354 this.argument = argument;
355 if (phone != null) {
356 this.phone = phone;
357 }
358 this.workSource = workSource;
359 }
360
vagdeviaf9a5b92018-08-15 16:01:53 -0700361 MainThreadRequest(Object argument, Integer subId, WorkSource workSource) {
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800362 this.argument = argument;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800363 if (subId != null) {
364 this.subId = subId;
365 }
vagdeviaf9a5b92018-08-15 16:01:53 -0700366 this.workSource = workSource;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800367 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700368 }
369
Sailesh Nepalcc0375f2013-11-13 09:15:18 -0800370 private static final class IncomingThirdPartyCallArgs {
371 public final ComponentName component;
372 public final String callId;
373 public final String callerDisplayName;
374
375 public IncomingThirdPartyCallArgs(ComponentName component, String callId,
376 String callerDisplayName) {
377 this.component = component;
378 this.callId = callId;
379 this.callerDisplayName = callerDisplayName;
380 }
381 }
382
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700383 /**
384 * A handler that processes messages on the main thread in the phone process. Since many
385 * of the Phone calls are not thread safe this is needed to shuttle the requests from the
386 * inbound binder threads to the main thread in the phone process. The Binder thread
387 * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
388 * on, which will be notified when the operation completes and will contain the result of the
389 * request.
390 *
391 * <p>If a MainThreadRequest object is provided in the msg.obj field,
392 * note that request.result must be set to something non-null for the calling thread to
393 * unblock.
394 */
395 private final class MainThreadHandler extends Handler {
396 @Override
397 public void handleMessage(Message msg) {
398 MainThreadRequest request;
399 Message onCompleted;
400 AsyncResult ar;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800401 UiccCard uiccCard;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700402 IccAPDUArgument iccArgument;
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800403 final Phone defaultPhone = getDefaultPhone();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700404
405 switch (msg.what) {
Pengquan Menga1bb6272018-09-06 09:59:22 -0700406 case CMD_HANDLE_USSD_REQUEST: {
407 request = (MainThreadRequest) msg.obj;
408 final Phone phone = getPhoneFromRequest(request);
409 Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
410 String ussdRequest = ussdObject.first;
411 ResultReceiver wrappedCallback = ussdObject.second;
Tyler Gunn65d45c22017-06-05 11:22:26 -0700412
Pengquan Menga1bb6272018-09-06 09:59:22 -0700413 if (!isUssdApiAllowed(request.subId)) {
414 // Carrier does not support use of this API, return failure.
415 Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
416 UssdResponse response = new UssdResponse(ussdRequest, null);
417 Bundle returnData = new Bundle();
418 returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
419 wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
Tyler Gunn65d45c22017-06-05 11:22:26 -0700420
Pengquan Menga1bb6272018-09-06 09:59:22 -0700421 request.result = true;
422 notifyRequester(request);
423 return;
424 }
Tyler Gunn65d45c22017-06-05 11:22:26 -0700425
Pengquan Menga1bb6272018-09-06 09:59:22 -0700426 try {
427 request.result = phone != null
428 ? phone.handleUssdRequest(ussdRequest, wrappedCallback) : false;
429 } catch (CallStateException cse) {
430 request.result = false;
431 }
432 // Wake up the requesting thread
433 notifyRequester(request);
434 break;
pkanwar32d516d2016-10-14 19:37:38 -0700435 }
436
Yorke Lee716f67e2015-06-17 15:39:16 -0700437 case CMD_HANDLE_PIN_MMI: {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700438 request = (MainThreadRequest) msg.obj;
Yorke Lee716f67e2015-06-17 15:39:16 -0700439 final Phone phone = getPhoneFromRequest(request);
440 request.result = phone != null ?
441 getPhoneFromRequest(request).handlePinMmi((String) request.argument)
442 : false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700443 // Wake up the requesting thread
Pengquan Menga1bb6272018-09-06 09:59:22 -0700444 notifyRequester(request);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700445 break;
Yorke Lee716f67e2015-06-17 15:39:16 -0700446 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700447
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700448 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700449 request = (MainThreadRequest) msg.obj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700450 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800451 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700452 if (uiccCard == null) {
453 loge("iccTransmitApduLogicalChannel: No UICC");
454 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700455 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700456 } else {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700457 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
458 request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700459 uiccCard.iccTransmitApduLogicalChannel(
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700460 iccArgument.channel, iccArgument.cla, iccArgument.command,
461 iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data,
Shishir Agrawal566b7612013-10-28 14:41:00 -0700462 onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700463 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700464 break;
465
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700466 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700467 ar = (AsyncResult) msg.obj;
468 request = (MainThreadRequest) ar.userObj;
469 if (ar.exception == null && ar.result != null) {
470 request.result = ar.result;
471 } else {
472 request.result = new IccIoResult(0x6F, 0, (byte[])null);
473 if (ar.result == null) {
474 loge("iccTransmitApduLogicalChannel: Empty response");
Jake Hambye994d462014-02-03 13:10:13 -0800475 } else if (ar.exception instanceof CommandException) {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700476 loge("iccTransmitApduLogicalChannel: CommandException: " +
Jake Hambye994d462014-02-03 13:10:13 -0800477 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700478 } else {
479 loge("iccTransmitApduLogicalChannel: Unknown exception");
480 }
481 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700482 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700483 break;
484
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700485 case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
486 request = (MainThreadRequest) msg.obj;
487 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800488 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700489 if (uiccCard == null) {
490 loge("iccTransmitApduBasicChannel: No UICC");
491 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700492 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700493 } else {
494 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
495 request);
496 uiccCard.iccTransmitApduBasicChannel(
497 iccArgument.cla, iccArgument.command, iccArgument.p1, iccArgument.p2,
498 iccArgument.p3, iccArgument.data, onCompleted);
499 }
500 break;
501
502 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
503 ar = (AsyncResult) msg.obj;
504 request = (MainThreadRequest) ar.userObj;
505 if (ar.exception == null && ar.result != null) {
506 request.result = ar.result;
507 } else {
508 request.result = new IccIoResult(0x6F, 0, (byte[])null);
509 if (ar.result == null) {
510 loge("iccTransmitApduBasicChannel: Empty response");
511 } else if (ar.exception instanceof CommandException) {
512 loge("iccTransmitApduBasicChannel: CommandException: " +
513 ar.exception);
514 } else {
515 loge("iccTransmitApduBasicChannel: Unknown exception");
516 }
517 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700518 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700519 break;
520
521 case CMD_EXCHANGE_SIM_IO:
522 request = (MainThreadRequest) msg.obj;
523 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800524 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700525 if (uiccCard == null) {
526 loge("iccExchangeSimIO: No UICC");
527 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700528 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700529 } else {
530 onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
531 request);
532 uiccCard.iccExchangeSimIO(iccArgument.cla, /* fileID */
533 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3,
534 iccArgument.data, onCompleted);
535 }
536 break;
537
538 case EVENT_EXCHANGE_SIM_IO_DONE:
539 ar = (AsyncResult) msg.obj;
540 request = (MainThreadRequest) ar.userObj;
541 if (ar.exception == null && ar.result != null) {
542 request.result = ar.result;
543 } else {
544 request.result = new IccIoResult(0x6f, 0, (byte[])null);
545 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700546 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700547 break;
548
Derek Tan4d5e5c12014-02-04 11:54:58 -0800549 case CMD_SEND_ENVELOPE:
550 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800551 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700552 if (uiccCard == null) {
553 loge("sendEnvelopeWithStatus: No UICC");
554 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700555 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700556 } else {
557 onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
558 uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted);
559 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800560 break;
561
562 case EVENT_SEND_ENVELOPE_DONE:
563 ar = (AsyncResult) msg.obj;
564 request = (MainThreadRequest) ar.userObj;
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700565 if (ar.exception == null && ar.result != null) {
566 request.result = ar.result;
Derek Tan4d5e5c12014-02-04 11:54:58 -0800567 } else {
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700568 request.result = new IccIoResult(0x6F, 0, (byte[])null);
569 if (ar.result == null) {
570 loge("sendEnvelopeWithStatus: Empty response");
571 } else if (ar.exception instanceof CommandException) {
572 loge("sendEnvelopeWithStatus: CommandException: " +
573 ar.exception);
574 } else {
575 loge("sendEnvelopeWithStatus: exception:" + ar.exception);
576 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800577 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700578 notifyRequester(request);
Derek Tan4d5e5c12014-02-04 11:54:58 -0800579 break;
580
Shishir Agrawal566b7612013-10-28 14:41:00 -0700581 case CMD_OPEN_CHANNEL:
582 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800583 uiccCard = getUiccCardFromRequest(request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800584 Pair<String, Integer> openChannelArgs = (Pair<String, Integer>) request.argument;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700585 if (uiccCard == null) {
586 loge("iccOpenLogicalChannel: No UICC");
Shishir Agrawalfc0492a2016-02-17 11:15:33 -0800587 request.result = new IccOpenLogicalChannelResponse(-1,
588 IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700589 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700590 } else {
591 onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800592 uiccCard.iccOpenLogicalChannel(openChannelArgs.first,
593 openChannelArgs.second, onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700594 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700595 break;
596
597 case EVENT_OPEN_CHANNEL_DONE:
598 ar = (AsyncResult) msg.obj;
599 request = (MainThreadRequest) ar.userObj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700600 IccOpenLogicalChannelResponse openChannelResp;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700601 if (ar.exception == null && ar.result != null) {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700602 int[] result = (int[]) ar.result;
603 int channelId = result[0];
604 byte[] selectResponse = null;
605 if (result.length > 1) {
606 selectResponse = new byte[result.length - 1];
607 for (int i = 1; i < result.length; ++i) {
608 selectResponse[i - 1] = (byte) result[i];
609 }
610 }
611 openChannelResp = new IccOpenLogicalChannelResponse(channelId,
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700612 IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700613 } else {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700614 if (ar.result == null) {
615 loge("iccOpenLogicalChannel: Empty response");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700616 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700617 if (ar.exception != null) {
618 loge("iccOpenLogicalChannel: Exception: " + ar.exception);
619 }
620
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700621 int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR;
Junda Liua754ba12015-05-20 01:17:52 -0700622 if (ar.exception instanceof CommandException) {
623 CommandException.Error error =
624 ((CommandException) (ar.exception)).getCommandError();
625 if (error == CommandException.Error.MISSING_RESOURCE) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700626 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE;
Junda Liua754ba12015-05-20 01:17:52 -0700627 } else if (error == CommandException.Error.NO_SUCH_ELEMENT) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700628 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700629 }
630 }
631 openChannelResp = new IccOpenLogicalChannelResponse(
632 IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700633 }
Shishir Agrawal82c8a462014-07-31 18:13:17 -0700634 request.result = openChannelResp;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700635 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700636 break;
637
638 case CMD_CLOSE_CHANNEL:
639 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800640 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700641 if (uiccCard == null) {
642 loge("iccCloseLogicalChannel: No UICC");
Yoshiaki Naka2e29d822016-09-02 19:27:39 +0900643 request.result = false;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700644 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700645 } else {
646 onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
647 uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
648 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700649 break;
650
651 case EVENT_CLOSE_CHANNEL_DONE:
Jake Hambye994d462014-02-03 13:10:13 -0800652 handleNullReturnEvent(msg, "iccCloseLogicalChannel");
653 break;
654
655 case CMD_NV_READ_ITEM:
656 request = (MainThreadRequest) msg.obj;
657 onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800658 defaultPhone.nvReadItem((Integer) request.argument, onCompleted,
659 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800660 break;
661
662 case EVENT_NV_READ_ITEM_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700663 ar = (AsyncResult) msg.obj;
664 request = (MainThreadRequest) ar.userObj;
Jake Hambye994d462014-02-03 13:10:13 -0800665 if (ar.exception == null && ar.result != null) {
666 request.result = ar.result; // String
Shishir Agrawal566b7612013-10-28 14:41:00 -0700667 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800668 request.result = "";
669 if (ar.result == null) {
670 loge("nvReadItem: Empty response");
671 } else if (ar.exception instanceof CommandException) {
672 loge("nvReadItem: CommandException: " +
673 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700674 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800675 loge("nvReadItem: Unknown exception");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700676 }
677 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700678 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700679 break;
680
Jake Hambye994d462014-02-03 13:10:13 -0800681 case CMD_NV_WRITE_ITEM:
682 request = (MainThreadRequest) msg.obj;
683 onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
684 Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800685 defaultPhone.nvWriteItem(idValue.first, idValue.second, onCompleted,
vagdeviaf9a5b92018-08-15 16:01:53 -0700686 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800687 break;
688
689 case EVENT_NV_WRITE_ITEM_DONE:
690 handleNullReturnEvent(msg, "nvWriteItem");
691 break;
692
693 case CMD_NV_WRITE_CDMA_PRL:
694 request = (MainThreadRequest) msg.obj;
695 onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800696 defaultPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
Jake Hambye994d462014-02-03 13:10:13 -0800697 break;
698
699 case EVENT_NV_WRITE_CDMA_PRL_DONE:
700 handleNullReturnEvent(msg, "nvWriteCdmaPrl");
701 break;
702
chen xu6dac5ab2018-10-26 17:39:23 -0700703 case CMD_RESET_MODEM_CONFIG:
Jake Hambye994d462014-02-03 13:10:13 -0800704 request = (MainThreadRequest) msg.obj;
chen xu6dac5ab2018-10-26 17:39:23 -0700705 onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800706 defaultPhone.resetModemConfig(onCompleted);
Jake Hambye994d462014-02-03 13:10:13 -0800707 break;
708
chen xu6dac5ab2018-10-26 17:39:23 -0700709 case EVENT_RESET_MODEM_CONFIG_DONE:
710 handleNullReturnEvent(msg, "resetModemConfig");
Jake Hambye994d462014-02-03 13:10:13 -0800711 break;
712
Jake Hamby7c27be32014-03-03 13:25:59 -0800713 case CMD_GET_PREFERRED_NETWORK_TYPE:
714 request = (MainThreadRequest) msg.obj;
715 onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request);
Stuart Scott54788802015-03-30 13:18:01 -0700716 getPhoneFromRequest(request).getPreferredNetworkType(onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800717 break;
718
719 case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE:
720 ar = (AsyncResult) msg.obj;
721 request = (MainThreadRequest) ar.userObj;
722 if (ar.exception == null && ar.result != null) {
723 request.result = ar.result; // Integer
724 } else {
Sanket Padawecfc2d352016-01-05 19:52:14 -0800725 request.result = null;
Jake Hamby7c27be32014-03-03 13:25:59 -0800726 if (ar.result == null) {
727 loge("getPreferredNetworkType: Empty response");
728 } else if (ar.exception instanceof CommandException) {
729 loge("getPreferredNetworkType: CommandException: " +
730 ar.exception);
731 } else {
732 loge("getPreferredNetworkType: Unknown exception");
733 }
734 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700735 notifyRequester(request);
Jake Hamby7c27be32014-03-03 13:25:59 -0800736 break;
737
738 case CMD_SET_PREFERRED_NETWORK_TYPE:
739 request = (MainThreadRequest) msg.obj;
740 onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request);
741 int networkType = (Integer) request.argument;
Stuart Scott54788802015-03-30 13:18:01 -0700742 getPhoneFromRequest(request).setPreferredNetworkType(networkType, onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800743 break;
744
745 case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE:
746 handleNullReturnEvent(msg, "setPreferredNetworkType");
747 break;
748
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000749 case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
750 request = (MainThreadRequest)msg.obj;
751 onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800752 defaultPhone.invokeOemRilRequestRaw((byte[]) request.argument, onCompleted);
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000753 break;
754
755 case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
756 ar = (AsyncResult)msg.obj;
757 request = (MainThreadRequest)ar.userObj;
758 request.result = ar;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700759 notifyRequester(request);
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000760 break;
761
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800762 case CMD_SET_VOICEMAIL_NUMBER:
763 request = (MainThreadRequest) msg.obj;
764 onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
765 Pair<String, String> tagNum = (Pair<String, String>) request.argument;
Stuart Scott584921c2015-01-15 17:10:34 -0800766 getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
767 onCompleted);
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800768 break;
769
770 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
771 handleNullReturnEvent(msg, "setVoicemailNumber");
772 break;
773
Stuart Scott54788802015-03-30 13:18:01 -0700774 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC:
775 request = (MainThreadRequest) msg.obj;
776 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE,
777 request);
778 getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted);
779 break;
780
781 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE:
782 handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic");
783 break;
784
Shishir Agrawal302c8692015-06-19 13:49:39 -0700785 case CMD_PERFORM_NETWORK_SCAN:
786 request = (MainThreadRequest) msg.obj;
787 onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request);
788 getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
789 break;
790
791 case EVENT_PERFORM_NETWORK_SCAN_DONE:
792 ar = (AsyncResult) msg.obj;
793 request = (MainThreadRequest) ar.userObj;
794 CellNetworkScanResult cellScanResult;
795 if (ar.exception == null && ar.result != null) {
796 cellScanResult = new CellNetworkScanResult(
797 CellNetworkScanResult.STATUS_SUCCESS,
798 (List<OperatorInfo>) ar.result);
799 } else {
800 if (ar.result == null) {
801 loge("getCellNetworkScanResults: Empty response");
802 }
803 if (ar.exception != null) {
804 loge("getCellNetworkScanResults: Exception: " + ar.exception);
805 }
806 int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR;
807 if (ar.exception instanceof CommandException) {
808 CommandException.Error error =
809 ((CommandException) (ar.exception)).getCommandError();
810 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
811 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE;
812 } else if (error == CommandException.Error.GENERIC_FAILURE) {
813 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE;
814 }
815 }
816 cellScanResult = new CellNetworkScanResult(errorCode, null);
817 }
818 request.result = cellScanResult;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700819 notifyRequester(request);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700820 break;
821
822 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
823 request = (MainThreadRequest) msg.obj;
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700824 ManualNetworkSelectionArgument selArg =
825 (ManualNetworkSelectionArgument) request.argument;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700826 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE,
827 request);
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700828 getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo,
829 selArg.persistSelection, onCompleted);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700830 break;
831
832 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
Pengquan Menge3d01e22018-09-20 15:25:35 -0700833 ar = (AsyncResult) msg.obj;
834 request = (MainThreadRequest) ar.userObj;
835 if (ar.exception == null) {
836 request.result = true;
837 } else {
838 request.result = false;
839 loge("setNetworkSelectionModeManual " + ar.exception);
840 }
841 notifyRequester(request);
842 mApp.onNetworkSelectionChanged(request.subId);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700843 break;
844
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700845 case CMD_GET_MODEM_ACTIVITY_INFO:
846 request = (MainThreadRequest) msg.obj;
847 onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
James Mattisab947702019-04-03 14:18:34 -0700848 if (defaultPhone != null) {
849 defaultPhone.getModemActivityInfo(onCompleted, request.workSource);
850 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700851 break;
852
853 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE:
854 ar = (AsyncResult) msg.obj;
855 request = (MainThreadRequest) ar.userObj;
856 if (ar.exception == null && ar.result != null) {
857 request.result = ar.result;
858 } else {
859 if (ar.result == null) {
860 loge("queryModemActivityInfo: Empty response");
861 } else if (ar.exception instanceof CommandException) {
862 loge("queryModemActivityInfo: CommandException: " +
863 ar.exception);
864 } else {
865 loge("queryModemActivityInfo: Unknown exception");
866 }
867 }
Amit Mahajand4766222016-01-28 15:28:28 -0800868 // Result cannot be null. Return ModemActivityInfo with all fields set to 0.
869 if (request.result == null) {
Chen Xud78231e2019-09-10 18:49:52 -0700870 request.result = new ModemActivityInfo(0, 0, 0, null, 0);
Amit Mahajand4766222016-01-28 15:28:28 -0800871 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700872 notifyRequester(request);
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700873 break;
874
Meng Wang1a7c35a2016-05-05 20:56:15 -0700875 case CMD_SET_ALLOWED_CARRIERS:
876 request = (MainThreadRequest) msg.obj;
Michele Berionne482f8202018-11-27 18:57:59 -0800877 CarrierRestrictionRules argument =
878 (CarrierRestrictionRules) request.argument;
Meng Wang1a7c35a2016-05-05 20:56:15 -0700879 onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
Michele Berionne482f8202018-11-27 18:57:59 -0800880 defaultPhone.setAllowedCarriers(argument, onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700881 break;
882
883 case EVENT_SET_ALLOWED_CARRIERS_DONE:
884 ar = (AsyncResult) msg.obj;
885 request = (MainThreadRequest) ar.userObj;
886 if (ar.exception == null && ar.result != null) {
887 request.result = ar.result;
888 } else {
Michele Berionne482f8202018-11-27 18:57:59 -0800889 request.result = TelephonyManager.SET_CARRIER_RESTRICTION_ERROR;
890 if (ar.exception instanceof CommandException) {
891 loge("setAllowedCarriers: CommandException: " + ar.exception);
892 CommandException.Error error =
893 ((CommandException) (ar.exception)).getCommandError();
894 if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
895 request.result =
896 TelephonyManager.SET_CARRIER_RESTRICTION_NOT_SUPPORTED;
897 }
Meng Wang1a7c35a2016-05-05 20:56:15 -0700898 } else {
899 loge("setAllowedCarriers: Unknown exception");
900 }
901 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700902 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700903 break;
904
905 case CMD_GET_ALLOWED_CARRIERS:
906 request = (MainThreadRequest) msg.obj;
907 onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800908 defaultPhone.getAllowedCarriers(onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700909 break;
910
911 case EVENT_GET_ALLOWED_CARRIERS_DONE:
912 ar = (AsyncResult) msg.obj;
913 request = (MainThreadRequest) ar.userObj;
914 if (ar.exception == null && ar.result != null) {
915 request.result = ar.result;
916 } else {
Michele Berionne482f8202018-11-27 18:57:59 -0800917 request.result = new IllegalStateException(
918 "Failed to get carrier restrictions");
Meng Wang1a7c35a2016-05-05 20:56:15 -0700919 if (ar.result == null) {
920 loge("getAllowedCarriers: Empty response");
921 } else if (ar.exception instanceof CommandException) {
922 loge("getAllowedCarriers: CommandException: " +
923 ar.exception);
924 } else {
925 loge("getAllowedCarriers: Unknown exception");
926 }
927 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700928 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700929 break;
930
Nathan Haroldb3014052017-01-25 15:57:32 -0800931 case EVENT_GET_FORBIDDEN_PLMNS_DONE:
932 ar = (AsyncResult) msg.obj;
933 request = (MainThreadRequest) ar.userObj;
934 if (ar.exception == null && ar.result != null) {
935 request.result = ar.result;
936 } else {
937 request.result = new IllegalArgumentException(
938 "Failed to retrieve Forbidden Plmns");
939 if (ar.result == null) {
940 loge("getForbiddenPlmns: Empty response");
941 } else {
942 loge("getForbiddenPlmns: Unknown exception");
943 }
944 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700945 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -0800946 break;
947
948 case CMD_GET_FORBIDDEN_PLMNS:
949 request = (MainThreadRequest) msg.obj;
950 uiccCard = getUiccCardFromRequest(request);
951 if (uiccCard == null) {
952 loge("getForbiddenPlmns() UiccCard is null");
953 request.result = new IllegalArgumentException(
954 "getForbiddenPlmns() UiccCard is null");
Pengquan Menga1bb6272018-09-06 09:59:22 -0700955 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -0800956 break;
957 }
958 Integer appType = (Integer) request.argument;
959 UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType);
960 if (uiccApp == null) {
961 loge("getForbiddenPlmns() no app with specified type -- "
962 + appType);
963 request.result = new IllegalArgumentException("Failed to get UICC App");
Pengquan Menga1bb6272018-09-06 09:59:22 -0700964 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -0800965 break;
966 } else {
967 if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
968 + " specified type -- " + appType);
969 }
970 onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
971 ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
972 onCompleted);
973 break;
974
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000975 case CMD_SWITCH_SLOTS:
976 request = (MainThreadRequest) msg.obj;
977 int[] physicalSlots = (int[]) request.argument;
978 onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
979 UiccController.getInstance().switchSlots(physicalSlots, onCompleted);
980 break;
981
982 case EVENT_SWITCH_SLOTS_DONE:
983 ar = (AsyncResult) msg.obj;
984 request = (MainThreadRequest) ar.userObj;
985 request.result = (ar.exception == null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700986 notifyRequester(request);
987 break;
988 case CMD_GET_NETWORK_SELECTION_MODE:
989 request = (MainThreadRequest) msg.obj;
990 onCompleted = obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE, request);
991 getPhoneFromRequest(request).getNetworkSelectionMode(onCompleted);
992 break;
993
994 case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
995 ar = (AsyncResult) msg.obj;
996 request = (MainThreadRequest) ar.userObj;
997 if (ar.exception != null) {
998 request.result = TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
999 } else {
1000 int mode = ((int[]) ar.result)[0];
1001 if (mode == 0) {
1002 request.result = TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
1003 } else {
1004 request.result = TelephonyManager.NETWORK_SELECTION_MODE_MANUAL;
1005 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001006 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001007 notifyRequester(request);
1008 break;
1009 case CMD_GET_CDMA_ROAMING_MODE:
1010 request = (MainThreadRequest) msg.obj;
1011 onCompleted = obtainMessage(EVENT_GET_CDMA_ROAMING_MODE_DONE, request);
1012 getPhoneFromRequest(request).queryCdmaRoamingPreference(onCompleted);
1013 break;
1014 case EVENT_GET_CDMA_ROAMING_MODE_DONE:
1015 ar = (AsyncResult) msg.obj;
1016 request = (MainThreadRequest) ar.userObj;
1017 if (ar.exception != null) {
1018 request.result = TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT;
1019 } else {
1020 request.result = ((int[]) ar.result)[0];
1021 }
1022 notifyRequester(request);
1023 break;
1024 case CMD_SET_CDMA_ROAMING_MODE:
1025 request = (MainThreadRequest) msg.obj;
1026 onCompleted = obtainMessage(EVENT_SET_CDMA_ROAMING_MODE_DONE, request);
1027 int mode = (int) request.argument;
1028 getPhoneFromRequest(request).setCdmaRoamingPreference(mode, onCompleted);
1029 break;
1030 case EVENT_SET_CDMA_ROAMING_MODE_DONE:
1031 ar = (AsyncResult) msg.obj;
1032 request = (MainThreadRequest) ar.userObj;
1033 request.result = ar.exception == null;
1034 notifyRequester(request);
1035 break;
1036 case CMD_SET_CDMA_SUBSCRIPTION_MODE:
1037 request = (MainThreadRequest) msg.obj;
1038 onCompleted = obtainMessage(EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1039 int subscriptionMode = (int) request.argument;
1040 getPhoneFromRequest(request).setCdmaSubscription(subscriptionMode, onCompleted);
1041 break;
1042 case EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE:
1043 ar = (AsyncResult) msg.obj;
1044 request = (MainThreadRequest) ar.userObj;
1045 request.result = ar.exception == null;
1046 notifyRequester(request);
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001047 break;
Nathan Harold3ff88932018-08-14 10:19:49 -07001048 case CMD_GET_ALL_CELL_INFO:
1049 request = (MainThreadRequest) msg.obj;
Nathan Harold3ff88932018-08-14 10:19:49 -07001050 onCompleted = obtainMessage(EVENT_GET_ALL_CELL_INFO_DONE, request);
Nathan Harold92bed182018-10-12 18:16:49 -07001051 request.phone.requestCellInfoUpdate(request.workSource, onCompleted);
Nathan Harold3ff88932018-08-14 10:19:49 -07001052 break;
Nathan Harold3ff88932018-08-14 10:19:49 -07001053 case EVENT_GET_ALL_CELL_INFO_DONE:
1054 ar = (AsyncResult) msg.obj;
1055 request = (MainThreadRequest) ar.userObj;
Nathan Harold8d0f1742018-10-02 12:14:47 -07001056 // If a timeout occurs, the response will be null
1057 request.result = (ar.exception == null && ar.result != null)
1058 ? ar.result : new ArrayList<CellInfo>();
Nathan Harold3ff88932018-08-14 10:19:49 -07001059 synchronized (request) {
1060 request.notifyAll();
1061 }
1062 break;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001063 case CMD_REQUEST_CELL_INFO_UPDATE:
1064 request = (MainThreadRequest) msg.obj;
1065 request.phone.requestCellInfoUpdate(request.workSource,
1066 obtainMessage(EVENT_REQUEST_CELL_INFO_UPDATE_DONE, request));
1067 break;
1068 case EVENT_REQUEST_CELL_INFO_UPDATE_DONE:
1069 ar = (AsyncResult) msg.obj;
1070 request = (MainThreadRequest) ar.userObj;
1071 ICellInfoCallback cb = (ICellInfoCallback) request.argument;
1072 try {
1073 if (ar.exception != null) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001074 Log.e(LOG_TAG, "Exception retrieving CellInfo=" + ar.exception);
Nathan Harolde82c4b82018-12-18 19:40:37 -08001075 cb.onError(TelephonyManager.CellInfoCallback.ERROR_MODEM_ERROR,
1076 new android.os.ParcelableException(ar.exception));
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001077 } else if (ar.result == null) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001078 Log.w(LOG_TAG, "Timeout Waiting for CellInfo!");
Nathan Harolde82c4b82018-12-18 19:40:37 -08001079 cb.onError(TelephonyManager.CellInfoCallback.ERROR_TIMEOUT, null);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001080 } else {
1081 // use the result as returned
1082 cb.onCellInfo((List<CellInfo>) ar.result);
1083 }
1084 } catch (RemoteException re) {
1085 Log.w(LOG_TAG, "Discarded CellInfo due to Callback RemoteException");
1086 }
1087 break;
1088 case CMD_GET_CELL_LOCATION:
Nathan Harold3ff88932018-08-14 10:19:49 -07001089 request = (MainThreadRequest) msg.obj;
1090 WorkSource ws = (WorkSource) request.argument;
1091 Phone phone = getPhoneFromRequest(request);
1092 phone.getCellLocation(ws, obtainMessage(EVENT_GET_CELL_LOCATION_DONE, request));
1093 break;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001094 case EVENT_GET_CELL_LOCATION_DONE:
Nathan Harold3ff88932018-08-14 10:19:49 -07001095 ar = (AsyncResult) msg.obj;
1096 request = (MainThreadRequest) ar.userObj;
1097 if (ar.exception == null) {
1098 request.result = ar.result;
1099 } else {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001100 phone = getPhoneFromRequest(request);
Nathan Harold3ff88932018-08-14 10:19:49 -07001101 request.result = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
1102 ? new CdmaCellLocation() : new GsmCellLocation();
1103 }
1104
1105 synchronized (request) {
1106 request.notifyAll();
1107 }
1108 break;
chen xu6dac5ab2018-10-26 17:39:23 -07001109 case CMD_MODEM_REBOOT:
1110 request = (MainThreadRequest) msg.obj;
1111 onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001112 defaultPhone.rebootModem(onCompleted);
chen xu6dac5ab2018-10-26 17:39:23 -07001113 break;
chen xu6dac5ab2018-10-26 17:39:23 -07001114 case EVENT_CMD_MODEM_REBOOT_DONE:
1115 handleNullReturnEvent(msg, "rebootModem");
1116 break;
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001117 case CMD_REQUEST_ENABLE_MODEM:
1118 request = (MainThreadRequest) msg.obj;
1119 boolean enable = (boolean) request.argument;
1120 onCompleted = obtainMessage(EVENT_ENABLE_MODEM_DONE, request);
Nazanin Bakhshi33d584b2019-02-27 10:44:32 -08001121 onCompleted.arg1 = enable ? 1 : 0;
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001122 PhoneConfigurationManager.getInstance()
1123 .enablePhone(request.phone, enable, onCompleted);
1124 break;
1125 case EVENT_ENABLE_MODEM_DONE:
1126 ar = (AsyncResult) msg.obj;
1127 request = (MainThreadRequest) ar.userObj;
1128 request.result = (ar.exception == null);
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07001129 int phoneId = request.phone.getPhoneId();
Nazanin Bakhshi33d584b2019-02-27 10:44:32 -08001130 //update the cache as modem status has changed
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07001131 if ((boolean) request.result) {
1132 mPhoneConfigurationManager.addToPhoneStatusCache(phoneId, msg.arg1 == 1);
1133 updateModemStateMetrics();
1134 } else {
1135 Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1136 + ar.exception);
1137 }
1138 notifyRequester(request);
1139 break;
1140 case CMD_GET_MODEM_STATUS:
1141 request = (MainThreadRequest) msg.obj;
1142 onCompleted = obtainMessage(EVENT_GET_MODEM_STATUS_DONE, request);
1143 PhoneConfigurationManager.getInstance()
1144 .getPhoneStatusFromModem(request.phone, onCompleted);
1145 break;
1146 case EVENT_GET_MODEM_STATUS_DONE:
1147 ar = (AsyncResult) msg.obj;
1148 request = (MainThreadRequest) ar.userObj;
1149 int id = request.phone.getPhoneId();
1150 if (ar.exception == null && ar.result != null) {
1151 request.result = ar.result;
1152 //update the cache as modem status has changed
1153 mPhoneConfigurationManager.addToPhoneStatusCache(id,
1154 (boolean) request.result);
1155 } else {
1156 // Return true if modem status cannot be retrieved. For most cases,
1157 // modem status is on. And for older version modems, GET_MODEM_STATUS
1158 // and disable modem are not supported. Modem is always on.
1159 // TODO: this should be fixed in R to support a third
1160 // status UNKNOWN b/131631629
1161 request.result = true;
1162 Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1163 + ar.exception);
1164 }
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001165 notifyRequester(request);
1166 break;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001167 default:
1168 Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
1169 break;
1170 }
1171 }
Jake Hambye994d462014-02-03 13:10:13 -08001172
Pengquan Menga1bb6272018-09-06 09:59:22 -07001173 private void notifyRequester(MainThreadRequest request) {
1174 synchronized (request) {
1175 request.notifyAll();
1176 }
1177 }
1178
Jake Hambye994d462014-02-03 13:10:13 -08001179 private void handleNullReturnEvent(Message msg, String command) {
1180 AsyncResult ar = (AsyncResult) msg.obj;
1181 MainThreadRequest request = (MainThreadRequest) ar.userObj;
1182 if (ar.exception == null) {
1183 request.result = true;
1184 } else {
1185 request.result = false;
1186 if (ar.exception instanceof CommandException) {
1187 loge(command + ": CommandException: " + ar.exception);
1188 } else {
1189 loge(command + ": Unknown exception");
1190 }
1191 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001192 notifyRequester(request);
Jake Hambye994d462014-02-03 13:10:13 -08001193 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001194 }
1195
1196 /**
1197 * Posts the specified command to be executed on the main thread,
1198 * waits for the request to complete, and returns the result.
1199 * @see #sendRequestAsync
1200 */
1201 private Object sendRequest(int command, Object argument) {
Nathan Harold92bed182018-10-12 18:16:49 -07001202 return sendRequest(
1203 command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, null, null);
vagdeviaf9a5b92018-08-15 16:01:53 -07001204 }
1205
1206 /**
1207 * Posts the specified command to be executed on the main thread,
1208 * waits for the request to complete, and returns the result.
1209 * @see #sendRequestAsync
1210 */
1211 private Object sendRequest(int command, Object argument, WorkSource workSource) {
1212 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
Nathan Harold92bed182018-10-12 18:16:49 -07001213 null, workSource);
Wink Saville36469e72014-06-11 15:17:00 -07001214 }
1215
1216 /**
1217 * Posts the specified command to be executed on the main thread,
1218 * waits for the request to complete, and returns the result.
1219 * @see #sendRequestAsync
1220 */
Shishir Agrawal76d5da92014-11-09 16:17:25 -08001221 private Object sendRequest(int command, Object argument, Integer subId) {
Nathan Harold92bed182018-10-12 18:16:49 -07001222 return sendRequest(command, argument, subId, null, null);
vagdeviaf9a5b92018-08-15 16:01:53 -07001223 }
1224
1225 /**
1226 * Posts the specified command to be executed on the main thread,
1227 * waits for the request to complete, and returns the result.
1228 * @see #sendRequestAsync
1229 */
Nathan Harold92bed182018-10-12 18:16:49 -07001230 private Object sendRequest(int command, Object argument, int subId, WorkSource workSource) {
1231 return sendRequest(command, argument, subId, null, workSource);
1232 }
1233
1234 /**
1235 * Posts the specified command to be executed on the main thread,
1236 * waits for the request to complete, and returns the result.
1237 * @see #sendRequestAsync
1238 */
1239 private Object sendRequest(int command, Object argument, Phone phone, WorkSource workSource) {
1240 return sendRequest(
1241 command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phone, workSource);
1242 }
1243
1244 /**
1245 * Posts the specified command to be executed on the main thread,
1246 * waits for the request to complete, and returns the result.
1247 * @see #sendRequestAsync
1248 */
1249 private Object sendRequest(
1250 int command, Object argument, Integer subId, Phone phone, WorkSource workSource) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001251 if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
1252 throw new RuntimeException("This method will deadlock if called from the main thread.");
1253 }
1254
Nathan Harold92bed182018-10-12 18:16:49 -07001255 MainThreadRequest request = null;
1256 if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && phone != null) {
1257 throw new IllegalArgumentException("subId and phone cannot both be specified!");
1258 } else if (phone != null) {
1259 request = new MainThreadRequest(argument, phone, workSource);
1260 } else {
1261 request = new MainThreadRequest(argument, subId, workSource);
1262 }
1263
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001264 Message msg = mMainThreadHandler.obtainMessage(command, request);
1265 msg.sendToTarget();
1266
1267 // Wait for the request to complete
1268 synchronized (request) {
1269 while (request.result == null) {
1270 try {
1271 request.wait();
1272 } catch (InterruptedException e) {
1273 // Do nothing, go back and wait until the request is complete
1274 }
1275 }
1276 }
1277 return request.result;
1278 }
1279
1280 /**
1281 * Asynchronous ("fire and forget") version of sendRequest():
1282 * Posts the specified command to be executed on the main thread, and
1283 * returns immediately.
1284 * @see #sendRequest
1285 */
1286 private void sendRequestAsync(int command) {
1287 mMainThreadHandler.sendEmptyMessage(command);
1288 }
1289
1290 /**
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001291 * Same as {@link #sendRequestAsync(int)} except it takes an argument.
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001292 * @see {@link #sendRequest(int)}
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001293 */
1294 private void sendRequestAsync(int command, Object argument) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001295 sendRequestAsync(command, argument, null, null);
1296 }
1297
1298 /**
1299 * Same as {@link #sendRequestAsync(int,Object)} except it takes a Phone and WorkSource.
1300 * @see {@link #sendRequest(int,Object)}
1301 */
1302 private void sendRequestAsync(
1303 int command, Object argument, Phone phone, WorkSource workSource) {
1304 MainThreadRequest request = new MainThreadRequest(argument, phone, workSource);
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001305 Message msg = mMainThreadHandler.obtainMessage(command, request);
1306 msg.sendToTarget();
1307 }
1308
1309 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001310 * Initialize the singleton PhoneInterfaceManager instance.
1311 * This is only done once, at startup, from PhoneApp.onCreate().
1312 */
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001313 /* package */ static PhoneInterfaceManager init(PhoneGlobals app) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001314 synchronized (PhoneInterfaceManager.class) {
1315 if (sInstance == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001316 sInstance = new PhoneInterfaceManager(app);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001317 } else {
1318 Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
1319 }
1320 return sInstance;
1321 }
1322 }
1323
1324 /** Private constructor; @see init() */
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001325 private PhoneInterfaceManager(PhoneGlobals app) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001326 mApp = app;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001327 mCM = PhoneGlobals.getInstance().mCM;
Stuart Scott981d8582015-04-21 14:09:50 -07001328 mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001329 mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
1330 mMainThreadHandler = new MainThreadHandler();
Tobias Thiererb19e1f12018-12-11 17:54:03 +00001331 mSubscriptionController = SubscriptionController.getInstance();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001332 mTelephonySharedPreferences =
1333 PreferenceManager.getDefaultSharedPreferences(mApp);
yinxub1bed742017-04-17 11:45:04 -07001334 mNetworkScanRequestTracker = new NetworkScanRequestTracker();
Malcolm Chen2c63d402018-08-14 16:00:53 -07001335 mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
Wink Saville3ab207e2014-11-20 13:07:20 -08001336
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001337 publish();
1338 }
1339
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001340 private Phone getDefaultPhone() {
1341 Phone thePhone = getPhone(getDefaultSubscription());
1342 return (thePhone != null) ? thePhone : PhoneFactory.getDefaultPhone();
1343 }
1344
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001345 private void publish() {
1346 if (DBG) log("publish: " + this);
1347
1348 ServiceManager.addService("phone", this);
1349 }
1350
Stuart Scott584921c2015-01-15 17:10:34 -08001351 private Phone getPhoneFromRequest(MainThreadRequest request) {
Jordan Liu4c733742019-02-28 12:03:40 -08001352 if (request.phone != null) {
1353 return request.phone;
1354 } else {
1355 return getPhoneFromSubId(request.subId);
1356 }
1357 }
1358
1359 private Phone getPhoneFromSubId(int subId) {
1360 return (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
1361 ? getDefaultPhone() : getPhone(subId);
Stuart Scott584921c2015-01-15 17:10:34 -08001362 }
1363
Shishir Agrawalc04d9752016-02-19 10:41:00 -08001364 private UiccCard getUiccCardFromRequest(MainThreadRequest request) {
1365 Phone phone = getPhoneFromRequest(request);
1366 return phone == null ? null :
1367 UiccController.getInstance().getUiccCard(phone.getPhoneId());
1368 }
1369
Wink Saville36469e72014-06-11 15:17:00 -07001370 // returns phone associated with the subId.
Wink Savilleb564aae2014-10-23 10:18:09 -07001371 private Phone getPhone(int subId) {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08001372 return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId));
Wink Saville36469e72014-06-11 15:17:00 -07001373 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001374
1375 public void dial(String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001376 dialForSubscriber(getPreferredVoiceSubscription(), number);
Wink Saville36469e72014-06-11 15:17:00 -07001377 }
1378
Wink Savilleb564aae2014-10-23 10:18:09 -07001379 public void dialForSubscriber(int subId, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001380 if (DBG) log("dial: " + number);
1381 // No permission check needed here: This is just a wrapper around the
1382 // ACTION_DIAL intent, which is available to any app since it puts up
1383 // the UI before it does anything.
1384
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001385 final long identity = Binder.clearCallingIdentity();
1386 try {
1387 String url = createTelUrl(number);
1388 if (url == null) {
1389 return;
1390 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001391
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001392 // PENDING: should we just silently fail if phone is offhook or ringing?
1393 PhoneConstants.State state = mCM.getState(subId);
1394 if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
1395 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
1396 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1397 mApp.startActivity(intent);
1398 }
1399 } finally {
1400 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001401 }
1402 }
1403
1404 public void call(String callingPackage, String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001405 callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number);
Wink Saville36469e72014-06-11 15:17:00 -07001406 }
1407
Wink Savilleb564aae2014-10-23 10:18:09 -07001408 public void callForSubscriber(int subId, String callingPackage, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001409 if (DBG) log("call: " + number);
1410
1411 // This is just a wrapper around the ACTION_CALL intent, but we still
1412 // need to do a permission check since we're calling startActivity()
1413 // from the context of the phone app.
1414 enforceCallPermission();
1415
Jordan Liu1617b712019-07-10 15:06:26 -07001416 if (mAppOps.noteOp(AppOpsManager.OPSTR_CALL_PHONE, Binder.getCallingUid(), callingPackage)
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001417 != AppOpsManager.MODE_ALLOWED) {
1418 return;
1419 }
1420
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001421 final long identity = Binder.clearCallingIdentity();
1422 try {
1423 String url = createTelUrl(number);
1424 if (url == null) {
1425 return;
1426 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001427
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001428 boolean isValid = false;
1429 final List<SubscriptionInfo> slist = getActiveSubscriptionInfoListPrivileged();
1430 if (slist != null) {
1431 for (SubscriptionInfo subInfoRecord : slist) {
1432 if (subInfoRecord.getSubscriptionId() == subId) {
1433 isValid = true;
1434 break;
1435 }
Wink Saville3ab207e2014-11-20 13:07:20 -08001436 }
Wink Saville08874612014-08-31 19:19:58 -07001437 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001438 if (!isValid) {
1439 return;
1440 }
Wink Saville08874612014-08-31 19:19:58 -07001441
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001442 Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
1443 intent.putExtra(SUBSCRIPTION_KEY, subId);
1444 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1445 mApp.startActivity(intent);
1446 } finally {
1447 Binder.restoreCallingIdentity(identity);
1448 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001449 }
1450
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001451 public boolean supplyPin(String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001452 return supplyPinForSubscriber(getDefaultSubscription(), pin);
Wink Saville36469e72014-06-11 15:17:00 -07001453 }
1454
Wink Savilleb564aae2014-10-23 10:18:09 -07001455 public boolean supplyPinForSubscriber(int subId, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001456 int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07001457 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1458 }
1459
1460 public boolean supplyPuk(String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001461 return supplyPukForSubscriber(getDefaultSubscription(), puk, pin);
Wink Saville36469e72014-06-11 15:17:00 -07001462 }
1463
Wink Savilleb564aae2014-10-23 10:18:09 -07001464 public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001465 int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07001466 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1467 }
1468
1469 /** {@hide} */
1470 public int[] supplyPinReportResult(String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001471 return supplyPinReportResultForSubscriber(getDefaultSubscription(), pin);
Wink Saville36469e72014-06-11 15:17:00 -07001472 }
1473
Wink Savilleb564aae2014-10-23 10:18:09 -07001474 public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001475 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001476
1477 final long identity = Binder.clearCallingIdentity();
1478 try {
1479 final UnlockSim checkSimPin = new UnlockSim(getPhone(subId).getIccCard());
1480 checkSimPin.start();
1481 return checkSimPin.unlockSim(null, pin);
1482 } finally {
1483 Binder.restoreCallingIdentity(identity);
1484 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001485 }
1486
Wink Saville9de0f752013-10-22 19:04:03 -07001487 /** {@hide} */
1488 public int[] supplyPukReportResult(String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001489 return supplyPukReportResultForSubscriber(getDefaultSubscription(), puk, pin);
Wink Saville36469e72014-06-11 15:17:00 -07001490 }
1491
Wink Savilleb564aae2014-10-23 10:18:09 -07001492 public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001493 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001494
1495 final long identity = Binder.clearCallingIdentity();
1496 try {
1497 final UnlockSim checkSimPuk = new UnlockSim(getPhone(subId).getIccCard());
1498 checkSimPuk.start();
1499 return checkSimPuk.unlockSim(puk, pin);
1500 } finally {
1501 Binder.restoreCallingIdentity(identity);
1502 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001503 }
1504
1505 /**
Wink Saville9de0f752013-10-22 19:04:03 -07001506 * Helper thread to turn async call to SimCard#supplyPin into
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001507 * a synchronous one.
1508 */
1509 private static class UnlockSim extends Thread {
1510
1511 private final IccCard mSimCard;
1512
1513 private boolean mDone = false;
Wink Saville9de0f752013-10-22 19:04:03 -07001514 private int mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1515 private int mRetryCount = -1;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001516
1517 // For replies from SimCard interface
1518 private Handler mHandler;
1519
1520 // For async handler to identify request type
1521 private static final int SUPPLY_PIN_COMPLETE = 100;
1522
1523 public UnlockSim(IccCard simCard) {
1524 mSimCard = simCard;
1525 }
1526
1527 @Override
1528 public void run() {
1529 Looper.prepare();
1530 synchronized (UnlockSim.this) {
1531 mHandler = new Handler() {
1532 @Override
1533 public void handleMessage(Message msg) {
1534 AsyncResult ar = (AsyncResult) msg.obj;
1535 switch (msg.what) {
1536 case SUPPLY_PIN_COMPLETE:
1537 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
1538 synchronized (UnlockSim.this) {
Wink Saville9de0f752013-10-22 19:04:03 -07001539 mRetryCount = msg.arg1;
1540 if (ar.exception != null) {
1541 if (ar.exception instanceof CommandException &&
1542 ((CommandException)(ar.exception)).getCommandError()
1543 == CommandException.Error.PASSWORD_INCORRECT) {
1544 mResult = PhoneConstants.PIN_PASSWORD_INCORRECT;
1545 } else {
1546 mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1547 }
1548 } else {
1549 mResult = PhoneConstants.PIN_RESULT_SUCCESS;
1550 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001551 mDone = true;
1552 UnlockSim.this.notifyAll();
1553 }
1554 break;
1555 }
1556 }
1557 };
1558 UnlockSim.this.notifyAll();
1559 }
1560 Looper.loop();
1561 }
1562
1563 /*
1564 * Use PIN or PUK to unlock SIM card
1565 *
1566 * If PUK is null, unlock SIM card with PIN
1567 *
1568 * If PUK is not null, unlock SIM card with PUK and set PIN code
1569 */
Wink Saville9de0f752013-10-22 19:04:03 -07001570 synchronized int[] unlockSim(String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001571
1572 while (mHandler == null) {
1573 try {
1574 wait();
1575 } catch (InterruptedException e) {
1576 Thread.currentThread().interrupt();
1577 }
1578 }
1579 Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
1580
1581 if (puk == null) {
1582 mSimCard.supplyPin(pin, callback);
1583 } else {
1584 mSimCard.supplyPuk(puk, pin, callback);
1585 }
1586
1587 while (!mDone) {
1588 try {
1589 Log.d(LOG_TAG, "wait for done");
1590 wait();
1591 } catch (InterruptedException e) {
1592 // Restore the interrupted status
1593 Thread.currentThread().interrupt();
1594 }
1595 }
1596 Log.d(LOG_TAG, "done");
Wink Saville9de0f752013-10-22 19:04:03 -07001597 int[] resultArray = new int[2];
1598 resultArray[0] = mResult;
1599 resultArray[1] = mRetryCount;
1600 return resultArray;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001601 }
1602 }
1603
1604 public void updateServiceLocation() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001605 updateServiceLocationForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001606
1607 }
1608
Wink Savilleb564aae2014-10-23 10:18:09 -07001609 public void updateServiceLocationForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001610 // No permission check needed here: this call is harmless, and it's
1611 // needed for the ServiceState.requestStateUpdate() call (which is
1612 // already intentionally exposed to 3rd parties.)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001613 final long identity = Binder.clearCallingIdentity();
1614 try {
1615 final Phone phone = getPhone(subId);
1616 if (phone != null) {
1617 phone.updateServiceLocation();
1618 }
1619 } finally {
1620 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001621 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001622 }
1623
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001624 @Override
1625 public boolean isRadioOn(String callingPackage) {
1626 return isRadioOnForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07001627 }
1628
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001629 @Override
1630 public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08001631 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08001632 mApp, subId, callingPackage, "isRadioOnForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001633 return false;
1634 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001635
1636 final long identity = Binder.clearCallingIdentity();
1637 try {
1638 return isRadioOnForSubscriber(subId);
1639 } finally {
1640 Binder.restoreCallingIdentity(identity);
1641 }
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001642 }
1643
1644 private boolean isRadioOnForSubscriber(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001645 final long identity = Binder.clearCallingIdentity();
1646 try {
1647 final Phone phone = getPhone(subId);
1648 if (phone != null) {
1649 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
1650 } else {
1651 return false;
1652 }
1653 } finally {
1654 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001655 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001656 }
1657
1658 public void toggleRadioOnOff() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001659 toggleRadioOnOffForSubscriber(getDefaultSubscription());
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001660 }
Wink Saville36469e72014-06-11 15:17:00 -07001661
Wink Savilleb564aae2014-10-23 10:18:09 -07001662 public void toggleRadioOnOffForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001663 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001664
1665 final long identity = Binder.clearCallingIdentity();
1666 try {
1667 final Phone phone = getPhone(subId);
1668 if (phone != null) {
1669 phone.setRadioPower(!isRadioOnForSubscriber(subId));
1670 }
1671 } finally {
1672 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001673 }
Wink Saville36469e72014-06-11 15:17:00 -07001674 }
1675
1676 public boolean setRadio(boolean turnOn) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001677 return setRadioForSubscriber(getDefaultSubscription(), turnOn);
Wink Saville36469e72014-06-11 15:17:00 -07001678 }
1679
Wink Savilleb564aae2014-10-23 10:18:09 -07001680 public boolean setRadioForSubscriber(int subId, boolean turnOn) {
Wink Saville36469e72014-06-11 15:17:00 -07001681 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001682
1683 final long identity = Binder.clearCallingIdentity();
1684 try {
1685 final Phone phone = getPhone(subId);
1686 if (phone == null) {
1687 return false;
1688 }
1689 if ((phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF) != turnOn) {
1690 toggleRadioOnOffForSubscriber(subId);
1691 }
1692 return true;
1693 } finally {
1694 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001695 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001696 }
Wink Saville36469e72014-06-11 15:17:00 -07001697
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001698 public boolean needMobileRadioShutdown() {
1699 /*
1700 * If any of the Radios are available, it will need to be
1701 * shutdown. So return true if any Radio is available.
1702 */
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001703 final long identity = Binder.clearCallingIdentity();
1704 try {
1705 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1706 Phone phone = PhoneFactory.getPhone(i);
1707 if (phone != null && phone.isRadioAvailable()) return true;
1708 }
1709 logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown.");
1710 return false;
1711 } finally {
1712 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001713 }
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001714 }
1715
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001716 @Override
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001717 public void shutdownMobileRadios() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001718 enforceModifyPermission();
1719
1720 final long identity = Binder.clearCallingIdentity();
1721 try {
1722 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1723 logv("Shutting down Phone " + i);
1724 shutdownRadioUsingPhoneId(i);
1725 }
1726 } finally {
1727 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001728 }
1729 }
1730
1731 private void shutdownRadioUsingPhoneId(int phoneId) {
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001732 Phone phone = PhoneFactory.getPhone(phoneId);
1733 if (phone != null && phone.isRadioAvailable()) {
1734 phone.shutdownRadio();
1735 }
1736 }
1737
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001738 public boolean setRadioPower(boolean turnOn) {
Jack Yub4e16162017-05-15 12:48:40 -07001739 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001740
1741 final long identity = Binder.clearCallingIdentity();
1742 try {
1743 final Phone defaultPhone = PhoneFactory.getDefaultPhone();
1744 if (defaultPhone != null) {
1745 defaultPhone.setRadioPower(turnOn);
1746 return true;
1747 } else {
1748 loge("There's no default phone.");
1749 return false;
1750 }
1751 } finally {
1752 Binder.restoreCallingIdentity(identity);
Wei Liu9ae2a062016-08-08 11:09:34 -07001753 }
Wink Saville36469e72014-06-11 15:17:00 -07001754 }
1755
Wink Savilleb564aae2014-10-23 10:18:09 -07001756 public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001757 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001758
1759 final long identity = Binder.clearCallingIdentity();
1760 try {
1761 final Phone phone = getPhone(subId);
1762 if (phone != null) {
1763 phone.setRadioPower(turnOn);
1764 return true;
1765 } else {
1766 return false;
1767 }
1768 } finally {
1769 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001770 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001771 }
1772
Wink Saville36469e72014-06-11 15:17:00 -07001773 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07001774 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001775 public boolean enableDataConnectivity() {
1776 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001777
1778 final long identity = Binder.clearCallingIdentity();
1779 try {
1780 int subId = mSubscriptionController.getDefaultDataSubId();
1781 final Phone phone = getPhone(subId);
1782 if (phone != null) {
Jack Yud79fba22018-12-13 11:51:28 -08001783 phone.getDataEnabledSettings().setUserDataEnabled(true);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001784 return true;
1785 } else {
1786 return false;
1787 }
1788 } finally {
1789 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001790 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001791 }
1792
Wink Saville36469e72014-06-11 15:17:00 -07001793 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07001794 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001795 public boolean disableDataConnectivity() {
1796 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001797
1798 final long identity = Binder.clearCallingIdentity();
1799 try {
1800 int subId = mSubscriptionController.getDefaultDataSubId();
1801 final Phone phone = getPhone(subId);
1802 if (phone != null) {
Jack Yud79fba22018-12-13 11:51:28 -08001803 phone.getDataEnabledSettings().setUserDataEnabled(false);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001804 return true;
1805 } else {
1806 return false;
1807 }
1808 } finally {
1809 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001810 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001811 }
1812
Sanket Padawe356d7632015-06-22 14:03:32 -07001813 @Override
Jack Yuacf8a132017-05-01 17:00:48 -07001814 public boolean isDataConnectivityPossible(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001815 final long identity = Binder.clearCallingIdentity();
1816 try {
1817 final Phone phone = getPhone(subId);
1818 if (phone != null) {
Jack Yub5d8f642018-11-26 11:20:48 -08001819 return phone.isDataAllowed(ApnSetting.TYPE_DEFAULT);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001820 } else {
1821 return false;
1822 }
1823 } finally {
1824 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001825 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001826 }
1827
1828 public boolean handlePinMmi(String dialString) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001829 return handlePinMmiForSubscriber(getDefaultSubscription(), dialString);
Wink Saville36469e72014-06-11 15:17:00 -07001830 }
1831
pkanwarae03a6b2016-11-06 20:37:09 -08001832 public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001833 enforceCallPermission();
1834
1835 final long identity = Binder.clearCallingIdentity();
1836 try {
1837 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1838 return;
1839 }
1840 Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback);
1841 sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId);
1842 } finally {
1843 Binder.restoreCallingIdentity(identity);
1844 }
pkanwar32d516d2016-10-14 19:37:38 -07001845 };
1846
Wink Savilleb564aae2014-10-23 10:18:09 -07001847 public boolean handlePinMmiForSubscriber(int subId, String dialString) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001848 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001849
1850 final long identity = Binder.clearCallingIdentity();
1851 try {
1852 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1853 return false;
1854 }
1855 return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
1856 } finally {
1857 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001858 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001859 }
1860
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001861 public int getCallState() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07001862 return getCallStateForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001863 }
1864
Sanket Padawe13bac7b2017-03-20 15:04:47 -07001865 public int getCallStateForSlot(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001866 final long identity = Binder.clearCallingIdentity();
1867 try {
1868 Phone phone = PhoneFactory.getPhone(slotIndex);
1869 return phone == null ? TelephonyManager.CALL_STATE_IDLE :
1870 PhoneConstantConversions.convertCallState(phone.getState());
1871 } finally {
1872 Binder.restoreCallingIdentity(identity);
1873 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001874 }
1875
Sanket Padawe356d7632015-06-22 14:03:32 -07001876 @Override
Nathan Harolde037c472019-06-26 00:41:07 +00001877 public int getDataState() {
Nathan Haroldc4689b12019-06-14 16:58:30 -07001878 return getDataStateForSubId(mSubscriptionController.getDefaultDataSubId());
1879 }
1880
1881 @Override
1882 public int getDataStateForSubId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001883 final long identity = Binder.clearCallingIdentity();
1884 try {
Nathan Haroldc4689b12019-06-14 16:58:30 -07001885 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001886 if (phone != null) {
1887 return PhoneConstantConversions.convertDataState(phone.getDataConnectionState());
1888 } else {
1889 return PhoneConstantConversions.convertDataState(
1890 PhoneConstants.DataState.DISCONNECTED);
1891 }
1892 } finally {
1893 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001894 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001895 }
1896
Sanket Padawe356d7632015-06-22 14:03:32 -07001897 @Override
Nathan Harolde037c472019-06-26 00:41:07 +00001898 public int getDataActivity() {
Nathan Haroldc4689b12019-06-14 16:58:30 -07001899 return getDataActivityForSubId(mSubscriptionController.getDefaultDataSubId());
1900 }
1901
1902 @Override
1903 public int getDataActivityForSubId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001904 final long identity = Binder.clearCallingIdentity();
1905 try {
Nathan Haroldc4689b12019-06-14 16:58:30 -07001906 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001907 if (phone != null) {
1908 return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState());
1909 } else {
1910 return TelephonyManager.DATA_ACTIVITY_NONE;
1911 }
1912 } finally {
1913 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001914 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001915 }
1916
1917 @Override
Svetoslav64fad262015-04-14 14:35:21 -07001918 public Bundle getCellLocation(String callingPackage) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001919 mApp.getSystemService(AppOpsManager.class)
Hall Liu1aa510f2017-11-22 17:40:08 -08001920 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08001921
1922 LocationAccessPolicy.LocationPermissionResult locationResult =
1923 LocationAccessPolicy.checkLocationPermission(mApp,
1924 new LocationAccessPolicy.LocationPermissionQuery.Builder()
1925 .setCallingPackage(callingPackage)
1926 .setCallingPid(Binder.getCallingPid())
1927 .setCallingUid(Binder.getCallingUid())
1928 .setMethod("getCellLocation")
1929 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
1930 .build());
1931 switch (locationResult) {
1932 case DENIED_HARD:
1933 throw new SecurityException("Not allowed to access cell location");
1934 case DENIED_SOFT:
1935 return new Bundle();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001936 }
1937
Narayan Kamathf04b5a12018-01-09 11:47:15 +00001938 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001939 final long identity = Binder.clearCallingIdentity();
1940 try {
1941 if (DBG_LOC) log("getCellLocation: is active user");
1942 Bundle data = new Bundle();
Nathan Harold3ff88932018-08-14 10:19:49 -07001943 int subId = mSubscriptionController.getDefaultDataSubId();
1944 CellLocation cl = (CellLocation) sendRequest(CMD_GET_CELL_LOCATION, workSource, subId);
1945 cl.fillInNotifierBundle(data);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001946 return data;
1947 } finally {
1948 Binder.restoreCallingIdentity(identity);
1949 }
Svetoslav64fad262015-04-14 14:35:21 -07001950 }
1951
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001952 @Override
Jack Yu1e81ccd2019-09-26 11:48:33 -07001953 public String getNetworkCountryIsoForPhone(int phoneId, String callingPackage) {
1954 if (!TextUtils.isEmpty(callingPackage)) {
1955 final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
1956 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
1957 mApp, subId, callingPackage, "getNetworkCountryIsoForPhone")) {
1958 return "";
1959 }
1960 }
1961
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001962 // Reporting the correct network country is ambiguous when IWLAN could conflict with
1963 // registered cell info, so return a NULL country instead.
1964 final long identity = Binder.clearCallingIdentity();
1965 try {
Malcolm Chen3732c2b2018-07-18 20:15:24 -07001966 if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
1967 // Get default phone in this case.
1968 phoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
1969 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001970 final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
Jack Yu5f7092c2018-04-13 14:05:37 -07001971 // Todo: fix this when we can get the actual cellular network info when the device
1972 // is on IWLAN.
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001973 if (TelephonyManager.NETWORK_TYPE_IWLAN
1974 == getVoiceNetworkTypeForSubscriber(subId, mApp.getPackageName())) {
1975 return "";
1976 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001977 Phone phone = PhoneFactory.getPhone(phoneId);
1978 if (phone != null) {
1979 ServiceStateTracker sst = phone.getServiceStateTracker();
sqianb9d961a2019-07-31 20:23:45 -07001980 EmergencyNumberTracker emergencyNumberTracker = phone.getEmergencyNumberTracker();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001981 if (sst != null) {
1982 LocaleTracker lt = sst.getLocaleTracker();
1983 if (lt != null) {
sqianb9d961a2019-07-31 20:23:45 -07001984 if (!TextUtils.isEmpty(lt.getCurrentCountry())) {
1985 return lt.getCurrentCountry();
1986 } else if (emergencyNumberTracker != null) {
1987 return emergencyNumberTracker.getEmergencyCountryIso();
1988 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001989 }
1990 }
1991 }
1992 return "";
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001993 } finally {
1994 Binder.restoreCallingIdentity(identity);
1995 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001996 }
1997
1998 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001999 public void enableLocationUpdates() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002000 enableLocationUpdatesForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002001 }
2002
Sanket Padawe356d7632015-06-22 14:03:32 -07002003 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002004 public void enableLocationUpdatesForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002005 mApp.enforceCallingOrSelfPermission(
2006 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002007
2008 final long identity = Binder.clearCallingIdentity();
2009 try {
2010 final Phone phone = getPhone(subId);
2011 if (phone != null) {
2012 phone.enableLocationUpdates();
2013 }
2014 } finally {
2015 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002016 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002017 }
2018
2019 @Override
2020 public void disableLocationUpdates() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002021 disableLocationUpdatesForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002022 }
2023
Sanket Padawe356d7632015-06-22 14:03:32 -07002024 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002025 public void disableLocationUpdatesForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002026 mApp.enforceCallingOrSelfPermission(
2027 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002028
2029 final long identity = Binder.clearCallingIdentity();
2030 try {
2031 final Phone phone = getPhone(subId);
2032 if (phone != null) {
2033 phone.disableLocationUpdates();
2034 }
2035 } finally {
2036 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002037 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002038 }
2039
Nathan Harold31d7ff32018-10-15 20:20:30 -07002040 /**
2041 * Returns the target SDK version number for a given package name.
2042 *
Nathan Haroldec184742019-07-10 17:04:16 -07002043 * This call MUST be invoked before clearing the calling UID.
2044 *
Nathan Harold31d7ff32018-10-15 20:20:30 -07002045 * @return target SDK if the package is found or INT_MAX.
2046 */
2047 private int getTargetSdk(String packageName) {
2048 try {
Nathan Haroldec184742019-07-10 17:04:16 -07002049 final ApplicationInfo ai = mApp.getPackageManager().getApplicationInfoAsUser(
Chen Xu0150f0e2019-07-30 15:12:06 -07002050 packageName, 0, UserHandle.getUserHandleForUid(Binder.getCallingUid()));
Nathan Harold31d7ff32018-10-15 20:20:30 -07002051 if (ai != null) return ai.targetSdkVersion;
2052 } catch (PackageManager.NameNotFoundException unexpected) {
Nathan Haroldec184742019-07-10 17:04:16 -07002053 loge("Failed to get package info for pkg="
2054 + packageName + ", uid=" + Binder.getCallingUid());
Nathan Harold31d7ff32018-10-15 20:20:30 -07002055 }
2056 return Integer.MAX_VALUE;
2057 }
2058
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002059 @Override
2060 @SuppressWarnings("unchecked")
Nathan Harold31d7ff32018-10-15 20:20:30 -07002061 public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage) {
2062 final int targetSdk = getTargetSdk(callingPackage);
Nathan Harolddbea45a2018-08-30 14:35:07 -07002063 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
2064 throw new SecurityException(
2065 "getNeighboringCellInfo() is unavailable to callers targeting Q+ SDK levels.");
2066 }
Nathan Haroldb4d55612018-07-20 13:13:08 -07002067
Jordan Liu1617b712019-07-10 15:06:26 -07002068 if (mAppOps.noteOp(AppOpsManager.OPSTR_NEIGHBORING_CELLS, Binder.getCallingUid(),
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002069 callingPackage) != AppOpsManager.MODE_ALLOWED) {
2070 return null;
2071 }
Svetoslav64fad262015-04-14 14:35:21 -07002072
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07002073 if (DBG_LOC) log("getNeighboringCellInfo: is active user");
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002074
Nathan Haroldf180aac2018-06-01 18:43:55 -07002075 List<CellInfo> info = getAllCellInfo(callingPackage);
2076 if (info == null) return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002077
Nathan Haroldf180aac2018-06-01 18:43:55 -07002078 List<NeighboringCellInfo> neighbors = new ArrayList<NeighboringCellInfo>();
2079 for (CellInfo ci : info) {
2080 if (ci instanceof CellInfoGsm) {
2081 neighbors.add(new NeighboringCellInfo((CellInfoGsm) ci));
2082 } else if (ci instanceof CellInfoWcdma) {
2083 neighbors.add(new NeighboringCellInfo((CellInfoWcdma) ci));
2084 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002085 }
Nathan Haroldf180aac2018-06-01 18:43:55 -07002086 return (neighbors.size()) > 0 ? neighbors : null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002087 }
2088
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002089 private List<CellInfo> getCachedCellInfo() {
2090 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
2091 for (Phone phone : PhoneFactory.getPhones()) {
2092 List<CellInfo> info = phone.getAllCellInfo();
2093 if (info != null) cellInfos.addAll(info);
2094 }
2095 return cellInfos;
2096 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002097
2098 @Override
Svetoslav64fad262015-04-14 14:35:21 -07002099 public List<CellInfo> getAllCellInfo(String callingPackage) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002100 mApp.getSystemService(AppOpsManager.class)
Hall Liu1aa510f2017-11-22 17:40:08 -08002101 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08002102
2103 LocationAccessPolicy.LocationPermissionResult locationResult =
2104 LocationAccessPolicy.checkLocationPermission(mApp,
2105 new LocationAccessPolicy.LocationPermissionQuery.Builder()
2106 .setCallingPackage(callingPackage)
2107 .setCallingPid(Binder.getCallingPid())
2108 .setCallingUid(Binder.getCallingUid())
2109 .setMethod("getAllCellInfo")
Nathan Harold5ae50b52019-02-20 15:46:36 -08002110 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
Hall Liuf19c44f2018-11-27 14:38:17 -08002111 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2112 .build());
2113 switch (locationResult) {
2114 case DENIED_HARD:
2115 throw new SecurityException("Not allowed to access cell info");
2116 case DENIED_SOFT:
2117 return new ArrayList<>();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002118 }
2119
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002120 final int targetSdk = getTargetSdk(callingPackage);
2121 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
2122 return getCachedCellInfo();
2123 }
2124
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07002125 if (DBG_LOC) log("getAllCellInfo: is active user");
Narayan Kamathf04b5a12018-01-09 11:47:15 +00002126 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002127 final long identity = Binder.clearCallingIdentity();
2128 try {
2129 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
2130 for (Phone phone : PhoneFactory.getPhones()) {
Nathan Harold3ff88932018-08-14 10:19:49 -07002131 final List<CellInfo> info = (List<CellInfo>) sendRequest(
Nathan Harold92bed182018-10-12 18:16:49 -07002132 CMD_GET_ALL_CELL_INFO, null, phone, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002133 if (info != null) cellInfos.addAll(info);
2134 }
2135 return cellInfos;
2136 } finally {
2137 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002138 }
2139 }
2140
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07002141 @Override
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002142 public void requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage) {
2143 requestCellInfoUpdateInternal(
2144 subId, cb, callingPackage, getWorkSource(Binder.getCallingUid()));
2145 }
2146
2147 @Override
2148 public void requestCellInfoUpdateWithWorkSource(
2149 int subId, ICellInfoCallback cb, String callingPackage, WorkSource workSource) {
2150 enforceModifyPermission();
2151 requestCellInfoUpdateInternal(subId, cb, callingPackage, workSource);
2152 }
2153
2154 private void requestCellInfoUpdateInternal(
2155 int subId, ICellInfoCallback cb, String callingPackage, WorkSource workSource) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002156 mApp.getSystemService(AppOpsManager.class)
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002157 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08002158
2159 LocationAccessPolicy.LocationPermissionResult locationResult =
2160 LocationAccessPolicy.checkLocationPermission(mApp,
2161 new LocationAccessPolicy.LocationPermissionQuery.Builder()
2162 .setCallingPackage(callingPackage)
2163 .setCallingPid(Binder.getCallingPid())
2164 .setCallingUid(Binder.getCallingUid())
2165 .setMethod("requestCellInfoUpdate")
2166 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2167 .build());
2168 switch (locationResult) {
2169 case DENIED_HARD:
2170 throw new SecurityException("Not allowed to access cell info");
2171 case DENIED_SOFT:
Nathan Harold5320c422019-05-09 10:26:08 -07002172 try {
2173 cb.onCellInfo(new ArrayList<CellInfo>());
2174 } catch (RemoteException re) {
2175 // Drop without consequences
2176 }
Hall Liuf19c44f2018-11-27 14:38:17 -08002177 return;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002178 }
2179
Nathan Harolda939a962019-05-09 10:13:47 -07002180
2181 final Phone phone = getPhoneFromSubId(subId);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002182 if (phone == null) throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
2183
2184 sendRequestAsync(CMD_REQUEST_CELL_INFO_UPDATE, cb, phone, workSource);
2185 }
2186
2187 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002188 public void setCellInfoListRate(int rateInMillis) {
Jack Yua8d8cb82017-01-16 10:15:34 -08002189 enforceModifyPermission();
Narayan Kamathf04b5a12018-01-09 11:47:15 +00002190 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002191
2192 final long identity = Binder.clearCallingIdentity();
2193 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002194 getDefaultPhone().setCellInfoListRate(rateInMillis, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002195 } finally {
2196 Binder.restoreCallingIdentity(identity);
2197 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002198 }
2199
Shishir Agrawala9f32182016-04-12 12:00:16 -07002200 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002201 public String getImeiForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002202 Phone phone = PhoneFactory.getPhone(slotIndex);
2203 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002204 return null;
2205 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002206 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07002207 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
2208 callingPackage, "getImeiForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002209 return null;
2210 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002211
2212 final long identity = Binder.clearCallingIdentity();
2213 try {
2214 return phone.getImei();
2215 } finally {
2216 Binder.restoreCallingIdentity(identity);
2217 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002218 }
2219
2220 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002221 public String getTypeAllocationCodeForSlot(int slotIndex) {
2222 Phone phone = PhoneFactory.getPhone(slotIndex);
2223 String tac = null;
2224 if (phone != null) {
2225 String imei = phone.getImei();
2226 tac = imei == null ? null : imei.substring(0, TYPE_ALLOCATION_CODE_LENGTH);
2227 }
2228 return tac;
2229 }
2230
2231 @Override
Jack Yu2af8d712017-03-15 17:14:14 -07002232 public String getMeidForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002233 Phone phone = PhoneFactory.getPhone(slotIndex);
2234 if (phone == null) {
Jack Yu2af8d712017-03-15 17:14:14 -07002235 return null;
2236 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002237
Jeff Davidson913390f2018-02-23 17:11:49 -08002238 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07002239 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
2240 callingPackage, "getMeidForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002241 return null;
2242 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002243
2244 final long identity = Binder.clearCallingIdentity();
2245 try {
2246 return phone.getMeid();
2247 } finally {
2248 Binder.restoreCallingIdentity(identity);
2249 }
Jack Yu2af8d712017-03-15 17:14:14 -07002250 }
2251
2252 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002253 public String getManufacturerCodeForSlot(int slotIndex) {
2254 Phone phone = PhoneFactory.getPhone(slotIndex);
2255 String manufacturerCode = null;
2256 if (phone != null) {
2257 String meid = phone.getMeid();
2258 manufacturerCode = meid == null ? null : meid.substring(0, MANUFACTURER_CODE_LENGTH);
2259 }
2260 return manufacturerCode;
2261 }
2262
2263 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002264 public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002265 Phone phone = PhoneFactory.getPhone(slotIndex);
2266 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002267 return null;
2268 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002269 int subId = phone.getSubId();
2270 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2271 mApp, subId, callingPackage, "getDeviceSoftwareVersionForSlot")) {
2272 return null;
2273 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002274
2275 final long identity = Binder.clearCallingIdentity();
2276 try {
2277 return phone.getDeviceSvn();
2278 } finally {
2279 Binder.restoreCallingIdentity(identity);
2280 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002281 }
2282
fionaxu43304da2017-11-27 22:51:16 -08002283 @Override
2284 public int getSubscriptionCarrierId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002285 final long identity = Binder.clearCallingIdentity();
2286 try {
2287 final Phone phone = getPhone(subId);
2288 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getCarrierId();
2289 } finally {
2290 Binder.restoreCallingIdentity(identity);
2291 }
fionaxu43304da2017-11-27 22:51:16 -08002292 }
2293
2294 @Override
2295 public String getSubscriptionCarrierName(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002296 final long identity = Binder.clearCallingIdentity();
2297 try {
2298 final Phone phone = getPhone(subId);
2299 return phone == null ? null : phone.getCarrierName();
2300 } finally {
2301 Binder.restoreCallingIdentity(identity);
2302 }
fionaxu43304da2017-11-27 22:51:16 -08002303 }
2304
calvinpanffe225e2018-11-01 19:43:06 +08002305 @Override
chen xu0026ca62019-03-06 15:28:50 -08002306 public int getSubscriptionSpecificCarrierId(int subId) {
chen xu25637222018-11-04 17:17:00 -08002307 final long identity = Binder.clearCallingIdentity();
2308 try {
2309 final Phone phone = getPhone(subId);
2310 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID
chen xu0026ca62019-03-06 15:28:50 -08002311 : phone.getSpecificCarrierId();
chen xu25637222018-11-04 17:17:00 -08002312 } finally {
2313 Binder.restoreCallingIdentity(identity);
2314 }
2315 }
2316
2317 @Override
chen xu0026ca62019-03-06 15:28:50 -08002318 public String getSubscriptionSpecificCarrierName(int subId) {
chen xu25637222018-11-04 17:17:00 -08002319 final long identity = Binder.clearCallingIdentity();
2320 try {
2321 final Phone phone = getPhone(subId);
chen xu0026ca62019-03-06 15:28:50 -08002322 return phone == null ? null : phone.getSpecificCarrierName();
chen xu25637222018-11-04 17:17:00 -08002323 } finally {
2324 Binder.restoreCallingIdentity(identity);
2325 }
2326 }
2327
chen xu651eec72018-11-11 19:03:44 -08002328 @Override
chen xu864e11c2018-12-06 22:10:03 -08002329 public int getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc) {
2330 if (!isSubscriptionMccMnc) {
2331 enforceReadPrivilegedPermission("getCarrierIdFromMccMnc");
2332 }
chen xu651eec72018-11-11 19:03:44 -08002333 final Phone phone = PhoneFactory.getPhone(slotIndex);
2334 if (phone == null) {
2335 return TelephonyManager.UNKNOWN_CARRIER_ID;
2336 }
2337 final long identity = Binder.clearCallingIdentity();
2338 try {
2339 return CarrierResolver.getCarrierIdFromMccMnc(phone.getContext(), mccmnc);
2340 } finally {
2341 Binder.restoreCallingIdentity(identity);
2342 }
2343 }
2344
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002345 //
2346 // Internal helper methods.
2347 //
2348
Sanket Padaweee13a9b2016-03-08 17:30:28 -08002349 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002350 * Make sure the caller has the MODIFY_PHONE_STATE permission.
2351 *
2352 * @throws SecurityException if the caller does not have the required permission
2353 */
2354 private void enforceModifyPermission() {
2355 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
2356 }
2357
2358 /**
2359 * Make sure the caller has the CALL_PHONE permission.
2360 *
2361 * @throws SecurityException if the caller does not have the required permission
2362 */
2363 private void enforceCallPermission() {
2364 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
2365 }
2366
Stuart Scott8eef64f2015-04-08 15:13:54 -07002367 private void enforceConnectivityInternalPermission() {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002368 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL,
Stuart Scott8eef64f2015-04-08 15:13:54 -07002369 "ConnectivityService");
2370 }
2371
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002372 private String createTelUrl(String number) {
2373 if (TextUtils.isEmpty(number)) {
2374 return null;
2375 }
2376
Jake Hambye994d462014-02-03 13:10:13 -08002377 return "tel:" + number;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002378 }
2379
Ihab Awadf9e92732013-12-05 18:02:52 -08002380 private static void log(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002381 Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg);
2382 }
2383
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002384 private static void logv(String msg) {
2385 Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg);
2386 }
2387
Ihab Awadf9e92732013-12-05 18:02:52 -08002388 private static void loge(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002389 Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg);
2390 }
2391
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002392 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002393 public int getActivePhoneType() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07002394 return getActivePhoneTypeForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002395 }
2396
Sanket Padawe356d7632015-06-22 14:03:32 -07002397 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002398 public int getActivePhoneTypeForSlot(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002399 final long identity = Binder.clearCallingIdentity();
2400 try {
2401 final Phone phone = PhoneFactory.getPhone(slotIndex);
2402 if (phone == null) {
2403 return PhoneConstants.PHONE_TYPE_NONE;
2404 } else {
2405 return phone.getPhoneType();
2406 }
2407 } finally {
2408 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002409 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002410 }
2411
2412 /**
2413 * Returns the CDMA ERI icon index to display
2414 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002415 @Override
2416 public int getCdmaEriIconIndex(String callingPackage) {
2417 return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002418 }
2419
Sanket Padawe356d7632015-06-22 14:03:32 -07002420 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002421 public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002422 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002423 mApp, subId, callingPackage, "getCdmaEriIconIndexForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002424 return -1;
2425 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002426
2427 final long identity = Binder.clearCallingIdentity();
2428 try {
2429 final Phone phone = getPhone(subId);
2430 if (phone != null) {
2431 return phone.getCdmaEriIconIndex();
2432 } else {
2433 return -1;
2434 }
2435 } finally {
2436 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002437 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002438 }
2439
2440 /**
2441 * Returns the CDMA ERI icon mode,
2442 * 0 - ON
2443 * 1 - FLASHING
2444 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002445 @Override
2446 public int getCdmaEriIconMode(String callingPackage) {
2447 return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002448 }
2449
Sanket Padawe356d7632015-06-22 14:03:32 -07002450 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002451 public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002452 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002453 mApp, subId, callingPackage, "getCdmaEriIconModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002454 return -1;
2455 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002456
2457 final long identity = Binder.clearCallingIdentity();
2458 try {
2459 final Phone phone = getPhone(subId);
2460 if (phone != null) {
2461 return phone.getCdmaEriIconMode();
2462 } else {
2463 return -1;
2464 }
2465 } finally {
2466 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002467 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002468 }
2469
2470 /**
2471 * Returns the CDMA ERI text,
2472 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002473 @Override
2474 public String getCdmaEriText(String callingPackage) {
2475 return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002476 }
2477
Sanket Padawe356d7632015-06-22 14:03:32 -07002478 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002479 public String getCdmaEriTextForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002480 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002481 mApp, subId, callingPackage, "getCdmaEriIconTextForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002482 return null;
2483 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002484
2485 final long identity = Binder.clearCallingIdentity();
2486 try {
2487 final Phone phone = getPhone(subId);
2488 if (phone != null) {
2489 return phone.getCdmaEriText();
2490 } else {
2491 return null;
2492 }
2493 } finally {
2494 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002495 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002496 }
2497
2498 /**
Junda Liuca05d5d2014-08-14 22:36:34 -07002499 * Returns the CDMA MDN.
2500 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002501 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002502 public String getCdmaMdn(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002503 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2504 mApp, subId, "getCdmaMdn");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002505
2506 final long identity = Binder.clearCallingIdentity();
2507 try {
2508 final Phone phone = getPhone(subId);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002509 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002510 return phone.getLine1Number();
2511 } else {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002512 loge("getCdmaMdn: no phone found. Invalid subId: " + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002513 return null;
2514 }
2515 } finally {
2516 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07002517 }
2518 }
2519
2520 /**
2521 * Returns the CDMA MIN.
2522 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002523 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002524 public String getCdmaMin(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002525 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2526 mApp, subId, "getCdmaMin");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002527
2528 final long identity = Binder.clearCallingIdentity();
2529 try {
2530 final Phone phone = getPhone(subId);
2531 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
2532 return phone.getCdmaMin();
2533 } else {
2534 return null;
2535 }
2536 } finally {
2537 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07002538 }
2539 }
2540
Hall Liud892bec2018-11-30 14:51:45 -08002541 @Override
2542 public void requestNumberVerification(PhoneNumberRange range, long timeoutMillis,
2543 INumberVerificationCallback callback, String callingPackage) {
2544 if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
2545 != PERMISSION_GRANTED) {
2546 throw new SecurityException("Caller must hold the MODIFY_PHONE_STATE permission");
2547 }
2548 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2549
2550 String authorizedPackage = NumberVerificationManager.getAuthorizedPackage(mApp);
2551 if (!TextUtils.equals(callingPackage, authorizedPackage)) {
2552 throw new SecurityException("Calling package must be configured in the device config");
2553 }
2554
2555 if (range == null) {
2556 throw new NullPointerException("Range must be non-null");
2557 }
2558
2559 timeoutMillis = Math.min(timeoutMillis,
Hall Liubd069e32019-02-28 18:56:30 -08002560 TelephonyManager.getMaxNumberVerificationTimeoutMillis());
Hall Liud892bec2018-11-30 14:51:45 -08002561
2562 NumberVerificationManager.getInstance().requestVerification(range, callback, timeoutMillis);
2563 }
2564
Junda Liuca05d5d2014-08-14 22:36:34 -07002565 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002566 * Returns true if CDMA provisioning needs to run.
2567 */
2568 public boolean needsOtaServiceProvisioning() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002569 final long identity = Binder.clearCallingIdentity();
2570 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002571 return getDefaultPhone().needsOtaServiceProvisioning();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002572 } finally {
2573 Binder.restoreCallingIdentity(identity);
2574 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002575 }
2576
2577 /**
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002578 * Sets the voice mail number of a given subId.
2579 */
2580 @Override
2581 public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002582 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setVoiceMailNumber");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002583
2584 final long identity = Binder.clearCallingIdentity();
2585 try {
2586 Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
2587 new Pair<String, String>(alphaTag, number), new Integer(subId));
2588 return success;
2589 } finally {
2590 Binder.restoreCallingIdentity(identity);
2591 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002592 }
2593
Ta-wei Yen87c49842016-05-13 21:19:52 -07002594 @Override
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002595 public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
2596 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002597 String systemDialer = TelecomManager.from(mApp).getSystemDialerPackage();
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002598 if (!TextUtils.equals(callingPackage, systemDialer)) {
2599 throw new SecurityException("caller must be system dialer");
2600 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002601
2602 final long identity = Binder.clearCallingIdentity();
2603 try {
2604 PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
2605 if (phoneAccountHandle == null) {
2606 return null;
2607 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002608 return VisualVoicemailSettingsUtil.dump(mApp, phoneAccountHandle);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002609 } finally {
2610 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002611 }
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002612 }
2613
2614 @Override
Ta-wei Yen409ac562017-03-06 16:00:44 -08002615 public String getVisualVoicemailPackageName(String callingPackage, int subId) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08002616 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jeff Davidson7e17e312018-02-13 18:17:36 -08002617 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002618 mApp, subId, callingPackage, "getVisualVoicemailPackageName")) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08002619 return null;
2620 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002621
Jeff Davidsona8e4e242018-03-15 17:16:18 -07002622 final long identity = Binder.clearCallingIdentity();
2623 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002624 return RemoteVvmTaskManager.getRemotePackage(mApp, subId).getPackageName();
Jeff Davidsona8e4e242018-03-15 17:16:18 -07002625 } finally {
2626 Binder.restoreCallingIdentity(identity);
2627 }
Ta-wei Yendca928f2017-01-10 16:17:08 -08002628 }
2629
2630 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002631 public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
2632 VisualVoicemailSmsFilterSettings settings) {
2633 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002634
2635 final long identity = Binder.clearCallingIdentity();
2636 try {
2637 VisualVoicemailSmsFilterConfig.enableVisualVoicemailSmsFilter(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002638 mApp, callingPackage, subId, settings);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002639 } finally {
2640 Binder.restoreCallingIdentity(identity);
2641 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002642 }
2643
2644 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002645 public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
2646 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002647
2648 final long identity = Binder.clearCallingIdentity();
2649 try {
2650 VisualVoicemailSmsFilterConfig.disableVisualVoicemailSmsFilter(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002651 mApp, callingPackage, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002652 } finally {
2653 Binder.restoreCallingIdentity(identity);
2654 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002655 }
2656
2657 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002658 public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
2659 String callingPackage, int subId) {
2660 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002661
2662 final long identity = Binder.clearCallingIdentity();
2663 try {
2664 return VisualVoicemailSmsFilterConfig.getVisualVoicemailSmsFilterSettings(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002665 mApp, callingPackage, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002666 } finally {
2667 Binder.restoreCallingIdentity(identity);
2668 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002669 }
2670
2671 @Override
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002672 public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002673 enforceReadPrivilegedPermission("getActiveVisualVoicemailSmsFilterSettings");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002674
2675 final long identity = Binder.clearCallingIdentity();
2676 try {
2677 return VisualVoicemailSmsFilterConfig.getActiveVisualVoicemailSmsFilterSettings(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002678 mApp, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002679 } finally {
2680 Binder.restoreCallingIdentity(identity);
2681 }
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002682 }
2683
2684 @Override
2685 public void sendVisualVoicemailSmsForSubscriber(String callingPackage, int subId,
2686 String number, int port, String text, PendingIntent sentIntent) {
2687 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Ta-wei Yen527a9c02017-01-06 15:29:25 -08002688 enforceVisualVoicemailPackage(callingPackage, subId);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002689 enforceSendSmsPermission();
Amit Mahajandccb3f12019-05-13 13:48:32 -07002690 SmsController smsController = PhoneFactory.getSmsController();
2691 smsController.sendVisualVoicemailSmsForSubscriber(callingPackage, subId, number, port, text,
2692 sentIntent);
Ta-wei Yen87c49842016-05-13 21:19:52 -07002693 }
Amit Mahajandccb3f12019-05-13 13:48:32 -07002694
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002695 /**
fionaxu0152e512016-11-14 13:36:14 -08002696 * Sets the voice activation state of a given subId.
2697 */
2698 @Override
2699 public void setVoiceActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002700 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2701 mApp, subId, "setVoiceActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002702
2703 final long identity = Binder.clearCallingIdentity();
2704 try {
2705 final Phone phone = getPhone(subId);
2706 if (phone != null) {
2707 phone.setVoiceActivationState(activationState);
2708 } else {
2709 loge("setVoiceActivationState fails with invalid subId: " + subId);
2710 }
2711 } finally {
2712 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002713 }
2714 }
2715
2716 /**
2717 * Sets the data activation state of a given subId.
2718 */
2719 @Override
2720 public void setDataActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002721 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2722 mApp, subId, "setDataActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002723
2724 final long identity = Binder.clearCallingIdentity();
2725 try {
2726 final Phone phone = getPhone(subId);
2727 if (phone != null) {
2728 phone.setDataActivationState(activationState);
2729 } else {
2730 loge("setVoiceActivationState fails with invalid subId: " + subId);
2731 }
2732 } finally {
2733 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002734 }
2735 }
2736
2737 /**
2738 * Returns the voice activation state of a given subId.
2739 */
2740 @Override
2741 public int getVoiceActivationState(int subId, String callingPackage) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002742 enforceReadPrivilegedPermission("getVoiceActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002743
fionaxu0152e512016-11-14 13:36:14 -08002744 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002745 final long identity = Binder.clearCallingIdentity();
2746 try {
2747 if (phone != null) {
2748 return phone.getVoiceActivationState();
2749 } else {
2750 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2751 }
2752 } finally {
2753 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002754 }
2755 }
2756
2757 /**
2758 * Returns the data activation state of a given subId.
2759 */
2760 @Override
2761 public int getDataActivationState(int subId, String callingPackage) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002762 enforceReadPrivilegedPermission("getDataActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002763
fionaxu0152e512016-11-14 13:36:14 -08002764 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002765 final long identity = Binder.clearCallingIdentity();
2766 try {
2767 if (phone != null) {
2768 return phone.getDataActivationState();
2769 } else {
2770 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2771 }
2772 } finally {
2773 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002774 }
2775 }
2776
2777 /**
Wink Saville36469e72014-06-11 15:17:00 -07002778 * Returns the unread count of voicemails for a subId
2779 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002780 @Override
Brad Ebingerf7664ba2018-11-29 12:43:38 -08002781 public int getVoiceMessageCountForSubscriber(int subId, String callingPackage) {
2782 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2783 mApp, subId, callingPackage, "getVoiceMessageCountForSubscriber")) {
2784 return 0;
2785 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002786 final long identity = Binder.clearCallingIdentity();
2787 try {
2788 final Phone phone = getPhone(subId);
2789 if (phone != null) {
2790 return phone.getVoiceMessageCount();
2791 } else {
2792 return 0;
2793 }
2794 } finally {
2795 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002796 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002797 }
2798
2799 /**
pkanwar8a4dcfb2017-01-19 13:43:16 -08002800 * returns true, if the device is in a state where both voice and data
2801 * are supported simultaneously. This can change based on location or network condition.
2802 */
2803 @Override
2804 public boolean isConcurrentVoiceAndDataAllowed(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002805 final long identity = Binder.clearCallingIdentity();
2806 try {
2807 final Phone phone = getPhone(subId);
2808 return (phone == null ? false : phone.isConcurrentVoiceAndDataAllowed());
2809 } finally {
2810 Binder.restoreCallingIdentity(identity);
2811 }
pkanwar8a4dcfb2017-01-19 13:43:16 -08002812 }
2813
2814 /**
fionaxu235cc5e2017-03-06 22:25:57 -08002815 * Send the dialer code if called from the current default dialer or the caller has
2816 * carrier privilege.
2817 * @param inputCode The dialer code to send
2818 */
2819 @Override
2820 public void sendDialerSpecialCode(String callingPackage, String inputCode) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002821 final Phone defaultPhone = getDefaultPhone();
fionaxu235cc5e2017-03-06 22:25:57 -08002822 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002823 String defaultDialer = TelecomManager.from(defaultPhone.getContext())
2824 .getDefaultDialerPackage();
fionaxu235cc5e2017-03-06 22:25:57 -08002825 if (!TextUtils.equals(callingPackage, defaultDialer)) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002826 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
2827 getDefaultSubscription(), "sendDialerSpecialCode");
fionaxu235cc5e2017-03-06 22:25:57 -08002828 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002829
2830 final long identity = Binder.clearCallingIdentity();
2831 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002832 defaultPhone.sendDialerSpecialCode(inputCode);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002833 } finally {
2834 Binder.restoreCallingIdentity(identity);
2835 }
fionaxu235cc5e2017-03-06 22:25:57 -08002836 }
2837
Pengquan Menga1bb6272018-09-06 09:59:22 -07002838 @Override
2839 public int getNetworkSelectionMode(int subId) {
Pengquan Menge92a50d2018-09-21 15:54:48 -07002840 if (!isActiveSubscription(subId)) {
2841 return TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
2842 }
2843
Pengquan Menga1bb6272018-09-06 09:59:22 -07002844 return (int) sendRequest(CMD_GET_NETWORK_SELECTION_MODE, null /* argument */, subId);
2845 }
2846
Brad Ebinger35c841c2018-10-01 10:40:55 -07002847 @Override
Brad Ebingerb2b65522019-03-15 13:48:47 -07002848 public boolean isInEmergencySmsMode() {
2849 enforceReadPrivilegedPermission("isInEmergencySmsMode");
2850 final long identity = Binder.clearCallingIdentity();
2851 try {
2852 for (Phone phone : PhoneFactory.getPhones()) {
2853 if (phone.isInEmergencySmsMode()) {
2854 return true;
2855 }
2856 }
2857 } finally {
2858 Binder.restoreCallingIdentity(identity);
2859 }
2860 return false;
2861 }
2862
2863 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08002864 public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback c)
2865 throws RemoteException {
2866 enforceReadPrivilegedPermission("registerImsRegistrationCallback");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002867 final long token = Binder.clearCallingIdentity();
2868 try {
Brad Ebinger4ae57f92019-01-09 16:51:30 -08002869 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002870 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger35c841c2018-10-01 10:40:55 -07002871 .addRegistrationCallbackForSubscription(c, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07002872 } catch (ImsException e) {
2873 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07002874 } finally {
2875 Binder.restoreCallingIdentity(token);
2876 }
2877 }
2878
2879 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08002880 public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c) {
2881 enforceReadPrivilegedPermission("unregisterImsRegistrationCallback");
Brad Ebinger4ae57f92019-01-09 16:51:30 -08002882 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2883 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
2884 }
2885 Binder.withCleanCallingIdentity(() -> {
2886 try {
2887 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002888 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08002889 .removeRegistrationCallbackForSubscription(c, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07002890 } catch (ImsException e) {
Brad Ebinger4ae57f92019-01-09 16:51:30 -08002891 Log.i(LOG_TAG, "unregisterImsRegistrationCallback: " + subId
2892 + "is inactive, ignoring unregister.");
2893 // If the subscription is no longer active, just return, since the callback
2894 // will already have been removed internally.
2895 }
2896 });
Brad Ebinger35c841c2018-10-01 10:40:55 -07002897 }
2898
2899 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08002900 public void registerMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)
2901 throws RemoteException {
2902 enforceReadPrivilegedPermission("registerMmTelCapabilityCallback");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002903 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2904 final long token = Binder.clearCallingIdentity();
2905 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002906 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger35c841c2018-10-01 10:40:55 -07002907 .addCapabilitiesCallbackForSubscription(c, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07002908 } catch (ImsException e) {
2909 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07002910 } finally {
2911 Binder.restoreCallingIdentity(token);
2912 }
2913 }
2914
2915 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08002916 public void unregisterMmTelCapabilityCallback(int subId, IImsCapabilityCallback c) {
2917 enforceReadPrivilegedPermission("unregisterMmTelCapabilityCallback");
Brad Ebinger4ae57f92019-01-09 16:51:30 -08002918
2919 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2920 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
2921 }
2922 Binder.withCleanCallingIdentity(() -> {
2923 try {
2924 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002925 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08002926 .removeCapabilitiesCallbackForSubscription(c, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07002927 } catch (ImsException e) {
Brad Ebinger4ae57f92019-01-09 16:51:30 -08002928 Log.i(LOG_TAG, "unregisterMmTelCapabilityCallback: " + subId
2929 + "is inactive, ignoring unregister.");
2930 // If the subscription is no longer active, just return, since the callback
2931 // will already have been removed internally.
2932 }
2933 });
Brad Ebinger35c841c2018-10-01 10:40:55 -07002934 }
2935
2936 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08002937 public boolean isCapable(int subId, int capability, int regTech) {
2938 enforceReadPrivilegedPermission("isCapable");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002939 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2940 final long token = Binder.clearCallingIdentity();
2941 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002942 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07002943 getSlotIndexOrException(subId)).queryMmTelCapability(capability, regTech);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07002944 } catch (com.android.ims.ImsException e) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002945 Log.w(LOG_TAG, "IMS isCapable - service unavailable: " + e.getMessage());
2946 return false;
Brad Ebinger1ce9c432019-07-16 13:19:44 -07002947 } catch (ImsException e) {
Brad Ebinger6b5ac222019-02-04 14:36:52 -08002948 Log.i(LOG_TAG, "isCapable: " + subId + " is inactive, returning false.");
2949 return false;
Brad Ebinger35c841c2018-10-01 10:40:55 -07002950 } finally {
2951 Binder.restoreCallingIdentity(token);
2952 }
2953 }
2954
2955 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08002956 public boolean isAvailable(int subId, int capability, int regTech) {
2957 enforceReadPrivilegedPermission("isAvailable");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002958 final long token = Binder.clearCallingIdentity();
2959 try {
2960 Phone phone = getPhone(subId);
2961 if (phone == null) return false;
2962 return phone.isImsCapabilityAvailable(capability, regTech);
2963 } finally {
2964 Binder.restoreCallingIdentity(token);
2965 }
2966 }
2967
2968 @Override
2969 public boolean isAdvancedCallingSettingEnabled(int subId) {
2970 enforceReadPrivilegedPermission("enforceReadPrivilegedPermission");
2971 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2972 final long token = Binder.clearCallingIdentity();
2973 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002974 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07002975 getSlotIndexOrException(subId)).isEnhanced4gLteModeSettingEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07002976 } catch (ImsException e) {
2977 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07002978 } finally {
2979 Binder.restoreCallingIdentity(token);
2980 }
2981 }
2982
2983 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08002984 public void setAdvancedCallingSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002985 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08002986 "setAdvancedCallingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002987 final long identity = Binder.clearCallingIdentity();
2988 try {
2989 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002990 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07002991 getSlotIndexOrException(subId)).setEnhanced4gLteModeSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07002992 } catch (ImsException e) {
2993 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07002994 } finally {
2995 Binder.restoreCallingIdentity(identity);
2996 }
2997 }
2998
2999 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003000 public boolean isVtSettingEnabled(int subId) {
3001 enforceReadPrivilegedPermission("isVtSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003002 final long identity = Binder.clearCallingIdentity();
3003 try {
3004 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003005 return ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).isVtEnabledByUser();
3006 } catch (ImsException e) {
3007 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003008 } finally {
3009 Binder.restoreCallingIdentity(identity);
3010 }
3011 }
3012
3013 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08003014 public void setVtSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003015 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08003016 "setVtSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003017 final long identity = Binder.clearCallingIdentity();
3018 try {
3019 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003020 ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setVtSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003021 } catch (ImsException e) {
3022 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003023 } finally {
3024 Binder.restoreCallingIdentity(identity);
3025 }
3026 }
3027
3028 @Override
3029 public boolean isVoWiFiSettingEnabled(int subId) {
3030 enforceReadPrivilegedPermission("isVoWiFiSettingEnabled");
3031 final long identity = Binder.clearCallingIdentity();
3032 try {
3033 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003034 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003035 getSlotIndexOrException(subId)).isWfcEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003036 } catch (ImsException e) {
3037 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003038 } finally {
3039 Binder.restoreCallingIdentity(identity);
3040 }
3041 }
3042
3043 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08003044 public void setVoWiFiSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003045 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08003046 "setVoWiFiSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003047 final long identity = Binder.clearCallingIdentity();
3048 try {
3049 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003050 ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setWfcSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003051 } catch (ImsException e) {
3052 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003053 } finally {
3054 Binder.restoreCallingIdentity(identity);
3055 }
3056 }
3057
3058 @Override
3059 public boolean isVoWiFiRoamingSettingEnabled(int subId) {
3060 enforceReadPrivilegedPermission("isVoWiFiRoamingSettingEnabled");
3061 final long identity = Binder.clearCallingIdentity();
3062 try {
3063 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003064 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003065 getSlotIndexOrException(subId)).isWfcRoamingEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003066 } catch (ImsException e) {
3067 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003068 } finally {
3069 Binder.restoreCallingIdentity(identity);
3070 }
3071 }
3072
3073 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08003074 public void setVoWiFiRoamingSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003075 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08003076 "setVoWiFiRoamingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003077 final long identity = Binder.clearCallingIdentity();
3078 try {
3079 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003080 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003081 getSlotIndexOrException(subId)).setWfcRoamingSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003082 } catch (ImsException e) {
3083 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003084 } finally {
3085 Binder.restoreCallingIdentity(identity);
3086 }
3087 }
3088
3089 @Override
3090 public void setVoWiFiNonPersistent(int subId, boolean isCapable, int mode) {
3091 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3092 "setVoWiFiNonPersistent");
3093 final long identity = Binder.clearCallingIdentity();
3094 try {
3095 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003096 ImsManager.getInstance(mApp,
Brad Ebinger2d29c012019-05-07 18:33:46 -07003097 getSlotIndexOrException(subId)).setWfcNonPersistent(isCapable, mode);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003098 } catch (ImsException e) {
3099 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003100 } finally {
3101 Binder.restoreCallingIdentity(identity);
3102 }
3103 }
3104
3105 @Override
3106 public int getVoWiFiModeSetting(int subId) {
3107 enforceReadPrivilegedPermission("getVoWiFiModeSetting");
3108 final long identity = Binder.clearCallingIdentity();
3109 try {
3110 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003111 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003112 getSlotIndexOrException(subId)).getWfcMode(false /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003113 } catch (ImsException e) {
3114 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003115 } finally {
3116 Binder.restoreCallingIdentity(identity);
3117 }
3118 }
3119
3120 @Override
3121 public void setVoWiFiModeSetting(int subId, int mode) {
3122 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3123 "setVoWiFiModeSetting");
3124 final long identity = Binder.clearCallingIdentity();
3125 try {
3126 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003127 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003128 getSlotIndexOrException(subId)).setWfcMode(mode, false /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003129 } catch (ImsException e) {
3130 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003131 } finally {
3132 Binder.restoreCallingIdentity(identity);
3133 }
3134 }
3135
3136 @Override
3137 public int getVoWiFiRoamingModeSetting(int subId) {
3138 enforceReadPrivilegedPermission("getVoWiFiRoamingModeSetting");
3139 final long identity = Binder.clearCallingIdentity();
3140 try {
3141 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003142 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003143 getSlotIndexOrException(subId)).getWfcMode(true /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003144 } catch (ImsException e) {
3145 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003146 } finally {
3147 Binder.restoreCallingIdentity(identity);
3148 }
3149 }
3150
3151 @Override
3152 public void setVoWiFiRoamingModeSetting(int subId, int mode) {
3153 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3154 "setVoWiFiRoamingModeSetting");
3155 final long identity = Binder.clearCallingIdentity();
3156 try {
3157 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003158 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003159 getSlotIndexOrException(subId)).setWfcMode(mode, true /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003160 } catch (ImsException e) {
3161 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003162 } finally {
3163 Binder.restoreCallingIdentity(identity);
3164 }
3165 }
3166
3167 @Override
3168 public void setRttCapabilitySetting(int subId, boolean isEnabled) {
3169 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3170 "setRttCapabilityEnabled");
3171 final long identity = Binder.clearCallingIdentity();
3172 try {
3173 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003174 ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setRttEnabled(isEnabled);
3175 } catch (ImsException e) {
3176 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003177 } finally {
3178 Binder.restoreCallingIdentity(identity);
3179 }
3180 }
3181
3182 @Override
3183 public boolean isTtyOverVolteEnabled(int subId) {
3184 enforceReadPrivilegedPermission("isTtyOverVolteEnabled");
3185 final long identity = Binder.clearCallingIdentity();
3186 try {
3187 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003188 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003189 getSlotIndexOrException(subId)).isTtyOnVoLteCapable();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003190 } catch (ImsException e) {
3191 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003192 } finally {
3193 Binder.restoreCallingIdentity(identity);
3194 }
3195 }
3196
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003197 @Override
3198 public void registerImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
3199 enforceReadPrivilegedPermission("registerImsProvisioningChangedCallback");
3200 final long identity = Binder.clearCallingIdentity();
3201 try {
3202 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003203 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003204 .addProvisioningCallbackForSubscription(callback, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003205 } catch (ImsException e) {
3206 throw new ServiceSpecificException(e.getCode());
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003207 } finally {
3208 Binder.restoreCallingIdentity(identity);
3209 }
3210 }
3211
3212 @Override
3213 public void unregisterImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
3214 enforceReadPrivilegedPermission("unregisterImsProvisioningChangedCallback");
3215 final long identity = Binder.clearCallingIdentity();
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003216 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3217 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
3218 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003219 try {
3220 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003221 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003222 .removeProvisioningCallbackForSubscription(callback, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003223 } catch (ImsException e) {
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003224 Log.i(LOG_TAG, "unregisterImsProvisioningChangedCallback: " + subId
3225 + "is inactive, ignoring unregister.");
3226 // If the subscription is no longer active, just return, since the callback will already
3227 // have been removed internally.
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003228 } finally {
3229 Binder.restoreCallingIdentity(identity);
3230 }
3231 }
3232
3233 @Override
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003234 public void setImsProvisioningStatusForCapability(int subId, int capability, int tech,
3235 boolean isProvisioned) {
3236 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3237 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3238 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
3239 }
3240 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3241 "setProvisioningStatusForCapability");
3242 final long identity = Binder.clearCallingIdentity();
3243 try {
3244 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3245 Phone phone = getPhone(subId);
3246 if (phone == null) {
3247 loge("setImsProvisioningStatusForCapability: phone instance null for subid "
3248 + subId);
3249 return;
3250 }
3251 if (!doesImsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
3252 return;
3253 }
3254
3255 // this capability requires provisioning, route to the correct API.
3256 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
3257 switch (capability) {
3258 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
3259 if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3260 ims.setVolteProvisioned(isProvisioned);
3261 } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
3262 ims.setWfcProvisioned(isProvisioned);
3263 }
3264 break;
3265 }
3266 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
3267 // There is currently no difference in VT provisioning type.
3268 ims.setVtProvisioned(isProvisioned);
3269 break;
3270 }
3271 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
3272 // There is no "deprecated" UT provisioning mechanism through ImsConfig, so
3273 // change the capability of the feature instead if needed.
3274 if (isMmTelCapabilityProvisionedInCache(subId, capability, tech)
3275 == isProvisioned) {
3276 // No change in provisioning.
3277 return;
3278 }
3279 cacheMmTelCapabilityProvisioning(subId, capability, tech, isProvisioned);
3280 try {
3281 ims.changeMmTelCapability(capability, tech, isProvisioned);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003282 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003283 loge("setImsProvisioningStatusForCapability: couldn't change UT capability"
3284 + ", Exception" + e.getMessage());
3285 }
3286 break;
3287 }
3288 default: {
3289 throw new IllegalArgumentException("Tried to set provisioning for capability '"
3290 + capability + "', which does not require provisioning.");
3291 }
3292 }
3293
3294 } finally {
3295 Binder.restoreCallingIdentity(identity);
3296 }
3297 }
3298
3299 @Override
3300 public boolean getImsProvisioningStatusForCapability(int subId, int capability, int tech) {
3301 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3302 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3303 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
3304 }
3305 enforceReadPrivilegedPermission("getProvisioningStatusForCapability");
3306 final long identity = Binder.clearCallingIdentity();
3307 try {
3308 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3309 Phone phone = getPhone(subId);
3310 if (phone == null) {
3311 loge("getImsProvisioningStatusForCapability: phone instance null for subid "
3312 + subId);
3313 // We will fail with "true" as the provisioning status because this is the default
3314 // if we do not require provisioning.
3315 return true;
3316 }
3317
3318 if (!doesImsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
3319 return true;
3320 }
3321
3322 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
3323 switch (capability) {
3324 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
3325 if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3326 return ims.isVolteProvisionedOnDevice();
3327 } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
3328 return ims.isWfcProvisionedOnDevice();
3329 }
3330 // This should never happen, since we are checking tech above to make sure it
3331 // is either LTE or IWLAN.
3332 throw new IllegalArgumentException("Invalid radio technology for voice "
3333 + "capability.");
3334 }
3335 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
3336 // There is currently no difference in VT provisioning type.
3337 return ims.isVtProvisionedOnDevice();
3338 }
3339 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
3340 // There is no "deprecated" UT provisioning mechanism, so get from shared prefs.
3341 return isMmTelCapabilityProvisionedInCache(subId, capability, tech);
3342 }
3343 default: {
3344 throw new IllegalArgumentException("Tried to get provisioning for capability '"
3345 + capability + "', which does not require provisioning.");
3346 }
3347 }
3348
3349 } finally {
3350 Binder.restoreCallingIdentity(identity);
3351 }
3352 }
3353
3354 @Override
3355 public boolean isMmTelCapabilityProvisionedInCache(int subId, int capability, int tech) {
3356 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3357 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3358 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
3359 }
3360 enforceReadPrivilegedPermission("isMmTelCapabilityProvisionedInCache");
3361 int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
3362 return (provisionedBits & capability) > 0;
3363 }
3364
3365 @Override
3366 public void cacheMmTelCapabilityProvisioning(int subId, int capability, int tech,
3367 boolean isProvisioned) {
3368 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3369 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3370 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
3371 }
3372 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3373 "setProvisioningStatusForCapability");
3374 int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
3375 // If the current provisioning status for capability already matches isProvisioned,
3376 // do nothing.
3377 if (((provisionedBits & capability) > 0) == isProvisioned) {
3378 return;
3379 }
3380 if (isProvisioned) {
3381 setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits | capability));
3382 } else {
3383 setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits & ~capability));
3384 }
3385 }
3386
3387 /**
3388 * @return the bitfield containing the MmTel provisioning for the provided subscription and
3389 * technology. The bitfield should mirror the bitfield defined by
3390 * {@link MmTelFeature.MmTelCapabilities.MmTelCapability}.
3391 */
3392 private int getMmTelCapabilityProvisioningBitfield(int subId, int tech) {
3393 String key = getMmTelProvisioningKey(subId, tech);
3394 // Default is no capabilities are provisioned.
3395 return mTelephonySharedPreferences.getInt(key, 0 /*default*/);
3396 }
3397
3398 /**
3399 * Sets the MmTel capability provisioning bitfield (defined by
3400 * {@link MmTelFeature.MmTelCapabilities.MmTelCapability}) for the subscription and
3401 * technology specified.
3402 *
3403 * Note: This is a synchronous command and should not be called on UI thread.
3404 */
3405 private void setMmTelCapabilityProvisioningBitfield(int subId, int tech, int newField) {
3406 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
3407 String key = getMmTelProvisioningKey(subId, tech);
3408 editor.putInt(key, newField);
3409 editor.commit();
3410 }
3411
3412 private static String getMmTelProvisioningKey(int subId, int tech) {
3413 // resulting key is provision_ims_mmtel_{subId}_{tech}
3414 return PREF_PROVISION_IMS_MMTEL_PREFIX + subId + "_" + tech;
3415 }
3416
3417 /**
3418 * Query CarrierConfig to see if the specified capability requires provisioning for the
3419 * carrier associated with the subscription id.
3420 */
3421 private boolean doesImsCapabilityRequireProvisioning(Context context, int subId,
3422 int capability) {
3423 CarrierConfigManager configManager = new CarrierConfigManager(context);
3424 PersistableBundle c = configManager.getConfigForSubId(subId);
3425 boolean requireUtProvisioning = c.getBoolean(
Brad Ebinger076903f2019-05-13 10:00:22 -07003426 CarrierConfigManager.KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL, false)
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003427 && c.getBoolean(CarrierConfigManager.KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL,
3428 false);
3429 boolean requireVoiceVtProvisioning = c.getBoolean(
3430 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, false);
3431
3432 // First check to make sure that the capability requires provisioning.
3433 switch (capability) {
3434 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE:
3435 // intentional fallthrough
3436 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
3437 if (requireVoiceVtProvisioning) {
3438 // Voice and Video requires provisioning
3439 return true;
3440 }
3441 break;
3442 }
3443 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
3444 if (requireUtProvisioning) {
3445 // UT requires provisioning
3446 return true;
3447 }
3448 break;
3449 }
3450 }
3451 return false;
3452 }
3453
3454 @Override
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003455 public int getImsProvisioningInt(int subId, int key) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003456 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3457 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
3458 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003459 enforceReadPrivilegedPermission("getImsProvisioningInt");
3460 final long identity = Binder.clearCallingIdentity();
3461 try {
3462 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003463 int slotId = getSlotIndex(subId);
3464 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
3465 Log.w(LOG_TAG, "getImsProvisioningInt: called with an inactive subscription '"
3466 + subId + "' for key:" + key);
3467 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
3468 }
3469 return ImsManager.getInstance(mApp, slotId).getConfigInterface().getConfigInt(key);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003470 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003471 Log.w(LOG_TAG, "getImsProvisioningInt: ImsService is not available for subscription '"
3472 + subId + "' for key:" + key);
3473 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003474 } finally {
3475 Binder.restoreCallingIdentity(identity);
3476 }
3477 }
3478
3479 @Override
3480 public String getImsProvisioningString(int subId, int key) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003481 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3482 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
3483 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003484 enforceReadPrivilegedPermission("getImsProvisioningString");
3485 final long identity = Binder.clearCallingIdentity();
3486 try {
3487 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003488 int slotId = getSlotIndex(subId);
3489 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
3490 Log.w(LOG_TAG, "getImsProvisioningString: called for an inactive subscription id '"
3491 + subId + "' for key:" + key);
3492 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_GENERIC;
3493 }
3494 return ImsManager.getInstance(mApp, slotId).getConfigInterface().getConfigString(key);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003495 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003496 Log.w(LOG_TAG, "getImsProvisioningString: ImsService is not available for sub '"
3497 + subId + "' for key:" + key);
3498 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_NOT_READY;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003499 } finally {
3500 Binder.restoreCallingIdentity(identity);
3501 }
3502 }
3503
3504 @Override
3505 public int setImsProvisioningInt(int subId, int key, int value) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003506 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3507 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
3508 }
Brad Ebinger3d0b34e2018-11-15 14:13:12 -08003509 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3510 "setImsProvisioningInt");
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003511 final long identity = Binder.clearCallingIdentity();
3512 try {
3513 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003514 int slotId = getSlotIndex(subId);
3515 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
3516 Log.w(LOG_TAG, "setImsProvisioningInt: called with an inactive subscription id '"
3517 + subId + "' for key:" + key);
3518 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
3519 }
3520 return ImsManager.getInstance(mApp, slotId).getConfigInterface().setConfig(key, value);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003521 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003522 Log.w(LOG_TAG, "setImsProvisioningInt: ImsService unavailable for sub '" + subId
3523 + "' for key:" + key);
3524 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003525 } finally {
3526 Binder.restoreCallingIdentity(identity);
3527 }
3528 }
3529
3530 @Override
3531 public int setImsProvisioningString(int subId, int key, String value) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003532 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3533 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
3534 }
Brad Ebinger3d0b34e2018-11-15 14:13:12 -08003535 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3536 "setImsProvisioningString");
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003537 final long identity = Binder.clearCallingIdentity();
3538 try {
3539 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003540 int slotId = getSlotIndex(subId);
3541 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
3542 Log.w(LOG_TAG, "setImsProvisioningString: called with an inactive subscription id '"
3543 + subId + "' for key:" + key);
3544 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
3545 }
3546 return ImsManager.getInstance(mApp, slotId).getConfigInterface().setConfig(key, value);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003547 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003548 Log.w(LOG_TAG, "setImsProvisioningString: ImsService unavailable for sub '" + subId
3549 + "' for key:" + key);
3550 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003551 } finally {
3552 Binder.restoreCallingIdentity(identity);
3553 }
3554 }
3555
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003556 private int getSlotIndexOrException(int subId) throws ImsException {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003557 int slotId = SubscriptionManager.getSlotIndex(subId);
3558 if (!SubscriptionManager.isValidSlotIndex(slotId)) {
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003559 throw new ImsException("Invalid Subscription Id, subId=" + subId,
3560 ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
Brad Ebinger35c841c2018-10-01 10:40:55 -07003561 }
3562 return slotId;
3563 }
3564
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003565 private int getSlotIndex(int subId) {
3566 int slotId = SubscriptionManager.getSlotIndex(subId);
3567 if (!SubscriptionManager.isValidSlotIndex(slotId)) {
3568 return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
3569 }
3570 return slotId;
3571 }
3572
Wink Saville36469e72014-06-11 15:17:00 -07003573 /**
Nathan Harold9042f0b2019-05-21 15:51:27 -07003574 * Returns the data network type for a subId; does not throw SecurityException.
Wink Saville36469e72014-06-11 15:17:00 -07003575 */
3576 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003577 public int getNetworkTypeForSubscriber(int subId, String callingPackage) {
Nathan Haroldef60dba2019-05-22 13:55:14 -07003578 final int targetSdk = getTargetSdk(callingPackage);
3579 if (targetSdk > android.os.Build.VERSION_CODES.Q) {
3580 return getDataNetworkTypeForSubscriber(subId, callingPackage);
3581 } else if (targetSdk == android.os.Build.VERSION_CODES.Q
Nathan Harold9042f0b2019-05-21 15:51:27 -07003582 && !TelephonyPermissions.checkCallingOrSelfReadPhoneStateNoThrow(
3583 mApp, subId, callingPackage, "getNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003584 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3585 }
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07003586
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003587 final long identity = Binder.clearCallingIdentity();
3588 try {
3589 final Phone phone = getPhone(subId);
3590 if (phone != null) {
3591 return phone.getServiceState().getDataNetworkType();
3592 } else {
3593 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3594 }
3595 } finally {
3596 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003597 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003598 }
3599
3600 /**
3601 * Returns the data network type
3602 */
3603 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003604 public int getDataNetworkType(String callingPackage) {
3605 return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07003606 }
3607
3608 /**
3609 * Returns the data network type for a subId
3610 */
3611 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003612 public int getDataNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003613 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003614 mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003615 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3616 }
3617
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003618 final long identity = Binder.clearCallingIdentity();
3619 try {
3620 final Phone phone = getPhone(subId);
3621 if (phone != null) {
3622 return phone.getServiceState().getDataNetworkType();
3623 } else {
3624 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3625 }
3626 } finally {
3627 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003628 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003629 }
3630
3631 /**
Wink Saville36469e72014-06-11 15:17:00 -07003632 * Returns the Voice network type for a subId
3633 */
3634 @Override
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07003635 public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003636 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003637 mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07003638 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3639 }
3640
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003641 final long identity = Binder.clearCallingIdentity();
3642 try {
3643 final Phone phone = getPhone(subId);
3644 if (phone != null) {
3645 return phone.getServiceState().getVoiceNetworkType();
3646 } else {
3647 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3648 }
3649 } finally {
3650 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003651 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003652 }
3653
3654 /**
3655 * @return true if a ICC card is present
3656 */
3657 public boolean hasIccCard() {
Wink Saville36469e72014-06-11 15:17:00 -07003658 // FIXME Make changes to pass defaultSimId of type int
Sanket Padawe13bac7b2017-03-20 15:04:47 -07003659 return hasIccCardUsingSlotIndex(mSubscriptionController.getSlotIndex(
3660 getDefaultSubscription()));
Wink Saville36469e72014-06-11 15:17:00 -07003661 }
3662
3663 /**
Sanket Padawe13bac7b2017-03-20 15:04:47 -07003664 * @return true if a ICC card is present for a slotIndex
Wink Saville36469e72014-06-11 15:17:00 -07003665 */
Sanket Padawe356d7632015-06-22 14:03:32 -07003666 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07003667 public boolean hasIccCardUsingSlotIndex(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003668 final long identity = Binder.clearCallingIdentity();
3669 try {
3670 final Phone phone = PhoneFactory.getPhone(slotIndex);
3671 if (phone != null) {
3672 return phone.getIccCard().hasIccCard();
3673 } else {
3674 return false;
3675 }
3676 } finally {
3677 Binder.restoreCallingIdentity(identity);
Amit Mahajana6fc2a82015-01-06 11:53:51 -08003678 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003679 }
3680
3681 /**
3682 * Return if the current radio is LTE on CDMA. This
3683 * is a tri-state return value as for a period of time
3684 * the mode may be unknown.
3685 *
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003686 * @param callingPackage the name of the package making the call.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003687 * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
Jake Hambye994d462014-02-03 13:10:13 -08003688 * or {@link Phone#LTE_ON_CDMA_TRUE}
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003689 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003690 @Override
3691 public int getLteOnCdmaMode(String callingPackage) {
3692 return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07003693 }
3694
Sanket Padawe356d7632015-06-22 14:03:32 -07003695 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003696 public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003697 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003698 mApp, subId, callingPackage, "getLteOnCdmaModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003699 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
3700 }
3701
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003702 final long identity = Binder.clearCallingIdentity();
3703 try {
3704 final Phone phone = getPhone(subId);
3705 if (phone == null) {
3706 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
3707 } else {
3708 return phone.getLteOnCdmaMode();
3709 }
3710 } finally {
3711 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003712 }
Wink Saville36469e72014-06-11 15:17:00 -07003713 }
3714
Wink Saville36469e72014-06-11 15:17:00 -07003715 /**
3716 * {@hide}
3717 * Returns Default subId, 0 in the case of single standby.
3718 */
Wink Savilleb564aae2014-10-23 10:18:09 -07003719 private int getDefaultSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08003720 return mSubscriptionController.getDefaultSubId();
Wink Saville36469e72014-06-11 15:17:00 -07003721 }
3722
Shishir Agrawala9f32182016-04-12 12:00:16 -07003723 private int getSlotForDefaultSubscription() {
3724 return mSubscriptionController.getPhoneId(getDefaultSubscription());
3725 }
3726
Wink Savilleb564aae2014-10-23 10:18:09 -07003727 private int getPreferredVoiceSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08003728 return mSubscriptionController.getDefaultVoiceSubId();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003729 }
Ihab Awadf2177b72013-11-25 13:33:23 -08003730
Pengquan Menge92a50d2018-09-21 15:54:48 -07003731 private boolean isActiveSubscription(int subId) {
3732 return mSubscriptionController.isActiveSubId(subId);
3733 }
3734
Ihab Awadf2177b72013-11-25 13:33:23 -08003735 /**
3736 * @see android.telephony.TelephonyManager.WifiCallingChoices
3737 */
3738 public int getWhenToMakeWifiCalls() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003739 final long identity = Binder.clearCallingIdentity();
3740 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003741 return Settings.System.getInt(mApp.getContentResolver(),
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003742 Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
3743 getWhenToMakeWifiCallsDefaultPreference());
3744 } finally {
3745 Binder.restoreCallingIdentity(identity);
3746 }
Ihab Awadf2177b72013-11-25 13:33:23 -08003747 }
3748
3749 /**
3750 * @see android.telephony.TelephonyManager.WifiCallingChoices
3751 */
3752 public void setWhenToMakeWifiCalls(int preference) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003753 final long identity = Binder.clearCallingIdentity();
3754 try {
3755 if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003756 Settings.System.putInt(mApp.getContentResolver(),
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003757 Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference);
3758 } finally {
3759 Binder.restoreCallingIdentity(identity);
3760 }
Ihab Awadf9e92732013-12-05 18:02:52 -08003761 }
3762
Sailesh Nepald1e68152013-12-12 19:08:02 -08003763 private static int getWhenToMakeWifiCallsDefaultPreference() {
Santos Cordonda120f42014-08-06 04:44:34 -07003764 // TODO: Use a build property to choose this value.
Evan Charlton9829e882013-12-19 15:30:38 -08003765 return TelephonyManager.WifiCallingChoices.ALWAYS_USE;
Ihab Awadf2177b72013-11-25 13:33:23 -08003766 }
Shishir Agrawal69f68122013-12-16 17:25:49 -08003767
Jordan Liu4c733742019-02-28 12:03:40 -08003768 private Phone getPhoneFromSlotIdOrThrowException(int slotIndex) {
3769 int phoneId = UiccController.getInstance().getPhoneIdFromSlotId(slotIndex);
3770 if (phoneId == -1) {
3771 throw new IllegalArgumentException("Given slot index: " + slotIndex
3772 + " does not correspond to an active phone");
3773 }
3774 return PhoneFactory.getPhone(phoneId);
3775 }
3776
Shishir Agrawal566b7612013-10-28 14:41:00 -07003777 @Override
Derek Tan740e1672017-06-27 14:56:27 -07003778 public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
3779 int subId, String callingPackage, String aid, int p2) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003780 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3781 mApp, subId, "iccOpenLogicalChannel");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003782 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jordan Liu4c733742019-02-28 12:03:40 -08003783 if (DBG) {
3784 log("iccOpenLogicalChannel: subId=" + subId + " aid=" + aid + " p2=" + p2);
3785 }
3786 return iccOpenLogicalChannelWithPermission(getPhoneFromSubId(subId), callingPackage, aid,
3787 p2);
3788 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003789
Jordan Liu4c733742019-02-28 12:03:40 -08003790
3791 @Override
3792 public IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(
3793 int slotIndex, String callingPackage, String aid, int p2) {
3794 enforceModifyPermission();
3795 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3796 if (DBG) {
3797 log("iccOpenLogicalChannelBySlot: slot=" + slotIndex + " aid=" + aid + " p2=" + p2);
3798 }
3799 return iccOpenLogicalChannelWithPermission(getPhoneFromSlotIdOrThrowException(slotIndex),
3800 callingPackage, aid, p2);
3801 }
3802
3803 private IccOpenLogicalChannelResponse iccOpenLogicalChannelWithPermission(Phone phone,
3804 String callingPackage, String aid, int p2) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003805 final long identity = Binder.clearCallingIdentity();
3806 try {
3807 if (TextUtils.equals(ISDR_AID, aid)) {
3808 // Only allows LPA to open logical channel to ISD-R.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003809 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
3810 .getContext().getPackageManager());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003811 if (bestComponent == null
3812 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
3813 loge("The calling package is not allowed to access ISD-R.");
3814 throw new SecurityException(
3815 "The calling package is not allowed to access ISD-R.");
3816 }
Derek Tan740e1672017-06-27 14:56:27 -07003817 }
Derek Tan740e1672017-06-27 14:56:27 -07003818
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003819 IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse) sendRequest(
Jordan Liu4c733742019-02-28 12:03:40 -08003820 CMD_OPEN_CHANNEL, new Pair<String, Integer>(aid, p2), phone,
3821 null /* workSource */);
3822 if (DBG) log("iccOpenLogicalChannelWithPermission: " + response);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003823 return response;
3824 } finally {
3825 Binder.restoreCallingIdentity(identity);
3826 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003827 }
3828
3829 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003830 public boolean iccCloseLogicalChannel(int subId, int channel) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003831 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3832 mApp, subId, "iccCloseLogicalChannel");
Jordan Liu4c733742019-02-28 12:03:40 -08003833 if (DBG) log("iccCloseLogicalChannel: subId=" + subId + " chnl=" + channel);
3834 return iccCloseLogicalChannelWithPermission(getPhoneFromSubId(subId), channel);
3835 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003836
Jordan Liu4c733742019-02-28 12:03:40 -08003837 @Override
3838 public boolean iccCloseLogicalChannelBySlot(int slotIndex, int channel) {
3839 enforceModifyPermission();
3840 if (DBG) log("iccCloseLogicalChannelBySlot: slotIndex=" + slotIndex + " chnl=" + channel);
3841 return iccCloseLogicalChannelWithPermission(getPhoneFromSlotIdOrThrowException(slotIndex),
3842 channel);
3843 }
3844
3845 private boolean iccCloseLogicalChannelWithPermission(Phone phone, int channel) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003846 final long identity = Binder.clearCallingIdentity();
3847 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003848 if (channel < 0) {
3849 return false;
3850 }
Jordan Liu4c733742019-02-28 12:03:40 -08003851 Boolean success = (Boolean) sendRequest(CMD_CLOSE_CHANNEL, channel, phone,
3852 null /* workSource */);
3853 if (DBG) log("iccCloseLogicalChannelWithPermission: " + success);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003854 return success;
3855 } finally {
3856 Binder.restoreCallingIdentity(identity);
Shishir Agrawal566b7612013-10-28 14:41:00 -07003857 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003858 }
3859
3860 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003861 public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
Shishir Agrawal566b7612013-10-28 14:41:00 -07003862 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003863 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3864 mApp, subId, "iccTransmitApduLogicalChannel");
Jordan Liu4c733742019-02-28 12:03:40 -08003865 if (DBG) {
3866 log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel
3867 + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
3868 + p3 + " data=" + data);
3869 }
3870 return iccTransmitApduLogicalChannelWithPermission(getPhoneFromSubId(subId), channel, cla,
3871 command, p1, p2, p3, data);
3872 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003873
Jordan Liu4c733742019-02-28 12:03:40 -08003874 @Override
3875 public String iccTransmitApduLogicalChannelBySlot(int slotIndex, int channel, int cla,
3876 int command, int p1, int p2, int p3, String data) {
3877 enforceModifyPermission();
3878 if (DBG) {
3879 log("iccTransmitApduLogicalChannelBySlot: slotIndex=" + slotIndex + " chnl=" + channel
3880 + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
3881 + p3 + " data=" + data);
3882 }
3883 return iccTransmitApduLogicalChannelWithPermission(
3884 getPhoneFromSlotIdOrThrowException(slotIndex), channel, cla, command, p1, p2, p3,
3885 data);
3886 }
3887
3888 private String iccTransmitApduLogicalChannelWithPermission(Phone phone, int channel, int cla,
3889 int command, int p1, int p2, int p3, String data) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003890 final long identity = Binder.clearCallingIdentity();
3891 try {
Hall Liu4fd771b2019-05-02 09:16:29 -07003892 if (channel <= 0) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003893 return "";
3894 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003895
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003896 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL,
Jordan Liu4c733742019-02-28 12:03:40 -08003897 new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), phone,
3898 null /* workSource */);
3899 if (DBG) log("iccTransmitApduLogicalChannelWithPermission: " + response);
Shishir Agrawal566b7612013-10-28 14:41:00 -07003900
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003901 // Append the returned status code to the end of the response payload.
3902 String s = Integer.toHexString(
3903 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
3904 if (response.payload != null) {
3905 s = IccUtils.bytesToHexString(response.payload) + s;
3906 }
3907 return s;
3908 } finally {
3909 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07003910 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003911 }
Jake Hambye994d462014-02-03 13:10:13 -08003912
Evan Charltonc66da362014-05-16 14:06:40 -07003913 @Override
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08003914 public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
3915 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003916 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3917 mApp, subId, "iccTransmitApduBasicChannel");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003918 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jordan Liu4c733742019-02-28 12:03:40 -08003919 if (DBG) {
3920 log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd="
3921 + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
3922 }
3923 return iccTransmitApduBasicChannelWithPermission(getPhoneFromSubId(subId), callingPackage,
3924 cla, command, p1, p2, p3, data);
3925 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003926
Jordan Liu4c733742019-02-28 12:03:40 -08003927 @Override
3928 public String iccTransmitApduBasicChannelBySlot(int slotIndex, String callingPackage, int cla,
3929 int command, int p1, int p2, int p3, String data) {
3930 enforceModifyPermission();
3931 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3932 if (DBG) {
3933 log("iccTransmitApduBasicChannelBySlot: slotIndex=" + slotIndex + " cla=" + cla
3934 + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3
3935 + " data=" + data);
3936 }
3937
3938 return iccTransmitApduBasicChannelWithPermission(
3939 getPhoneFromSlotIdOrThrowException(slotIndex), callingPackage, cla, command, p1,
3940 p2, p3, data);
3941 }
3942
3943 // open APDU basic channel assuming the caller has sufficient permissions
3944 private String iccTransmitApduBasicChannelWithPermission(Phone phone, String callingPackage,
3945 int cla, int command, int p1, int p2, int p3, String data) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003946 final long identity = Binder.clearCallingIdentity();
3947 try {
3948 if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
3949 && TextUtils.equals(ISDR_AID, data)) {
3950 // Only allows LPA to select ISD-R.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003951 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
3952 .getContext().getPackageManager());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003953 if (bestComponent == null
3954 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
3955 loge("The calling package is not allowed to select ISD-R.");
3956 throw new SecurityException(
3957 "The calling package is not allowed to select ISD-R.");
3958 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08003959 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08003960
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003961 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL,
Jordan Liu4c733742019-02-28 12:03:40 -08003962 new IccAPDUArgument(0, cla, command, p1, p2, p3, data), phone,
3963 null /* workSource */);
3964 if (DBG) log("iccTransmitApduBasicChannelWithPermission: " + response);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003965
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003966 // Append the returned status code to the end of the response payload.
3967 String s = Integer.toHexString(
3968 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
3969 if (response.payload != null) {
3970 s = IccUtils.bytesToHexString(response.payload) + s;
3971 }
3972 return s;
3973 } finally {
3974 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07003975 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003976 }
3977
3978 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003979 public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003980 String filePath) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003981 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3982 mApp, subId, "iccExchangeSimIO");
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003983
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003984 final long identity = Binder.clearCallingIdentity();
3985 try {
3986 if (DBG) {
3987 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " "
3988 + p1 + " " + p2 + " " + p3 + ":" + filePath);
3989 }
3990
3991 IccIoResult response =
3992 (IccIoResult) sendRequest(CMD_EXCHANGE_SIM_IO,
3993 new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath),
3994 subId);
3995
3996 if (DBG) {
3997 log("Exchange SIM_IO [R]" + response);
3998 }
3999
4000 byte[] result = null;
4001 int length = 2;
4002 if (response.payload != null) {
4003 length = 2 + response.payload.length;
4004 result = new byte[length];
4005 System.arraycopy(response.payload, 0, result, 0, response.payload.length);
4006 } else {
4007 result = new byte[length];
4008 }
4009
4010 result[length - 1] = (byte) response.sw2;
4011 result[length - 2] = (byte) response.sw1;
4012 return result;
4013 } finally {
4014 Binder.restoreCallingIdentity(identity);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004015 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004016 }
4017
Nathan Haroldb3014052017-01-25 15:57:32 -08004018 /**
4019 * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
4020 * on a particular subscription
4021 */
sqianb6e41952018-03-12 14:54:01 -07004022 public String[] getForbiddenPlmns(int subId, int appType, String callingPackage) {
4023 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4024 mApp, subId, callingPackage, "getForbiddenPlmns")) {
4025 return null;
4026 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004027
4028 final long identity = Binder.clearCallingIdentity();
4029 try {
4030 if (appType != TelephonyManager.APPTYPE_USIM
4031 && appType != TelephonyManager.APPTYPE_SIM) {
4032 loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
4033 return null;
4034 }
4035 Object response = sendRequest(
4036 CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
4037 if (response instanceof String[]) {
4038 return (String[]) response;
4039 }
4040 // Response is an Exception of some kind,
4041 // which is signalled to the user as a NULL retval
Nathan Haroldb3014052017-01-25 15:57:32 -08004042 return null;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004043 } finally {
4044 Binder.restoreCallingIdentity(identity);
Nathan Haroldb3014052017-01-25 15:57:32 -08004045 }
Nathan Haroldb3014052017-01-25 15:57:32 -08004046 }
4047
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004048 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004049 public String sendEnvelopeWithStatus(int subId, String content) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004050 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4051 mApp, subId, "sendEnvelopeWithStatus");
Evan Charltonc66da362014-05-16 14:06:40 -07004052
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004053 final long identity = Binder.clearCallingIdentity();
4054 try {
4055 IccIoResult response = (IccIoResult) sendRequest(CMD_SEND_ENVELOPE, content, subId);
4056 if (response.payload == null) {
4057 return "";
4058 }
Evan Charltonc66da362014-05-16 14:06:40 -07004059
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004060 // Append the returned status code to the end of the response payload.
4061 String s = Integer.toHexString(
4062 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
4063 s = IccUtils.bytesToHexString(response.payload) + s;
4064 return s;
4065 } finally {
4066 Binder.restoreCallingIdentity(identity);
4067 }
Evan Charltonc66da362014-05-16 14:06:40 -07004068 }
4069
Jake Hambye994d462014-02-03 13:10:13 -08004070 /**
4071 * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
4072 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
4073 *
4074 * @param itemID the ID of the item to read
4075 * @return the NV item as a String, or null on error.
4076 */
4077 @Override
4078 public String nvReadItem(int itemID) {
vagdeviaf9a5b92018-08-15 16:01:53 -07004079 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08004080 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4081 mApp, getDefaultSubscription(), "nvReadItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004082
4083 final long identity = Binder.clearCallingIdentity();
4084 try {
4085 if (DBG) log("nvReadItem: item " + itemID);
vagdeviaf9a5b92018-08-15 16:01:53 -07004086 String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004087 if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
4088 return value;
4089 } finally {
4090 Binder.restoreCallingIdentity(identity);
4091 }
Jake Hambye994d462014-02-03 13:10:13 -08004092 }
4093
4094 /**
4095 * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
4096 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
4097 *
4098 * @param itemID the ID of the item to read
4099 * @param itemValue the value to write, as a String
4100 * @return true on success; false on any failure
4101 */
4102 @Override
4103 public boolean nvWriteItem(int itemID, String itemValue) {
vagdeviaf9a5b92018-08-15 16:01:53 -07004104 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08004105 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4106 mApp, getDefaultSubscription(), "nvWriteItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004107
4108 final long identity = Binder.clearCallingIdentity();
4109 try {
4110 if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
4111 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
vagdeviaf9a5b92018-08-15 16:01:53 -07004112 new Pair<Integer, String>(itemID, itemValue), workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004113 if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
4114 return success;
4115 } finally {
4116 Binder.restoreCallingIdentity(identity);
4117 }
Jake Hambye994d462014-02-03 13:10:13 -08004118 }
4119
4120 /**
4121 * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
4122 * Used for device configuration by some CDMA operators.
4123 *
4124 * @param preferredRoamingList byte array containing the new PRL
4125 * @return true on success; false on any failure
4126 */
4127 @Override
4128 public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004129 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4130 mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004131
4132 final long identity = Binder.clearCallingIdentity();
4133 try {
4134 if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
4135 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
4136 if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
4137 return success;
4138 } finally {
4139 Binder.restoreCallingIdentity(identity);
4140 }
Jake Hambye994d462014-02-03 13:10:13 -08004141 }
4142
4143 /**
chen xu6dac5ab2018-10-26 17:39:23 -07004144 * Rollback modem configurations to factory default except some config which are in whitelist.
Jake Hambye994d462014-02-03 13:10:13 -08004145 * Used for device configuration by some CDMA operators.
4146 *
chen xu6dac5ab2018-10-26 17:39:23 -07004147 * @param slotIndex - device slot.
4148 *
Jake Hambye994d462014-02-03 13:10:13 -08004149 * @return true on success; false on any failure
4150 */
4151 @Override
chen xu6dac5ab2018-10-26 17:39:23 -07004152 public boolean resetModemConfig(int slotIndex) {
4153 Phone phone = PhoneFactory.getPhone(slotIndex);
4154 if (phone != null) {
4155 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4156 mApp, phone.getSubId(), "resetModemConfig");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004157
chen xu6dac5ab2018-10-26 17:39:23 -07004158 final long identity = Binder.clearCallingIdentity();
4159 try {
4160 Boolean success = (Boolean) sendRequest(CMD_RESET_MODEM_CONFIG, null);
4161 if (DBG) log("resetModemConfig:" + ' ' + (success ? "ok" : "fail"));
4162 return success;
4163 } finally {
4164 Binder.restoreCallingIdentity(identity);
4165 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004166 }
chen xu6dac5ab2018-10-26 17:39:23 -07004167 return false;
4168 }
4169
4170 /**
4171 * Generate a radio modem reset. Used for device configuration by some CDMA operators.
4172 *
4173 * @param slotIndex - device slot.
4174 *
4175 * @return true on success; false on any failure
4176 */
4177 @Override
4178 public boolean rebootModem(int slotIndex) {
4179 Phone phone = PhoneFactory.getPhone(slotIndex);
4180 if (phone != null) {
4181 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4182 mApp, phone.getSubId(), "rebootModem");
4183
4184 final long identity = Binder.clearCallingIdentity();
4185 try {
4186 Boolean success = (Boolean) sendRequest(CMD_MODEM_REBOOT, null);
4187 if (DBG) log("rebootModem:" + ' ' + (success ? "ok" : "fail"));
4188 return success;
4189 } finally {
4190 Binder.restoreCallingIdentity(identity);
4191 }
4192 }
4193 return false;
Jake Hambye994d462014-02-03 13:10:13 -08004194 }
Jake Hamby7c27be32014-03-03 13:25:59 -08004195
Svet Ganovb320e182015-04-16 12:30:10 -07004196 public String[] getPcscfAddress(String apnType, String callingPackage) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004197 final Phone defaultPhone = getDefaultPhone();
Jeff Davidson7e17e312018-02-13 18:17:36 -08004198 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004199 mApp, defaultPhone.getSubId(), callingPackage, "getPcscfAddress")) {
Svet Ganovb320e182015-04-16 12:30:10 -07004200 return new String[0];
4201 }
4202
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004203 final long identity = Binder.clearCallingIdentity();
4204 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004205 return defaultPhone.getPcscfAddress(apnType);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004206 } finally {
4207 Binder.restoreCallingIdentity(identity);
4208 }
Wink Saville36469e72014-06-11 15:17:00 -07004209 }
4210
Brad Ebinger51f743a2017-01-23 13:50:20 -08004211 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004212 * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
4213 * status updates, if not already enabled.
Brad Ebinger51f743a2017-01-23 13:50:20 -08004214 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004215 public void enableIms(int slotId) {
Brad Ebinger51f743a2017-01-23 13:50:20 -08004216 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004217
4218 final long identity = Binder.clearCallingIdentity();
4219 try {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004220 ImsResolver resolver = PhoneFactory.getImsResolver();
4221 if (resolver == null) {
4222 // may happen if the device does not support IMS.
4223 return;
4224 }
4225 resolver.enableIms(slotId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004226 } finally {
4227 Binder.restoreCallingIdentity(identity);
4228 }
Brad Ebinger34bef922017-11-09 10:27:08 -08004229 }
4230
4231 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004232 * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
4233 * status updates to disabled.
Brad Ebinger34bef922017-11-09 10:27:08 -08004234 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004235 public void disableIms(int slotId) {
4236 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004237
4238 final long identity = Binder.clearCallingIdentity();
4239 try {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004240 ImsResolver resolver = PhoneFactory.getImsResolver();
4241 if (resolver == null) {
4242 // may happen if the device does not support IMS.
4243 return;
4244 }
4245 resolver.disableIms(slotId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004246 } finally {
4247 Binder.restoreCallingIdentity(identity);
4248 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004249 }
4250
4251 /**
4252 * Returns the {@link IImsMmTelFeature} that corresponds to the given slot Id for the MMTel
4253 * feature or {@link null} if the service is not available. If the feature is available, the
4254 * {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates.
4255 */
4256 public IImsMmTelFeature getMmTelFeatureAndListen(int slotId,
Brad Ebinger34bef922017-11-09 10:27:08 -08004257 IImsServiceFeatureCallback callback) {
4258 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004259
4260 final long identity = Binder.clearCallingIdentity();
4261 try {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004262 ImsResolver resolver = PhoneFactory.getImsResolver();
4263 if (resolver == null) {
4264 // may happen if the device does not support IMS.
4265 return null;
4266 }
4267 return resolver.getMmTelFeatureAndListen(slotId, callback);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004268 } finally {
4269 Binder.restoreCallingIdentity(identity);
4270 }
Brad Ebinger34bef922017-11-09 10:27:08 -08004271 }
4272
4273 /**
4274 * Returns the {@link IImsRcsFeature} that corresponds to the given slot Id for the RCS
4275 * feature during emergency calling or {@link null} if the service is not available. If the
4276 * feature is available, the {@link IImsServiceFeatureCallback} callback is registered as a
4277 * listener for feature updates.
4278 */
4279 public IImsRcsFeature getRcsFeatureAndListen(int slotId, IImsServiceFeatureCallback callback) {
4280 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004281
4282 final long identity = Binder.clearCallingIdentity();
4283 try {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004284 ImsResolver resolver = PhoneFactory.getImsResolver();
4285 if (resolver == null) {
4286 // may happen if the device does not support IMS.
4287 return null;
4288 }
4289 return resolver.getRcsFeatureAndListen(slotId, callback);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004290 } finally {
4291 Binder.restoreCallingIdentity(identity);
4292 }
Brad Ebinger51f743a2017-01-23 13:50:20 -08004293 }
4294
Brad Ebinger5f64b052017-12-14 14:26:15 -08004295 /**
4296 * Returns the {@link IImsRegistration} structure associated with the slotId and feature
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004297 * specified or null if IMS is not supported on the slot specified.
Brad Ebinger5f64b052017-12-14 14:26:15 -08004298 */
4299 public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
4300 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004301
4302 final long identity = Binder.clearCallingIdentity();
4303 try {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004304 ImsResolver resolver = PhoneFactory.getImsResolver();
4305 if (resolver == null) {
4306 // may happen if the device does not support IMS.
4307 return null;
4308 }
4309 return resolver.getImsRegistration(slotId, feature);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004310 } finally {
4311 Binder.restoreCallingIdentity(identity);
4312 }
Brad Ebinger5f64b052017-12-14 14:26:15 -08004313 }
4314
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004315 /**
4316 * Returns the {@link IImsConfig} structure associated with the slotId and feature
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004317 * specified or null if IMS is not supported on the slot specified.
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004318 */
4319 public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
4320 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004321
4322 final long identity = Binder.clearCallingIdentity();
4323 try {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004324 ImsResolver resolver = PhoneFactory.getImsResolver();
4325 if (resolver == null) {
4326 // may happen if the device does not support IMS.
4327 return null;
4328 }
4329 return resolver.getImsConfig(slotId, feature);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004330 } finally {
4331 Binder.restoreCallingIdentity(identity);
4332 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004333 }
4334
Brad Ebinger884c07b2018-02-15 16:17:40 -08004335 /**
Brad Ebingerdac2f002018-04-03 15:17:52 -07004336 * Sets the ImsService Package Name that Telephony will bind to.
4337 *
4338 * @param slotId the slot ID that the ImsService should bind for.
4339 * @param isCarrierImsService true if the ImsService is the carrier override, false if the
4340 * ImsService is the device default ImsService.
4341 * @param packageName The package name of the application that contains the ImsService to bind
4342 * to.
4343 * @return true if setting the ImsService to bind to succeeded, false if it did not.
4344 * @hide
4345 */
4346 public boolean setImsService(int slotId, boolean isCarrierImsService, String packageName) {
Brad Ebingerde696de2018-04-06 09:56:40 -07004347 int[] subIds = SubscriptionManager.getSubId(slotId);
4348 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
4349 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
4350 "setImsService");
4351
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004352 final long identity = Binder.clearCallingIdentity();
4353 try {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004354 ImsResolver resolver = PhoneFactory.getImsResolver();
4355 if (resolver == null) {
4356 // may happen if the device does not support IMS.
4357 return false;
4358 }
4359 return resolver.overrideImsServiceConfiguration(slotId, isCarrierImsService,
4360 packageName);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004361 } finally {
4362 Binder.restoreCallingIdentity(identity);
4363 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07004364 }
4365
4366 /**
4367 * Return the ImsService configuration.
4368 *
4369 * @param slotId The slot that the ImsService is associated with.
4370 * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
4371 * the device default.
4372 * @return the package name of the ImsService configuration.
4373 */
4374 public String getImsService(int slotId, boolean isCarrierImsService) {
Brad Ebingerde696de2018-04-06 09:56:40 -07004375 int[] subIds = SubscriptionManager.getSubId(slotId);
4376 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
4377 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
4378 "getImsService");
4379
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004380 final long identity = Binder.clearCallingIdentity();
4381 try {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004382 ImsResolver resolver = PhoneFactory.getImsResolver();
4383 if (resolver == null) {
4384 // may happen if the device does not support IMS.
4385 return "";
4386 }
4387 return resolver.getImsServiceConfiguration(slotId, isCarrierImsService);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004388 } finally {
4389 Binder.restoreCallingIdentity(identity);
4390 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07004391 }
4392
Wink Saville36469e72014-06-11 15:17:00 -07004393 public void setImsRegistrationState(boolean registered) {
4394 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004395
4396 final long identity = Binder.clearCallingIdentity();
4397 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004398 getDefaultPhone().setImsRegistrationState(registered);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004399 } finally {
4400 Binder.restoreCallingIdentity(identity);
4401 }
Wink Saville36469e72014-06-11 15:17:00 -07004402 }
4403
4404 /**
Stuart Scott54788802015-03-30 13:18:01 -07004405 * Set the network selection mode to automatic.
4406 *
4407 */
4408 @Override
4409 public void setNetworkSelectionModeAutomatic(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004410 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4411 mApp, subId, "setNetworkSelectionModeAutomatic");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004412
Pengquan Menge92a50d2018-09-21 15:54:48 -07004413 if (!isActiveSubscription(subId)) {
4414 return;
4415 }
4416
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004417 final long identity = Binder.clearCallingIdentity();
4418 try {
4419 if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
4420 sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId);
4421 } finally {
4422 Binder.restoreCallingIdentity(identity);
4423 }
Stuart Scott54788802015-03-30 13:18:01 -07004424 }
4425
Pengquan Mengea84e042018-09-20 14:57:26 -07004426 /**
4427 * Ask the radio to connect to the input network and change selection mode to manual.
4428 *
4429 * @param subId the id of the subscription.
4430 * @param operatorInfo the operator information, included the PLMN, long name and short name of
4431 * the operator to attach to.
4432 * @param persistSelection whether the selection will persist until reboot. If true, only allows
4433 * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
4434 * normal network selection next time.
4435 * @return {@code true} on success; {@code true} on any failure.
Shishir Agrawal302c8692015-06-19 13:49:39 -07004436 */
4437 @Override
Pengquan Mengea84e042018-09-20 14:57:26 -07004438 public boolean setNetworkSelectionModeManual(
4439 int subId, OperatorInfo operatorInfo, boolean persistSelection) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004440 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4441 mApp, subId, "setNetworkSelectionModeManual");
Pengquan Menge92a50d2018-09-21 15:54:48 -07004442
4443 if (!isActiveSubscription(subId)) {
4444 return false;
4445 }
4446
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004447 final long identity = Binder.clearCallingIdentity();
4448 try {
Pengquan Mengea84e042018-09-20 14:57:26 -07004449 ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operatorInfo,
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004450 persistSelection);
Pengquan Mengea84e042018-09-20 14:57:26 -07004451 if (DBG) {
4452 log("setNetworkSelectionModeManual: subId: " + subId
4453 + " operator: " + operatorInfo);
4454 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004455 return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
4456 } finally {
4457 Binder.restoreCallingIdentity(identity);
4458 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07004459 }
4460
4461 /**
4462 * Scans for available networks.
4463 */
4464 @Override
Hall Liuf19c44f2018-11-27 14:38:17 -08004465 public CellNetworkScanResult getCellNetworkScanResults(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004466 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4467 mApp, subId, "getCellNetworkScanResults");
Hall Liuf19c44f2018-11-27 14:38:17 -08004468 LocationAccessPolicy.LocationPermissionResult locationResult =
4469 LocationAccessPolicy.checkLocationPermission(mApp,
4470 new LocationAccessPolicy.LocationPermissionQuery.Builder()
4471 .setCallingPackage(callingPackage)
4472 .setCallingPid(Binder.getCallingPid())
4473 .setCallingUid(Binder.getCallingUid())
4474 .setMethod("getCellNetworkScanResults")
4475 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
4476 .build());
4477 switch (locationResult) {
4478 case DENIED_HARD:
4479 throw new SecurityException("Not allowed to access scan results -- location");
4480 case DENIED_SOFT:
4481 return null;
4482 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004483
Pengquan Menga1bb6272018-09-06 09:59:22 -07004484 long identity = Binder.clearCallingIdentity();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004485 try {
4486 if (DBG) log("getCellNetworkScanResults: subId " + subId);
Pengquan Menga1bb6272018-09-06 09:59:22 -07004487 return (CellNetworkScanResult) sendRequest(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004488 CMD_PERFORM_NETWORK_SCAN, null, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004489 } finally {
4490 Binder.restoreCallingIdentity(identity);
4491 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07004492 }
4493
4494 /**
yinxub1bed742017-04-17 11:45:04 -07004495 * Starts a new network scan and returns the id of this scan.
yinxu504e1392017-04-12 16:03:22 -07004496 *
yinxub1bed742017-04-17 11:45:04 -07004497 * @param subId id of the subscription
4498 * @param request contains the radio access networks with bands/channels to scan
4499 * @param messenger callback messenger for scan results or errors
4500 * @param binder for the purpose of auto clean when the user thread crashes
yinxu504e1392017-04-12 16:03:22 -07004501 * @return the id of the requested scan which can be used to stop the scan.
4502 */
4503 @Override
4504 public int requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger,
Hall Liuf19c44f2018-11-27 14:38:17 -08004505 IBinder binder, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004506 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4507 mApp, subId, "requestNetworkScan");
Hall Liuf19c44f2018-11-27 14:38:17 -08004508 LocationAccessPolicy.LocationPermissionResult locationResult =
4509 LocationAccessPolicy.checkLocationPermission(mApp,
4510 new LocationAccessPolicy.LocationPermissionQuery.Builder()
4511 .setCallingPackage(callingPackage)
4512 .setCallingPid(Binder.getCallingPid())
4513 .setCallingUid(Binder.getCallingUid())
4514 .setMethod("requestNetworkScan")
4515 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
4516 .build());
Hall Liub2ac8ef2019-02-28 15:56:23 -08004517 if (locationResult != LocationAccessPolicy.LocationPermissionResult.ALLOWED) {
Hall Liu558027f2019-05-15 19:14:05 -07004518 SecurityException e = checkNetworkRequestForSanitizedLocationAccess(request, subId);
Hall Liub2ac8ef2019-02-28 15:56:23 -08004519 if (e != null) {
4520 if (locationResult == LocationAccessPolicy.LocationPermissionResult.DENIED_HARD) {
4521 throw e;
4522 } else {
Hall Liu0e5abaf2019-04-04 01:25:30 -07004523 loge(e.getMessage());
Hall Liub2ac8ef2019-02-28 15:56:23 -08004524 return TelephonyScanManager.INVALID_SCAN_ID;
4525 }
4526 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004527 }
Hall Liu912dfd32019-04-25 14:02:26 -07004528 int callingUid = Binder.getCallingUid();
4529 int callingPid = Binder.getCallingPid();
Ying Xu94a46582019-04-18 17:14:56 -07004530 final long identity = Binder.clearCallingIdentity();
4531 try {
4532 return mNetworkScanRequestTracker.startNetworkScan(
4533 request, messenger, binder, getPhone(subId),
Hall Liu912dfd32019-04-25 14:02:26 -07004534 callingUid, callingPid, callingPackage);
Ying Xu94a46582019-04-18 17:14:56 -07004535 } finally {
4536 Binder.restoreCallingIdentity(identity);
4537 }
yinxu504e1392017-04-12 16:03:22 -07004538 }
4539
Hall Liub2ac8ef2019-02-28 15:56:23 -08004540 private SecurityException checkNetworkRequestForSanitizedLocationAccess(
Hall Liu558027f2019-05-15 19:14:05 -07004541 NetworkScanRequest request, int subId) {
4542 boolean hasCarrierPriv = getCarrierPrivilegeStatusForUid(subId, Binder.getCallingUid())
4543 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
4544 boolean hasNetworkScanPermission =
4545 mApp.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_SCAN)
4546 == PERMISSION_GRANTED;
4547
4548 if (!hasCarrierPriv && !hasNetworkScanPermission) {
4549 return new SecurityException("permission.NETWORK_SCAN or carrier privileges is needed"
4550 + " for network scans without location access.");
Hall Liub2ac8ef2019-02-28 15:56:23 -08004551 }
4552
4553 if (request.getSpecifiers() != null && request.getSpecifiers().length > 0) {
4554 for (RadioAccessSpecifier ras : request.getSpecifiers()) {
Hall Liub2ac8ef2019-02-28 15:56:23 -08004555 if (ras.getChannels() != null && ras.getChannels().length > 0) {
4556 return new SecurityException("Specific channels must not be"
4557 + " scanned without location access.");
4558 }
4559 }
4560 }
4561
Hall Liub2ac8ef2019-02-28 15:56:23 -08004562 return null;
4563 }
4564
yinxu504e1392017-04-12 16:03:22 -07004565 /**
4566 * Stops an existing network scan with the given scanId.
yinxub1bed742017-04-17 11:45:04 -07004567 *
4568 * @param subId id of the subscription
4569 * @param scanId id of the scan that needs to be stopped
yinxu504e1392017-04-12 16:03:22 -07004570 */
4571 @Override
4572 public void stopNetworkScan(int subId, int scanId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004573 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4574 mApp, subId, "stopNetworkScan");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004575
Hall Liu912dfd32019-04-25 14:02:26 -07004576 int callingUid = Binder.getCallingUid();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004577 final long identity = Binder.clearCallingIdentity();
4578 try {
Hall Liu912dfd32019-04-25 14:02:26 -07004579 mNetworkScanRequestTracker.stopNetworkScan(scanId, callingUid);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004580 } finally {
4581 Binder.restoreCallingIdentity(identity);
4582 }
yinxu504e1392017-04-12 16:03:22 -07004583 }
4584
4585 /**
Junda Liu84d15a22014-07-02 11:21:04 -07004586 * Get the calculated preferred network type.
4587 * Used for debugging incorrect network type.
4588 *
4589 * @return the preferred network type, defined in RILConstants.java.
4590 */
4591 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004592 public int getCalculatedPreferredNetworkType(String callingPackage) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004593 final Phone defaultPhone = getDefaultPhone();
4594 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
4595 callingPackage, "getCalculatedPreferredNetworkType")) {
Svet Ganovb320e182015-04-16 12:30:10 -07004596 return RILConstants.PREFERRED_NETWORK_MODE;
4597 }
4598
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004599 final long identity = Binder.clearCallingIdentity();
4600 try {
4601 // FIXME: need to get SubId from somewhere.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004602 return PhoneFactory.calculatePreferredNetworkType(defaultPhone.getContext(), 0);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004603 } finally {
4604 Binder.restoreCallingIdentity(identity);
4605 }
Junda Liu84d15a22014-07-02 11:21:04 -07004606 }
4607
4608 /**
Jake Hamby7c27be32014-03-03 13:25:59 -08004609 * Get the preferred network type.
4610 * Used for device configuration by some CDMA operators.
4611 *
4612 * @return the preferred network type, defined in RILConstants.java.
4613 */
4614 @Override
Stuart Scott54788802015-03-30 13:18:01 -07004615 public int getPreferredNetworkType(int subId) {
Pengquan Menga4009cb2018-12-20 11:00:24 -08004616 TelephonyPermissions
4617 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
4618 mApp, subId, "getPreferredNetworkType");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004619
4620 final long identity = Binder.clearCallingIdentity();
4621 try {
4622 if (DBG) log("getPreferredNetworkType");
4623 int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null, subId);
4624 int networkType = (result != null ? result[0] : -1);
4625 if (DBG) log("getPreferredNetworkType: " + networkType);
4626 return networkType;
4627 } finally {
4628 Binder.restoreCallingIdentity(identity);
4629 }
Jake Hamby7c27be32014-03-03 13:25:59 -08004630 }
4631
4632 /**
4633 * Set the preferred network type.
4634 * Used for device configuration by some CDMA operators.
4635 *
4636 * @param networkType the preferred network type, defined in RILConstants.java.
4637 * @return true on success; false on any failure.
4638 */
4639 @Override
Stuart Scott54788802015-03-30 13:18:01 -07004640 public boolean setPreferredNetworkType(int subId, int networkType) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004641 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4642 mApp, subId, "setPreferredNetworkType");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004643
4644 final long identity = Binder.clearCallingIdentity();
4645 try {
4646 if (DBG) log("setPreferredNetworkType: subId " + subId + " type " + networkType);
4647 Boolean success = (Boolean) sendRequest(
4648 CMD_SET_PREFERRED_NETWORK_TYPE, networkType, subId);
4649 if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail"));
4650 if (success) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004651 Settings.Global.putInt(mApp.getContentResolver(),
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004652 Settings.Global.PREFERRED_NETWORK_MODE + subId, networkType);
4653 }
4654 return success;
4655 } finally {
4656 Binder.restoreCallingIdentity(identity);
Junda Liu80bc0d12014-07-14 16:36:44 -07004657 }
Jake Hamby7c27be32014-03-03 13:25:59 -08004658 }
Robert Greenwalted86e582014-05-21 20:03:20 -07004659
4660 /**
Miaoa84611c2019-03-15 09:21:10 +08004661 * Check whether DUN APN is required for tethering with subId.
Junda Liu475951f2014-11-07 16:45:03 -08004662 *
Miaoa84611c2019-03-15 09:21:10 +08004663 * @param subId the id of the subscription to require tethering.
Amit Mahajanfe58cdf2017-07-11 12:01:53 -07004664 * @return {@code true} if DUN APN is required for tethering.
Junda Liu475951f2014-11-07 16:45:03 -08004665 * @hide
4666 */
4667 @Override
Miaoa84611c2019-03-15 09:21:10 +08004668 public boolean getTetherApnRequiredForSubscriber(int subId) {
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004669 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004670 final long identity = Binder.clearCallingIdentity();
Miaoa84611c2019-03-15 09:21:10 +08004671 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004672 try {
Miaoa84611c2019-03-15 09:21:10 +08004673 if (phone != null) {
4674 return phone.hasMatchedTetherApnSetting();
4675 } else {
4676 return false;
4677 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004678 } finally {
4679 Binder.restoreCallingIdentity(identity);
Junda Liu475951f2014-11-07 16:45:03 -08004680 }
Junda Liu475951f2014-11-07 16:45:03 -08004681 }
4682
4683 /**
Robert Greenwalted86e582014-05-21 20:03:20 -07004684 * Set mobile data enabled
4685 * Used by the user through settings etc to turn on/off mobile data
4686 *
4687 * @param enable {@code true} turn turn data on, else {@code false}
4688 */
4689 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08004690 public void setUserDataEnabled(int subId, boolean enable) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004691 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4692 mApp, subId, "setUserDataEnabled");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004693
4694 final long identity = Binder.clearCallingIdentity();
4695 try {
4696 int phoneId = mSubscriptionController.getPhoneId(subId);
4697 if (DBG) log("setUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
4698 Phone phone = PhoneFactory.getPhone(phoneId);
4699 if (phone != null) {
4700 if (DBG) log("setUserDataEnabled: subId=" + subId + " enable=" + enable);
Jack Yud79fba22018-12-13 11:51:28 -08004701 phone.getDataEnabledSettings().setUserDataEnabled(enable);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004702 } else {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004703 loge("setUserDataEnabled: no phone found. Invalid subId=" + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004704 }
4705 } finally {
4706 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08004707 }
Robert Greenwalted86e582014-05-21 20:03:20 -07004708 }
4709
4710 /**
Malcolm Chen964682d2017-11-28 16:20:07 -08004711 * Get the user enabled state of Mobile Data.
4712 *
4713 * TODO: remove and use isUserDataEnabled.
4714 * This can't be removed now because some vendor codes
4715 * calls through ITelephony directly while they should
4716 * use TelephonyManager.
4717 *
4718 * @return true on enabled
4719 */
4720 @Override
4721 public boolean getDataEnabled(int subId) {
4722 return isUserDataEnabled(subId);
4723 }
4724
4725 /**
4726 * Get whether mobile data is enabled per user setting.
4727 *
4728 * There are other factors deciding whether mobile data is actually enabled, but they are
4729 * not considered here. See {@link #isDataEnabled(int)} for more details.
Robert Greenwalt646120a2014-05-23 11:54:03 -07004730 *
Jeff Davidsona1920712016-11-18 17:05:56 -08004731 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
Robert Greenwalted86e582014-05-21 20:03:20 -07004732 *
4733 * @return {@code true} if data is enabled else {@code false}
4734 */
4735 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08004736 public boolean isUserDataEnabled(int subId) {
Robert Greenwalt646120a2014-05-23 11:54:03 -07004737 try {
4738 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
4739 null);
4740 } catch (Exception e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004741 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4742 mApp, subId, "isUserDataEnabled");
Robert Greenwalt646120a2014-05-23 11:54:03 -07004743 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004744
4745 final long identity = Binder.clearCallingIdentity();
4746 try {
4747 int phoneId = mSubscriptionController.getPhoneId(subId);
4748 if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
4749 Phone phone = PhoneFactory.getPhone(phoneId);
4750 if (phone != null) {
4751 boolean retVal = phone.isUserDataEnabled();
4752 if (DBG) log("isUserDataEnabled: subId=" + subId + " retVal=" + retVal);
4753 return retVal;
4754 } else {
4755 if (DBG) loge("isUserDataEnabled: no phone subId=" + subId + " retVal=false");
4756 return false;
4757 }
4758 } finally {
4759 Binder.restoreCallingIdentity(identity);
Malcolm Chen964682d2017-11-28 16:20:07 -08004760 }
4761 }
4762
4763 /**
4764 * Get whether mobile data is enabled.
4765 *
4766 * Comparable to {@link #isUserDataEnabled(int)}, this considers all factors deciding
4767 * whether mobile data is actually enabled.
4768 *
4769 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
4770 *
4771 * @return {@code true} if data is enabled else {@code false}
4772 */
4773 @Override
4774 public boolean isDataEnabled(int subId) {
4775 try {
4776 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
4777 null);
4778 } catch (Exception e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004779 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4780 mApp, subId, "isDataEnabled");
Malcolm Chen964682d2017-11-28 16:20:07 -08004781 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004782
4783 final long identity = Binder.clearCallingIdentity();
4784 try {
4785 int phoneId = mSubscriptionController.getPhoneId(subId);
4786 if (DBG) log("isDataEnabled: subId=" + subId + " phoneId=" + phoneId);
4787 Phone phone = PhoneFactory.getPhone(phoneId);
4788 if (phone != null) {
Jack Yud79fba22018-12-13 11:51:28 -08004789 boolean retVal = phone.getDataEnabledSettings().isDataEnabled();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004790 if (DBG) log("isDataEnabled: subId=" + subId + " retVal=" + retVal);
4791 return retVal;
4792 } else {
4793 if (DBG) loge("isDataEnabled: no phone subId=" + subId + " retVal=false");
4794 return false;
4795 }
4796 } finally {
4797 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08004798 }
Robert Greenwalted86e582014-05-21 20:03:20 -07004799 }
Shishir Agrawal60f9c952014-06-23 12:00:43 -07004800
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07004801 private int getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim,
4802 Phone phone) {
4803 //load access rules from carrier configs, and check those as well: b/139133814
4804 SubscriptionController subController = SubscriptionController.getInstance();
4805 if (privilegeFromSim == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
4806 || subController == null) return privilegeFromSim;
4807
4808 int uid = Binder.getCallingUid();
4809 PackageManager pkgMgr = phone.getContext().getPackageManager();
4810 String[] packages = pkgMgr.getPackagesForUid(uid);
4811
4812 final long identity = Binder.clearCallingIdentity();
4813 try {
4814 SubscriptionInfo subInfo = subController.getSubscriptionInfo(phone.getSubId());
4815 SubscriptionManager subManager = (SubscriptionManager)
4816 phone.getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
4817 for (String pkg : packages) {
4818 if (subManager.canManageSubscription(subInfo, pkg)) {
4819 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
4820 }
4821 }
4822 return privilegeFromSim;
4823 } finally {
4824 Binder.restoreCallingIdentity(identity);
4825 }
4826 }
4827
4828 private int getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, Phone phone,
4829 String pkgName) {
4830 //load access rules from carrier configs, and check those as well: b/139133814
4831 SubscriptionController subController = SubscriptionController.getInstance();
4832 if (privilegeFromSim == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
4833 || subController == null) return privilegeFromSim;
4834
4835 final long identity = Binder.clearCallingIdentity();
4836 try {
4837 SubscriptionInfo subInfo = subController.getSubscriptionInfo(phone.getSubId());
4838 SubscriptionManager subManager = (SubscriptionManager)
4839 phone.getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
4840 return subManager.canManageSubscription(subInfo, pkgName)
4841 ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS : privilegeFromSim;
4842 } finally {
4843 Binder.restoreCallingIdentity(identity);
4844 }
4845 }
4846
Shishir Agrawal60f9c952014-06-23 12:00:43 -07004847 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004848 public int getCarrierPrivilegeStatus(int subId) {
4849 final Phone phone = getPhone(subId);
4850 if (phone == null) {
4851 loge("getCarrierPrivilegeStatus: Invalid subId");
4852 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
4853 }
4854 UiccCard card = UiccController.getInstance().getUiccCard(phone.getPhoneId());
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07004855 if (card == null) {
Shishir Agrawal5e5becd2014-11-18 11:38:23 -08004856 loge("getCarrierPrivilegeStatus: No UICC");
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07004857 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
4858 }
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07004859
4860 return getCarrierPrivilegeStatusFromCarrierConfigRules(
4861 card.getCarrierPrivilegeStatusForCurrentTransaction(
4862 phone.getContext().getPackageManager()), phone);
Shishir Agrawal60f9c952014-06-23 12:00:43 -07004863 }
Junda Liu29340342014-07-10 15:23:27 -07004864
4865 @Override
Jeff Davidson7e17e312018-02-13 18:17:36 -08004866 public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
4867 final Phone phone = getPhone(subId);
4868 if (phone == null) {
4869 loge("getCarrierPrivilegeStatus: Invalid subId");
4870 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
4871 }
4872 UiccProfile profile =
4873 UiccController.getInstance().getUiccProfileForPhone(phone.getPhoneId());
4874 if (profile == null) {
4875 loge("getCarrierPrivilegeStatus: No UICC");
4876 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
4877 }
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07004878 return getCarrierPrivilegeStatusFromCarrierConfigRules(
4879 profile.getCarrierPrivilegeStatusForUid(
4880 phone.getContext().getPackageManager(), uid), phone);
Jeff Davidson7e17e312018-02-13 18:17:36 -08004881 }
4882
4883 @Override
chen xuf7e9fe82019-05-09 19:31:02 -07004884 public int checkCarrierPrivilegesForPackage(int subId, String pkgName) {
4885 if (TextUtils.isEmpty(pkgName)) {
Junda Liu317d70b2016-03-08 09:33:53 -08004886 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
chen xuf7e9fe82019-05-09 19:31:02 -07004887 }
4888
4889 int phoneId = SubscriptionManager.getPhoneId(subId);
4890 UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07004891 if (card == null) {
chen xuf7e9fe82019-05-09 19:31:02 -07004892 loge("checkCarrierPrivilegesForPackage: No UICC on subId " + subId);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07004893 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
4894 }
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07004895 return getCarrierPrivilegeStatusFromCarrierConfigRules(
4896 card.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName),
4897 getPhone(phoneId), pkgName);
Zach Johnson50ecba32015-05-19 00:24:21 -07004898 }
4899
4900 @Override
4901 public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
Junda Liu317d70b2016-03-08 09:33:53 -08004902 if (TextUtils.isEmpty(pkgName))
4903 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Zach Johnson50ecba32015-05-19 00:24:21 -07004904 int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
4905 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
4906 UiccCard card = UiccController.getInstance().getUiccCard(i);
4907 if (card == null) {
Jonathan Basseri7d320df2015-06-16 12:17:08 -07004908 // No UICC in that slot.
Zach Johnson50ecba32015-05-19 00:24:21 -07004909 continue;
4910 }
4911
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07004912 result = getCarrierPrivilegeStatusFromCarrierConfigRules(
4913 card.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName),
4914 getPhone(i), pkgName);
Zach Johnson50ecba32015-05-19 00:24:21 -07004915 if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
4916 break;
4917 }
4918 }
4919
4920 return result;
Junda Liu29340342014-07-10 15:23:27 -07004921 }
Derek Tan89e89d42014-07-08 17:00:10 -07004922
4923 @Override
Junda Liue64de782015-04-16 17:19:16 -07004924 public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
4925 if (!SubscriptionManager.isValidPhoneId(phoneId)) {
4926 loge("phoneId " + phoneId + " is not valid.");
4927 return null;
4928 }
4929 UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07004930 if (card == null) {
Diego Pontorieroaf74c862014-08-28 11:51:16 -07004931 loge("getCarrierPackageNamesForIntent: No UICC");
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07004932 return null ;
4933 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004934 return card.getCarrierPackageNamesForIntent(mApp.getPackageManager(), intent);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07004935 }
4936
Amith Yamasani6e118872016-02-19 12:53:51 -08004937 @Override
chen xuf7e9fe82019-05-09 19:31:02 -07004938 public List<String> getPackagesWithCarrierPrivileges(int phoneId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004939 PackageManager pm = mApp.getPackageManager();
Amith Yamasani6e118872016-02-19 12:53:51 -08004940 List<String> privilegedPackages = new ArrayList<>();
4941 List<PackageInfo> packages = null;
chen xuf7e9fe82019-05-09 19:31:02 -07004942 UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
4943 // has UICC in that slot.
4944 if (card != null) {
Amith Yamasani6e118872016-02-19 12:53:51 -08004945 if (card.hasCarrierPrivilegeRules()) {
4946 if (packages == null) {
4947 // Only check packages in user 0 for now
4948 packages = pm.getInstalledPackagesAsUser(
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07004949 PackageManager.MATCH_DISABLED_COMPONENTS
4950 | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
Cheonho Park17089c62019-08-01 15:23:12 +09004951 | PackageManager.GET_SIGNING_CERTIFICATES,
4952 UserHandle.USER_SYSTEM);
Amith Yamasani6e118872016-02-19 12:53:51 -08004953 }
4954 for (int p = packages.size() - 1; p >= 0; p--) {
4955 PackageInfo pkgInfo = packages.get(p);
4956 if (pkgInfo != null && pkgInfo.packageName != null
4957 && card.getCarrierPrivilegeStatus(pkgInfo)
chen xuf7e9fe82019-05-09 19:31:02 -07004958 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
Amith Yamasani6e118872016-02-19 12:53:51 -08004959 privilegedPackages.add(pkgInfo.packageName);
4960 }
4961 }
4962 }
4963 }
4964 return privilegedPackages;
4965 }
4966
chen xuf7e9fe82019-05-09 19:31:02 -07004967 @Override
4968 public List<String> getPackagesWithCarrierPrivilegesForAllPhones() {
4969 List<String> privilegedPackages = new ArrayList<>();
4970 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
4971 privilegedPackages.addAll(getPackagesWithCarrierPrivileges(i));
4972 }
4973 return privilegedPackages;
4974 }
4975
Wink Savilleb564aae2014-10-23 10:18:09 -07004976 private String getIccId(int subId) {
Sanket Padawe356d7632015-06-22 14:03:32 -07004977 final Phone phone = getPhone(subId);
4978 UiccCard card = phone == null ? null : phone.getUiccCard();
Derek Tan97ebb422014-09-05 16:55:38 -07004979 if (card == null) {
4980 loge("getIccId: No UICC");
4981 return null;
4982 }
4983 String iccId = card.getIccId();
4984 if (TextUtils.isEmpty(iccId)) {
4985 loge("getIccId: ICC ID is null or empty.");
4986 return null;
4987 }
4988 return iccId;
4989 }
4990
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07004991 @Override
Jeff Sharkey85190e62014-12-05 09:40:12 -08004992 public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
4993 String number) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004994 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
4995 subId, "setLine1NumberForDisplayForSubscriber");
Derek Tan97ebb422014-09-05 16:55:38 -07004996
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004997 final long identity = Binder.clearCallingIdentity();
4998 try {
4999 final String iccId = getIccId(subId);
5000 final Phone phone = getPhone(subId);
5001 if (phone == null) {
5002 return false;
5003 }
5004 final String subscriberId = phone.getSubscriberId();
5005
5006 if (DBG_MERGE) {
5007 Slog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId="
5008 + subscriberId + " to " + number);
5009 }
5010
5011 if (TextUtils.isEmpty(iccId)) {
5012 return false;
5013 }
5014
5015 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
5016
5017 final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
5018 if (alphaTag == null) {
5019 editor.remove(alphaTagPrefKey);
5020 } else {
5021 editor.putString(alphaTagPrefKey, alphaTag);
5022 }
5023
5024 // Record both the line number and IMSI for this ICCID, since we need to
5025 // track all merged IMSIs based on line number
5026 final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
5027 final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
5028 if (number == null) {
5029 editor.remove(numberPrefKey);
5030 editor.remove(subscriberPrefKey);
5031 } else {
5032 editor.putString(numberPrefKey, number);
5033 editor.putString(subscriberPrefKey, subscriberId);
5034 }
5035
5036 editor.commit();
5037 return true;
5038 } finally {
5039 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07005040 }
Derek Tan7226c842014-07-02 17:42:23 -07005041 }
5042
5043 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07005044 public String getLine1NumberForDisplay(int subId, String callingPackage) {
Makoto Onukifee69342015-06-29 14:44:50 -07005045 // This is open to apps with WRITE_SMS.
Jeff Davidson7e17e312018-02-13 18:17:36 -08005046 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
Jeff Davidson913390f2018-02-23 17:11:49 -08005047 mApp, subId, callingPackage, "getLine1NumberForDisplay")) {
Amit Mahajan9cf11512015-11-09 11:40:48 -08005048 if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
Svet Ganovb320e182015-04-16 12:30:10 -07005049 return null;
5050 }
Derek Tan97ebb422014-09-05 16:55:38 -07005051
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005052 final long identity = Binder.clearCallingIdentity();
5053 try {
5054 String iccId = getIccId(subId);
5055 if (iccId != null) {
5056 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
5057 if (DBG_MERGE) {
5058 log("getLine1NumberForDisplay returning "
5059 + mTelephonySharedPreferences.getString(numberPrefKey, null));
5060 }
5061 return mTelephonySharedPreferences.getString(numberPrefKey, null);
Amit Mahajan9cf11512015-11-09 11:40:48 -08005062 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005063 if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null");
5064 return null;
5065 } finally {
5066 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07005067 }
Derek Tan7226c842014-07-02 17:42:23 -07005068 }
5069
5070 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07005071 public String getLine1AlphaTagForDisplay(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005072 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08005073 mApp, subId, callingPackage, "getLine1AlphaTagForDisplay")) {
Svet Ganovb320e182015-04-16 12:30:10 -07005074 return null;
5075 }
Derek Tan97ebb422014-09-05 16:55:38 -07005076
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005077 final long identity = Binder.clearCallingIdentity();
5078 try {
5079 String iccId = getIccId(subId);
5080 if (iccId != null) {
5081 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
5082 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null);
5083 }
5084 return null;
5085 } finally {
5086 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07005087 }
Derek Tan7226c842014-07-02 17:42:23 -07005088 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07005089
5090 @Override
Jordan Liub49b04b2019-05-06 14:45:15 -07005091 public String[] getMergedSubscriberIds(int subId, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08005092 // This API isn't public, so no need to provide a valid subscription ID - we're not worried
5093 // about carrier-privileged callers not having access.
Jeff Davidson7e17e312018-02-13 18:17:36 -08005094 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08005095 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
5096 "getMergedSubscriberIds")) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07005097 return null;
5098 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08005099
Jordan Liub49b04b2019-05-06 14:45:15 -07005100 // Clear calling identity, when calling TelephonyManager, because callerUid must be
5101 // the process, where TelephonyManager was instantiated.
5102 // Otherwise AppOps check will fail.
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07005103 final long identity = Binder.clearCallingIdentity();
5104 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005105 final Context context = mApp;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005106 final TelephonyManager tele = TelephonyManager.from(context);
5107 final SubscriptionManager sub = SubscriptionManager.from(context);
5108
5109 // Figure out what subscribers are currently active
5110 final ArraySet<String> activeSubscriberIds = new ArraySet<>();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005111
Jordan Liub49b04b2019-05-06 14:45:15 -07005112 // Only consider subs which match the current subId
5113 // This logic can be simplified. See b/131189269 for progress.
5114 if (isActiveSubscription(subId)) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07005115 activeSubscriberIds.add(tele.getSubscriberId(subId));
5116 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005117
5118 // First pass, find a number override for an active subscriber
5119 String mergeNumber = null;
5120 final Map<String, ?> prefs = mTelephonySharedPreferences.getAll();
5121 for (String key : prefs.keySet()) {
5122 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) {
5123 final String subscriberId = (String) prefs.get(key);
5124 if (activeSubscriberIds.contains(subscriberId)) {
5125 final String iccId = key.substring(
5126 PREF_CARRIERS_SUBSCRIBER_PREFIX.length());
5127 final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
5128 mergeNumber = (String) prefs.get(numberKey);
5129 if (DBG_MERGE) {
5130 Slog.d(LOG_TAG, "Found line number " + mergeNumber
5131 + " for active subscriber " + subscriberId);
5132 }
5133 if (!TextUtils.isEmpty(mergeNumber)) {
5134 break;
5135 }
5136 }
5137 }
5138 }
5139
5140 // Shortcut when no active merged subscribers
5141 if (TextUtils.isEmpty(mergeNumber)) {
5142 return null;
5143 }
5144
5145 // Second pass, find all subscribers under that line override
5146 final ArraySet<String> result = new ArraySet<>();
5147 for (String key : prefs.keySet()) {
5148 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) {
5149 final String number = (String) prefs.get(key);
5150 if (mergeNumber.equals(number)) {
5151 final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length());
5152 final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
5153 final String subscriberId = (String) prefs.get(subscriberKey);
5154 if (!TextUtils.isEmpty(subscriberId)) {
5155 result.add(subscriberId);
5156 }
5157 }
5158 }
5159 }
5160
5161 final String[] resultArray = result.toArray(new String[result.size()]);
5162 Arrays.sort(resultArray);
5163 if (DBG_MERGE) {
5164 Slog.d(LOG_TAG,
5165 "Found subscribers " + Arrays.toString(resultArray) + " after merge");
5166 }
5167 return resultArray;
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07005168 } finally {
5169 Binder.restoreCallingIdentity(identity);
Jeff Sharkey85190e62014-12-05 09:40:12 -08005170 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08005171 }
5172
5173 @Override
Malcolm Chen6ca97372019-07-01 16:28:21 -07005174 public String[] getMergedSubscriberIdsFromGroup(int subId, String callingPackage) {
5175 enforceReadPrivilegedPermission("getMergedSubscriberIdsFromGroup");
5176
5177 final long identity = Binder.clearCallingIdentity();
5178 try {
5179 final TelephonyManager telephonyManager = mApp.getSystemService(
5180 TelephonyManager.class);
5181 String subscriberId = telephonyManager.getSubscriberId(subId);
5182 if (subscriberId == null) {
5183 if (DBG) {
5184 log("getMergedSubscriberIdsFromGroup can't find subscriberId for subId "
5185 + subId);
5186 }
5187 return null;
5188 }
5189
5190 final SubscriptionInfo info = SubscriptionController.getInstance()
5191 .getSubscriptionInfo(subId);
5192 final ParcelUuid groupUuid = info.getGroupUuid();
5193 // If it doesn't belong to any group, return just subscriberId of itself.
5194 if (groupUuid == null) {
5195 return new String[]{subscriberId};
5196 }
5197
5198 // Get all subscriberIds from the group.
5199 final List<String> mergedSubscriberIds = new ArrayList<>();
5200 final List<SubscriptionInfo> groupInfos = SubscriptionController.getInstance()
5201 .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName());
5202 for (SubscriptionInfo subInfo : groupInfos) {
5203 subscriberId = telephonyManager.getSubscriberId(subInfo.getSubscriptionId());
5204 if (subscriberId != null) {
5205 mergedSubscriberIds.add(subscriberId);
5206 }
5207 }
5208
5209 return mergedSubscriberIds.toArray(new String[mergedSubscriberIds.size()]);
5210 } finally {
5211 Binder.restoreCallingIdentity(identity);
5212
5213 }
5214 }
5215
5216 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08005217 public boolean setOperatorBrandOverride(int subId, String brand) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005218 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
5219 subId, "setOperatorBrandOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005220
5221 final long identity = Binder.clearCallingIdentity();
5222 try {
5223 final Phone phone = getPhone(subId);
5224 return phone == null ? false : phone.setOperatorBrandOverride(brand);
5225 } finally {
5226 Binder.restoreCallingIdentity(identity);
5227 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07005228 }
Steven Liu4bf01bc2014-07-17 11:05:29 -05005229
5230 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08005231 public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
Shishir Agrawal621a47c2014-12-01 10:25:09 -08005232 List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
5233 List<String> cdmaNonRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005234 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setRoamingOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005235
5236 final long identity = Binder.clearCallingIdentity();
5237 try {
5238 final Phone phone = getPhone(subId);
5239 if (phone == null) {
5240 return false;
5241 }
5242 return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList,
5243 cdmaNonRoamingList);
5244 } finally {
5245 Binder.restoreCallingIdentity(identity);
Shishir Agrawalc04d9752016-02-19 10:41:00 -08005246 }
Shishir Agrawal621a47c2014-12-01 10:25:09 -08005247 }
5248
5249 @Override
Shuo Qian850e4d6a2018-04-25 21:02:08 +00005250 @Deprecated
5251 public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
5252 enforceModifyPermission();
5253
5254 int returnValue = 0;
5255 try {
vagdeviaf9a5b92018-08-15 16:01:53 -07005256 AsyncResult result = (AsyncResult) sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
Shuo Qian850e4d6a2018-04-25 21:02:08 +00005257 if(result.exception == null) {
5258 if (result.result != null) {
5259 byte[] responseData = (byte[])(result.result);
5260 if(responseData.length > oemResp.length) {
5261 Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +
5262 responseData.length + "bytes. Buffer Size is " +
5263 oemResp.length + "bytes.");
5264 }
5265 System.arraycopy(responseData, 0, oemResp, 0, responseData.length);
5266 returnValue = responseData.length;
5267 }
5268 } else {
5269 CommandException ex = (CommandException) result.exception;
5270 returnValue = ex.getCommandError().ordinal();
5271 if(returnValue > 0) returnValue *= -1;
5272 }
5273 } catch (RuntimeException e) {
5274 Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");
5275 returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());
5276 if(returnValue > 0) returnValue *= -1;
5277 }
5278
5279 return returnValue;
5280 }
5281
5282 @Override
Wink Saville5d475dd2014-10-17 15:00:58 -07005283 public void setRadioCapability(RadioAccessFamily[] rafs) {
5284 try {
5285 ProxyController.getInstance().setRadioCapability(rafs);
5286 } catch (RuntimeException e) {
5287 Log.w(LOG_TAG, "setRadioCapability: Runtime Exception");
5288 }
5289 }
5290
5291 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07005292 public int getRadioAccessFamily(int phoneId, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08005293 Phone phone = PhoneFactory.getPhone(phoneId);
chen xub97461a2018-10-26 14:17:57 -07005294 int raf = RadioAccessFamily.RAF_UNKNOWN;
Jeff Davidson913390f2018-02-23 17:11:49 -08005295 if (phone == null) {
chen xub97461a2018-10-26 14:17:57 -07005296 return raf;
Jeff Davidson913390f2018-02-23 17:11:49 -08005297 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005298 final long identity = Binder.clearCallingIdentity();
5299 try {
chen xub97461a2018-10-26 14:17:57 -07005300 TelephonyPermissions
5301 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5302 mApp, phone.getSubId(), "getRadioAccessFamily");
5303 raf = ProxyController.getInstance().getRadioAccessFamily(phoneId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005304 } finally {
5305 Binder.restoreCallingIdentity(identity);
5306 }
chen xub97461a2018-10-26 14:17:57 -07005307 return raf;
Wink Saville5d475dd2014-10-17 15:00:58 -07005308 }
Andrew Leedf14ead2014-10-17 14:22:52 -07005309
5310 @Override
5311 public void enableVideoCalling(boolean enable) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005312 final Phone defaultPhone = getDefaultPhone();
Andrew Leedf14ead2014-10-17 14:22:52 -07005313 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005314
5315 final long identity = Binder.clearCallingIdentity();
5316 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005317 ImsManager.getInstance(defaultPhone.getContext(),
5318 defaultPhone.getPhoneId()).setVtSetting(enable);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005319 } finally {
5320 Binder.restoreCallingIdentity(identity);
5321 }
Andrew Leedf14ead2014-10-17 14:22:52 -07005322 }
5323
5324 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07005325 public boolean isVideoCallingEnabled(String callingPackage) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005326 final Phone defaultPhone = getDefaultPhone();
Amit Mahajan578e53d2018-03-20 16:18:38 +00005327 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005328 mApp, defaultPhone.getSubId(), callingPackage, "isVideoCallingEnabled")) {
Amit Mahajan578e53d2018-03-20 16:18:38 +00005329 return false;
5330 }
Svet Ganovb320e182015-04-16 12:30:10 -07005331
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005332 final long identity = Binder.clearCallingIdentity();
5333 try {
5334 // Check the user preference and the system-level IMS setting. Even if the user has
5335 // enabled video calling, if IMS is disabled we aren't able to support video calling.
5336 // In the long run, we may instead need to check if there exists a connection service
5337 // which can support video calling.
5338 ImsManager imsManager =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005339 ImsManager.getInstance(defaultPhone.getContext(), defaultPhone.getPhoneId());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005340 return imsManager.isVtEnabledByPlatform()
5341 && imsManager.isEnhanced4gLteModeSettingEnabledByUser()
5342 && imsManager.isVtEnabledByUser();
5343 } finally {
5344 Binder.restoreCallingIdentity(identity);
5345 }
Andrew Leedf14ead2014-10-17 14:22:52 -07005346 }
Libin.Tang@motorola.comafe82642014-12-18 13:27:53 -06005347
Andrew Leea1239f22015-03-02 17:44:07 -08005348 @Override
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005349 public boolean canChangeDtmfToneLength(int subId, String callingPackage) {
5350 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5351 mApp, subId, callingPackage, "isVideoCallingEnabled")) {
5352 return false;
5353 }
5354
5355 final long identity = Binder.clearCallingIdentity();
5356 try {
5357 CarrierConfigManager configManager =
5358 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005359 return configManager.getConfigForSubId(subId)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005360 .getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL);
5361 } finally {
5362 Binder.restoreCallingIdentity(identity);
5363 }
Andrew Leea1239f22015-03-02 17:44:07 -08005364 }
5365
5366 @Override
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005367 public boolean isWorldPhone(int subId, String callingPackage) {
5368 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5369 mApp, subId, callingPackage, "isVideoCallingEnabled")) {
5370 return false;
5371 }
5372
5373 final long identity = Binder.clearCallingIdentity();
5374 try {
5375 CarrierConfigManager configManager =
5376 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005377 return configManager.getConfigForSubId(subId)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005378 .getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL);
5379 } finally {
5380 Binder.restoreCallingIdentity(identity);
5381 }
Andrew Leea1239f22015-03-02 17:44:07 -08005382 }
5383
Andrew Lee9431b832015-03-09 18:46:45 -07005384 @Override
5385 public boolean isTtyModeSupported() {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005386 TelecomManager telecomManager = TelecomManager.from(mApp);
Wooki Wu1f82f7a2016-02-15 15:59:58 +08005387 return telecomManager.isTtySupported();
Andrew Lee9431b832015-03-09 18:46:45 -07005388 }
5389
5390 @Override
5391 public boolean isHearingAidCompatibilitySupported() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005392 final long identity = Binder.clearCallingIdentity();
5393 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005394 return mApp.getResources().getBoolean(R.bool.hac_enabled);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005395 } finally {
5396 Binder.restoreCallingIdentity(identity);
5397 }
Andrew Lee9431b832015-03-09 18:46:45 -07005398 }
5399
Hall Liuf6668912018-10-31 17:05:23 -07005400 /**
5401 * Determines whether the device currently supports RTT (Real-time text). Based both on carrier
5402 * support for the feature and device firmware support.
5403 *
5404 * @return {@code true} if the device and carrier both support RTT, {@code false} otherwise.
5405 */
5406 @Override
5407 public boolean isRttSupported(int subscriptionId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005408 final long identity = Binder.clearCallingIdentity();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005409 final Phone phone = getPhone(subscriptionId);
5410 if (phone == null) {
5411 loge("isRttSupported: no Phone found. Invalid subId:" + subscriptionId);
5412 return false;
5413 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005414 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005415 boolean isCarrierSupported = mApp.getCarrierConfigForSubId(subscriptionId).getBoolean(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005416 CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
5417 boolean isDeviceSupported =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005418 phone.getContext().getResources().getBoolean(R.bool.config_support_rtt);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005419 return isCarrierSupported && isDeviceSupported;
5420 } finally {
5421 Binder.restoreCallingIdentity(identity);
5422 }
Hall Liu98187582018-01-22 19:15:32 -08005423 }
5424
Hall Liuf6668912018-10-31 17:05:23 -07005425 /**
Hall Liuf2daa022019-07-23 18:39:00 -07005426 * Determines whether the user has turned on RTT. If the carrier wants to ignore the user-set
5427 * RTT setting, will return true if the device and carrier both support RTT.
5428 * Otherwise. only returns true if the device and carrier both also support RTT.
Hall Liuf6668912018-10-31 17:05:23 -07005429 */
5430 public boolean isRttEnabled(int subscriptionId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005431 final long identity = Binder.clearCallingIdentity();
5432 try {
Hall Liuf2daa022019-07-23 18:39:00 -07005433 boolean isRttSupported = isRttSupported(subscriptionId);
5434 boolean isUserRttSettingOn = Settings.Secure.getInt(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005435 mApp.getContentResolver(), Settings.Secure.RTT_CALLING_MODE, 0) != 0;
Hall Liuf2daa022019-07-23 18:39:00 -07005436 boolean shouldIgnoreUserRttSetting = mApp.getCarrierConfigForSubId(subscriptionId)
5437 .getBoolean(CarrierConfigManager.KEY_IGNORE_RTT_MODE_SETTING_BOOL);
5438 return isRttSupported && (isUserRttSettingOn || shouldIgnoreUserRttSetting);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005439 } finally {
5440 Binder.restoreCallingIdentity(identity);
5441 }
Hall Liu3ad5f012018-04-06 16:23:39 -07005442 }
5443
Sanket Padawe7310cc72015-01-14 09:53:20 -08005444 /**
5445 * Returns the unique device ID of phone, for example, the IMEI for
5446 * GSM and the MEID for CDMA phones. Return null if device ID is not available.
5447 *
5448 * <p>Requires Permission:
5449 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
5450 */
5451 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07005452 public String getDeviceId(String callingPackage) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08005453 final Phone phone = PhoneFactory.getPhone(0);
Jeff Davidson913390f2018-02-23 17:11:49 -08005454 if (phone == null) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08005455 return null;
5456 }
Jeff Davidson913390f2018-02-23 17:11:49 -08005457 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07005458 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
5459 callingPackage, "getDeviceId")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08005460 return null;
5461 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005462
5463 final long identity = Binder.clearCallingIdentity();
5464 try {
5465 return phone.getDeviceId();
5466 } finally {
5467 Binder.restoreCallingIdentity(identity);
5468 }
Sanket Padawe7310cc72015-01-14 09:53:20 -08005469 }
5470
Ping Sunc67b7c22016-03-02 19:16:45 +08005471 /**
5472 * {@hide}
5473 * Returns the IMS Registration Status on a particular subid
5474 *
5475 * @param subId
5476 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005477 public boolean isImsRegistered(int subId) {
Ping Sunc67b7c22016-03-02 19:16:45 +08005478 Phone phone = getPhone(subId);
5479 if (phone != null) {
5480 return phone.isImsRegistered();
5481 } else {
5482 return false;
5483 }
5484 }
5485
Santos Cordon7a1885b2015-02-03 11:15:19 -08005486 @Override
5487 public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005488 final long identity = Binder.clearCallingIdentity();
5489 try {
5490 return PhoneUtils.getSubIdForPhoneAccount(phoneAccount);
5491 } finally {
5492 Binder.restoreCallingIdentity(identity);
5493 }
Santos Cordon7a1885b2015-02-03 11:15:19 -08005494 }
Nathan Harolddcfc7932015-03-18 10:01:20 -07005495
Tyler Gunnf70ed162019-04-03 15:28:53 -07005496 @Override
5497 public @Nullable PhoneAccountHandle getPhoneAccountHandleForSubscriptionId(int subscriptionId) {
5498 final long identity = Binder.clearCallingIdentity();
5499 try {
5500 Phone phone = getPhone(subscriptionId);
5501 if (phone == null) {
5502 return null;
5503 }
5504 return PhoneUtils.makePstnPhoneAccountHandle(phone);
5505 } finally {
5506 Binder.restoreCallingIdentity(identity);
5507 }
5508 }
5509
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005510 /**
5511 * @return the VoWiFi calling availability.
Nathan Haroldc55097a2015-03-11 18:14:50 -07005512 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005513 public boolean isWifiCallingAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005514 final long identity = Binder.clearCallingIdentity();
5515 try {
5516 Phone phone = getPhone(subId);
5517 if (phone != null) {
5518 return phone.isWifiCallingEnabled();
5519 } else {
5520 return false;
5521 }
5522 } finally {
5523 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005524 }
Nathan Haroldc55097a2015-03-11 18:14:50 -07005525 }
5526
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005527 /**
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005528 * @return the VT calling availability.
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07005529 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005530 public boolean isVideoTelephonyAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005531 final long identity = Binder.clearCallingIdentity();
5532 try {
5533 Phone phone = getPhone(subId);
5534 if (phone != null) {
5535 return phone.isVideoEnabled();
5536 } else {
5537 return false;
5538 }
5539 } finally {
5540 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005541 }
5542 }
5543
5544 /**
5545 * @return the IMS registration technology for the MMTEL feature. Valid return values are
5546 * defined in {@link ImsRegistrationImplBase}.
5547 */
5548 public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005549 final long identity = Binder.clearCallingIdentity();
5550 try {
5551 Phone phone = getPhone(subId);
5552 if (phone != null) {
5553 return phone.getImsRegistrationTech();
5554 } else {
5555 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
5556 }
5557 } finally {
5558 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005559 }
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07005560 }
5561
Stuart Scott8eef64f2015-04-08 15:13:54 -07005562 @Override
5563 public void factoryReset(int subId) {
5564 enforceConnectivityInternalPermission();
Stuart Scott981d8582015-04-21 14:09:50 -07005565 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
5566 return;
5567 }
5568
Svet Ganovcc087f82015-05-12 20:35:54 -07005569 final long identity = Binder.clearCallingIdentity();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005570
Svet Ganovcc087f82015-05-12 20:35:54 -07005571 try {
Stuart Scott981d8582015-04-21 14:09:50 -07005572 if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
5573 UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
Pengquan Meng85728fb2018-03-12 16:31:21 -07005574 setUserDataEnabled(subId, getDefaultDataEnabled());
Svet Ganovcc087f82015-05-12 20:35:54 -07005575 setNetworkSelectionModeAutomatic(subId);
Pengquan Meng85728fb2018-03-12 16:31:21 -07005576 setPreferredNetworkType(subId, getDefaultNetworkType(subId));
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005577 setDataRoamingEnabled(subId, getDefaultDataRoamingEnabled(subId));
5578 CarrierInfoManager.deleteAllCarrierKeysForImsiEncryption(mApp);
Svet Ganovcc087f82015-05-12 20:35:54 -07005579 }
Amit Mahajan7dbbd822019-03-13 17:33:47 -07005580 // There has been issues when Sms raw table somehow stores orphan
5581 // fragments. They lead to garbled message when new fragments come
5582 // in and combined with those stale ones. In case this happens again,
5583 // user can reset all network settings which will clean up this table.
5584 cleanUpSmsRawTable(getDefaultPhone().getContext());
Svet Ganovcc087f82015-05-12 20:35:54 -07005585 } finally {
5586 Binder.restoreCallingIdentity(identity);
Stuart Scott8eef64f2015-04-08 15:13:54 -07005587 }
5588 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01005589
Amit Mahajan7dbbd822019-03-13 17:33:47 -07005590 private void cleanUpSmsRawTable(Context context) {
5591 ContentResolver resolver = context.getContentResolver();
5592 Uri uri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete");
5593 resolver.delete(uri, null, null);
5594 }
5595
Narayan Kamath1c496c22015-04-16 14:40:19 +01005596 @Override
chen xu5d3637b2019-01-21 23:31:38 -08005597 public String getSimLocaleForSubscriber(int subId) {
5598 enforceReadPrivilegedPermission("getSimLocaleForSubscriber, subId: " + subId);
5599 final Phone phone = getPhone(subId);
5600 if (phone == null) {
5601 log("getSimLocaleForSubscriber, invalid subId");
chen xu2bb91e42019-01-24 14:35:54 -08005602 return null;
chen xu5d3637b2019-01-21 23:31:38 -08005603 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005604 final long identity = Binder.clearCallingIdentity();
5605 try {
chen xu5d3637b2019-01-21 23:31:38 -08005606 final SubscriptionInfo info = mSubscriptionController.getActiveSubscriptionInfo(subId,
5607 phone.getContext().getOpPackageName());
chen xu6291c472019-02-04 12:55:53 -08005608 if (info == null) {
5609 log("getSimLocaleForSubscriber, inactive subId: " + subId);
5610 return null;
5611 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005612 // Try and fetch the locale from the carrier properties or from the SIM language
5613 // preferences (EF-PL and EF-LI)...
5614 final int mcc = info.getMcc();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005615 String simLanguage = null;
chen xu5d3637b2019-01-21 23:31:38 -08005616 final Locale localeFromDefaultSim = phone.getLocaleFromSimAndCarrierPrefs();
5617 if (localeFromDefaultSim != null) {
5618 if (!localeFromDefaultSim.getCountry().isEmpty()) {
5619 if (DBG) log("Using locale from subId: " + subId + " locale: "
5620 + localeFromDefaultSim);
5621 return localeFromDefaultSim.toLanguageTag();
5622 } else {
5623 simLanguage = localeFromDefaultSim.getLanguage();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005624 }
5625 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01005626
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005627 // The SIM language preferences only store a language (e.g. fr = French), not an
5628 // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
5629 // the SIM and carrier preferences does not include a country we add the country
5630 // determined from the SIM MCC to provide an exact locale.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005631 final Locale mccLocale = MccTable.getLocaleFromMcc(mApp, mcc, simLanguage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005632 if (mccLocale != null) {
chen xu5d3637b2019-01-21 23:31:38 -08005633 if (DBG) log("No locale from SIM, using mcc locale:" + mccLocale);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005634 return mccLocale.toLanguageTag();
5635 }
5636
5637 if (DBG) log("No locale found - returning null");
5638 return null;
5639 } finally {
5640 Binder.restoreCallingIdentity(identity);
5641 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01005642 }
5643
5644 private List<SubscriptionInfo> getAllSubscriptionInfoList() {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005645 return mSubscriptionController.getAllSubInfoList(mApp.getOpPackageName());
Narayan Kamath1c496c22015-04-16 14:40:19 +01005646 }
5647
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005648 /**
5649 * NOTE: this method assumes permission checks are done and caller identity has been cleared.
5650 */
5651 private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005652 return mSubscriptionController.getActiveSubscriptionInfoList(mApp.getOpPackageName());
Narayan Kamath1c496c22015-04-16 14:40:19 +01005653 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07005654
Chenjie Yu1ba97252018-01-11 18:16:20 -08005655 private final ModemActivityInfo mLastModemActivityInfo =
Chen Xud78231e2019-09-10 18:49:52 -07005656 new ModemActivityInfo(0, 0, 0, new int[0], 0);
Chenjie Yu1ba97252018-01-11 18:16:20 -08005657
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07005658 /**
Adam Lesinski903a54c2016-04-11 14:49:52 -07005659 * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
5660 * representing the state of the modem.
5661 *
Chenjie Yu1ba97252018-01-11 18:16:20 -08005662 * NOTE: The underlying implementation clears the modem state, so there should only ever be one
5663 * caller to it. Everyone should call this class to get cumulative data.
Adam Lesinski903a54c2016-04-11 14:49:52 -07005664 * @hide
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07005665 */
5666 @Override
Adam Lesinski903a54c2016-04-11 14:49:52 -07005667 public void requestModemActivityInfo(ResultReceiver result) {
5668 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07005669 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005670
5671 final long identity = Binder.clearCallingIdentity();
5672 try {
5673 ModemActivityInfo ret = null;
5674 synchronized (mLastModemActivityInfo) {
5675 ModemActivityInfo info = (ModemActivityInfo) sendRequest(
5676 CMD_GET_MODEM_ACTIVITY_INFO,
vagdeviaf9a5b92018-08-15 16:01:53 -07005677 null, workSource);
Siddharth Rayb8114062018-06-17 15:02:38 -07005678 if (isModemActivityInfoValid(info)) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005679 int[] mergedTxTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
Chen Xud78231e2019-09-10 18:49:52 -07005680 int[] txTimeMs = info.getTransmitTimeMillis();
5681 int[] lastModemTxTimeMs = mLastModemActivityInfo.getTransmitTimeMillis();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005682 for (int i = 0; i < mergedTxTimeMs.length; i++) {
Chen Xud78231e2019-09-10 18:49:52 -07005683 mergedTxTimeMs[i] = txTimeMs[i] + lastModemTxTimeMs[i];
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005684 }
5685 mLastModemActivityInfo.setTimestamp(info.getTimestamp());
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005686 mLastModemActivityInfo.setSleepTimeMillis(info.getSleepTimeMillis()
5687 + mLastModemActivityInfo.getSleepTimeMillis());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005688 mLastModemActivityInfo.setIdleTimeMillis(
5689 info.getIdleTimeMillis() + mLastModemActivityInfo.getIdleTimeMillis());
Chen Xud78231e2019-09-10 18:49:52 -07005690 mLastModemActivityInfo.setTransmitTimeMillis(mergedTxTimeMs);
5691 mLastModemActivityInfo.setReceiveTimeMillis(
5692 info.getReceiveTimeMillis() + mLastModemActivityInfo
5693 .getReceiveTimeMillis());
Chenjie Yu1ba97252018-01-11 18:16:20 -08005694 }
Chen Xud78231e2019-09-10 18:49:52 -07005695
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005696 ret = new ModemActivityInfo(mLastModemActivityInfo.getTimestamp(),
5697 mLastModemActivityInfo.getSleepTimeMillis(),
5698 mLastModemActivityInfo.getIdleTimeMillis(),
Chen Xud78231e2019-09-10 18:49:52 -07005699 mLastModemActivityInfo.getTransmitTimeMillis(),
5700 mLastModemActivityInfo.getReceiveTimeMillis());
Chenjie Yu1ba97252018-01-11 18:16:20 -08005701 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005702 Bundle bundle = new Bundle();
5703 bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, ret);
5704 result.send(0, bundle);
5705 } finally {
5706 Binder.restoreCallingIdentity(identity);
Chenjie Yu1ba97252018-01-11 18:16:20 -08005707 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07005708 }
Jack Yu85bd38a2015-11-09 11:34:32 -08005709
Siddharth Rayb8114062018-06-17 15:02:38 -07005710 // Checks that ModemActivityInfo is valid. Sleep time, Idle time, Rx time and Tx time should be
5711 // less than total activity duration.
5712 private boolean isModemActivityInfoValid(ModemActivityInfo info) {
5713 if (info == null) {
5714 return false;
5715 }
5716 int activityDurationMs =
5717 (int) (info.getTimestamp() - mLastModemActivityInfo.getTimestamp());
5718 int totalTxTimeMs = 0;
Chen Xud78231e2019-09-10 18:49:52 -07005719 int[] txTimeMs = info.getTransmitTimeMillis();
5720 for (int i = 0; i < info.getTransmitPowerInfo().size(); i++) {
5721 totalTxTimeMs += txTimeMs[i];
Siddharth Rayb8114062018-06-17 15:02:38 -07005722 }
5723 return (info.isValid()
5724 && (info.getSleepTimeMillis() <= activityDurationMs)
5725 && (info.getIdleTimeMillis() <= activityDurationMs)
Chen Xud78231e2019-09-10 18:49:52 -07005726 && (info.getReceiveTimeMillis() <= activityDurationMs)
Siddharth Rayb8114062018-06-17 15:02:38 -07005727 && (totalTxTimeMs <= activityDurationMs));
5728 }
5729
Jack Yu85bd38a2015-11-09 11:34:32 -08005730 /**
5731 * {@hide}
5732 * Returns the service state information on specified subscription.
5733 */
5734 @Override
5735 public ServiceState getServiceStateForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005736 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08005737 mApp, subId, callingPackage, "getServiceStateForSubscriber")) {
Jack Yu85bd38a2015-11-09 11:34:32 -08005738 return null;
5739 }
5740
Hall Liuf19c44f2018-11-27 14:38:17 -08005741 LocationAccessPolicy.LocationPermissionResult fineLocationResult =
5742 LocationAccessPolicy.checkLocationPermission(mApp,
5743 new LocationAccessPolicy.LocationPermissionQuery.Builder()
5744 .setCallingPackage(callingPackage)
5745 .setCallingPid(Binder.getCallingPid())
5746 .setCallingUid(Binder.getCallingUid())
5747 .setMethod("getServiceStateForSubscriber")
Hall Liuf18a0cf2019-04-17 13:37:11 -07005748 .setLogAsInfo(true)
Hall Liuf19c44f2018-11-27 14:38:17 -08005749 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
5750 .build());
5751
5752 LocationAccessPolicy.LocationPermissionResult coarseLocationResult =
5753 LocationAccessPolicy.checkLocationPermission(mApp,
5754 new LocationAccessPolicy.LocationPermissionQuery.Builder()
5755 .setCallingPackage(callingPackage)
5756 .setCallingPid(Binder.getCallingPid())
5757 .setCallingUid(Binder.getCallingUid())
5758 .setMethod("getServiceStateForSubscriber")
Hall Liuf18a0cf2019-04-17 13:37:11 -07005759 .setLogAsInfo(true)
Hall Liuf19c44f2018-11-27 14:38:17 -08005760 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
5761 .build());
5762 // We don't care about hard or soft here -- all we need to know is how much info to scrub.
5763 boolean hasFinePermission =
5764 fineLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
5765 boolean hasCoarsePermission =
5766 coarseLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
5767
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005768 final long identity = Binder.clearCallingIdentity();
5769 try {
5770 final Phone phone = getPhone(subId);
5771 if (phone == null) {
5772 return null;
5773 }
Jack Yu85bd38a2015-11-09 11:34:32 -08005774
Hall Liuf19c44f2018-11-27 14:38:17 -08005775 ServiceState ss = phone.getServiceState();
5776
5777 // Scrub out the location info in ServiceState depending on what level of access
5778 // the caller has.
5779 if (hasFinePermission) return ss;
5780 if (hasCoarsePermission) return ss.sanitizeLocationInfo(false);
5781 return ss.sanitizeLocationInfo(true);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005782 } finally {
5783 Binder.restoreCallingIdentity(identity);
5784 }
Jack Yu85bd38a2015-11-09 11:34:32 -08005785 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08005786
5787 /**
5788 * Returns the URI for the per-account voicemail ringtone set in Phone settings.
5789 *
5790 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
5791 * voicemail ringtone.
5792 * @return The URI for the ringtone to play when receiving a voicemail from a specific
5793 * PhoneAccount.
5794 */
5795 @Override
5796 public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005797 final long identity = Binder.clearCallingIdentity();
5798 try {
5799 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
5800 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005801 phone = getDefaultPhone();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005802 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08005803
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005804 return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext());
5805 } finally {
5806 Binder.restoreCallingIdentity(identity);
5807 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08005808 }
5809
5810 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005811 * Sets the per-account voicemail ringtone.
5812 *
5813 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
5814 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
5815 *
5816 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
5817 * voicemail ringtone.
5818 * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
5819 * PhoneAccount.
5820 */
5821 @Override
5822 public void setVoicemailRingtoneUri(String callingPackage,
5823 PhoneAccountHandle phoneAccountHandle, Uri uri) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005824 final Phone defaultPhone = getDefaultPhone();
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005825 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
5826 if (!TextUtils.equals(callingPackage,
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005827 TelecomManager.from(defaultPhone.getContext()).getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005828 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5829 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
5830 "setVoicemailRingtoneUri");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005831 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005832
5833 final long identity = Binder.clearCallingIdentity();
5834 try {
5835 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
5836 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005837 phone = defaultPhone;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005838 }
5839 VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri);
5840 } finally {
5841 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005842 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005843 }
5844
5845 /**
Nancy Chen31f9ba12016-01-06 11:42:12 -08005846 * Returns whether vibration is set for voicemail notification in Phone settings.
5847 *
5848 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
5849 * voicemail vibration setting.
5850 * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
5851 */
5852 @Override
5853 public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005854 final long identity = Binder.clearCallingIdentity();
5855 try {
5856 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
5857 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005858 phone = getDefaultPhone();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005859 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08005860
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005861 return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext());
5862 } finally {
5863 Binder.restoreCallingIdentity(identity);
5864 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08005865 }
5866
Youhan Wange64578a2016-05-02 15:32:42 -07005867 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005868 * Sets the per-account voicemail vibration.
5869 *
5870 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
5871 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
5872 *
5873 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
5874 * voicemail vibration setting.
5875 * @param enabled Whether to enable or disable vibration for voicemail notifications from a
5876 * specific PhoneAccount.
5877 */
5878 @Override
5879 public void setVoicemailVibrationEnabled(String callingPackage,
5880 PhoneAccountHandle phoneAccountHandle, boolean enabled) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005881 final Phone defaultPhone = getDefaultPhone();
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005882 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
5883 if (!TextUtils.equals(callingPackage,
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005884 TelecomManager.from(defaultPhone.getContext()).getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005885 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5886 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
5887 "setVoicemailVibrationEnabled");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005888 }
5889
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005890 final long identity = Binder.clearCallingIdentity();
5891 try {
5892 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
5893 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005894 phone = defaultPhone;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005895 }
5896 VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled);
5897 } finally {
5898 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005899 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005900 }
5901
5902 /**
Youhan Wange64578a2016-05-02 15:32:42 -07005903 * Make sure either called from same process as self (phone) or IPC caller has read privilege.
5904 *
5905 * @throws SecurityException if the caller does not have the required permission
5906 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07005907 private void enforceReadPrivilegedPermission(String message) {
Youhan Wange64578a2016-05-02 15:32:42 -07005908 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
Brad Ebinger35c841c2018-10-01 10:40:55 -07005909 message);
Youhan Wange64578a2016-05-02 15:32:42 -07005910 }
5911
5912 /**
Ta-wei Yen30a69c82016-12-27 14:52:32 -08005913 * Make sure either called from same process as self (phone) or IPC caller has send SMS
5914 * permission.
5915 *
5916 * @throws SecurityException if the caller does not have the required permission
5917 */
5918 private void enforceSendSmsPermission() {
5919 mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null);
5920 }
5921
5922 /**
Ta-wei Yen527a9c02017-01-06 15:29:25 -08005923 * Make sure called from the package in charge of visual voicemail.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08005924 *
Ta-wei Yen527a9c02017-01-06 15:29:25 -08005925 * @throws SecurityException if the caller is not the visual voicemail package.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08005926 */
Ta-wei Yen527a9c02017-01-06 15:29:25 -08005927 private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005928 final long identity = Binder.clearCallingIdentity();
5929 try {
5930 ComponentName componentName =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005931 RemoteVvmTaskManager.getRemotePackage(mApp, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005932 if (componentName == null) {
5933 throw new SecurityException(
5934 "Caller not current active visual voicemail package[null]");
5935 }
5936 String vvmPackage = componentName.getPackageName();
5937 if (!callingPackage.equals(vvmPackage)) {
5938 throw new SecurityException("Caller not current active visual voicemail package["
5939 + vvmPackage + "]");
5940 }
5941 } finally {
5942 Binder.restoreCallingIdentity(identity);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08005943 }
5944 }
5945
5946 /**
Youhan Wange64578a2016-05-02 15:32:42 -07005947 * Return the application ID for the app type.
5948 *
5949 * @param subId the subscription ID that this request applies to.
5950 * @param appType the uicc app type.
5951 * @return Application ID for specificied app type, or null if no uicc.
5952 */
5953 @Override
5954 public String getAidForAppType(int subId, int appType) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005955 enforceReadPrivilegedPermission("getAidForAppType");
Youhan Wange64578a2016-05-02 15:32:42 -07005956 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005957
5958 final long identity = Binder.clearCallingIdentity();
Youhan Wange64578a2016-05-02 15:32:42 -07005959 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005960 if (phone == null) {
5961 return null;
5962 }
5963 String aid = null;
5964 try {
5965 aid = UiccController.getInstance().getUiccCard(phone.getPhoneId())
5966 .getApplicationByType(appType).getAid();
5967 } catch (Exception e) {
5968 Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e);
5969 }
5970 return aid;
5971 } finally {
5972 Binder.restoreCallingIdentity(identity);
Youhan Wange64578a2016-05-02 15:32:42 -07005973 }
Youhan Wange64578a2016-05-02 15:32:42 -07005974 }
5975
Youhan Wang4001d252016-05-11 10:29:41 -07005976 /**
5977 * Return the Electronic Serial Number.
5978 *
5979 * @param subId the subscription ID that this request applies to.
5980 * @return ESN or null if error.
5981 */
5982 @Override
5983 public String getEsn(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005984 enforceReadPrivilegedPermission("getEsn");
Youhan Wang4001d252016-05-11 10:29:41 -07005985 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005986
5987 final long identity = Binder.clearCallingIdentity();
Youhan Wang4001d252016-05-11 10:29:41 -07005988 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005989 if (phone == null) {
5990 return null;
5991 }
5992 String esn = null;
5993 try {
5994 esn = phone.getEsn();
5995 } catch (Exception e) {
5996 Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e);
5997 }
5998 return esn;
5999 } finally {
6000 Binder.restoreCallingIdentity(identity);
Youhan Wang4001d252016-05-11 10:29:41 -07006001 }
Youhan Wang4001d252016-05-11 10:29:41 -07006002 }
6003
Sanket Padawe99ef1e32016-05-18 16:12:33 -07006004 /**
Youhan Wang66ad5d72016-07-18 17:56:58 -07006005 * Return the Preferred Roaming List Version.
6006 *
6007 * @param subId the subscription ID that this request applies to.
6008 * @return PRLVersion or null if error.
6009 */
6010 @Override
6011 public String getCdmaPrlVersion(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07006012 enforceReadPrivilegedPermission("getCdmaPrlVersion");
Youhan Wang66ad5d72016-07-18 17:56:58 -07006013 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006014
6015 final long identity = Binder.clearCallingIdentity();
Youhan Wang66ad5d72016-07-18 17:56:58 -07006016 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006017 if (phone == null) {
6018 return null;
6019 }
6020 String cdmaPrlVersion = null;
6021 try {
6022 cdmaPrlVersion = phone.getCdmaPrlVersion();
6023 } catch (Exception e) {
6024 Log.e(LOG_TAG, "Not getting PRLVersion", e);
6025 }
6026 return cdmaPrlVersion;
6027 } finally {
6028 Binder.restoreCallingIdentity(identity);
Youhan Wang66ad5d72016-07-18 17:56:58 -07006029 }
Youhan Wang66ad5d72016-07-18 17:56:58 -07006030 }
6031
6032 /**
Sanket Padawe99ef1e32016-05-18 16:12:33 -07006033 * Get snapshot of Telephony histograms
6034 * @return List of Telephony histograms
6035 * @hide
6036 */
6037 @Override
6038 public List<TelephonyHistogram> getTelephonyHistograms() {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006039 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6040 mApp, getDefaultSubscription(), "getTelephonyHistograms");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006041
6042 final long identity = Binder.clearCallingIdentity();
6043 try {
6044 return RIL.getTelephonyRILTimingHistograms();
6045 } finally {
6046 Binder.restoreCallingIdentity(identity);
6047 }
Sanket Padawe99ef1e32016-05-18 16:12:33 -07006048 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07006049
6050 /**
6051 * {@hide}
Michele Berionne482f8202018-11-27 18:57:59 -08006052 * Set the allowed carrier list and the excluded carrier list, indicating the priority between
6053 * the two lists.
Meng Wang1a7c35a2016-05-05 20:56:15 -07006054 * Require system privileges. In the future we may add this to carrier APIs.
6055 *
Michele Berionne482f8202018-11-27 18:57:59 -08006056 * @return Integer with the result of the operation, as defined in {@link TelephonyManager}.
Meng Wang1a7c35a2016-05-05 20:56:15 -07006057 */
6058 @Override
Michele Berionne482f8202018-11-27 18:57:59 -08006059 @TelephonyManager.SetCarrierRestrictionResult
6060 public int setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules) {
Meng Wang1a7c35a2016-05-05 20:56:15 -07006061 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07006062 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Sanket Padawe13bac7b2017-03-20 15:04:47 -07006063
Michele Berionne482f8202018-11-27 18:57:59 -08006064 if (carrierRestrictionRules == null) {
6065 throw new NullPointerException("carrier restriction cannot be null");
Meng Wang9b7c4e92017-02-17 11:41:27 -08006066 }
Sanket Padawe13bac7b2017-03-20 15:04:47 -07006067
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006068 final long identity = Binder.clearCallingIdentity();
6069 try {
Michele Berionne482f8202018-11-27 18:57:59 -08006070 return (int) sendRequest(CMD_SET_ALLOWED_CARRIERS, carrierRestrictionRules,
vagdeviaf9a5b92018-08-15 16:01:53 -07006071 workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006072 } finally {
6073 Binder.restoreCallingIdentity(identity);
6074 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07006075 }
6076
6077 /**
6078 * {@hide}
Michele Berionne482f8202018-11-27 18:57:59 -08006079 * Get the allowed carrier list and the excluded carrier list, including the priority between
6080 * the two lists.
Meng Wang1a7c35a2016-05-05 20:56:15 -07006081 * Require system privileges. In the future we may add this to carrier APIs.
6082 *
Michele Berionne482f8202018-11-27 18:57:59 -08006083 * @return {@link android.telephony.CarrierRestrictionRules}
Meng Wang1a7c35a2016-05-05 20:56:15 -07006084 */
6085 @Override
Michele Berionne482f8202018-11-27 18:57:59 -08006086 public CarrierRestrictionRules getAllowedCarriers() {
Brad Ebinger35c841c2018-10-01 10:40:55 -07006087 enforceReadPrivilegedPermission("getAllowedCarriers");
vagdeviaf9a5b92018-08-15 16:01:53 -07006088 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006089
6090 final long identity = Binder.clearCallingIdentity();
6091 try {
Michele Berionne482f8202018-11-27 18:57:59 -08006092 Object response = sendRequest(CMD_GET_ALLOWED_CARRIERS, null, workSource);
6093 if (response instanceof CarrierRestrictionRules) {
6094 return (CarrierRestrictionRules) response;
6095 }
6096 // Response is an Exception of some kind,
6097 // which is signalled to the user as a NULL retval
6098 return null;
6099 } catch (Exception e) {
6100 Log.e(LOG_TAG, "getAllowedCarriers. Exception ex=" + e);
6101 return null;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006102 } finally {
6103 Binder.restoreCallingIdentity(identity);
6104 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07006105 }
6106
fionaxu59545b42016-05-25 15:53:37 -07006107 /**
6108 * Action set from carrier signalling broadcast receivers to enable/disable metered apns
6109 * @param subId the subscription ID that this action applies to.
6110 * @param enabled control enable or disable metered apns.
6111 * {@hide}
6112 */
6113 @Override
6114 public void carrierActionSetMeteredApnsEnabled(int subId, boolean enabled) {
6115 enforceModifyPermission();
6116 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006117
6118 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07006119 if (phone == null) {
6120 loge("carrierAction: SetMeteredApnsEnabled fails with invalid subId: " + subId);
6121 return;
6122 }
6123 try {
6124 phone.carrierActionSetMeteredApnsEnabled(enabled);
6125 } catch (Exception e) {
6126 Log.e(LOG_TAG, "carrierAction: SetMeteredApnsEnabled fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006127 } finally {
6128 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07006129 }
6130 }
6131
6132 /**
6133 * Action set from carrier signalling broadcast receivers to enable/disable radio
6134 * @param subId the subscription ID that this action applies to.
6135 * @param enabled control enable or disable radio.
6136 * {@hide}
6137 */
6138 @Override
6139 public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
6140 enforceModifyPermission();
6141 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006142
6143 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07006144 if (phone == null) {
6145 loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
6146 return;
6147 }
6148 try {
6149 phone.carrierActionSetRadioEnabled(enabled);
6150 } catch (Exception e) {
6151 Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006152 } finally {
6153 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07006154 }
6155 }
6156
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07006157 /**
fionaxu8da9cb12017-05-23 15:02:46 -07006158 * Action set from carrier signalling broadcast receivers to start/stop reporting the default
6159 * network status based on which carrier apps could apply actions accordingly,
6160 * enable/disable default url handler for example.
6161 *
6162 * @param subId the subscription ID that this action applies to.
6163 * @param report control start/stop reporting the default network status.
6164 * {@hide}
6165 */
6166 @Override
6167 public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
6168 enforceModifyPermission();
6169 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006170
6171 final long identity = Binder.clearCallingIdentity();
fionaxu8da9cb12017-05-23 15:02:46 -07006172 if (phone == null) {
6173 loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId);
6174 return;
6175 }
6176 try {
6177 phone.carrierActionReportDefaultNetworkStatus(report);
6178 } catch (Exception e) {
6179 Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006180 } finally {
6181 Binder.restoreCallingIdentity(identity);
fionaxu8da9cb12017-05-23 15:02:46 -07006182 }
6183 }
6184
6185 /**
fionaxud9622282017-07-17 17:51:30 -07006186 * Action set from carrier signalling broadcast receivers to reset all carrier actions
6187 * @param subId the subscription ID that this action applies to.
6188 * {@hide}
6189 */
6190 @Override
6191 public void carrierActionResetAll(int subId) {
6192 enforceModifyPermission();
6193 final Phone phone = getPhone(subId);
6194 if (phone == null) {
6195 loge("carrierAction: ResetAll fails with invalid sibId: " + subId);
6196 return;
6197 }
6198 try {
6199 phone.carrierActionResetAll();
6200 } catch (Exception e) {
6201 Log.e(LOG_TAG, "carrierAction: ResetAll fails. Exception ex=" + e);
6202 }
6203 }
6204
6205 /**
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07006206 * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a
6207 * bug report is being generated.
6208 */
6209 @Override
Ta-wei Yen99282e02016-06-21 18:19:35 -07006210 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006211 if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
6212 != PackageManager.PERMISSION_GRANTED) {
dcashman22b950d2016-06-27 11:39:02 -07006213 writer.println("Permission Denial: can't dump Phone from pid="
6214 + Binder.getCallingPid()
6215 + ", uid=" + Binder.getCallingUid()
6216 + "without permission "
6217 + android.Manifest.permission.DUMP);
6218 return;
6219 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006220 DumpsysHandler.dump(mApp, fd, writer, args);
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07006221 }
Jack Yueb89b242016-06-22 13:27:47 -07006222
Brad Ebingerdac2f002018-04-03 15:17:52 -07006223 @Override
6224 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
6225 String[] args, ShellCallback callback, ResultReceiver resultReceiver)
6226 throws RemoteException {
6227 (new TelephonyShellCommand(this)).exec(this, in, out, err, args, callback, resultReceiver);
6228 }
6229
Jack Yueb89b242016-06-22 13:27:47 -07006230 /**
Jack Yu84291ec2017-05-26 16:07:50 -07006231 * Get aggregated video call data usage since boot.
6232 *
6233 * @param perUidStats True if requesting data usage per uid, otherwise overall usage.
6234 * @return Snapshot of video call data usage
Jack Yueb89b242016-06-22 13:27:47 -07006235 * {@hide}
6236 */
6237 @Override
Jack Yu84291ec2017-05-26 16:07:50 -07006238 public NetworkStats getVtDataUsage(int subId, boolean perUidStats) {
Jack Yueb89b242016-06-22 13:27:47 -07006239 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_NETWORK_USAGE_HISTORY,
6240 null);
6241
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006242 final long identity = Binder.clearCallingIdentity();
6243 try {
6244 // NetworkStatsService keeps tracking the active network interface and identity. It
6245 // records the delta with the corresponding network identity.
6246 // We just return the total video call data usage snapshot since boot.
6247 Phone phone = getPhone(subId);
6248 if (phone != null) {
6249 return phone.getVtDataUsage(perUidStats);
6250 }
6251 return null;
6252 } finally {
6253 Binder.restoreCallingIdentity(identity);
Jack Yueb89b242016-06-22 13:27:47 -07006254 }
Jack Yueb89b242016-06-22 13:27:47 -07006255 }
Jack Yu75ab2952016-07-08 14:29:33 -07006256
6257 /**
6258 * Policy control of data connection. Usually used when data limit is passed.
6259 * @param enabled True if enabling the data, otherwise disabling.
6260 * @param subId Subscription index
6261 * {@hide}
6262 */
6263 @Override
6264 public void setPolicyDataEnabled(boolean enabled, int subId) {
6265 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006266
6267 final long identity = Binder.clearCallingIdentity();
6268 try {
6269 Phone phone = getPhone(subId);
6270 if (phone != null) {
Jack Yud79fba22018-12-13 11:51:28 -08006271 phone.getDataEnabledSettings().setPolicyDataEnabled(enabled);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006272 }
6273 } finally {
6274 Binder.restoreCallingIdentity(identity);
Jack Yu75ab2952016-07-08 14:29:33 -07006275 }
6276 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07006277
6278 /**
6279 * Get Client request stats
6280 * @return List of Client Request Stats
6281 * @hide
6282 */
6283 @Override
6284 public List<ClientRequestStats> getClientRequestStats(String callingPackage, int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006285 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08006286 mApp, subId, callingPackage, "getClientRequestStats")) {
Sooraj Sasindran9a909312016-07-18 11:57:25 -07006287 return null;
6288 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07006289 Phone phone = getPhone(subId);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07006290
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006291 final long identity = Binder.clearCallingIdentity();
6292 try {
6293 if (phone != null) {
6294 return phone.getClientRequestStats();
6295 }
6296
6297 return null;
6298 } finally {
6299 Binder.restoreCallingIdentity(identity);
6300 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07006301 }
6302
Narayan Kamathf04b5a12018-01-09 11:47:15 +00006303 private WorkSource getWorkSource(int uid) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006304 String packageName = mApp.getPackageManager().getNameForUid(uid);
Narayan Kamathf04b5a12018-01-09 11:47:15 +00006305 return new WorkSource(uid, packageName);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07006306 }
Jack Yueb4124c2017-02-16 15:32:43 -08006307
6308 /**
Grace Chen70990072017-03-24 17:21:30 -07006309 * Set SIM card power state.
Jack Yueb4124c2017-02-16 15:32:43 -08006310 *
Sanket Padawe13bac7b2017-03-20 15:04:47 -07006311 * @param slotIndex SIM slot id.
Grace Chen70990072017-03-24 17:21:30 -07006312 * @param state State of SIM (power down, power up, pass through)
6313 * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
6314 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
6315 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
Jack Yueb4124c2017-02-16 15:32:43 -08006316 *
6317 **/
6318 @Override
Grace Chen70990072017-03-24 17:21:30 -07006319 public void setSimPowerStateForSlot(int slotIndex, int state) {
Jack Yueb4124c2017-02-16 15:32:43 -08006320 enforceModifyPermission();
Sanket Padawe13bac7b2017-03-20 15:04:47 -07006321 Phone phone = PhoneFactory.getPhone(slotIndex);
6322
vagdeviaf9a5b92018-08-15 16:01:53 -07006323 WorkSource workSource = getWorkSource(Binder.getCallingUid());
6324
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006325 final long identity = Binder.clearCallingIdentity();
6326 try {
6327 if (phone != null) {
vagdeviaf9a5b92018-08-15 16:01:53 -07006328 phone.setSimPowerState(state, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006329 }
6330 } finally {
6331 Binder.restoreCallingIdentity(identity);
Jack Yueb4124c2017-02-16 15:32:43 -08006332 }
6333 }
Shuo Qiandd210312017-04-12 22:11:33 +00006334
Tyler Gunn65d45c22017-06-05 11:22:26 -07006335 private boolean isUssdApiAllowed(int subId) {
6336 CarrierConfigManager configManager =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006337 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Tyler Gunn65d45c22017-06-05 11:22:26 -07006338 if (configManager == null) {
6339 return false;
6340 }
6341 PersistableBundle pb = configManager.getConfigForSubId(subId);
6342 if (pb == null) {
6343 return false;
6344 }
6345 return pb.getBoolean(
6346 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL);
6347 }
6348
Shuo Qiandd210312017-04-12 22:11:33 +00006349 /**
6350 * Check if phone is in emergency callback mode
6351 * @return true if phone is in emergency callback mode
6352 * @param subId sub id
6353 */
goneil9c5f4872017-12-05 14:07:56 -08006354 @Override
Shuo Qiandd210312017-04-12 22:11:33 +00006355 public boolean getEmergencyCallbackMode(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07006356 enforceReadPrivilegedPermission("getEmergencyCallbackMode");
Shuo Qiandd210312017-04-12 22:11:33 +00006357 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006358
6359 final long identity = Binder.clearCallingIdentity();
6360 try {
6361 if (phone != null) {
6362 return phone.isInEcm();
6363 } else {
6364 return false;
6365 }
6366 } finally {
6367 Binder.restoreCallingIdentity(identity);
Shuo Qiandd210312017-04-12 22:11:33 +00006368 }
6369 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08006370
6371 /**
6372 * Get the current signal strength information for the given subscription.
6373 * Because this information is not updated when the device is in a low power state
6374 * it should not be relied-upon to be current.
6375 * @param subId Subscription index
6376 * @return the most recent cached signal strength info from the modem
6377 */
6378 @Override
6379 public SignalStrength getSignalStrength(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006380 final long identity = Binder.clearCallingIdentity();
6381 try {
6382 Phone p = getPhone(subId);
6383 if (p == null) {
6384 return null;
6385 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08006386
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006387 return p.getSignalStrength();
6388 } finally {
6389 Binder.restoreCallingIdentity(identity);
6390 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08006391 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00006392
Pengquan Meng77b7f132018-08-22 14:49:57 -07006393 /**
Chen Xuf792fd62018-10-17 17:54:36 +00006394 * Get the current modem radio state for the given slot.
6395 * @param slotIndex slot index.
6396 * @param callingPackage the name of the package making the call.
6397 * @return the current radio power state from the modem
6398 */
6399 @Override
6400 public int getRadioPowerState(int slotIndex, String callingPackage) {
6401 Phone phone = PhoneFactory.getPhone(slotIndex);
6402 if (phone != null) {
6403 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
6404 mApp, phone.getSubId(), callingPackage, "getRadioPowerState")) {
6405 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
6406 }
6407
6408 final long identity = Binder.clearCallingIdentity();
6409 try {
6410 return phone.getRadioPowerState();
6411 } finally {
6412 Binder.restoreCallingIdentity(identity);
6413 }
6414 }
6415 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
6416 }
6417
6418 /**
Pengquan Meng77b7f132018-08-22 14:49:57 -07006419 * Checks if data roaming is enabled on the subscription with id {@code subId}.
6420 *
6421 * <p>Requires one of the following permissions:
6422 * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
6423 * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
6424 * privileges.
6425 *
6426 * @param subId subscription id
6427 * @return {@code true} if data roaming is enabled on this subscription, otherwise return
6428 * {@code false}.
6429 */
6430 @Override
6431 public boolean isDataRoamingEnabled(int subId) {
Pengquan Meng44e66f12019-04-01 10:48:20 -07006432 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
6433 null /* message */);
6434
Pengquan Menga1bb6272018-09-06 09:59:22 -07006435 boolean isEnabled = false;
6436 final long identity = Binder.clearCallingIdentity();
Pengquan Meng77b7f132018-08-22 14:49:57 -07006437 try {
Pengquan Menga1bb6272018-09-06 09:59:22 -07006438 Phone phone = getPhone(subId);
6439 isEnabled = phone != null ? phone.getDataRoamingEnabled() : false;
Pengquan Meng77b7f132018-08-22 14:49:57 -07006440 } catch (Exception e) {
6441 TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
6442 mApp, subId, "isDataRoamingEnabled");
Pengquan Menga1bb6272018-09-06 09:59:22 -07006443 } finally {
6444 Binder.restoreCallingIdentity(identity);
Pengquan Meng77b7f132018-08-22 14:49:57 -07006445 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07006446 return isEnabled;
Pengquan Meng77b7f132018-08-22 14:49:57 -07006447 }
6448
6449
6450 /**
6451 * Enables/Disables the data roaming on the subscription with id {@code subId}.
6452 *
6453 * <p> Requires permission:
6454 * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier
6455 * privileges.
6456 *
6457 * @param subId subscription id
6458 * @param isEnabled {@code true} means enable, {@code false} means disable.
6459 */
6460 @Override
6461 public void setDataRoamingEnabled(int subId, boolean isEnabled) {
Pengquan Meng44e66f12019-04-01 10:48:20 -07006462 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6463 mApp, subId, "setDataRoamingEnabled");
6464
Pengquan Menga1bb6272018-09-06 09:59:22 -07006465 final long identity = Binder.clearCallingIdentity();
6466 try {
Pengquan Menga1bb6272018-09-06 09:59:22 -07006467 Phone phone = getPhone(subId);
6468 if (phone != null) {
6469 phone.setDataRoamingEnabled(isEnabled);
6470 }
6471 } finally {
6472 Binder.restoreCallingIdentity(identity);
Pengquan Meng77b7f132018-08-22 14:49:57 -07006473 }
6474 }
6475
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00006476 @Override
Pengquan Meng6884a2c2018-10-03 12:19:13 -07006477 public boolean isManualNetworkSelectionAllowed(int subId) {
Pengquan Meng44e66f12019-04-01 10:48:20 -07006478 TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
6479 mApp, subId, "isManualNetworkSelectionAllowed");
6480
Pengquan Meng6884a2c2018-10-03 12:19:13 -07006481 boolean isAllowed = true;
6482 final long identity = Binder.clearCallingIdentity();
6483 try {
Pengquan Meng6884a2c2018-10-03 12:19:13 -07006484 Phone phone = getPhone(subId);
6485 if (phone != null) {
6486 isAllowed = phone.isCspPlmnEnabled();
6487 }
6488 } finally {
6489 Binder.restoreCallingIdentity(identity);
6490 }
6491 return isAllowed;
6492 }
6493
6494 @Override
Jordan Liu75f43ea2019-01-17 16:56:37 -08006495 public List<UiccCardInfo> getUiccCardsInfo(String callingPackage) {
Jordan Liu1e142fc2019-04-22 15:10:43 -07006496 boolean hasReadPermission = false;
Jordan Liuc65bc952019-02-12 17:54:02 -08006497 try {
6498 enforceReadPrivilegedPermission("getUiccCardsInfo");
Jordan Liu1e142fc2019-04-22 15:10:43 -07006499 hasReadPermission = true;
Jordan Liuc65bc952019-02-12 17:54:02 -08006500 } catch (SecurityException e) {
6501 // even without READ_PRIVILEGED_PHONE_STATE, we allow the call to continue if the caller
6502 // has carrier privileges on an active UICC
6503 if (checkCarrierPrivilegesForPackageAnyPhone(callingPackage)
6504 != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
Jordan Liu1e142fc2019-04-22 15:10:43 -07006505 throw new SecurityException("Caller does not have permission.");
Jordan Liuc65bc952019-02-12 17:54:02 -08006506 }
Jordan Liu75f43ea2019-01-17 16:56:37 -08006507 }
Jordan Liu5aa07002018-12-18 15:44:48 -08006508
6509 final long identity = Binder.clearCallingIdentity();
6510 try {
Jordan Liu75f43ea2019-01-17 16:56:37 -08006511 UiccController uiccController = UiccController.getInstance();
6512 ArrayList<UiccCardInfo> cardInfos = uiccController.getAllUiccCardInfos();
Jordan Liu1e142fc2019-04-22 15:10:43 -07006513 if (hasReadPermission) {
6514 return cardInfos;
Jordan Liu75f43ea2019-01-17 16:56:37 -08006515 }
Jordan Liu1e142fc2019-04-22 15:10:43 -07006516
6517 // Remove private info if the caller doesn't have access
6518 ArrayList<UiccCardInfo> filteredInfos = new ArrayList<>();
6519 for (UiccCardInfo cardInfo : cardInfos) {
6520 // For an inactive eUICC, the UiccCard will be null even though the UiccCardInfo
6521 // is available
6522 UiccCard card = uiccController.getUiccCardForSlot(cardInfo.getSlotIndex());
6523 if (card == null || card.getUiccProfile() == null) {
6524 // assume no access if the card or profile is unavailable
6525 filteredInfos.add(cardInfo.getUnprivileged());
6526 continue;
6527 }
6528 UiccProfile profile = card.getUiccProfile();
6529 if (profile.getCarrierPrivilegeStatus(mApp.getPackageManager(), callingPackage)
6530 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
6531 filteredInfos.add(cardInfo);
6532 } else {
6533 filteredInfos.add(cardInfo.getUnprivileged());
6534 }
6535 }
6536 return filteredInfos;
Jordan Liu5aa07002018-12-18 15:44:48 -08006537 } finally {
6538 Binder.restoreCallingIdentity(identity);
6539 }
6540 }
6541
6542 @Override
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00006543 public UiccSlotInfo[] getUiccSlotsInfo() {
Brad Ebinger35c841c2018-10-01 10:40:55 -07006544 enforceReadPrivilegedPermission("getUiccSlotsInfo");
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00006545
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006546 final long identity = Binder.clearCallingIdentity();
6547 try {
6548 UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
6549 if (slots == null) {
6550 Rlog.i(LOG_TAG, "slots is null.");
6551 return null;
6552 }
6553
6554 UiccSlotInfo[] infos = new UiccSlotInfo[slots.length];
6555 for (int i = 0; i < slots.length; i++) {
6556 UiccSlot slot = slots[i];
6557 if (slot == null) {
6558 continue;
6559 }
6560
Jordan Liu7be7e652019-05-06 18:55:02 +00006561 String cardId;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006562 UiccCard card = slot.getUiccCard();
6563 if (card != null) {
6564 cardId = card.getCardId();
Jordan Liu7be7e652019-05-06 18:55:02 +00006565 } else {
Jordan Liu01bd00d2019-09-12 16:19:43 -07006566 cardId = slot.getEid();
6567 if (TextUtils.isEmpty(cardId)) {
6568 cardId = slot.getIccId();
6569 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006570 }
6571
Jordan Liu857451f2019-05-09 16:35:35 -07006572 if (cardId != null) {
6573 // if cardId is an ICCID, strip off trailing Fs before exposing to user
6574 // if cardId is an EID, it's all digits so this is fine
6575 cardId = IccUtils.stripTrailingFs(cardId);
6576 }
6577
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006578 int cardState = 0;
6579 switch (slot.getCardState()) {
6580 case CARDSTATE_ABSENT:
6581 cardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
6582 break;
6583 case CARDSTATE_PRESENT:
6584 cardState = UiccSlotInfo.CARD_STATE_INFO_PRESENT;
6585 break;
6586 case CARDSTATE_ERROR:
6587 cardState = UiccSlotInfo.CARD_STATE_INFO_ERROR;
6588 break;
6589 case CARDSTATE_RESTRICTED:
6590 cardState = UiccSlotInfo.CARD_STATE_INFO_RESTRICTED;
6591 break;
6592 default:
6593 break;
6594
6595 }
6596
6597 infos[i] = new UiccSlotInfo(
6598 slot.isActive(),
6599 slot.isEuicc(),
6600 cardId,
6601 cardState,
6602 slot.getPhoneId(),
Jordan Liua2619582019-02-14 12:56:40 -08006603 slot.isExtendedApduSupported(),
6604 slot.isRemovable());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006605 }
6606 return infos;
6607 } finally {
6608 Binder.restoreCallingIdentity(identity);
Holly Jiuyu Sun1d957c52018-04-04 13:52:42 -07006609 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00006610 }
6611
6612 @Override
6613 public boolean switchSlots(int[] physicalSlots) {
6614 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006615
6616 final long identity = Binder.clearCallingIdentity();
6617 try {
6618 return (Boolean) sendRequest(CMD_SWITCH_SLOTS, physicalSlots);
6619 } finally {
6620 Binder.restoreCallingIdentity(identity);
6621 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00006622 }
Jack Yu4c988042018-02-27 15:30:01 -08006623
6624 @Override
Jordan Liu7de49fa2018-12-06 14:48:49 -08006625 public int getCardIdForDefaultEuicc(int subId, String callingPackage) {
Jordan Liu7de49fa2018-12-06 14:48:49 -08006626 final long identity = Binder.clearCallingIdentity();
6627 try {
6628 return UiccController.getInstance().getCardIdForDefaultEuicc();
6629 } finally {
6630 Binder.restoreCallingIdentity(identity);
6631 }
6632 }
6633
6634 @Override
Jack Yu4c988042018-02-27 15:30:01 -08006635 public void setRadioIndicationUpdateMode(int subId, int filters, int mode) {
6636 enforceModifyPermission();
6637 final Phone phone = getPhone(subId);
6638 if (phone == null) {
6639 loge("setRadioIndicationUpdateMode fails with invalid subId: " + subId);
6640 return;
6641 }
6642
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006643 final long identity = Binder.clearCallingIdentity();
6644 try {
6645 phone.setRadioIndicationUpdateMode(filters, mode);
6646 } finally {
6647 Binder.restoreCallingIdentity(identity);
6648 }
Jack Yu4c988042018-02-27 15:30:01 -08006649 }
Pengquan Meng85728fb2018-03-12 16:31:21 -07006650
6651 /**
goneil47ffb6e2018-04-06 15:40:58 -07006652 * A test API to reload the UICC profile.
6653 *
6654 * <p>Requires that the calling app has permission
6655 * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
6656 * @hide
6657 */
6658 @Override
6659 public void refreshUiccProfile(int subId) {
6660 enforceModifyPermission();
6661
6662 final long identity = Binder.clearCallingIdentity();
6663 try {
6664 Phone phone = getPhone(subId);
6665 if (phone == null) {
6666 return;
6667 }
6668 UiccCard uiccCard = phone.getUiccCard();
6669 if (uiccCard == null) {
6670 return;
6671 }
6672 UiccProfile uiccProfile = uiccCard.getUiccProfile();
6673 if (uiccProfile == null) {
6674 return;
6675 }
6676 uiccProfile.refresh();
6677 } finally {
6678 Binder.restoreCallingIdentity(identity);
6679 }
6680 }
6681
6682 /**
Pengquan Meng85728fb2018-03-12 16:31:21 -07006683 * Returns false if the mobile data is disabled by default, otherwise return true.
6684 */
6685 private boolean getDefaultDataEnabled() {
6686 return "true".equalsIgnoreCase(
6687 SystemProperties.get(DEFAULT_MOBILE_DATA_PROPERTY_NAME, "true"));
6688 }
6689
6690 /**
6691 * Returns true if the data roaming is enabled by default, i.e the system property
6692 * of {@link #DEFAULT_DATA_ROAMING_PROPERTY_NAME} is true or the config of
6693 * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} is true.
6694 */
6695 private boolean getDefaultDataRoamingEnabled(int subId) {
6696 final CarrierConfigManager configMgr = (CarrierConfigManager)
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006697 mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Pengquan Meng85728fb2018-03-12 16:31:21 -07006698 boolean isDataRoamingEnabled = "true".equalsIgnoreCase(
6699 SystemProperties.get(DEFAULT_DATA_ROAMING_PROPERTY_NAME, "false"));
6700 isDataRoamingEnabled |= configMgr.getConfigForSubId(subId).getBoolean(
6701 CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
6702 return isDataRoamingEnabled;
6703 }
6704
6705 /**
6706 * Returns the default network type for the given {@code subId}, if the default network type is
6707 * not set, return {@link Phone#PREFERRED_NT_MODE}.
6708 */
6709 private int getDefaultNetworkType(int subId) {
6710 return Integer.parseInt(
6711 TelephonyManager.getTelephonyProperty(
6712 mSubscriptionController.getPhoneId(subId),
6713 DEFAULT_NETWORK_MODE_PROPERTY_NAME,
6714 String.valueOf(Phone.PREFERRED_NT_MODE)));
6715 }
fionaxua13278b2018-03-21 00:08:13 -07006716
6717 @Override
6718 public void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String
chen xueaba88a2019-03-15 13:15:10 -07006719 gid1, String gid2, String plmn, String spn, String carrierPrivilegeRules, String apn) {
fionaxua13278b2018-03-21 00:08:13 -07006720 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006721
6722 final long identity = Binder.clearCallingIdentity();
6723 try {
6724 final Phone phone = getPhone(subId);
6725 if (phone == null) {
6726 loge("setCarrierTestOverride fails with invalid subId: " + subId);
6727 return;
6728 }
chen xueaba88a2019-03-15 13:15:10 -07006729 phone.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, plmn, spn,
6730 carrierPrivilegeRules, apn);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006731 } finally {
6732 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07006733 }
fionaxua13278b2018-03-21 00:08:13 -07006734 }
6735
6736 @Override
6737 public int getCarrierIdListVersion(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07006738 enforceReadPrivilegedPermission("getCarrierIdListVersion");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006739
6740 final long identity = Binder.clearCallingIdentity();
6741 try {
6742 final Phone phone = getPhone(subId);
6743 if (phone == null) {
6744 loge("getCarrierIdListVersion fails with invalid subId: " + subId);
6745 return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
6746 }
6747 return phone.getCarrierIdListVersion();
6748 } finally {
6749 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07006750 }
fionaxua13278b2018-03-21 00:08:13 -07006751 }
Malcolm Chen2c63d402018-08-14 16:00:53 -07006752
6753 @Override
6754 public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage) {
6755 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
6756 mApp, subId, callingPackage, "getNumberOfModemsWithSimultaneousDataConnections")) {
6757 return -1;
6758 }
6759
6760 final long identity = Binder.clearCallingIdentity();
6761 try {
6762 return mPhoneConfigurationManager.getNumberOfModemsWithSimultaneousDataConnections();
6763 } finally {
6764 Binder.restoreCallingIdentity(identity);
6765 }
6766 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07006767
6768 @Override
6769 public int getCdmaRoamingMode(int subId) {
6770 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6771 mApp, subId, "getCdmaRoamingMode");
6772
6773 final long identity = Binder.clearCallingIdentity();
6774 try {
6775 return (int) sendRequest(CMD_GET_CDMA_ROAMING_MODE, null /* argument */, subId);
6776 } finally {
6777 Binder.restoreCallingIdentity(identity);
6778 }
6779 }
6780
6781 @Override
6782 public boolean setCdmaRoamingMode(int subId, int mode) {
6783 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6784 mApp, subId, "setCdmaRoamingMode");
6785
6786 final long identity = Binder.clearCallingIdentity();
6787 try {
6788 return (boolean) sendRequest(CMD_SET_CDMA_ROAMING_MODE, mode, subId);
6789 } finally {
6790 Binder.restoreCallingIdentity(identity);
6791 }
6792 }
6793
6794 @Override
6795 public boolean setCdmaSubscriptionMode(int subId, int mode) {
6796 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6797 mApp, subId, "setCdmaSubscriptionMode");
6798
6799 final long identity = Binder.clearCallingIdentity();
6800 try {
6801 return (boolean) sendRequest(CMD_SET_CDMA_SUBSCRIPTION_MODE, mode, subId);
6802 } finally {
6803 Binder.restoreCallingIdentity(identity);
6804 }
6805 }
Makoto Onukida3bf792018-09-18 16:06:29 -07006806
6807 private void ensureUserRunning(int userId) {
6808 if (!mUserManager.isUserRunning(userId)) {
6809 throw new IllegalStateException("User " + userId + " does not exist or not running");
6810 }
6811 }
6812
6813 /**
6814 * Returns a list of SMS apps on a given user.
6815 *
6816 * Only the shell user (UID 2000 or 0) can call it.
6817 * Target user must be running.
6818 */
6819 @Override
6820 public String[] getSmsApps(int userId) {
6821 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getSmsApps");
6822 ensureUserRunning(userId);
6823
6824 final Collection<SmsApplicationData> apps =
6825 SmsApplication.getApplicationCollectionAsUser(mApp, userId);
6826
6827 String[] ret = new String[apps.size()];
6828 int i = 0;
6829 for (SmsApplicationData app : apps) {
6830 ret[i++] = app.mPackageName;
6831 }
6832 return ret;
6833 }
6834
6835 /**
6836 * Returns the default SMS app package name on a given user.
6837 *
6838 * Only the shell user (UID 2000 or 0) can call it.
6839 * Target user must be running.
6840 */
6841 @Override
6842 public String getDefaultSmsApp(int userId) {
6843 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getDefaultSmsApp");
6844 ensureUserRunning(userId);
6845
6846 final ComponentName cn = SmsApplication.getDefaultSmsApplicationAsUser(mApp,
6847 /* updateIfNeeded= */ true, userId);
6848 return cn == null ? null : cn.getPackageName();
6849 }
6850
6851 /**
6852 * Set a package as the default SMS app on a given user.
6853 *
6854 * Only the shell user (UID 2000 or 0) can call it.
6855 * Target user must be running.
6856 */
6857 @Override
6858 public void setDefaultSmsApp(int userId, String packageName) {
6859 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setDefaultSmsApp");
6860 ensureUserRunning(userId);
6861
6862 boolean found = false;
6863 for (String pkg : getSmsApps(userId)) {
6864 if (TextUtils.equals(packageName, pkg)) {
6865 found = true;
6866 break;
6867 }
6868 }
6869 if (!found) {
6870 throw new IllegalArgumentException("Package " + packageName + " is not an SMS app");
6871 }
6872
6873 SmsApplication.setDefaultApplicationAsUser(packageName, mApp, userId);
6874 }
sqianc5eccab2018-10-19 18:46:41 -07006875
6876 @Override
sqian8c685422019-02-22 15:55:18 -08006877 public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList(
sqianc5eccab2018-10-19 18:46:41 -07006878 String callingPackage) {
sqian11b7a0e2018-12-05 18:48:28 -08006879 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
sqian8c685422019-02-22 15:55:18 -08006880 mApp, getDefaultSubscription(), callingPackage, "getEmergencyNumberList")) {
sqian11b7a0e2018-12-05 18:48:28 -08006881 throw new SecurityException("Requires READ_PHONE_STATE permission.");
6882 }
6883 final long identity = Binder.clearCallingIdentity();
6884 try {
sqian854d44b2018-12-12 16:48:18 -08006885 Map<Integer, List<EmergencyNumber>> emergencyNumberListInternal = new HashMap<>();
6886 for (Phone phone: PhoneFactory.getPhones()) {
6887 if (phone.getEmergencyNumberTracker() != null
6888 && phone.getEmergencyNumberTracker().getEmergencyNumberList() != null) {
6889 emergencyNumberListInternal.put(
6890 phone.getSubId(),
6891 phone.getEmergencyNumberTracker().getEmergencyNumberList());
6892 }
sqian11b7a0e2018-12-05 18:48:28 -08006893 }
sqian854d44b2018-12-12 16:48:18 -08006894 return emergencyNumberListInternal;
sqian11b7a0e2018-12-05 18:48:28 -08006895 } finally {
6896 Binder.restoreCallingIdentity(identity);
6897 }
sqianc5eccab2018-10-19 18:46:41 -07006898 }
6899
6900 @Override
sqian8c685422019-02-22 15:55:18 -08006901 public boolean isEmergencyNumber(String number, boolean exactMatch) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006902 final Phone defaultPhone = getDefaultPhone();
sqian11b7a0e2018-12-05 18:48:28 -08006903 if (!exactMatch) {
6904 TelephonyPermissions
6905 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
sqian8c685422019-02-22 15:55:18 -08006906 mApp, defaultPhone.getSubId(), "isEmergencyNumber(Potential)");
sqian11b7a0e2018-12-05 18:48:28 -08006907 }
6908 final long identity = Binder.clearCallingIdentity();
6909 try {
sqian854d44b2018-12-12 16:48:18 -08006910 for (Phone phone: PhoneFactory.getPhones()) {
6911 if (phone.getEmergencyNumberTracker() != null
6912 && phone.getEmergencyNumberTracker() != null) {
6913 if (phone.getEmergencyNumberTracker().isEmergencyNumber(
6914 number, exactMatch)) {
6915 return true;
sqian11b7a0e2018-12-05 18:48:28 -08006916 }
6917 }
sqian11b7a0e2018-12-05 18:48:28 -08006918 }
6919 return false;
6920 } finally {
6921 Binder.restoreCallingIdentity(identity);
6922 }
6923 }
6924
sqianf4ca7ed2019-01-15 18:32:07 -08006925 /**
6926 * Update emergency number list for test mode.
6927 */
6928 @Override
6929 public void updateEmergencyNumberListTestMode(int action, EmergencyNumber num) {
6930 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
6931 "updateEmergencyNumberListTestMode");
6932
6933 final long identity = Binder.clearCallingIdentity();
6934 try {
6935 for (Phone phone: PhoneFactory.getPhones()) {
6936 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
6937 if (tracker != null) {
6938 tracker.executeEmergencyNumberTestModeCommand(action, num);
6939 }
6940 }
6941 } finally {
6942 Binder.restoreCallingIdentity(identity);
6943 }
6944 }
6945
6946 /**
6947 * Get the full emergency number list for test mode.
6948 */
6949 @Override
6950 public List<String> getEmergencyNumberListTestMode() {
6951 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
6952 "getEmergencyNumberListTestMode");
6953
6954 final long identity = Binder.clearCallingIdentity();
6955 try {
6956 Set<String> emergencyNumbers = new HashSet<>();
6957 for (Phone phone: PhoneFactory.getPhones()) {
6958 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
6959 if (tracker != null) {
6960 for (EmergencyNumber num : tracker.getEmergencyNumberList()) {
6961 emergencyNumbers.add(num.getNumber());
6962 }
6963 }
6964 }
6965 return new ArrayList<>(emergencyNumbers);
6966 } finally {
6967 Binder.restoreCallingIdentity(identity);
6968 }
6969 }
6970
chen xud6b45bd2018-10-30 22:27:10 -07006971 @Override
6972 public List<String> getCertsFromCarrierPrivilegeAccessRules(int subId) {
6973 enforceReadPrivilegedPermission("getCertsFromCarrierPrivilegeAccessRules");
6974 Phone phone = getPhone(subId);
6975 if (phone == null) {
6976 return null;
6977 }
6978 final long identity = Binder.clearCallingIdentity();
6979 try {
6980 UiccProfile profile = UiccController.getInstance()
6981 .getUiccProfileForPhone(phone.getPhoneId());
6982 if (profile != null) {
6983 return profile.getCertsFromCarrierPrivilegeAccessRules();
6984 }
6985 } finally {
6986 Binder.restoreCallingIdentity(identity);
6987 }
6988 return null;
6989 }
Malcolm Chen8e4ed912019-01-15 20:22:16 -08006990
6991 /**
6992 * Enable or disable a modem stack.
6993 */
6994 @Override
6995 public boolean enableModemForSlot(int slotIndex, boolean enable) {
6996 enforceModifyPermission();
6997
6998 final long identity = Binder.clearCallingIdentity();
6999 try {
7000 Phone phone = PhoneFactory.getPhone(slotIndex);
7001 if (phone == null) {
7002 return false;
7003 } else {
7004 return (Boolean) sendRequest(CMD_REQUEST_ENABLE_MODEM, enable, phone, null);
7005 }
7006 } finally {
7007 Binder.restoreCallingIdentity(identity);
7008 }
7009 }
Michelecea4cf22018-12-21 15:00:11 -08007010
Malcolm Chen4bcd9822019-03-27 18:34:05 -07007011 /**
7012 * Whether a modem stack is enabled or not.
7013 */
7014 @Override
7015 public boolean isModemEnabledForSlot(int slotIndex, String callingPackage) {
7016 Phone phone = PhoneFactory.getPhone(slotIndex);
7017 if (phone == null) return false;
7018
7019 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
7020 mApp, phone.getSubId(), callingPackage, "isModemEnabledForSlot")) {
7021 throw new SecurityException("Requires READ_PHONE_STATE permission.");
7022 }
7023
7024 final long identity = Binder.clearCallingIdentity();
7025 try {
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07007026 try {
7027 return mPhoneConfigurationManager.getPhoneStatusFromCache(phone.getPhoneId());
7028 } catch (NoSuchElementException ex) {
7029 return (Boolean) sendRequest(CMD_GET_MODEM_STATUS, null, phone, null);
7030 }
Malcolm Chen4bcd9822019-03-27 18:34:05 -07007031 } finally {
7032 Binder.restoreCallingIdentity(identity);
7033 }
7034 }
7035
Michelecea4cf22018-12-21 15:00:11 -08007036 @Override
Michele0ea7d782019-03-19 14:58:42 -07007037 public void setMultiSimCarrierRestriction(boolean isMultiSimCarrierRestricted) {
Michelecea4cf22018-12-21 15:00:11 -08007038 enforceModifyPermission();
7039
7040 final long identity = Binder.clearCallingIdentity();
7041 try {
7042 mTelephonySharedPreferences.edit()
Michele0ea7d782019-03-19 14:58:42 -07007043 .putBoolean(PREF_MULTI_SIM_RESTRICTED, isMultiSimCarrierRestricted)
Michelecea4cf22018-12-21 15:00:11 -08007044 .commit();
7045 } finally {
7046 Binder.restoreCallingIdentity(identity);
7047 }
7048 }
7049
7050 @Override
Michele0ea7d782019-03-19 14:58:42 -07007051 @TelephonyManager.IsMultiSimSupportedResult
7052 public int isMultiSimSupported(String callingPackage) {
Michele4245e952019-02-04 11:36:23 -08007053 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp,
Michele0ea7d782019-03-19 14:58:42 -07007054 getDefaultPhone().getSubId(), callingPackage, "isMultiSimSupported")) {
7055 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele4245e952019-02-04 11:36:23 -08007056 }
Michelecea4cf22018-12-21 15:00:11 -08007057
7058 final long identity = Binder.clearCallingIdentity();
7059 try {
Michele0ea7d782019-03-19 14:58:42 -07007060 return isMultiSimSupportedInternal();
Michelecea4cf22018-12-21 15:00:11 -08007061 } finally {
7062 Binder.restoreCallingIdentity(identity);
7063 }
7064 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08007065
Michele0ea7d782019-03-19 14:58:42 -07007066 @TelephonyManager.IsMultiSimSupportedResult
7067 private int isMultiSimSupportedInternal() {
Michele30b57b22019-03-01 12:01:14 -08007068 // If the device has less than 2 SIM cards, indicate that multisim is restricted.
7069 int numPhysicalSlots = UiccController.getInstance().getUiccSlots().length;
7070 if (numPhysicalSlots < 2) {
Michele0ea7d782019-03-19 14:58:42 -07007071 loge("isMultiSimSupportedInternal: requires at least 2 cards");
7072 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -08007073 }
7074 // Check if the hardware supports multisim functionality. If usage of multisim is not
7075 // supported by the modem, indicate that it is restricted.
7076 PhoneCapability staticCapability =
7077 mPhoneConfigurationManager.getStaticPhoneCapability();
7078 if (staticCapability == null) {
Michele0ea7d782019-03-19 14:58:42 -07007079 loge("isMultiSimSupportedInternal: no static configuration available");
7080 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -08007081 }
7082 if (staticCapability.logicalModemList.size() < 2) {
Michele0ea7d782019-03-19 14:58:42 -07007083 loge("isMultiSimSupportedInternal: maximum number of modem is < 2");
7084 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -08007085 }
7086 // Check if support of multiple SIMs is restricted by carrier
7087 if (mTelephonySharedPreferences.getBoolean(PREF_MULTI_SIM_RESTRICTED, false)) {
Michele0ea7d782019-03-19 14:58:42 -07007088 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_CARRIER;
Michele30b57b22019-03-01 12:01:14 -08007089 }
7090
Michele0ea7d782019-03-19 14:58:42 -07007091 return TelephonyManager.MULTISIM_ALLOWED;
Michele30b57b22019-03-01 12:01:14 -08007092 }
7093
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08007094 /**
7095 * Switch configs to enable multi-sim or switch back to single-sim
Nazanin Bakhshi17318782019-03-01 11:56:08 -08007096 * Note: Switch from multi-sim to single-sim is only possible with MODIFY_PHONE_STATE
7097 * permission, but the other way around is possible with either MODIFY_PHONE_STATE
7098 * or carrier privileges
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08007099 * @param numOfSims number of active sims we want to switch to
7100 */
7101 @Override
7102 public void switchMultiSimConfig(int numOfSims) {
Nazanin Bakhshi17318782019-03-01 11:56:08 -08007103 if (numOfSims == 1) {
7104 enforceModifyPermission();
7105 } else {
7106 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7107 mApp, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, "switchMultiSimConfig");
7108 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08007109 final long identity = Binder.clearCallingIdentity();
Michele30b57b22019-03-01 12:01:14 -08007110
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08007111 try {
Michele30b57b22019-03-01 12:01:14 -08007112 //only proceed if multi-sim is not restricted
Michele0ea7d782019-03-19 14:58:42 -07007113 if (isMultiSimSupportedInternal() != TelephonyManager.MULTISIM_ALLOWED) {
Michele30b57b22019-03-01 12:01:14 -08007114 loge("switchMultiSimConfig not possible. It is restricted or not supported.");
7115 return;
7116 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08007117 mPhoneConfigurationManager.switchMultiSimConfig(numOfSims);
7118 } finally {
7119 Binder.restoreCallingIdentity(identity);
7120 }
7121 }
7122
Hyungjun Parkbb07fde2019-01-10 15:28:51 +09007123 @Override
7124 public boolean isApplicationOnUicc(int subId, int appType) {
7125 enforceReadPrivilegedPermission("isApplicationOnUicc");
7126 Phone phone = getPhone(subId);
7127 if (phone == null) {
7128 return false;
7129 }
7130 final long identity = Binder.clearCallingIdentity();
7131 try {
7132 UiccCard uiccCard = phone.getUiccCard();
7133 if (uiccCard == null) {
7134 return false;
7135 }
7136 UiccProfile uiccProfile = uiccCard.getUiccProfile();
7137 if (uiccProfile == null) {
7138 return false;
7139 }
7140 if (TelephonyManager.APPTYPE_SIM <= appType
7141 && appType <= TelephonyManager.APPTYPE_ISIM) {
7142 return uiccProfile.isApplicationOnIcc(AppType.values()[appType]);
7143 }
7144 return false;
7145 } finally {
7146 Binder.restoreCallingIdentity(identity);
7147 }
7148 }
7149
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08007150 /**
chen xub4baa772019-04-03 10:23:41 -07007151 * Get whether making changes to modem configurations will trigger reboot.
7152 * Return value defaults to true.
Nazanin Bakhshi5fe5ef22019-01-30 10:52:09 -08007153 */
7154 @Override
chen xub4baa772019-04-03 10:23:41 -07007155 public boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage) {
7156 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
7157 mApp, subId, callingPackage, "doesSwitchMultiSimConfigTriggerReboot")) {
7158 return false;
7159 }
Nazanin Bakhshi5fe5ef22019-01-30 10:52:09 -08007160 final long identity = Binder.clearCallingIdentity();
7161 try {
7162 return mPhoneConfigurationManager.isRebootRequiredForModemConfigChange();
7163 } finally {
7164 Binder.restoreCallingIdentity(identity);
7165 }
7166 }
7167
Nathan Harold29f5f052019-02-15 13:41:57 -08007168 private void updateModemStateMetrics() {
7169 TelephonyMetrics metrics = TelephonyMetrics.getInstance();
7170 // TODO: check the state for each modem if the api is ready.
7171 metrics.updateEnabledModemBitmap((1 << TelephonyManager.from(mApp).getPhoneCount()) - 1);
7172 }
7173
Pengquan Meng3889a572019-01-23 11:16:29 -08007174 @Override
7175 public int[] getSlotsMapping() {
7176 enforceReadPrivilegedPermission("getSlotsMapping");
7177
7178 final long identity = Binder.clearCallingIdentity();
7179 try {
7180 int phoneCount = TelephonyManager.getDefault().getPhoneCount();
7181 // All logical slots should have a mapping to a physical slot.
7182 int[] logicalSlotsMapping = new int[phoneCount];
7183 UiccSlotInfo[] slotInfos = getUiccSlotsInfo();
7184 for (int i = 0; i < slotInfos.length; i++) {
7185 if (SubscriptionManager.isValidPhoneId(slotInfos[i].getLogicalSlotIdx())) {
7186 logicalSlotsMapping[slotInfos[i].getLogicalSlotIdx()] = i;
7187 }
7188 }
7189 return logicalSlotsMapping;
7190 } finally {
7191 Binder.restoreCallingIdentity(identity);
7192 }
7193 }
Nathan Harold48d6fd52019-02-06 19:01:40 -08007194
7195 /**
7196 * Get the IRadio HAL Version
7197 */
7198 @Override
7199 public int getRadioHalVersion() {
7200 Phone phone = getDefaultPhone();
7201 if (phone == null) return -1;
7202 HalVersion hv = phone.getHalVersion();
7203 if (hv.equals(HalVersion.UNKNOWN)) return -1;
7204 return hv.major * 100 + hv.minor;
7205 }
Malcolm Chendc8c10e2019-04-10 18:25:07 -07007206
7207 /**
Malcolm Chene5ad5792019-04-18 13:51:02 -07007208 * Return whether data is enabled for certain APN type. This will tell if framework will accept
7209 * corresponding network requests on a subId.
7210 *
7211 * Data is enabled if:
Malcolm Chendc8c10e2019-04-10 18:25:07 -07007212 * 1) user data is turned on, or
Malcolm Chene5ad5792019-04-18 13:51:02 -07007213 * 2) APN is un-metered for this subscription, or
7214 * 3) APN type is whitelisted. E.g. MMS is whitelisted if
7215 * {@link SubscriptionManager#setAlwaysAllowMmsData} is turned on.
7216 *
7217 * @return whether data is allowed for a apn type.
7218 *
7219 * @hide
Malcolm Chendc8c10e2019-04-10 18:25:07 -07007220 */
7221 @Override
Malcolm Chene5ad5792019-04-18 13:51:02 -07007222 public boolean isDataEnabledForApn(int apnType, int subId, String callingPackage) {
Malcolm Chendc8c10e2019-04-10 18:25:07 -07007223 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Malcolm Chene5ad5792019-04-18 13:51:02 -07007224 mApp, subId, callingPackage, "isDataEnabledForApn")) {
7225 throw new SecurityException("Needs READ_PHONE_STATE for isDataEnabledForApn");
Malcolm Chendc8c10e2019-04-10 18:25:07 -07007226 }
7227
7228 // Now that all security checks passes, perform the operation as ourselves.
7229 final long identity = Binder.clearCallingIdentity();
7230 try {
7231 Phone phone = getPhone(subId);
7232 if (phone == null) return false;
7233
Jack Yu41407ee2019-05-13 16:54:09 -07007234 boolean isMetered = ApnSettingUtils.isMeteredApnType(apnType, phone);
Malcolm Chene5ad5792019-04-18 13:51:02 -07007235 return !isMetered || phone.getDataEnabledSettings().isDataEnabled(apnType);
7236 } finally {
7237 Binder.restoreCallingIdentity(identity);
7238 }
7239 }
7240
7241 @Override
Jack Yu41407ee2019-05-13 16:54:09 -07007242 public boolean isApnMetered(@ApnType int apnType, int subId) {
Malcolm Chene5ad5792019-04-18 13:51:02 -07007243 enforceReadPrivilegedPermission("isApnMetered");
7244
7245 // Now that all security checks passes, perform the operation as ourselves.
7246 final long identity = Binder.clearCallingIdentity();
7247 try {
7248 Phone phone = getPhone(subId);
7249 if (phone == null) return true; // By default return true.
7250
Jack Yu41407ee2019-05-13 16:54:09 -07007251 return ApnSettingUtils.isMeteredApnType(apnType, phone);
Malcolm Chendc8c10e2019-04-10 18:25:07 -07007252 } finally {
7253 Binder.restoreCallingIdentity(identity);
7254 }
7255 }
Brad Ebingera63db5f2019-04-23 16:31:13 -07007256
7257 @Override
7258 public void enqueueSmsPickResult(String callingPackage, IIntegerConsumer pendingSubIdResult) {
7259 SmsPermissions permissions = new SmsPermissions(getDefaultPhone(), mApp,
7260 (AppOpsManager) mApp.getSystemService(Context.APP_OPS_SERVICE));
7261 if (!permissions.checkCallingCanSendSms(callingPackage, "Sending message")) {
7262 throw new SecurityException("Requires SEND_SMS permission to perform this operation");
7263 }
7264 PickSmsSubscriptionActivity.addPendingResult(pendingSubIdResult);
7265 Intent intent = new Intent();
7266 intent.setClass(mApp, PickSmsSubscriptionActivity.class);
7267 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7268 // Bring up choose default SMS subscription dialog right now
7269 intent.putExtra(PickSmsSubscriptionActivity.DIALOG_TYPE_KEY,
7270 PickSmsSubscriptionActivity.SMS_PICK_FOR_MESSAGE);
7271 mApp.startActivity(intent);
7272 }
chen xud5ca2d52019-05-28 15:20:57 -07007273
7274 @Override
7275 public String getMmsUAProfUrl(int subId) {
7276 //TODO investigate if this API should require proper permission check in R b/133791609
7277 final long identity = Binder.clearCallingIdentity();
7278 try {
7279 return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
7280 .getString(com.android.internal.R.string.config_mms_user_agent_profile_url);
7281 } finally {
7282 Binder.restoreCallingIdentity(identity);
7283 }
7284 }
7285
7286 @Override
7287 public String getMmsUserAgent(int subId) {
7288 //TODO investigate if this API should require proper permission check in R b/133791609
7289 final long identity = Binder.clearCallingIdentity();
7290 try {
7291 return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
7292 .getString(com.android.internal.R.string.config_mms_user_agent);
7293 } finally {
7294 Binder.restoreCallingIdentity(identity);
7295 }
7296 }
Jack Yub07d4972019-05-28 16:12:25 -07007297
7298 @Override
7299 public boolean setDataAllowedDuringVoiceCall(int subId, boolean allow) {
7300 enforceModifyPermission();
7301
7302 // Now that all security checks passes, perform the operation as ourselves.
7303 final long identity = Binder.clearCallingIdentity();
7304 try {
7305 Phone phone = getPhone(subId);
7306 if (phone == null) return false;
7307
7308 return phone.getDataEnabledSettings().setAllowDataDuringVoiceCall(allow);
7309 } finally {
7310 Binder.restoreCallingIdentity(identity);
7311 }
7312 }
7313
7314 @Override
7315 public boolean isDataAllowedInVoiceCall(int subId) {
7316 enforceReadPrivilegedPermission("isDataAllowedInVoiceCall");
7317
7318 // Now that all security checks passes, perform the operation as ourselves.
7319 final long identity = Binder.clearCallingIdentity();
7320 try {
7321 Phone phone = getPhone(subId);
7322 if (phone == null) return false;
7323
7324 return phone.getDataEnabledSettings().isDataAllowedInVoiceCall();
7325 } finally {
7326 Binder.restoreCallingIdentity(identity);
7327 }
7328 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07007329}