blob: 74ac71a98d9c061aaba793c092a2dd0f28d00c92 [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;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070024import android.app.AppOpsManager;
Ta-wei Yen30a69c82016-12-27 14:52:32 -080025import android.app.PendingIntent;
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -070026import android.content.ComponentName;
Amit Mahajan7dbbd822019-03-13 17:33:47 -070027import android.content.ContentResolver;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070028import android.content.Context;
29import android.content.Intent;
Derek Tan97ebb422014-09-05 16:55:38 -070030import android.content.SharedPreferences;
Nathan Harold31d7ff32018-10-15 20:20:30 -070031import android.content.pm.ApplicationInfo;
Derek Tan740e1672017-06-27 14:56:27 -070032import android.content.pm.ComponentInfo;
Amith Yamasani6e118872016-02-19 12:53:51 -080033import android.content.pm.PackageInfo;
Shishir Agrawal60f9c952014-06-23 12:00:43 -070034import android.content.pm.PackageManager;
Jack Yu84291ec2017-05-26 16:07:50 -070035import android.net.NetworkStats;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070036import android.net.Uri;
37import android.os.AsyncResult;
38import android.os.Binder;
Hall Liuf19c44f2018-11-27 14:38:17 -080039import android.os.Build;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070040import android.os.Bundle;
41import android.os.Handler;
yinxu504e1392017-04-12 16:03:22 -070042import android.os.IBinder;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070043import android.os.Looper;
44import android.os.Message;
yinxu504e1392017-04-12 16:03:22 -070045import android.os.Messenger;
Tyler Gunn65d45c22017-06-05 11:22:26 -070046import android.os.PersistableBundle;
Brad Ebinger5f64b052017-12-14 14:26:15 -080047import android.os.RemoteException;
Adam Lesinski903a54c2016-04-11 14:49:52 -070048import android.os.ResultReceiver;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070049import android.os.ServiceManager;
Brad Ebingerdac2f002018-04-03 15:17:52 -070050import android.os.ShellCallback;
Pengquan Meng85728fb2018-03-12 16:31:21 -070051import android.os.SystemProperties;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070052import android.os.UserHandle;
Stuart Scott981d8582015-04-21 14:09:50 -070053import android.os.UserManager;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070054import android.os.WorkSource;
Derek Tan97ebb422014-09-05 16:55:38 -070055import android.preference.PreferenceManager;
Ihab Awadf2177b72013-11-25 13:33:23 -080056import android.provider.Settings;
Amit Mahajan7dbbd822019-03-13 17:33:47 -070057import android.provider.Telephony;
Santos Cordon7a1885b2015-02-03 11:15:19 -080058import android.telecom.PhoneAccount;
Nancy Chen31f9ba12016-01-06 11:42:12 -080059import android.telecom.PhoneAccountHandle;
Andrew Lee9431b832015-03-09 18:46:45 -070060import android.telecom.TelecomManager;
Junda Liu12f7d802015-05-01 12:06:44 -070061import android.telephony.CarrierConfigManager;
Michele Berionne482f8202018-11-27 18:57:59 -080062import android.telephony.CarrierRestrictionRules;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070063import android.telephony.CellInfo;
Nathan Haroldf180aac2018-06-01 18:43:55 -070064import android.telephony.CellInfoGsm;
65import android.telephony.CellInfoWcdma;
Nathan Harold3ff88932018-08-14 10:19:49 -070066import android.telephony.CellLocation;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070067import android.telephony.ClientRequestStats;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -070068import android.telephony.ICellInfoCallback;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -070069import android.telephony.IccOpenLogicalChannelResponse;
Hall Liu1aa510f2017-11-22 17:40:08 -080070import android.telephony.LocationAccessPolicy;
Ta-wei Yen87c49842016-05-13 21:19:52 -070071import android.telephony.ModemActivityInfo;
Jake Hambye994d462014-02-03 13:10:13 -080072import android.telephony.NeighboringCellInfo;
yinxu504e1392017-04-12 16:03:22 -070073import android.telephony.NetworkScanRequest;
Michele4245e952019-02-04 11:36:23 -080074import android.telephony.PhoneCapability;
Hall Liud892bec2018-11-30 14:51:45 -080075import android.telephony.PhoneNumberRange;
Wink Saville5d475dd2014-10-17 15:00:58 -070076import android.telephony.RadioAccessFamily;
Hall Liub2ac8ef2019-02-28 15:56:23 -080077import android.telephony.RadioAccessSpecifier;
Tyler Gunn65d45c22017-06-05 11:22:26 -070078import android.telephony.Rlog;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070079import android.telephony.ServiceState;
Nathan Harold46b42aa2017-03-10 19:38:22 -080080import android.telephony.SignalStrength;
Jack Yu84291ec2017-05-26 16:07:50 -070081import android.telephony.SmsManager;
Wink Saville0f3b5fc2014-11-11 08:40:49 -080082import android.telephony.SubscriptionInfo;
Jeff Sharkey85190e62014-12-05 09:40:12 -080083import android.telephony.SubscriptionManager;
Sanket Padawe99ef1e32016-05-18 16:12:33 -070084import android.telephony.TelephonyHistogram;
Ta-wei Yenb6929602016-05-24 15:48:27 -070085import android.telephony.TelephonyManager;
Hall Liub2ac8ef2019-02-28 15:56:23 -080086import android.telephony.TelephonyScanManager;
Jordan Liu5aa07002018-12-18 15:44:48 -080087import android.telephony.UiccCardInfo;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +000088import android.telephony.UiccSlotInfo;
Tyler Gunn65d45c22017-06-05 11:22:26 -070089import android.telephony.UssdResponse;
Ta-wei Yenb6929602016-05-24 15:48:27 -070090import android.telephony.VisualVoicemailSmsFilterSettings;
Nathan Harold3ff88932018-08-14 10:19:49 -070091import android.telephony.cdma.CdmaCellLocation;
Jack Yub5d8f642018-11-26 11:20:48 -080092import android.telephony.data.ApnSetting;
93import android.telephony.emergency.EmergencyNumber;
Nathan Harold3ff88932018-08-14 10:19:49 -070094import android.telephony.gsm.GsmCellLocation;
Brad Ebinger1c8542e2019-01-14 13:43:14 -080095import android.telephony.ims.ProvisioningManager;
Brad Ebinger35c841c2018-10-01 10:40:55 -070096import android.telephony.ims.aidl.IImsCapabilityCallback;
Brad Ebinger22bc3e42018-01-16 09:39:35 -080097import android.telephony.ims.aidl.IImsConfig;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -070098import android.telephony.ims.aidl.IImsConfigCallback;
Brad Ebinger22bc3e42018-01-16 09:39:35 -080099import android.telephony.ims.aidl.IImsMmTelFeature;
100import android.telephony.ims.aidl.IImsRcsFeature;
101import android.telephony.ims.aidl.IImsRegistration;
Brad Ebinger35c841c2018-10-01 10:40:55 -0700102import android.telephony.ims.aidl.IImsRegistrationCallback;
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800103import android.telephony.ims.feature.MmTelFeature;
104import android.telephony.ims.stub.ImsConfigImplBase;
Brad Ebinger1f2b5082018-02-08 16:11:32 -0800105import android.telephony.ims.stub.ImsRegistrationImplBase;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700106import android.text.TextUtils;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800107import android.util.ArraySet;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700108import android.util.Log;
Jake Hambye994d462014-02-03 13:10:13 -0800109import android.util.Pair;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800110import android.util.Slog;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800111
Brad Ebinger35c841c2018-10-01 10:40:55 -0700112import com.android.ims.ImsException;
Andrew Lee312e8172014-10-23 17:01:36 -0700113import com.android.ims.ImsManager;
Brad Ebinger34bef922017-11-09 10:27:08 -0800114import com.android.ims.internal.IImsServiceFeatureCallback;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700115import com.android.internal.telephony.CallManager;
Tyler Gunn52dcf772017-04-26 11:30:31 -0700116import com.android.internal.telephony.CallStateException;
pkanwar79ec0542017-07-31 14:10:01 -0700117import com.android.internal.telephony.CarrierInfoManager;
chen xu651eec72018-11-11 19:03:44 -0800118import com.android.internal.telephony.CarrierResolver;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700119import com.android.internal.telephony.CellNetworkScanResult;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700120import com.android.internal.telephony.CommandException;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700121import com.android.internal.telephony.DefaultPhoneNotifier;
Nathan Harold48d6fd52019-02-06 19:01:40 -0800122import com.android.internal.telephony.HalVersion;
Hall Liud892bec2018-11-30 14:51:45 -0800123import com.android.internal.telephony.INumberVerificationCallback;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700124import com.android.internal.telephony.ITelephony;
Jake Hambye994d462014-02-03 13:10:13 -0800125import com.android.internal.telephony.IccCard;
Jack Yu5f7092c2018-04-13 14:05:37 -0700126import com.android.internal.telephony.LocaleTracker;
Narayan Kamath1c496c22015-04-16 14:40:19 +0100127import com.android.internal.telephony.MccTable;
yinxub1bed742017-04-17 11:45:04 -0700128import com.android.internal.telephony.NetworkScanRequestTracker;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700129import com.android.internal.telephony.OperatorInfo;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700130import com.android.internal.telephony.Phone;
Malcolm Chen2c63d402018-08-14 16:00:53 -0700131import com.android.internal.telephony.PhoneConfigurationManager;
Nathan Harolda667c152016-12-14 11:27:20 -0800132import com.android.internal.telephony.PhoneConstantConversions;
Ta-wei Yen87c49842016-05-13 21:19:52 -0700133import com.android.internal.telephony.PhoneConstants;
Wink Saville36469e72014-06-11 15:17:00 -0700134import com.android.internal.telephony.PhoneFactory;
Wink Saville5d475dd2014-10-17 15:00:58 -0700135import com.android.internal.telephony.ProxyController;
Sanket Padawe99ef1e32016-05-18 16:12:33 -0700136import com.android.internal.telephony.RIL;
Svet Ganovb320e182015-04-16 12:30:10 -0700137import com.android.internal.telephony.RILConstants;
Jack Yu5f7092c2018-04-13 14:05:37 -0700138import com.android.internal.telephony.ServiceStateTracker;
Makoto Onukida3bf792018-09-18 16:06:29 -0700139import com.android.internal.telephony.SmsApplication;
140import com.android.internal.telephony.SmsApplication.SmsApplicationData;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800141import com.android.internal.telephony.SubscriptionController;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800142import com.android.internal.telephony.TelephonyPermissions;
sqianf4ca7ed2019-01-15 18:32:07 -0800143import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Derek Tan740e1672017-06-27 14:56:27 -0700144import com.android.internal.telephony.euicc.EuiccConnector;
Brad Ebinger9c0eb502019-01-23 15:06:19 -0800145import com.android.internal.telephony.ims.ImsResolver;
Pengquan Meng6c2dc9f2019-02-06 11:12:53 -0800146import com.android.internal.telephony.metrics.TelephonyMetrics;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700147import com.android.internal.telephony.uicc.IccIoResult;
148import com.android.internal.telephony.uicc.IccUtils;
Nathan Haroldb3014052017-01-25 15:57:32 -0800149import com.android.internal.telephony.uicc.SIMRecords;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700150import com.android.internal.telephony.uicc.UiccCard;
Nathan Haroldb3014052017-01-25 15:57:32 -0800151import com.android.internal.telephony.uicc.UiccCardApplication;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700152import com.android.internal.telephony.uicc.UiccController;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800153import com.android.internal.telephony.uicc.UiccProfile;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000154import com.android.internal.telephony.uicc.UiccSlot;
fionaxu7ed723d2017-05-30 18:58:54 -0700155import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
Jake Hambye994d462014-02-03 13:10:13 -0800156import com.android.internal.util.HexDump;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700157import com.android.phone.vvm.PhoneAccountHandleConverter;
Ta-wei Yen527a9c02017-01-06 15:29:25 -0800158import com.android.phone.vvm.RemoteVvmTaskManager;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700159import com.android.phone.vvm.VisualVoicemailSettingsUtil;
Ta-wei Yenc8905312017-03-28 11:14:45 -0700160import com.android.phone.vvm.VisualVoicemailSmsFilterConfig;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800161
Ta-wei Yenc236d6b2016-06-21 13:33:12 -0700162import java.io.FileDescriptor;
163import java.io.PrintWriter;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800164import java.nio.charset.StandardCharsets;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700165import java.util.ArrayList;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800166import java.util.Arrays;
Makoto Onukida3bf792018-09-18 16:06:29 -0700167import java.util.Collection;
sqian11b7a0e2018-12-05 18:48:28 -0800168import java.util.HashMap;
sqianf4ca7ed2019-01-15 18:32:07 -0800169import java.util.HashSet;
Jake Hambye994d462014-02-03 13:10:13 -0800170import java.util.List;
Narayan Kamath1c496c22015-04-16 14:40:19 +0100171import java.util.Locale;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800172import java.util.Map;
sqianf4ca7ed2019-01-15 18:32:07 -0800173import java.util.Set;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700174
175/**
176 * Implementation of the ITelephony interface.
177 */
Santos Cordon117fee72014-05-16 17:56:12 -0700178public class PhoneInterfaceManager extends ITelephony.Stub {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700179 private static final String LOG_TAG = "PhoneInterfaceManager";
180 private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
181 private static final boolean DBG_LOC = false;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800182 private static final boolean DBG_MERGE = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700183
184 // Message codes used with mMainThreadHandler
185 private static final int CMD_HANDLE_PIN_MMI = 1;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700186 private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7;
187 private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700188 private static final int CMD_OPEN_CHANNEL = 9;
189 private static final int EVENT_OPEN_CHANNEL_DONE = 10;
190 private static final int CMD_CLOSE_CHANNEL = 11;
191 private static final int EVENT_CLOSE_CHANNEL_DONE = 12;
Jake Hambye994d462014-02-03 13:10:13 -0800192 private static final int CMD_NV_READ_ITEM = 13;
193 private static final int EVENT_NV_READ_ITEM_DONE = 14;
194 private static final int CMD_NV_WRITE_ITEM = 15;
195 private static final int EVENT_NV_WRITE_ITEM_DONE = 16;
196 private static final int CMD_NV_WRITE_CDMA_PRL = 17;
197 private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18;
chen xu6dac5ab2018-10-26 17:39:23 -0700198 private static final int CMD_RESET_MODEM_CONFIG = 19;
199 private static final int EVENT_RESET_MODEM_CONFIG_DONE = 20;
Jake Hamby7c27be32014-03-03 13:25:59 -0800200 private static final int CMD_GET_PREFERRED_NETWORK_TYPE = 21;
201 private static final int EVENT_GET_PREFERRED_NETWORK_TYPE_DONE = 22;
202 private static final int CMD_SET_PREFERRED_NETWORK_TYPE = 23;
203 private static final int EVENT_SET_PREFERRED_NETWORK_TYPE_DONE = 24;
Sailesh Nepal35b59452014-03-06 09:26:56 -0800204 private static final int CMD_SEND_ENVELOPE = 25;
205 private static final int EVENT_SEND_ENVELOPE_DONE = 26;
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000206 private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27;
207 private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28;
Derek Tan6b088ee2014-09-05 14:15:18 -0700208 private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29;
209 private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30;
210 private static final int CMD_EXCHANGE_SIM_IO = 31;
211 private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800212 private static final int CMD_SET_VOICEMAIL_NUMBER = 33;
213 private static final int EVENT_SET_VOICEMAIL_NUMBER_DONE = 34;
Stuart Scott54788802015-03-30 13:18:01 -0700214 private static final int CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC = 35;
215 private static final int EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE = 36;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700216 private static final int CMD_GET_MODEM_ACTIVITY_INFO = 37;
217 private static final int EVENT_GET_MODEM_ACTIVITY_INFO_DONE = 38;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700218 private static final int CMD_PERFORM_NETWORK_SCAN = 39;
219 private static final int EVENT_PERFORM_NETWORK_SCAN_DONE = 40;
220 private static final int CMD_SET_NETWORK_SELECTION_MODE_MANUAL = 41;
221 private static final int EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE = 42;
Meng Wang1a7c35a2016-05-05 20:56:15 -0700222 private static final int CMD_SET_ALLOWED_CARRIERS = 43;
223 private static final int EVENT_SET_ALLOWED_CARRIERS_DONE = 44;
224 private static final int CMD_GET_ALLOWED_CARRIERS = 45;
225 private static final int EVENT_GET_ALLOWED_CARRIERS_DONE = 46;
pkanwar32d516d2016-10-14 19:37:38 -0700226 private static final int CMD_HANDLE_USSD_REQUEST = 47;
Nathan Haroldb3014052017-01-25 15:57:32 -0800227 private static final int CMD_GET_FORBIDDEN_PLMNS = 48;
228 private static final int EVENT_GET_FORBIDDEN_PLMNS_DONE = 49;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000229 private static final int CMD_SWITCH_SLOTS = 50;
230 private static final int EVENT_SWITCH_SLOTS_DONE = 51;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700231 private static final int CMD_GET_NETWORK_SELECTION_MODE = 52;
232 private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 53;
233 private static final int CMD_GET_CDMA_ROAMING_MODE = 54;
234 private static final int EVENT_GET_CDMA_ROAMING_MODE_DONE = 55;
235 private static final int CMD_SET_CDMA_ROAMING_MODE = 56;
236 private static final int EVENT_SET_CDMA_ROAMING_MODE_DONE = 57;
237 private static final int CMD_SET_CDMA_SUBSCRIPTION_MODE = 58;
238 private static final int EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE = 59;
Nathan Harold3ff88932018-08-14 10:19:49 -0700239 private static final int CMD_GET_ALL_CELL_INFO = 60;
240 private static final int EVENT_GET_ALL_CELL_INFO_DONE = 61;
241 private static final int CMD_GET_CELL_LOCATION = 62;
242 private static final int EVENT_GET_CELL_LOCATION_DONE = 63;
chen xu6dac5ab2018-10-26 17:39:23 -0700243 private static final int CMD_MODEM_REBOOT = 64;
244 private static final int EVENT_CMD_MODEM_REBOOT_DONE = 65;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -0700245 private static final int CMD_REQUEST_CELL_INFO_UPDATE = 66;
246 private static final int EVENT_REQUEST_CELL_INFO_UPDATE_DONE = 67;
Malcolm Chen8e4ed912019-01-15 20:22:16 -0800247 private static final int CMD_REQUEST_ENABLE_MODEM = 68;
248 private static final int EVENT_ENABLE_MODEM_DONE = 69;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700249
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -0800250 // Parameters of select command.
251 private static final int SELECT_COMMAND = 0xA4;
252 private static final int SELECT_P1 = 0x04;
253 private static final int SELECT_P2 = 0;
254 private static final int SELECT_P3 = 0x10;
255
Pengquan Meng85728fb2018-03-12 16:31:21 -0700256 private static final String DEFAULT_NETWORK_MODE_PROPERTY_NAME = "ro.telephony.default_network";
257 private static final String DEFAULT_DATA_ROAMING_PROPERTY_NAME = "ro.com.android.dataroaming";
258 private static final String DEFAULT_MOBILE_DATA_PROPERTY_NAME = "ro.com.android.mobiledata";
259
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700260 /** The singleton instance. */
261 private static PhoneInterfaceManager sInstance;
262
Wink Saville3ab207e2014-11-20 13:07:20 -0800263 private PhoneGlobals mApp;
Wink Saville3ab207e2014-11-20 13:07:20 -0800264 private CallManager mCM;
Stuart Scott981d8582015-04-21 14:09:50 -0700265 private UserManager mUserManager;
Wink Saville3ab207e2014-11-20 13:07:20 -0800266 private AppOpsManager mAppOps;
267 private MainThreadHandler mMainThreadHandler;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800268 private SubscriptionController mSubscriptionController;
Wink Saville3ab207e2014-11-20 13:07:20 -0800269 private SharedPreferences mTelephonySharedPreferences;
Malcolm Chen2c63d402018-08-14 16:00:53 -0700270 private PhoneConfigurationManager mPhoneConfigurationManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700271
Derek Tan97ebb422014-09-05 16:55:38 -0700272 private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
273 private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
Jeff Sharkey85190e62014-12-05 09:40:12 -0800274 private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800275 private static final String PREF_PROVISION_IMS_MMTEL_PREFIX = "provision_ims_mmtel_";
Derek Tan89e89d42014-07-08 17:00:10 -0700276
Michelecea4cf22018-12-21 15:00:11 -0800277 // String to store multi SIM allowed
278 private static final String PREF_MULTI_SIM_RESTRICTED = "multisim_restricted";
279
Derek Tan740e1672017-06-27 14:56:27 -0700280 // The AID of ISD-R.
281 private static final String ISDR_AID = "A0000005591010FFFFFFFF8900000100";
282
yinxub1bed742017-04-17 11:45:04 -0700283 private NetworkScanRequestTracker mNetworkScanRequestTracker;
284
David Kelly5e06a7f2018-03-12 14:10:59 +0000285 private static final int TYPE_ALLOCATION_CODE_LENGTH = 8;
286 private static final int MANUFACTURER_CODE_LENGTH = 8;
287
Derek Tan89e89d42014-07-08 17:00:10 -0700288 /**
Shishir Agrawal566b7612013-10-28 14:41:00 -0700289 * A request object to use for transmitting data to an ICC.
290 */
291 private static final class IccAPDUArgument {
292 public int channel, cla, command, p1, p2, p3;
293 public String data;
294
295 public IccAPDUArgument(int channel, int cla, int command,
296 int p1, int p2, int p3, String data) {
297 this.channel = channel;
298 this.cla = cla;
299 this.command = command;
300 this.p1 = p1;
301 this.p2 = p2;
302 this.p3 = p3;
303 this.data = data;
304 }
305 }
306
307 /**
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700308 * A request object to use for transmitting data to an ICC.
309 */
310 private static final class ManualNetworkSelectionArgument {
311 public OperatorInfo operatorInfo;
312 public boolean persistSelection;
313
314 public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) {
315 this.operatorInfo = operatorInfo;
316 this.persistSelection = persistSelection;
317 }
318 }
319
320 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700321 * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
322 * request after sending. The main thread will notify the request when it is complete.
323 */
324 private static final class MainThreadRequest {
325 /** The argument to use for the request */
326 public Object argument;
327 /** The result of the request that is run on the main thread */
328 public Object result;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800329 // The subscriber id that this request applies to. Defaults to
330 // SubscriptionManager.INVALID_SUBSCRIPTION_ID
331 public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700332
Nathan Harold92bed182018-10-12 18:16:49 -0700333 // In cases where subId is unavailable, the caller needs to specify the phone.
334 public Phone phone;
335
vagdeviaf9a5b92018-08-15 16:01:53 -0700336 public WorkSource workSource;
337
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700338 public MainThreadRequest(Object argument) {
339 this.argument = argument;
340 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800341
Nathan Harold92bed182018-10-12 18:16:49 -0700342 MainThreadRequest(Object argument, Phone phone, WorkSource workSource) {
343 this.argument = argument;
344 if (phone != null) {
345 this.phone = phone;
346 }
347 this.workSource = workSource;
348 }
349
vagdeviaf9a5b92018-08-15 16:01:53 -0700350 MainThreadRequest(Object argument, Integer subId, WorkSource workSource) {
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800351 this.argument = argument;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800352 if (subId != null) {
353 this.subId = subId;
354 }
vagdeviaf9a5b92018-08-15 16:01:53 -0700355 this.workSource = workSource;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800356 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700357 }
358
Sailesh Nepalcc0375f2013-11-13 09:15:18 -0800359 private static final class IncomingThirdPartyCallArgs {
360 public final ComponentName component;
361 public final String callId;
362 public final String callerDisplayName;
363
364 public IncomingThirdPartyCallArgs(ComponentName component, String callId,
365 String callerDisplayName) {
366 this.component = component;
367 this.callId = callId;
368 this.callerDisplayName = callerDisplayName;
369 }
370 }
371
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700372 /**
373 * A handler that processes messages on the main thread in the phone process. Since many
374 * of the Phone calls are not thread safe this is needed to shuttle the requests from the
375 * inbound binder threads to the main thread in the phone process. The Binder thread
376 * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
377 * on, which will be notified when the operation completes and will contain the result of the
378 * request.
379 *
380 * <p>If a MainThreadRequest object is provided in the msg.obj field,
381 * note that request.result must be set to something non-null for the calling thread to
382 * unblock.
383 */
384 private final class MainThreadHandler extends Handler {
385 @Override
386 public void handleMessage(Message msg) {
387 MainThreadRequest request;
388 Message onCompleted;
389 AsyncResult ar;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800390 UiccCard uiccCard;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700391 IccAPDUArgument iccArgument;
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800392 final Phone defaultPhone = getDefaultPhone();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700393
394 switch (msg.what) {
Pengquan Menga1bb6272018-09-06 09:59:22 -0700395 case CMD_HANDLE_USSD_REQUEST: {
396 request = (MainThreadRequest) msg.obj;
397 final Phone phone = getPhoneFromRequest(request);
398 Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
399 String ussdRequest = ussdObject.first;
400 ResultReceiver wrappedCallback = ussdObject.second;
Tyler Gunn65d45c22017-06-05 11:22:26 -0700401
Pengquan Menga1bb6272018-09-06 09:59:22 -0700402 if (!isUssdApiAllowed(request.subId)) {
403 // Carrier does not support use of this API, return failure.
404 Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
405 UssdResponse response = new UssdResponse(ussdRequest, null);
406 Bundle returnData = new Bundle();
407 returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
408 wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
Tyler Gunn65d45c22017-06-05 11:22:26 -0700409
Pengquan Menga1bb6272018-09-06 09:59:22 -0700410 request.result = true;
411 notifyRequester(request);
412 return;
413 }
Tyler Gunn65d45c22017-06-05 11:22:26 -0700414
Pengquan Menga1bb6272018-09-06 09:59:22 -0700415 try {
416 request.result = phone != null
417 ? phone.handleUssdRequest(ussdRequest, wrappedCallback) : false;
418 } catch (CallStateException cse) {
419 request.result = false;
420 }
421 // Wake up the requesting thread
422 notifyRequester(request);
423 break;
pkanwar32d516d2016-10-14 19:37:38 -0700424 }
425
Yorke Lee716f67e2015-06-17 15:39:16 -0700426 case CMD_HANDLE_PIN_MMI: {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700427 request = (MainThreadRequest) msg.obj;
Yorke Lee716f67e2015-06-17 15:39:16 -0700428 final Phone phone = getPhoneFromRequest(request);
429 request.result = phone != null ?
430 getPhoneFromRequest(request).handlePinMmi((String) request.argument)
431 : false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700432 // Wake up the requesting thread
Pengquan Menga1bb6272018-09-06 09:59:22 -0700433 notifyRequester(request);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700434 break;
Yorke Lee716f67e2015-06-17 15:39:16 -0700435 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700436
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700437 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700438 request = (MainThreadRequest) msg.obj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700439 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800440 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700441 if (uiccCard == null) {
442 loge("iccTransmitApduLogicalChannel: No UICC");
443 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700444 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700445 } else {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700446 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
447 request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700448 uiccCard.iccTransmitApduLogicalChannel(
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700449 iccArgument.channel, iccArgument.cla, iccArgument.command,
450 iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data,
Shishir Agrawal566b7612013-10-28 14:41:00 -0700451 onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700452 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700453 break;
454
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700455 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700456 ar = (AsyncResult) msg.obj;
457 request = (MainThreadRequest) ar.userObj;
458 if (ar.exception == null && ar.result != null) {
459 request.result = ar.result;
460 } else {
461 request.result = new IccIoResult(0x6F, 0, (byte[])null);
462 if (ar.result == null) {
463 loge("iccTransmitApduLogicalChannel: Empty response");
Jake Hambye994d462014-02-03 13:10:13 -0800464 } else if (ar.exception instanceof CommandException) {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700465 loge("iccTransmitApduLogicalChannel: CommandException: " +
Jake Hambye994d462014-02-03 13:10:13 -0800466 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700467 } else {
468 loge("iccTransmitApduLogicalChannel: Unknown exception");
469 }
470 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700471 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700472 break;
473
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700474 case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
475 request = (MainThreadRequest) msg.obj;
476 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800477 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700478 if (uiccCard == null) {
479 loge("iccTransmitApduBasicChannel: No UICC");
480 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700481 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700482 } else {
483 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
484 request);
485 uiccCard.iccTransmitApduBasicChannel(
486 iccArgument.cla, iccArgument.command, iccArgument.p1, iccArgument.p2,
487 iccArgument.p3, iccArgument.data, onCompleted);
488 }
489 break;
490
491 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
492 ar = (AsyncResult) msg.obj;
493 request = (MainThreadRequest) ar.userObj;
494 if (ar.exception == null && ar.result != null) {
495 request.result = ar.result;
496 } else {
497 request.result = new IccIoResult(0x6F, 0, (byte[])null);
498 if (ar.result == null) {
499 loge("iccTransmitApduBasicChannel: Empty response");
500 } else if (ar.exception instanceof CommandException) {
501 loge("iccTransmitApduBasicChannel: CommandException: " +
502 ar.exception);
503 } else {
504 loge("iccTransmitApduBasicChannel: Unknown exception");
505 }
506 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700507 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700508 break;
509
510 case CMD_EXCHANGE_SIM_IO:
511 request = (MainThreadRequest) msg.obj;
512 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800513 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700514 if (uiccCard == null) {
515 loge("iccExchangeSimIO: No UICC");
516 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700517 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700518 } else {
519 onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
520 request);
521 uiccCard.iccExchangeSimIO(iccArgument.cla, /* fileID */
522 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3,
523 iccArgument.data, onCompleted);
524 }
525 break;
526
527 case EVENT_EXCHANGE_SIM_IO_DONE:
528 ar = (AsyncResult) msg.obj;
529 request = (MainThreadRequest) ar.userObj;
530 if (ar.exception == null && ar.result != null) {
531 request.result = ar.result;
532 } else {
533 request.result = new IccIoResult(0x6f, 0, (byte[])null);
534 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700535 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700536 break;
537
Derek Tan4d5e5c12014-02-04 11:54:58 -0800538 case CMD_SEND_ENVELOPE:
539 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800540 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700541 if (uiccCard == null) {
542 loge("sendEnvelopeWithStatus: No UICC");
543 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700544 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700545 } else {
546 onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
547 uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted);
548 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800549 break;
550
551 case EVENT_SEND_ENVELOPE_DONE:
552 ar = (AsyncResult) msg.obj;
553 request = (MainThreadRequest) ar.userObj;
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700554 if (ar.exception == null && ar.result != null) {
555 request.result = ar.result;
Derek Tan4d5e5c12014-02-04 11:54:58 -0800556 } else {
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700557 request.result = new IccIoResult(0x6F, 0, (byte[])null);
558 if (ar.result == null) {
559 loge("sendEnvelopeWithStatus: Empty response");
560 } else if (ar.exception instanceof CommandException) {
561 loge("sendEnvelopeWithStatus: CommandException: " +
562 ar.exception);
563 } else {
564 loge("sendEnvelopeWithStatus: exception:" + ar.exception);
565 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800566 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700567 notifyRequester(request);
Derek Tan4d5e5c12014-02-04 11:54:58 -0800568 break;
569
Shishir Agrawal566b7612013-10-28 14:41:00 -0700570 case CMD_OPEN_CHANNEL:
571 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800572 uiccCard = getUiccCardFromRequest(request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800573 Pair<String, Integer> openChannelArgs = (Pair<String, Integer>) request.argument;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700574 if (uiccCard == null) {
575 loge("iccOpenLogicalChannel: No UICC");
Shishir Agrawalfc0492a2016-02-17 11:15:33 -0800576 request.result = new IccOpenLogicalChannelResponse(-1,
577 IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700578 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700579 } else {
580 onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800581 uiccCard.iccOpenLogicalChannel(openChannelArgs.first,
582 openChannelArgs.second, onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700583 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700584 break;
585
586 case EVENT_OPEN_CHANNEL_DONE:
587 ar = (AsyncResult) msg.obj;
588 request = (MainThreadRequest) ar.userObj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700589 IccOpenLogicalChannelResponse openChannelResp;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700590 if (ar.exception == null && ar.result != null) {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700591 int[] result = (int[]) ar.result;
592 int channelId = result[0];
593 byte[] selectResponse = null;
594 if (result.length > 1) {
595 selectResponse = new byte[result.length - 1];
596 for (int i = 1; i < result.length; ++i) {
597 selectResponse[i - 1] = (byte) result[i];
598 }
599 }
600 openChannelResp = new IccOpenLogicalChannelResponse(channelId,
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700601 IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700602 } else {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700603 if (ar.result == null) {
604 loge("iccOpenLogicalChannel: Empty response");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700605 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700606 if (ar.exception != null) {
607 loge("iccOpenLogicalChannel: Exception: " + ar.exception);
608 }
609
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700610 int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR;
Junda Liua754ba12015-05-20 01:17:52 -0700611 if (ar.exception instanceof CommandException) {
612 CommandException.Error error =
613 ((CommandException) (ar.exception)).getCommandError();
614 if (error == CommandException.Error.MISSING_RESOURCE) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700615 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE;
Junda Liua754ba12015-05-20 01:17:52 -0700616 } else if (error == CommandException.Error.NO_SUCH_ELEMENT) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700617 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700618 }
619 }
620 openChannelResp = new IccOpenLogicalChannelResponse(
621 IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700622 }
Shishir Agrawal82c8a462014-07-31 18:13:17 -0700623 request.result = openChannelResp;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700624 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700625 break;
626
627 case CMD_CLOSE_CHANNEL:
628 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800629 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700630 if (uiccCard == null) {
631 loge("iccCloseLogicalChannel: No UICC");
Yoshiaki Naka2e29d822016-09-02 19:27:39 +0900632 request.result = false;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700633 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700634 } else {
635 onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
636 uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
637 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700638 break;
639
640 case EVENT_CLOSE_CHANNEL_DONE:
Jake Hambye994d462014-02-03 13:10:13 -0800641 handleNullReturnEvent(msg, "iccCloseLogicalChannel");
642 break;
643
644 case CMD_NV_READ_ITEM:
645 request = (MainThreadRequest) msg.obj;
646 onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800647 defaultPhone.nvReadItem((Integer) request.argument, onCompleted,
648 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800649 break;
650
651 case EVENT_NV_READ_ITEM_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700652 ar = (AsyncResult) msg.obj;
653 request = (MainThreadRequest) ar.userObj;
Jake Hambye994d462014-02-03 13:10:13 -0800654 if (ar.exception == null && ar.result != null) {
655 request.result = ar.result; // String
Shishir Agrawal566b7612013-10-28 14:41:00 -0700656 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800657 request.result = "";
658 if (ar.result == null) {
659 loge("nvReadItem: Empty response");
660 } else if (ar.exception instanceof CommandException) {
661 loge("nvReadItem: CommandException: " +
662 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700663 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800664 loge("nvReadItem: Unknown exception");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700665 }
666 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700667 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700668 break;
669
Jake Hambye994d462014-02-03 13:10:13 -0800670 case CMD_NV_WRITE_ITEM:
671 request = (MainThreadRequest) msg.obj;
672 onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
673 Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800674 defaultPhone.nvWriteItem(idValue.first, idValue.second, onCompleted,
vagdeviaf9a5b92018-08-15 16:01:53 -0700675 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800676 break;
677
678 case EVENT_NV_WRITE_ITEM_DONE:
679 handleNullReturnEvent(msg, "nvWriteItem");
680 break;
681
682 case CMD_NV_WRITE_CDMA_PRL:
683 request = (MainThreadRequest) msg.obj;
684 onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800685 defaultPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
Jake Hambye994d462014-02-03 13:10:13 -0800686 break;
687
688 case EVENT_NV_WRITE_CDMA_PRL_DONE:
689 handleNullReturnEvent(msg, "nvWriteCdmaPrl");
690 break;
691
chen xu6dac5ab2018-10-26 17:39:23 -0700692 case CMD_RESET_MODEM_CONFIG:
Jake Hambye994d462014-02-03 13:10:13 -0800693 request = (MainThreadRequest) msg.obj;
chen xu6dac5ab2018-10-26 17:39:23 -0700694 onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800695 defaultPhone.resetModemConfig(onCompleted);
Jake Hambye994d462014-02-03 13:10:13 -0800696 break;
697
chen xu6dac5ab2018-10-26 17:39:23 -0700698 case EVENT_RESET_MODEM_CONFIG_DONE:
699 handleNullReturnEvent(msg, "resetModemConfig");
Jake Hambye994d462014-02-03 13:10:13 -0800700 break;
701
Jake Hamby7c27be32014-03-03 13:25:59 -0800702 case CMD_GET_PREFERRED_NETWORK_TYPE:
703 request = (MainThreadRequest) msg.obj;
704 onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request);
Stuart Scott54788802015-03-30 13:18:01 -0700705 getPhoneFromRequest(request).getPreferredNetworkType(onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800706 break;
707
708 case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE:
709 ar = (AsyncResult) msg.obj;
710 request = (MainThreadRequest) ar.userObj;
711 if (ar.exception == null && ar.result != null) {
712 request.result = ar.result; // Integer
713 } else {
Sanket Padawecfc2d352016-01-05 19:52:14 -0800714 request.result = null;
Jake Hamby7c27be32014-03-03 13:25:59 -0800715 if (ar.result == null) {
716 loge("getPreferredNetworkType: Empty response");
717 } else if (ar.exception instanceof CommandException) {
718 loge("getPreferredNetworkType: CommandException: " +
719 ar.exception);
720 } else {
721 loge("getPreferredNetworkType: Unknown exception");
722 }
723 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700724 notifyRequester(request);
Jake Hamby7c27be32014-03-03 13:25:59 -0800725 break;
726
727 case CMD_SET_PREFERRED_NETWORK_TYPE:
728 request = (MainThreadRequest) msg.obj;
729 onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request);
730 int networkType = (Integer) request.argument;
Stuart Scott54788802015-03-30 13:18:01 -0700731 getPhoneFromRequest(request).setPreferredNetworkType(networkType, onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800732 break;
733
734 case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE:
735 handleNullReturnEvent(msg, "setPreferredNetworkType");
736 break;
737
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000738 case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
739 request = (MainThreadRequest)msg.obj;
740 onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800741 defaultPhone.invokeOemRilRequestRaw((byte[]) request.argument, onCompleted);
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000742 break;
743
744 case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
745 ar = (AsyncResult)msg.obj;
746 request = (MainThreadRequest)ar.userObj;
747 request.result = ar;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700748 notifyRequester(request);
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000749 break;
750
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800751 case CMD_SET_VOICEMAIL_NUMBER:
752 request = (MainThreadRequest) msg.obj;
753 onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
754 Pair<String, String> tagNum = (Pair<String, String>) request.argument;
Stuart Scott584921c2015-01-15 17:10:34 -0800755 getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
756 onCompleted);
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800757 break;
758
759 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
760 handleNullReturnEvent(msg, "setVoicemailNumber");
761 break;
762
Stuart Scott54788802015-03-30 13:18:01 -0700763 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC:
764 request = (MainThreadRequest) msg.obj;
765 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE,
766 request);
767 getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted);
768 break;
769
770 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE:
771 handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic");
772 break;
773
Shishir Agrawal302c8692015-06-19 13:49:39 -0700774 case CMD_PERFORM_NETWORK_SCAN:
775 request = (MainThreadRequest) msg.obj;
776 onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request);
777 getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
778 break;
779
780 case EVENT_PERFORM_NETWORK_SCAN_DONE:
781 ar = (AsyncResult) msg.obj;
782 request = (MainThreadRequest) ar.userObj;
783 CellNetworkScanResult cellScanResult;
784 if (ar.exception == null && ar.result != null) {
785 cellScanResult = new CellNetworkScanResult(
786 CellNetworkScanResult.STATUS_SUCCESS,
787 (List<OperatorInfo>) ar.result);
788 } else {
789 if (ar.result == null) {
790 loge("getCellNetworkScanResults: Empty response");
791 }
792 if (ar.exception != null) {
793 loge("getCellNetworkScanResults: Exception: " + ar.exception);
794 }
795 int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR;
796 if (ar.exception instanceof CommandException) {
797 CommandException.Error error =
798 ((CommandException) (ar.exception)).getCommandError();
799 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
800 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE;
801 } else if (error == CommandException.Error.GENERIC_FAILURE) {
802 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE;
803 }
804 }
805 cellScanResult = new CellNetworkScanResult(errorCode, null);
806 }
807 request.result = cellScanResult;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700808 notifyRequester(request);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700809 break;
810
811 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
812 request = (MainThreadRequest) msg.obj;
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700813 ManualNetworkSelectionArgument selArg =
814 (ManualNetworkSelectionArgument) request.argument;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700815 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE,
816 request);
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700817 getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo,
818 selArg.persistSelection, onCompleted);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700819 break;
820
821 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
Pengquan Menge3d01e22018-09-20 15:25:35 -0700822 ar = (AsyncResult) msg.obj;
823 request = (MainThreadRequest) ar.userObj;
824 if (ar.exception == null) {
825 request.result = true;
826 } else {
827 request.result = false;
828 loge("setNetworkSelectionModeManual " + ar.exception);
829 }
830 notifyRequester(request);
831 mApp.onNetworkSelectionChanged(request.subId);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700832 break;
833
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700834 case CMD_GET_MODEM_ACTIVITY_INFO:
835 request = (MainThreadRequest) msg.obj;
836 onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
James Mattisab947702019-04-03 14:18:34 -0700837 if (defaultPhone != null) {
838 defaultPhone.getModemActivityInfo(onCompleted, request.workSource);
839 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700840 break;
841
842 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE:
843 ar = (AsyncResult) msg.obj;
844 request = (MainThreadRequest) ar.userObj;
845 if (ar.exception == null && ar.result != null) {
846 request.result = ar.result;
847 } else {
848 if (ar.result == null) {
849 loge("queryModemActivityInfo: Empty response");
850 } else if (ar.exception instanceof CommandException) {
851 loge("queryModemActivityInfo: CommandException: " +
852 ar.exception);
853 } else {
854 loge("queryModemActivityInfo: Unknown exception");
855 }
856 }
Amit Mahajand4766222016-01-28 15:28:28 -0800857 // Result cannot be null. Return ModemActivityInfo with all fields set to 0.
858 if (request.result == null) {
859 request.result = new ModemActivityInfo(0, 0, 0, null, 0, 0);
860 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700861 notifyRequester(request);
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700862 break;
863
Meng Wang1a7c35a2016-05-05 20:56:15 -0700864 case CMD_SET_ALLOWED_CARRIERS:
865 request = (MainThreadRequest) msg.obj;
Michele Berionne482f8202018-11-27 18:57:59 -0800866 CarrierRestrictionRules argument =
867 (CarrierRestrictionRules) request.argument;
Meng Wang1a7c35a2016-05-05 20:56:15 -0700868 onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
Michele Berionne482f8202018-11-27 18:57:59 -0800869 defaultPhone.setAllowedCarriers(argument, onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700870 break;
871
872 case EVENT_SET_ALLOWED_CARRIERS_DONE:
873 ar = (AsyncResult) msg.obj;
874 request = (MainThreadRequest) ar.userObj;
875 if (ar.exception == null && ar.result != null) {
876 request.result = ar.result;
877 } else {
Michele Berionne482f8202018-11-27 18:57:59 -0800878 request.result = TelephonyManager.SET_CARRIER_RESTRICTION_ERROR;
879 if (ar.exception instanceof CommandException) {
880 loge("setAllowedCarriers: CommandException: " + ar.exception);
881 CommandException.Error error =
882 ((CommandException) (ar.exception)).getCommandError();
883 if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
884 request.result =
885 TelephonyManager.SET_CARRIER_RESTRICTION_NOT_SUPPORTED;
886 }
Meng Wang1a7c35a2016-05-05 20:56:15 -0700887 } else {
888 loge("setAllowedCarriers: Unknown exception");
889 }
890 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700891 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700892 break;
893
894 case CMD_GET_ALLOWED_CARRIERS:
895 request = (MainThreadRequest) msg.obj;
896 onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800897 defaultPhone.getAllowedCarriers(onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700898 break;
899
900 case EVENT_GET_ALLOWED_CARRIERS_DONE:
901 ar = (AsyncResult) msg.obj;
902 request = (MainThreadRequest) ar.userObj;
903 if (ar.exception == null && ar.result != null) {
904 request.result = ar.result;
905 } else {
Michele Berionne482f8202018-11-27 18:57:59 -0800906 request.result = new IllegalStateException(
907 "Failed to get carrier restrictions");
Meng Wang1a7c35a2016-05-05 20:56:15 -0700908 if (ar.result == null) {
909 loge("getAllowedCarriers: Empty response");
910 } else if (ar.exception instanceof CommandException) {
911 loge("getAllowedCarriers: CommandException: " +
912 ar.exception);
913 } else {
914 loge("getAllowedCarriers: Unknown exception");
915 }
916 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700917 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700918 break;
919
Nathan Haroldb3014052017-01-25 15:57:32 -0800920 case EVENT_GET_FORBIDDEN_PLMNS_DONE:
921 ar = (AsyncResult) msg.obj;
922 request = (MainThreadRequest) ar.userObj;
923 if (ar.exception == null && ar.result != null) {
924 request.result = ar.result;
925 } else {
926 request.result = new IllegalArgumentException(
927 "Failed to retrieve Forbidden Plmns");
928 if (ar.result == null) {
929 loge("getForbiddenPlmns: Empty response");
930 } else {
931 loge("getForbiddenPlmns: Unknown exception");
932 }
933 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700934 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -0800935 break;
936
937 case CMD_GET_FORBIDDEN_PLMNS:
938 request = (MainThreadRequest) msg.obj;
939 uiccCard = getUiccCardFromRequest(request);
940 if (uiccCard == null) {
941 loge("getForbiddenPlmns() UiccCard is null");
942 request.result = new IllegalArgumentException(
943 "getForbiddenPlmns() UiccCard is null");
Pengquan Menga1bb6272018-09-06 09:59:22 -0700944 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -0800945 break;
946 }
947 Integer appType = (Integer) request.argument;
948 UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType);
949 if (uiccApp == null) {
950 loge("getForbiddenPlmns() no app with specified type -- "
951 + appType);
952 request.result = new IllegalArgumentException("Failed to get UICC App");
Pengquan Menga1bb6272018-09-06 09:59:22 -0700953 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -0800954 break;
955 } else {
956 if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
957 + " specified type -- " + appType);
958 }
959 onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
960 ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
961 onCompleted);
962 break;
963
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000964 case CMD_SWITCH_SLOTS:
965 request = (MainThreadRequest) msg.obj;
966 int[] physicalSlots = (int[]) request.argument;
967 onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
968 UiccController.getInstance().switchSlots(physicalSlots, onCompleted);
969 break;
970
971 case EVENT_SWITCH_SLOTS_DONE:
972 ar = (AsyncResult) msg.obj;
973 request = (MainThreadRequest) ar.userObj;
974 request.result = (ar.exception == null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700975 notifyRequester(request);
976 break;
977 case CMD_GET_NETWORK_SELECTION_MODE:
978 request = (MainThreadRequest) msg.obj;
979 onCompleted = obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE, request);
980 getPhoneFromRequest(request).getNetworkSelectionMode(onCompleted);
981 break;
982
983 case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
984 ar = (AsyncResult) msg.obj;
985 request = (MainThreadRequest) ar.userObj;
986 if (ar.exception != null) {
987 request.result = TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
988 } else {
989 int mode = ((int[]) ar.result)[0];
990 if (mode == 0) {
991 request.result = TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
992 } else {
993 request.result = TelephonyManager.NETWORK_SELECTION_MODE_MANUAL;
994 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000995 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700996 notifyRequester(request);
997 break;
998 case CMD_GET_CDMA_ROAMING_MODE:
999 request = (MainThreadRequest) msg.obj;
1000 onCompleted = obtainMessage(EVENT_GET_CDMA_ROAMING_MODE_DONE, request);
1001 getPhoneFromRequest(request).queryCdmaRoamingPreference(onCompleted);
1002 break;
1003 case EVENT_GET_CDMA_ROAMING_MODE_DONE:
1004 ar = (AsyncResult) msg.obj;
1005 request = (MainThreadRequest) ar.userObj;
1006 if (ar.exception != null) {
1007 request.result = TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT;
1008 } else {
1009 request.result = ((int[]) ar.result)[0];
1010 }
1011 notifyRequester(request);
1012 break;
1013 case CMD_SET_CDMA_ROAMING_MODE:
1014 request = (MainThreadRequest) msg.obj;
1015 onCompleted = obtainMessage(EVENT_SET_CDMA_ROAMING_MODE_DONE, request);
1016 int mode = (int) request.argument;
1017 getPhoneFromRequest(request).setCdmaRoamingPreference(mode, onCompleted);
1018 break;
1019 case EVENT_SET_CDMA_ROAMING_MODE_DONE:
1020 ar = (AsyncResult) msg.obj;
1021 request = (MainThreadRequest) ar.userObj;
1022 request.result = ar.exception == null;
1023 notifyRequester(request);
1024 break;
1025 case CMD_SET_CDMA_SUBSCRIPTION_MODE:
1026 request = (MainThreadRequest) msg.obj;
1027 onCompleted = obtainMessage(EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1028 int subscriptionMode = (int) request.argument;
1029 getPhoneFromRequest(request).setCdmaSubscription(subscriptionMode, onCompleted);
1030 break;
1031 case EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE:
1032 ar = (AsyncResult) msg.obj;
1033 request = (MainThreadRequest) ar.userObj;
1034 request.result = ar.exception == null;
1035 notifyRequester(request);
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001036 break;
Nathan Harold3ff88932018-08-14 10:19:49 -07001037 case CMD_GET_ALL_CELL_INFO:
1038 request = (MainThreadRequest) msg.obj;
Nathan Harold3ff88932018-08-14 10:19:49 -07001039 onCompleted = obtainMessage(EVENT_GET_ALL_CELL_INFO_DONE, request);
Nathan Harold92bed182018-10-12 18:16:49 -07001040 request.phone.requestCellInfoUpdate(request.workSource, onCompleted);
Nathan Harold3ff88932018-08-14 10:19:49 -07001041 break;
Nathan Harold3ff88932018-08-14 10:19:49 -07001042 case EVENT_GET_ALL_CELL_INFO_DONE:
1043 ar = (AsyncResult) msg.obj;
1044 request = (MainThreadRequest) ar.userObj;
Nathan Harold8d0f1742018-10-02 12:14:47 -07001045 // If a timeout occurs, the response will be null
1046 request.result = (ar.exception == null && ar.result != null)
1047 ? ar.result : new ArrayList<CellInfo>();
Nathan Harold3ff88932018-08-14 10:19:49 -07001048 synchronized (request) {
1049 request.notifyAll();
1050 }
1051 break;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001052 case CMD_REQUEST_CELL_INFO_UPDATE:
1053 request = (MainThreadRequest) msg.obj;
1054 request.phone.requestCellInfoUpdate(request.workSource,
1055 obtainMessage(EVENT_REQUEST_CELL_INFO_UPDATE_DONE, request));
1056 break;
1057 case EVENT_REQUEST_CELL_INFO_UPDATE_DONE:
1058 ar = (AsyncResult) msg.obj;
1059 request = (MainThreadRequest) ar.userObj;
1060 ICellInfoCallback cb = (ICellInfoCallback) request.argument;
1061 try {
1062 if (ar.exception != null) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001063 Log.e(LOG_TAG, "Exception retrieving CellInfo=" + ar.exception);
Nathan Harolde82c4b82018-12-18 19:40:37 -08001064 cb.onError(TelephonyManager.CellInfoCallback.ERROR_MODEM_ERROR,
1065 new android.os.ParcelableException(ar.exception));
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001066 } else if (ar.result == null) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001067 Log.w(LOG_TAG, "Timeout Waiting for CellInfo!");
Nathan Harolde82c4b82018-12-18 19:40:37 -08001068 cb.onError(TelephonyManager.CellInfoCallback.ERROR_TIMEOUT, null);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001069 } else {
1070 // use the result as returned
1071 cb.onCellInfo((List<CellInfo>) ar.result);
1072 }
1073 } catch (RemoteException re) {
1074 Log.w(LOG_TAG, "Discarded CellInfo due to Callback RemoteException");
1075 }
1076 break;
1077 case CMD_GET_CELL_LOCATION:
Nathan Harold3ff88932018-08-14 10:19:49 -07001078 request = (MainThreadRequest) msg.obj;
1079 WorkSource ws = (WorkSource) request.argument;
1080 Phone phone = getPhoneFromRequest(request);
1081 phone.getCellLocation(ws, obtainMessage(EVENT_GET_CELL_LOCATION_DONE, request));
1082 break;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001083 case EVENT_GET_CELL_LOCATION_DONE:
Nathan Harold3ff88932018-08-14 10:19:49 -07001084 ar = (AsyncResult) msg.obj;
1085 request = (MainThreadRequest) ar.userObj;
1086 if (ar.exception == null) {
1087 request.result = ar.result;
1088 } else {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001089 phone = getPhoneFromRequest(request);
Nathan Harold3ff88932018-08-14 10:19:49 -07001090 request.result = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
1091 ? new CdmaCellLocation() : new GsmCellLocation();
1092 }
1093
1094 synchronized (request) {
1095 request.notifyAll();
1096 }
1097 break;
chen xu6dac5ab2018-10-26 17:39:23 -07001098 case CMD_MODEM_REBOOT:
1099 request = (MainThreadRequest) msg.obj;
1100 onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001101 defaultPhone.rebootModem(onCompleted);
chen xu6dac5ab2018-10-26 17:39:23 -07001102 break;
chen xu6dac5ab2018-10-26 17:39:23 -07001103 case EVENT_CMD_MODEM_REBOOT_DONE:
1104 handleNullReturnEvent(msg, "rebootModem");
1105 break;
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001106 case CMD_REQUEST_ENABLE_MODEM:
1107 request = (MainThreadRequest) msg.obj;
1108 boolean enable = (boolean) request.argument;
1109 onCompleted = obtainMessage(EVENT_ENABLE_MODEM_DONE, request);
Nazanin Bakhshi33d584b2019-02-27 10:44:32 -08001110 onCompleted.arg1 = enable ? 1 : 0;
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001111 PhoneConfigurationManager.getInstance()
1112 .enablePhone(request.phone, enable, onCompleted);
1113 break;
1114 case EVENT_ENABLE_MODEM_DONE:
1115 ar = (AsyncResult) msg.obj;
1116 request = (MainThreadRequest) ar.userObj;
1117 request.result = (ar.exception == null);
Nazanin Bakhshi33d584b2019-02-27 10:44:32 -08001118 //update the cache as modem status has changed
1119 mPhoneConfigurationManager.addToPhoneStatusCache(
1120 request.phone.getPhoneId(), msg.arg1 == 1);
Pengquan Meng6c2dc9f2019-02-06 11:12:53 -08001121 updateModemStateMetrics();
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001122 notifyRequester(request);
1123 break;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001124 default:
1125 Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
1126 break;
1127 }
1128 }
Jake Hambye994d462014-02-03 13:10:13 -08001129
Pengquan Menga1bb6272018-09-06 09:59:22 -07001130 private void notifyRequester(MainThreadRequest request) {
1131 synchronized (request) {
1132 request.notifyAll();
1133 }
1134 }
1135
Jake Hambye994d462014-02-03 13:10:13 -08001136 private void handleNullReturnEvent(Message msg, String command) {
1137 AsyncResult ar = (AsyncResult) msg.obj;
1138 MainThreadRequest request = (MainThreadRequest) ar.userObj;
1139 if (ar.exception == null) {
1140 request.result = true;
1141 } else {
1142 request.result = false;
1143 if (ar.exception instanceof CommandException) {
1144 loge(command + ": CommandException: " + ar.exception);
1145 } else {
1146 loge(command + ": Unknown exception");
1147 }
1148 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001149 notifyRequester(request);
Jake Hambye994d462014-02-03 13:10:13 -08001150 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001151 }
1152
1153 /**
1154 * Posts the specified command to be executed on the main thread,
1155 * waits for the request to complete, and returns the result.
1156 * @see #sendRequestAsync
1157 */
1158 private Object sendRequest(int command, Object argument) {
Nathan Harold92bed182018-10-12 18:16:49 -07001159 return sendRequest(
1160 command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, null, null);
vagdeviaf9a5b92018-08-15 16:01:53 -07001161 }
1162
1163 /**
1164 * Posts the specified command to be executed on the main thread,
1165 * waits for the request to complete, and returns the result.
1166 * @see #sendRequestAsync
1167 */
1168 private Object sendRequest(int command, Object argument, WorkSource workSource) {
1169 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
Nathan Harold92bed182018-10-12 18:16:49 -07001170 null, workSource);
Wink Saville36469e72014-06-11 15:17:00 -07001171 }
1172
1173 /**
1174 * Posts the specified command to be executed on the main thread,
1175 * waits for the request to complete, and returns the result.
1176 * @see #sendRequestAsync
1177 */
Shishir Agrawal76d5da92014-11-09 16:17:25 -08001178 private Object sendRequest(int command, Object argument, Integer subId) {
Nathan Harold92bed182018-10-12 18:16:49 -07001179 return sendRequest(command, argument, subId, null, null);
vagdeviaf9a5b92018-08-15 16:01:53 -07001180 }
1181
1182 /**
1183 * Posts the specified command to be executed on the main thread,
1184 * waits for the request to complete, and returns the result.
1185 * @see #sendRequestAsync
1186 */
Nathan Harold92bed182018-10-12 18:16:49 -07001187 private Object sendRequest(int command, Object argument, int subId, WorkSource workSource) {
1188 return sendRequest(command, argument, subId, null, workSource);
1189 }
1190
1191 /**
1192 * Posts the specified command to be executed on the main thread,
1193 * waits for the request to complete, and returns the result.
1194 * @see #sendRequestAsync
1195 */
1196 private Object sendRequest(int command, Object argument, Phone phone, WorkSource workSource) {
1197 return sendRequest(
1198 command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phone, workSource);
1199 }
1200
1201 /**
1202 * Posts the specified command to be executed on the main thread,
1203 * waits for the request to complete, and returns the result.
1204 * @see #sendRequestAsync
1205 */
1206 private Object sendRequest(
1207 int command, Object argument, Integer subId, Phone phone, WorkSource workSource) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001208 if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
1209 throw new RuntimeException("This method will deadlock if called from the main thread.");
1210 }
1211
Nathan Harold92bed182018-10-12 18:16:49 -07001212 MainThreadRequest request = null;
1213 if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && phone != null) {
1214 throw new IllegalArgumentException("subId and phone cannot both be specified!");
1215 } else if (phone != null) {
1216 request = new MainThreadRequest(argument, phone, workSource);
1217 } else {
1218 request = new MainThreadRequest(argument, subId, workSource);
1219 }
1220
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001221 Message msg = mMainThreadHandler.obtainMessage(command, request);
1222 msg.sendToTarget();
1223
1224 // Wait for the request to complete
1225 synchronized (request) {
1226 while (request.result == null) {
1227 try {
1228 request.wait();
1229 } catch (InterruptedException e) {
1230 // Do nothing, go back and wait until the request is complete
1231 }
1232 }
1233 }
1234 return request.result;
1235 }
1236
1237 /**
1238 * Asynchronous ("fire and forget") version of sendRequest():
1239 * Posts the specified command to be executed on the main thread, and
1240 * returns immediately.
1241 * @see #sendRequest
1242 */
1243 private void sendRequestAsync(int command) {
1244 mMainThreadHandler.sendEmptyMessage(command);
1245 }
1246
1247 /**
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001248 * Same as {@link #sendRequestAsync(int)} except it takes an argument.
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001249 * @see {@link #sendRequest(int)}
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001250 */
1251 private void sendRequestAsync(int command, Object argument) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001252 sendRequestAsync(command, argument, null, null);
1253 }
1254
1255 /**
1256 * Same as {@link #sendRequestAsync(int,Object)} except it takes a Phone and WorkSource.
1257 * @see {@link #sendRequest(int,Object)}
1258 */
1259 private void sendRequestAsync(
1260 int command, Object argument, Phone phone, WorkSource workSource) {
1261 MainThreadRequest request = new MainThreadRequest(argument, phone, workSource);
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001262 Message msg = mMainThreadHandler.obtainMessage(command, request);
1263 msg.sendToTarget();
1264 }
1265
1266 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001267 * Initialize the singleton PhoneInterfaceManager instance.
1268 * This is only done once, at startup, from PhoneApp.onCreate().
1269 */
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001270 /* package */ static PhoneInterfaceManager init(PhoneGlobals app) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001271 synchronized (PhoneInterfaceManager.class) {
1272 if (sInstance == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001273 sInstance = new PhoneInterfaceManager(app);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001274 } else {
1275 Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
1276 }
1277 return sInstance;
1278 }
1279 }
1280
1281 /** Private constructor; @see init() */
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001282 private PhoneInterfaceManager(PhoneGlobals app) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001283 mApp = app;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001284 mCM = PhoneGlobals.getInstance().mCM;
Stuart Scott981d8582015-04-21 14:09:50 -07001285 mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001286 mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
1287 mMainThreadHandler = new MainThreadHandler();
Tobias Thiererb19e1f12018-12-11 17:54:03 +00001288 mSubscriptionController = SubscriptionController.getInstance();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001289 mTelephonySharedPreferences =
1290 PreferenceManager.getDefaultSharedPreferences(mApp);
yinxub1bed742017-04-17 11:45:04 -07001291 mNetworkScanRequestTracker = new NetworkScanRequestTracker();
Malcolm Chen2c63d402018-08-14 16:00:53 -07001292 mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
Wink Saville3ab207e2014-11-20 13:07:20 -08001293
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001294 publish();
1295 }
1296
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001297 private Phone getDefaultPhone() {
1298 Phone thePhone = getPhone(getDefaultSubscription());
1299 return (thePhone != null) ? thePhone : PhoneFactory.getDefaultPhone();
1300 }
1301
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001302 private void publish() {
1303 if (DBG) log("publish: " + this);
1304
1305 ServiceManager.addService("phone", this);
1306 }
1307
Stuart Scott584921c2015-01-15 17:10:34 -08001308 private Phone getPhoneFromRequest(MainThreadRequest request) {
Jordan Liu4c733742019-02-28 12:03:40 -08001309 if (request.phone != null) {
1310 return request.phone;
1311 } else {
1312 return getPhoneFromSubId(request.subId);
1313 }
1314 }
1315
1316 private Phone getPhoneFromSubId(int subId) {
1317 return (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
1318 ? getDefaultPhone() : getPhone(subId);
Stuart Scott584921c2015-01-15 17:10:34 -08001319 }
1320
Shishir Agrawalc04d9752016-02-19 10:41:00 -08001321 private UiccCard getUiccCardFromRequest(MainThreadRequest request) {
1322 Phone phone = getPhoneFromRequest(request);
1323 return phone == null ? null :
1324 UiccController.getInstance().getUiccCard(phone.getPhoneId());
1325 }
1326
Wink Saville36469e72014-06-11 15:17:00 -07001327 // returns phone associated with the subId.
Wink Savilleb564aae2014-10-23 10:18:09 -07001328 private Phone getPhone(int subId) {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08001329 return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId));
Wink Saville36469e72014-06-11 15:17:00 -07001330 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001331
1332 public void dial(String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001333 dialForSubscriber(getPreferredVoiceSubscription(), number);
Wink Saville36469e72014-06-11 15:17:00 -07001334 }
1335
Wink Savilleb564aae2014-10-23 10:18:09 -07001336 public void dialForSubscriber(int subId, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001337 if (DBG) log("dial: " + number);
1338 // No permission check needed here: This is just a wrapper around the
1339 // ACTION_DIAL intent, which is available to any app since it puts up
1340 // the UI before it does anything.
1341
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001342 final long identity = Binder.clearCallingIdentity();
1343 try {
1344 String url = createTelUrl(number);
1345 if (url == null) {
1346 return;
1347 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001348
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001349 // PENDING: should we just silently fail if phone is offhook or ringing?
1350 PhoneConstants.State state = mCM.getState(subId);
1351 if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
1352 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
1353 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1354 mApp.startActivity(intent);
1355 }
1356 } finally {
1357 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001358 }
1359 }
1360
1361 public void call(String callingPackage, String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001362 callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number);
Wink Saville36469e72014-06-11 15:17:00 -07001363 }
1364
Wink Savilleb564aae2014-10-23 10:18:09 -07001365 public void callForSubscriber(int subId, String callingPackage, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001366 if (DBG) log("call: " + number);
1367
1368 // This is just a wrapper around the ACTION_CALL intent, but we still
1369 // need to do a permission check since we're calling startActivity()
1370 // from the context of the phone app.
1371 enforceCallPermission();
1372
1373 if (mAppOps.noteOp(AppOpsManager.OP_CALL_PHONE, Binder.getCallingUid(), callingPackage)
1374 != AppOpsManager.MODE_ALLOWED) {
1375 return;
1376 }
1377
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001378 final long identity = Binder.clearCallingIdentity();
1379 try {
1380 String url = createTelUrl(number);
1381 if (url == null) {
1382 return;
1383 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001384
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001385 boolean isValid = false;
1386 final List<SubscriptionInfo> slist = getActiveSubscriptionInfoListPrivileged();
1387 if (slist != null) {
1388 for (SubscriptionInfo subInfoRecord : slist) {
1389 if (subInfoRecord.getSubscriptionId() == subId) {
1390 isValid = true;
1391 break;
1392 }
Wink Saville3ab207e2014-11-20 13:07:20 -08001393 }
Wink Saville08874612014-08-31 19:19:58 -07001394 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001395 if (!isValid) {
1396 return;
1397 }
Wink Saville08874612014-08-31 19:19:58 -07001398
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001399 Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
1400 intent.putExtra(SUBSCRIPTION_KEY, subId);
1401 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1402 mApp.startActivity(intent);
1403 } finally {
1404 Binder.restoreCallingIdentity(identity);
1405 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001406 }
1407
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001408 public boolean supplyPin(String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001409 return supplyPinForSubscriber(getDefaultSubscription(), pin);
Wink Saville36469e72014-06-11 15:17:00 -07001410 }
1411
Wink Savilleb564aae2014-10-23 10:18:09 -07001412 public boolean supplyPinForSubscriber(int subId, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001413 int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07001414 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1415 }
1416
1417 public boolean supplyPuk(String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001418 return supplyPukForSubscriber(getDefaultSubscription(), puk, pin);
Wink Saville36469e72014-06-11 15:17:00 -07001419 }
1420
Wink Savilleb564aae2014-10-23 10:18:09 -07001421 public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001422 int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07001423 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1424 }
1425
1426 /** {@hide} */
1427 public int[] supplyPinReportResult(String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001428 return supplyPinReportResultForSubscriber(getDefaultSubscription(), pin);
Wink Saville36469e72014-06-11 15:17:00 -07001429 }
1430
Wink Savilleb564aae2014-10-23 10:18:09 -07001431 public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001432 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001433
1434 final long identity = Binder.clearCallingIdentity();
1435 try {
1436 final UnlockSim checkSimPin = new UnlockSim(getPhone(subId).getIccCard());
1437 checkSimPin.start();
1438 return checkSimPin.unlockSim(null, pin);
1439 } finally {
1440 Binder.restoreCallingIdentity(identity);
1441 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001442 }
1443
Wink Saville9de0f752013-10-22 19:04:03 -07001444 /** {@hide} */
1445 public int[] supplyPukReportResult(String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001446 return supplyPukReportResultForSubscriber(getDefaultSubscription(), puk, pin);
Wink Saville36469e72014-06-11 15:17:00 -07001447 }
1448
Wink Savilleb564aae2014-10-23 10:18:09 -07001449 public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001450 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001451
1452 final long identity = Binder.clearCallingIdentity();
1453 try {
1454 final UnlockSim checkSimPuk = new UnlockSim(getPhone(subId).getIccCard());
1455 checkSimPuk.start();
1456 return checkSimPuk.unlockSim(puk, pin);
1457 } finally {
1458 Binder.restoreCallingIdentity(identity);
1459 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001460 }
1461
1462 /**
Wink Saville9de0f752013-10-22 19:04:03 -07001463 * Helper thread to turn async call to SimCard#supplyPin into
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001464 * a synchronous one.
1465 */
1466 private static class UnlockSim extends Thread {
1467
1468 private final IccCard mSimCard;
1469
1470 private boolean mDone = false;
Wink Saville9de0f752013-10-22 19:04:03 -07001471 private int mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1472 private int mRetryCount = -1;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001473
1474 // For replies from SimCard interface
1475 private Handler mHandler;
1476
1477 // For async handler to identify request type
1478 private static final int SUPPLY_PIN_COMPLETE = 100;
1479
1480 public UnlockSim(IccCard simCard) {
1481 mSimCard = simCard;
1482 }
1483
1484 @Override
1485 public void run() {
1486 Looper.prepare();
1487 synchronized (UnlockSim.this) {
1488 mHandler = new Handler() {
1489 @Override
1490 public void handleMessage(Message msg) {
1491 AsyncResult ar = (AsyncResult) msg.obj;
1492 switch (msg.what) {
1493 case SUPPLY_PIN_COMPLETE:
1494 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
1495 synchronized (UnlockSim.this) {
Wink Saville9de0f752013-10-22 19:04:03 -07001496 mRetryCount = msg.arg1;
1497 if (ar.exception != null) {
1498 if (ar.exception instanceof CommandException &&
1499 ((CommandException)(ar.exception)).getCommandError()
1500 == CommandException.Error.PASSWORD_INCORRECT) {
1501 mResult = PhoneConstants.PIN_PASSWORD_INCORRECT;
1502 } else {
1503 mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1504 }
1505 } else {
1506 mResult = PhoneConstants.PIN_RESULT_SUCCESS;
1507 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001508 mDone = true;
1509 UnlockSim.this.notifyAll();
1510 }
1511 break;
1512 }
1513 }
1514 };
1515 UnlockSim.this.notifyAll();
1516 }
1517 Looper.loop();
1518 }
1519
1520 /*
1521 * Use PIN or PUK to unlock SIM card
1522 *
1523 * If PUK is null, unlock SIM card with PIN
1524 *
1525 * If PUK is not null, unlock SIM card with PUK and set PIN code
1526 */
Wink Saville9de0f752013-10-22 19:04:03 -07001527 synchronized int[] unlockSim(String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001528
1529 while (mHandler == null) {
1530 try {
1531 wait();
1532 } catch (InterruptedException e) {
1533 Thread.currentThread().interrupt();
1534 }
1535 }
1536 Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
1537
1538 if (puk == null) {
1539 mSimCard.supplyPin(pin, callback);
1540 } else {
1541 mSimCard.supplyPuk(puk, pin, callback);
1542 }
1543
1544 while (!mDone) {
1545 try {
1546 Log.d(LOG_TAG, "wait for done");
1547 wait();
1548 } catch (InterruptedException e) {
1549 // Restore the interrupted status
1550 Thread.currentThread().interrupt();
1551 }
1552 }
1553 Log.d(LOG_TAG, "done");
Wink Saville9de0f752013-10-22 19:04:03 -07001554 int[] resultArray = new int[2];
1555 resultArray[0] = mResult;
1556 resultArray[1] = mRetryCount;
1557 return resultArray;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001558 }
1559 }
1560
1561 public void updateServiceLocation() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001562 updateServiceLocationForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001563
1564 }
1565
Wink Savilleb564aae2014-10-23 10:18:09 -07001566 public void updateServiceLocationForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001567 // No permission check needed here: this call is harmless, and it's
1568 // needed for the ServiceState.requestStateUpdate() call (which is
1569 // already intentionally exposed to 3rd parties.)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001570 final long identity = Binder.clearCallingIdentity();
1571 try {
1572 final Phone phone = getPhone(subId);
1573 if (phone != null) {
1574 phone.updateServiceLocation();
1575 }
1576 } finally {
1577 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001578 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001579 }
1580
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001581 @Override
1582 public boolean isRadioOn(String callingPackage) {
1583 return isRadioOnForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07001584 }
1585
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001586 @Override
1587 public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08001588 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08001589 mApp, subId, callingPackage, "isRadioOnForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001590 return false;
1591 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001592
1593 final long identity = Binder.clearCallingIdentity();
1594 try {
1595 return isRadioOnForSubscriber(subId);
1596 } finally {
1597 Binder.restoreCallingIdentity(identity);
1598 }
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001599 }
1600
1601 private boolean isRadioOnForSubscriber(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001602 final long identity = Binder.clearCallingIdentity();
1603 try {
1604 final Phone phone = getPhone(subId);
1605 if (phone != null) {
1606 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
1607 } else {
1608 return false;
1609 }
1610 } finally {
1611 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001612 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001613 }
1614
1615 public void toggleRadioOnOff() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001616 toggleRadioOnOffForSubscriber(getDefaultSubscription());
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001617 }
Wink Saville36469e72014-06-11 15:17:00 -07001618
Wink Savilleb564aae2014-10-23 10:18:09 -07001619 public void toggleRadioOnOffForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001620 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001621
1622 final long identity = Binder.clearCallingIdentity();
1623 try {
1624 final Phone phone = getPhone(subId);
1625 if (phone != null) {
1626 phone.setRadioPower(!isRadioOnForSubscriber(subId));
1627 }
1628 } finally {
1629 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001630 }
Wink Saville36469e72014-06-11 15:17:00 -07001631 }
1632
1633 public boolean setRadio(boolean turnOn) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001634 return setRadioForSubscriber(getDefaultSubscription(), turnOn);
Wink Saville36469e72014-06-11 15:17:00 -07001635 }
1636
Wink Savilleb564aae2014-10-23 10:18:09 -07001637 public boolean setRadioForSubscriber(int subId, boolean turnOn) {
Wink Saville36469e72014-06-11 15:17:00 -07001638 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001639
1640 final long identity = Binder.clearCallingIdentity();
1641 try {
1642 final Phone phone = getPhone(subId);
1643 if (phone == null) {
1644 return false;
1645 }
1646 if ((phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF) != turnOn) {
1647 toggleRadioOnOffForSubscriber(subId);
1648 }
1649 return true;
1650 } finally {
1651 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001652 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001653 }
Wink Saville36469e72014-06-11 15:17:00 -07001654
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001655 public boolean needMobileRadioShutdown() {
1656 /*
1657 * If any of the Radios are available, it will need to be
1658 * shutdown. So return true if any Radio is available.
1659 */
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001660 final long identity = Binder.clearCallingIdentity();
1661 try {
1662 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1663 Phone phone = PhoneFactory.getPhone(i);
1664 if (phone != null && phone.isRadioAvailable()) return true;
1665 }
1666 logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown.");
1667 return false;
1668 } finally {
1669 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001670 }
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001671 }
1672
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001673 @Override
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001674 public void shutdownMobileRadios() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001675 enforceModifyPermission();
1676
1677 final long identity = Binder.clearCallingIdentity();
1678 try {
1679 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1680 logv("Shutting down Phone " + i);
1681 shutdownRadioUsingPhoneId(i);
1682 }
1683 } finally {
1684 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001685 }
1686 }
1687
1688 private void shutdownRadioUsingPhoneId(int phoneId) {
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001689 Phone phone = PhoneFactory.getPhone(phoneId);
1690 if (phone != null && phone.isRadioAvailable()) {
1691 phone.shutdownRadio();
1692 }
1693 }
1694
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001695 public boolean setRadioPower(boolean turnOn) {
Jack Yub4e16162017-05-15 12:48:40 -07001696 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001697
1698 final long identity = Binder.clearCallingIdentity();
1699 try {
1700 final Phone defaultPhone = PhoneFactory.getDefaultPhone();
1701 if (defaultPhone != null) {
1702 defaultPhone.setRadioPower(turnOn);
1703 return true;
1704 } else {
1705 loge("There's no default phone.");
1706 return false;
1707 }
1708 } finally {
1709 Binder.restoreCallingIdentity(identity);
Wei Liu9ae2a062016-08-08 11:09:34 -07001710 }
Wink Saville36469e72014-06-11 15:17:00 -07001711 }
1712
Wink Savilleb564aae2014-10-23 10:18:09 -07001713 public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001714 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001715
1716 final long identity = Binder.clearCallingIdentity();
1717 try {
1718 final Phone phone = getPhone(subId);
1719 if (phone != null) {
1720 phone.setRadioPower(turnOn);
1721 return true;
1722 } else {
1723 return false;
1724 }
1725 } finally {
1726 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001727 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001728 }
1729
Wink Saville36469e72014-06-11 15:17:00 -07001730 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07001731 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001732 public boolean enableDataConnectivity() {
1733 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001734
1735 final long identity = Binder.clearCallingIdentity();
1736 try {
1737 int subId = mSubscriptionController.getDefaultDataSubId();
1738 final Phone phone = getPhone(subId);
1739 if (phone != null) {
Jack Yud79fba22018-12-13 11:51:28 -08001740 phone.getDataEnabledSettings().setUserDataEnabled(true);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001741 return true;
1742 } else {
1743 return false;
1744 }
1745 } finally {
1746 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001747 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001748 }
1749
Wink Saville36469e72014-06-11 15:17:00 -07001750 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07001751 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001752 public boolean disableDataConnectivity() {
1753 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001754
1755 final long identity = Binder.clearCallingIdentity();
1756 try {
1757 int subId = mSubscriptionController.getDefaultDataSubId();
1758 final Phone phone = getPhone(subId);
1759 if (phone != null) {
Jack Yud79fba22018-12-13 11:51:28 -08001760 phone.getDataEnabledSettings().setUserDataEnabled(false);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001761 return true;
1762 } else {
1763 return false;
1764 }
1765 } finally {
1766 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001767 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001768 }
1769
Sanket Padawe356d7632015-06-22 14:03:32 -07001770 @Override
Jack Yuacf8a132017-05-01 17:00:48 -07001771 public boolean isDataConnectivityPossible(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001772 final long identity = Binder.clearCallingIdentity();
1773 try {
1774 final Phone phone = getPhone(subId);
1775 if (phone != null) {
Jack Yub5d8f642018-11-26 11:20:48 -08001776 return phone.isDataAllowed(ApnSetting.TYPE_DEFAULT);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001777 } else {
1778 return false;
1779 }
1780 } finally {
1781 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001782 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001783 }
1784
1785 public boolean handlePinMmi(String dialString) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001786 return handlePinMmiForSubscriber(getDefaultSubscription(), dialString);
Wink Saville36469e72014-06-11 15:17:00 -07001787 }
1788
pkanwarae03a6b2016-11-06 20:37:09 -08001789 public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001790 enforceCallPermission();
1791
1792 final long identity = Binder.clearCallingIdentity();
1793 try {
1794 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1795 return;
1796 }
1797 Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback);
1798 sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId);
1799 } finally {
1800 Binder.restoreCallingIdentity(identity);
1801 }
pkanwar32d516d2016-10-14 19:37:38 -07001802 };
1803
Wink Savilleb564aae2014-10-23 10:18:09 -07001804 public boolean handlePinMmiForSubscriber(int subId, String dialString) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001805 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001806
1807 final long identity = Binder.clearCallingIdentity();
1808 try {
1809 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1810 return false;
1811 }
1812 return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
1813 } finally {
1814 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001815 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001816 }
1817
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001818 public int getCallState() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07001819 return getCallStateForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001820 }
1821
Sanket Padawe13bac7b2017-03-20 15:04:47 -07001822 public int getCallStateForSlot(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001823 final long identity = Binder.clearCallingIdentity();
1824 try {
1825 Phone phone = PhoneFactory.getPhone(slotIndex);
1826 return phone == null ? TelephonyManager.CALL_STATE_IDLE :
1827 PhoneConstantConversions.convertCallState(phone.getState());
1828 } finally {
1829 Binder.restoreCallingIdentity(identity);
1830 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001831 }
1832
Sanket Padawe356d7632015-06-22 14:03:32 -07001833 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001834 public int getDataState() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001835 final long identity = Binder.clearCallingIdentity();
1836 try {
1837 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1838 if (phone != null) {
1839 return PhoneConstantConversions.convertDataState(phone.getDataConnectionState());
1840 } else {
1841 return PhoneConstantConversions.convertDataState(
1842 PhoneConstants.DataState.DISCONNECTED);
1843 }
1844 } finally {
1845 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001846 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001847 }
1848
Sanket Padawe356d7632015-06-22 14:03:32 -07001849 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001850 public int getDataActivity() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001851 final long identity = Binder.clearCallingIdentity();
1852 try {
1853 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1854 if (phone != null) {
1855 return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState());
1856 } else {
1857 return TelephonyManager.DATA_ACTIVITY_NONE;
1858 }
1859 } finally {
1860 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001861 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001862 }
1863
1864 @Override
Svetoslav64fad262015-04-14 14:35:21 -07001865 public Bundle getCellLocation(String callingPackage) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001866 mApp.getSystemService(AppOpsManager.class)
Hall Liu1aa510f2017-11-22 17:40:08 -08001867 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08001868
1869 LocationAccessPolicy.LocationPermissionResult locationResult =
1870 LocationAccessPolicy.checkLocationPermission(mApp,
1871 new LocationAccessPolicy.LocationPermissionQuery.Builder()
1872 .setCallingPackage(callingPackage)
1873 .setCallingPid(Binder.getCallingPid())
1874 .setCallingUid(Binder.getCallingUid())
1875 .setMethod("getCellLocation")
1876 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
1877 .build());
1878 switch (locationResult) {
1879 case DENIED_HARD:
1880 throw new SecurityException("Not allowed to access cell location");
1881 case DENIED_SOFT:
1882 return new Bundle();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001883 }
1884
Narayan Kamathf04b5a12018-01-09 11:47:15 +00001885 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001886 final long identity = Binder.clearCallingIdentity();
1887 try {
1888 if (DBG_LOC) log("getCellLocation: is active user");
1889 Bundle data = new Bundle();
Nathan Harold3ff88932018-08-14 10:19:49 -07001890 int subId = mSubscriptionController.getDefaultDataSubId();
1891 CellLocation cl = (CellLocation) sendRequest(CMD_GET_CELL_LOCATION, workSource, subId);
1892 cl.fillInNotifierBundle(data);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001893 return data;
1894 } finally {
1895 Binder.restoreCallingIdentity(identity);
1896 }
Svetoslav64fad262015-04-14 14:35:21 -07001897 }
1898
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001899 @Override
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001900 public String getNetworkCountryIsoForPhone(int phoneId) {
1901 // Reporting the correct network country is ambiguous when IWLAN could conflict with
1902 // registered cell info, so return a NULL country instead.
1903 final long identity = Binder.clearCallingIdentity();
1904 try {
Malcolm Chen3732c2b2018-07-18 20:15:24 -07001905 if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
1906 // Get default phone in this case.
1907 phoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
1908 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001909 final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
Jack Yu5f7092c2018-04-13 14:05:37 -07001910 // Todo: fix this when we can get the actual cellular network info when the device
1911 // is on IWLAN.
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001912 if (TelephonyManager.NETWORK_TYPE_IWLAN
1913 == getVoiceNetworkTypeForSubscriber(subId, mApp.getPackageName())) {
1914 return "";
1915 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001916 Phone phone = PhoneFactory.getPhone(phoneId);
1917 if (phone != null) {
1918 ServiceStateTracker sst = phone.getServiceStateTracker();
1919 if (sst != null) {
1920 LocaleTracker lt = sst.getLocaleTracker();
1921 if (lt != null) {
1922 return lt.getCurrentCountry();
1923 }
1924 }
1925 }
1926 return "";
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001927 } finally {
1928 Binder.restoreCallingIdentity(identity);
1929 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001930 }
1931
1932 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001933 public void enableLocationUpdates() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001934 enableLocationUpdatesForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001935 }
1936
Sanket Padawe356d7632015-06-22 14:03:32 -07001937 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07001938 public void enableLocationUpdatesForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001939 mApp.enforceCallingOrSelfPermission(
1940 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001941
1942 final long identity = Binder.clearCallingIdentity();
1943 try {
1944 final Phone phone = getPhone(subId);
1945 if (phone != null) {
1946 phone.enableLocationUpdates();
1947 }
1948 } finally {
1949 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001950 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001951 }
1952
1953 @Override
1954 public void disableLocationUpdates() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001955 disableLocationUpdatesForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001956 }
1957
Sanket Padawe356d7632015-06-22 14:03:32 -07001958 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07001959 public void disableLocationUpdatesForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001960 mApp.enforceCallingOrSelfPermission(
1961 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001962
1963 final long identity = Binder.clearCallingIdentity();
1964 try {
1965 final Phone phone = getPhone(subId);
1966 if (phone != null) {
1967 phone.disableLocationUpdates();
1968 }
1969 } finally {
1970 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001971 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001972 }
1973
Nathan Harold31d7ff32018-10-15 20:20:30 -07001974 /**
1975 * Returns the target SDK version number for a given package name.
1976 *
1977 * @return target SDK if the package is found or INT_MAX.
1978 */
1979 private int getTargetSdk(String packageName) {
1980 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001981 final ApplicationInfo ai = mApp.getPackageManager().getApplicationInfo(
1982 packageName, 0);
Nathan Harold31d7ff32018-10-15 20:20:30 -07001983 if (ai != null) return ai.targetSdkVersion;
1984 } catch (PackageManager.NameNotFoundException unexpected) {
1985 }
1986 return Integer.MAX_VALUE;
1987 }
1988
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001989 @Override
1990 @SuppressWarnings("unchecked")
Nathan Harold31d7ff32018-10-15 20:20:30 -07001991 public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage) {
1992 final int targetSdk = getTargetSdk(callingPackage);
Nathan Harolddbea45a2018-08-30 14:35:07 -07001993 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
1994 throw new SecurityException(
1995 "getNeighboringCellInfo() is unavailable to callers targeting Q+ SDK levels.");
1996 }
Nathan Haroldb4d55612018-07-20 13:13:08 -07001997
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001998 if (mAppOps.noteOp(AppOpsManager.OP_NEIGHBORING_CELLS, Binder.getCallingUid(),
1999 callingPackage) != AppOpsManager.MODE_ALLOWED) {
2000 return null;
2001 }
Svetoslav64fad262015-04-14 14:35:21 -07002002
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07002003 if (DBG_LOC) log("getNeighboringCellInfo: is active user");
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002004
Nathan Haroldf180aac2018-06-01 18:43:55 -07002005 List<CellInfo> info = getAllCellInfo(callingPackage);
2006 if (info == null) return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002007
Nathan Haroldf180aac2018-06-01 18:43:55 -07002008 List<NeighboringCellInfo> neighbors = new ArrayList<NeighboringCellInfo>();
2009 for (CellInfo ci : info) {
2010 if (ci instanceof CellInfoGsm) {
2011 neighbors.add(new NeighboringCellInfo((CellInfoGsm) ci));
2012 } else if (ci instanceof CellInfoWcdma) {
2013 neighbors.add(new NeighboringCellInfo((CellInfoWcdma) ci));
2014 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002015 }
Nathan Haroldf180aac2018-06-01 18:43:55 -07002016 return (neighbors.size()) > 0 ? neighbors : null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002017 }
2018
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002019 private List<CellInfo> getCachedCellInfo() {
2020 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
2021 for (Phone phone : PhoneFactory.getPhones()) {
2022 List<CellInfo> info = phone.getAllCellInfo();
2023 if (info != null) cellInfos.addAll(info);
2024 }
2025 return cellInfos;
2026 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002027
2028 @Override
Svetoslav64fad262015-04-14 14:35:21 -07002029 public List<CellInfo> getAllCellInfo(String callingPackage) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002030 mApp.getSystemService(AppOpsManager.class)
Hall Liu1aa510f2017-11-22 17:40:08 -08002031 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08002032
2033 LocationAccessPolicy.LocationPermissionResult locationResult =
2034 LocationAccessPolicy.checkLocationPermission(mApp,
2035 new LocationAccessPolicy.LocationPermissionQuery.Builder()
2036 .setCallingPackage(callingPackage)
2037 .setCallingPid(Binder.getCallingPid())
2038 .setCallingUid(Binder.getCallingUid())
2039 .setMethod("getAllCellInfo")
Nathan Harold5ae50b52019-02-20 15:46:36 -08002040 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
Hall Liuf19c44f2018-11-27 14:38:17 -08002041 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2042 .build());
2043 switch (locationResult) {
2044 case DENIED_HARD:
2045 throw new SecurityException("Not allowed to access cell info");
2046 case DENIED_SOFT:
2047 return new ArrayList<>();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002048 }
2049
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002050 final int targetSdk = getTargetSdk(callingPackage);
2051 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
2052 return getCachedCellInfo();
2053 }
2054
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07002055 if (DBG_LOC) log("getAllCellInfo: is active user");
Narayan Kamathf04b5a12018-01-09 11:47:15 +00002056 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002057 final long identity = Binder.clearCallingIdentity();
2058 try {
2059 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
2060 for (Phone phone : PhoneFactory.getPhones()) {
Nathan Harold3ff88932018-08-14 10:19:49 -07002061 final List<CellInfo> info = (List<CellInfo>) sendRequest(
Nathan Harold92bed182018-10-12 18:16:49 -07002062 CMD_GET_ALL_CELL_INFO, null, phone, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002063 if (info != null) cellInfos.addAll(info);
2064 }
2065 return cellInfos;
2066 } finally {
2067 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002068 }
2069 }
2070
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07002071 @Override
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002072 public void requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage) {
2073 requestCellInfoUpdateInternal(
2074 subId, cb, callingPackage, getWorkSource(Binder.getCallingUid()));
2075 }
2076
2077 @Override
2078 public void requestCellInfoUpdateWithWorkSource(
2079 int subId, ICellInfoCallback cb, String callingPackage, WorkSource workSource) {
2080 enforceModifyPermission();
2081 requestCellInfoUpdateInternal(subId, cb, callingPackage, workSource);
2082 }
2083
2084 private void requestCellInfoUpdateInternal(
2085 int subId, ICellInfoCallback cb, String callingPackage, WorkSource workSource) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002086 mApp.getSystemService(AppOpsManager.class)
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002087 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08002088
2089 LocationAccessPolicy.LocationPermissionResult locationResult =
2090 LocationAccessPolicy.checkLocationPermission(mApp,
2091 new LocationAccessPolicy.LocationPermissionQuery.Builder()
2092 .setCallingPackage(callingPackage)
2093 .setCallingPid(Binder.getCallingPid())
2094 .setCallingUid(Binder.getCallingUid())
2095 .setMethod("requestCellInfoUpdate")
2096 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2097 .build());
2098 switch (locationResult) {
2099 case DENIED_HARD:
2100 throw new SecurityException("Not allowed to access cell info");
2101 case DENIED_SOFT:
2102 return;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002103 }
2104
2105 final Phone phone = getPhone(subId);
2106 if (phone == null) throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
2107
2108 sendRequestAsync(CMD_REQUEST_CELL_INFO_UPDATE, cb, phone, workSource);
2109 }
2110
2111 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002112 public void setCellInfoListRate(int rateInMillis) {
Jack Yua8d8cb82017-01-16 10:15:34 -08002113 enforceModifyPermission();
Narayan Kamathf04b5a12018-01-09 11:47:15 +00002114 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002115
2116 final long identity = Binder.clearCallingIdentity();
2117 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002118 getDefaultPhone().setCellInfoListRate(rateInMillis, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002119 } finally {
2120 Binder.restoreCallingIdentity(identity);
2121 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002122 }
2123
Shishir Agrawala9f32182016-04-12 12:00:16 -07002124 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002125 public String getImeiForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002126 Phone phone = PhoneFactory.getPhone(slotIndex);
2127 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002128 return null;
2129 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002130 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07002131 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
2132 callingPackage, "getImeiForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002133 return null;
2134 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002135
2136 final long identity = Binder.clearCallingIdentity();
2137 try {
2138 return phone.getImei();
2139 } finally {
2140 Binder.restoreCallingIdentity(identity);
2141 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002142 }
2143
2144 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002145 public String getTypeAllocationCodeForSlot(int slotIndex) {
2146 Phone phone = PhoneFactory.getPhone(slotIndex);
2147 String tac = null;
2148 if (phone != null) {
2149 String imei = phone.getImei();
2150 tac = imei == null ? null : imei.substring(0, TYPE_ALLOCATION_CODE_LENGTH);
2151 }
2152 return tac;
2153 }
2154
2155 @Override
Jack Yu2af8d712017-03-15 17:14:14 -07002156 public String getMeidForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002157 Phone phone = PhoneFactory.getPhone(slotIndex);
2158 if (phone == null) {
Jack Yu2af8d712017-03-15 17:14:14 -07002159 return null;
2160 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002161
Jeff Davidson913390f2018-02-23 17:11:49 -08002162 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07002163 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
2164 callingPackage, "getMeidForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002165 return null;
2166 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002167
2168 final long identity = Binder.clearCallingIdentity();
2169 try {
2170 return phone.getMeid();
2171 } finally {
2172 Binder.restoreCallingIdentity(identity);
2173 }
Jack Yu2af8d712017-03-15 17:14:14 -07002174 }
2175
2176 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002177 public String getManufacturerCodeForSlot(int slotIndex) {
2178 Phone phone = PhoneFactory.getPhone(slotIndex);
2179 String manufacturerCode = null;
2180 if (phone != null) {
2181 String meid = phone.getMeid();
2182 manufacturerCode = meid == null ? null : meid.substring(0, MANUFACTURER_CODE_LENGTH);
2183 }
2184 return manufacturerCode;
2185 }
2186
2187 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002188 public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002189 Phone phone = PhoneFactory.getPhone(slotIndex);
2190 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002191 return null;
2192 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002193 int subId = phone.getSubId();
2194 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2195 mApp, subId, callingPackage, "getDeviceSoftwareVersionForSlot")) {
2196 return null;
2197 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002198
2199 final long identity = Binder.clearCallingIdentity();
2200 try {
2201 return phone.getDeviceSvn();
2202 } finally {
2203 Binder.restoreCallingIdentity(identity);
2204 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002205 }
2206
fionaxu43304da2017-11-27 22:51:16 -08002207 @Override
2208 public int getSubscriptionCarrierId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002209 final long identity = Binder.clearCallingIdentity();
2210 try {
2211 final Phone phone = getPhone(subId);
2212 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getCarrierId();
2213 } finally {
2214 Binder.restoreCallingIdentity(identity);
2215 }
fionaxu43304da2017-11-27 22:51:16 -08002216 }
2217
2218 @Override
2219 public String getSubscriptionCarrierName(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002220 final long identity = Binder.clearCallingIdentity();
2221 try {
2222 final Phone phone = getPhone(subId);
2223 return phone == null ? null : phone.getCarrierName();
2224 } finally {
2225 Binder.restoreCallingIdentity(identity);
2226 }
fionaxu43304da2017-11-27 22:51:16 -08002227 }
2228
calvinpanffe225e2018-11-01 19:43:06 +08002229 @Override
chen xu0026ca62019-03-06 15:28:50 -08002230 public int getSubscriptionSpecificCarrierId(int subId) {
chen xu25637222018-11-04 17:17:00 -08002231 final long identity = Binder.clearCallingIdentity();
2232 try {
2233 final Phone phone = getPhone(subId);
2234 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID
chen xu0026ca62019-03-06 15:28:50 -08002235 : phone.getSpecificCarrierId();
chen xu25637222018-11-04 17:17:00 -08002236 } finally {
2237 Binder.restoreCallingIdentity(identity);
2238 }
2239 }
2240
2241 @Override
chen xu0026ca62019-03-06 15:28:50 -08002242 public String getSubscriptionSpecificCarrierName(int subId) {
chen xu25637222018-11-04 17:17:00 -08002243 final long identity = Binder.clearCallingIdentity();
2244 try {
2245 final Phone phone = getPhone(subId);
chen xu0026ca62019-03-06 15:28:50 -08002246 return phone == null ? null : phone.getSpecificCarrierName();
chen xu25637222018-11-04 17:17:00 -08002247 } finally {
2248 Binder.restoreCallingIdentity(identity);
2249 }
2250 }
2251
chen xu651eec72018-11-11 19:03:44 -08002252 @Override
chen xu864e11c2018-12-06 22:10:03 -08002253 public int getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc) {
2254 if (!isSubscriptionMccMnc) {
2255 enforceReadPrivilegedPermission("getCarrierIdFromMccMnc");
2256 }
chen xu651eec72018-11-11 19:03:44 -08002257 final Phone phone = PhoneFactory.getPhone(slotIndex);
2258 if (phone == null) {
2259 return TelephonyManager.UNKNOWN_CARRIER_ID;
2260 }
2261 final long identity = Binder.clearCallingIdentity();
2262 try {
2263 return CarrierResolver.getCarrierIdFromMccMnc(phone.getContext(), mccmnc);
2264 } finally {
2265 Binder.restoreCallingIdentity(identity);
2266 }
2267 }
2268
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002269 //
2270 // Internal helper methods.
2271 //
2272
Sanket Padaweee13a9b2016-03-08 17:30:28 -08002273 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002274 * Make sure the caller has the MODIFY_PHONE_STATE permission.
2275 *
2276 * @throws SecurityException if the caller does not have the required permission
2277 */
2278 private void enforceModifyPermission() {
2279 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
2280 }
2281
2282 /**
2283 * Make sure the caller has the CALL_PHONE permission.
2284 *
2285 * @throws SecurityException if the caller does not have the required permission
2286 */
2287 private void enforceCallPermission() {
2288 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
2289 }
2290
Stuart Scott8eef64f2015-04-08 15:13:54 -07002291 private void enforceConnectivityInternalPermission() {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002292 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL,
Stuart Scott8eef64f2015-04-08 15:13:54 -07002293 "ConnectivityService");
2294 }
2295
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002296 private String createTelUrl(String number) {
2297 if (TextUtils.isEmpty(number)) {
2298 return null;
2299 }
2300
Jake Hambye994d462014-02-03 13:10:13 -08002301 return "tel:" + number;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002302 }
2303
Ihab Awadf9e92732013-12-05 18:02:52 -08002304 private static void log(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002305 Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg);
2306 }
2307
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002308 private static void logv(String msg) {
2309 Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg);
2310 }
2311
Ihab Awadf9e92732013-12-05 18:02:52 -08002312 private static void loge(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002313 Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg);
2314 }
2315
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002316 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002317 public int getActivePhoneType() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07002318 return getActivePhoneTypeForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002319 }
2320
Sanket Padawe356d7632015-06-22 14:03:32 -07002321 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002322 public int getActivePhoneTypeForSlot(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002323 final long identity = Binder.clearCallingIdentity();
2324 try {
2325 final Phone phone = PhoneFactory.getPhone(slotIndex);
2326 if (phone == null) {
2327 return PhoneConstants.PHONE_TYPE_NONE;
2328 } else {
2329 return phone.getPhoneType();
2330 }
2331 } finally {
2332 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002333 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002334 }
2335
2336 /**
2337 * Returns the CDMA ERI icon index to display
2338 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002339 @Override
2340 public int getCdmaEriIconIndex(String callingPackage) {
2341 return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002342 }
2343
Sanket Padawe356d7632015-06-22 14:03:32 -07002344 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002345 public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002346 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002347 mApp, subId, callingPackage, "getCdmaEriIconIndexForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002348 return -1;
2349 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002350
2351 final long identity = Binder.clearCallingIdentity();
2352 try {
2353 final Phone phone = getPhone(subId);
2354 if (phone != null) {
2355 return phone.getCdmaEriIconIndex();
2356 } else {
2357 return -1;
2358 }
2359 } finally {
2360 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002361 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002362 }
2363
2364 /**
2365 * Returns the CDMA ERI icon mode,
2366 * 0 - ON
2367 * 1 - FLASHING
2368 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002369 @Override
2370 public int getCdmaEriIconMode(String callingPackage) {
2371 return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002372 }
2373
Sanket Padawe356d7632015-06-22 14:03:32 -07002374 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002375 public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002376 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002377 mApp, subId, callingPackage, "getCdmaEriIconModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002378 return -1;
2379 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002380
2381 final long identity = Binder.clearCallingIdentity();
2382 try {
2383 final Phone phone = getPhone(subId);
2384 if (phone != null) {
2385 return phone.getCdmaEriIconMode();
2386 } else {
2387 return -1;
2388 }
2389 } finally {
2390 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002391 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002392 }
2393
2394 /**
2395 * Returns the CDMA ERI text,
2396 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002397 @Override
2398 public String getCdmaEriText(String callingPackage) {
2399 return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002400 }
2401
Sanket Padawe356d7632015-06-22 14:03:32 -07002402 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002403 public String getCdmaEriTextForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002404 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002405 mApp, subId, callingPackage, "getCdmaEriIconTextForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002406 return null;
2407 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002408
2409 final long identity = Binder.clearCallingIdentity();
2410 try {
2411 final Phone phone = getPhone(subId);
2412 if (phone != null) {
2413 return phone.getCdmaEriText();
2414 } else {
2415 return null;
2416 }
2417 } finally {
2418 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002419 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002420 }
2421
2422 /**
Junda Liuca05d5d2014-08-14 22:36:34 -07002423 * Returns the CDMA MDN.
2424 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002425 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002426 public String getCdmaMdn(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002427 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2428 mApp, subId, "getCdmaMdn");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002429
2430 final long identity = Binder.clearCallingIdentity();
2431 try {
2432 final Phone phone = getPhone(subId);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002433 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002434 return phone.getLine1Number();
2435 } else {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002436 loge("getCdmaMdn: no phone found. Invalid subId: " + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002437 return null;
2438 }
2439 } finally {
2440 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07002441 }
2442 }
2443
2444 /**
2445 * Returns the CDMA MIN.
2446 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002447 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002448 public String getCdmaMin(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002449 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2450 mApp, subId, "getCdmaMin");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002451
2452 final long identity = Binder.clearCallingIdentity();
2453 try {
2454 final Phone phone = getPhone(subId);
2455 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
2456 return phone.getCdmaMin();
2457 } else {
2458 return null;
2459 }
2460 } finally {
2461 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07002462 }
2463 }
2464
Hall Liud892bec2018-11-30 14:51:45 -08002465 @Override
2466 public void requestNumberVerification(PhoneNumberRange range, long timeoutMillis,
2467 INumberVerificationCallback callback, String callingPackage) {
2468 if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
2469 != PERMISSION_GRANTED) {
2470 throw new SecurityException("Caller must hold the MODIFY_PHONE_STATE permission");
2471 }
2472 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2473
2474 String authorizedPackage = NumberVerificationManager.getAuthorizedPackage(mApp);
2475 if (!TextUtils.equals(callingPackage, authorizedPackage)) {
2476 throw new SecurityException("Calling package must be configured in the device config");
2477 }
2478
2479 if (range == null) {
2480 throw new NullPointerException("Range must be non-null");
2481 }
2482
2483 timeoutMillis = Math.min(timeoutMillis,
Hall Liubd069e32019-02-28 18:56:30 -08002484 TelephonyManager.getMaxNumberVerificationTimeoutMillis());
Hall Liud892bec2018-11-30 14:51:45 -08002485
2486 NumberVerificationManager.getInstance().requestVerification(range, callback, timeoutMillis);
2487 }
2488
Junda Liuca05d5d2014-08-14 22:36:34 -07002489 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002490 * Returns true if CDMA provisioning needs to run.
2491 */
2492 public boolean needsOtaServiceProvisioning() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002493 final long identity = Binder.clearCallingIdentity();
2494 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002495 return getDefaultPhone().needsOtaServiceProvisioning();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002496 } finally {
2497 Binder.restoreCallingIdentity(identity);
2498 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002499 }
2500
2501 /**
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002502 * Sets the voice mail number of a given subId.
2503 */
2504 @Override
2505 public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002506 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setVoiceMailNumber");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002507
2508 final long identity = Binder.clearCallingIdentity();
2509 try {
2510 Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
2511 new Pair<String, String>(alphaTag, number), new Integer(subId));
2512 return success;
2513 } finally {
2514 Binder.restoreCallingIdentity(identity);
2515 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002516 }
2517
Ta-wei Yen87c49842016-05-13 21:19:52 -07002518 @Override
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002519 public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
2520 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002521 String systemDialer = TelecomManager.from(mApp).getSystemDialerPackage();
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002522 if (!TextUtils.equals(callingPackage, systemDialer)) {
2523 throw new SecurityException("caller must be system dialer");
2524 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002525
2526 final long identity = Binder.clearCallingIdentity();
2527 try {
2528 PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
2529 if (phoneAccountHandle == null) {
2530 return null;
2531 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002532 return VisualVoicemailSettingsUtil.dump(mApp, phoneAccountHandle);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002533 } finally {
2534 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002535 }
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002536 }
2537
2538 @Override
Ta-wei Yen409ac562017-03-06 16:00:44 -08002539 public String getVisualVoicemailPackageName(String callingPackage, int subId) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08002540 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jeff Davidson7e17e312018-02-13 18:17:36 -08002541 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002542 mApp, subId, callingPackage, "getVisualVoicemailPackageName")) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08002543 return null;
2544 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002545
Jeff Davidsona8e4e242018-03-15 17:16:18 -07002546 final long identity = Binder.clearCallingIdentity();
2547 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002548 return RemoteVvmTaskManager.getRemotePackage(mApp, subId).getPackageName();
Jeff Davidsona8e4e242018-03-15 17:16:18 -07002549 } finally {
2550 Binder.restoreCallingIdentity(identity);
2551 }
Ta-wei Yendca928f2017-01-10 16:17:08 -08002552 }
2553
2554 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002555 public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
2556 VisualVoicemailSmsFilterSettings settings) {
2557 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002558
2559 final long identity = Binder.clearCallingIdentity();
2560 try {
2561 VisualVoicemailSmsFilterConfig.enableVisualVoicemailSmsFilter(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002562 mApp, callingPackage, subId, settings);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002563 } finally {
2564 Binder.restoreCallingIdentity(identity);
2565 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002566 }
2567
2568 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002569 public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
2570 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002571
2572 final long identity = Binder.clearCallingIdentity();
2573 try {
2574 VisualVoicemailSmsFilterConfig.disableVisualVoicemailSmsFilter(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002575 mApp, callingPackage, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002576 } finally {
2577 Binder.restoreCallingIdentity(identity);
2578 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002579 }
2580
2581 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002582 public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
2583 String callingPackage, int subId) {
2584 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002585
2586 final long identity = Binder.clearCallingIdentity();
2587 try {
2588 return VisualVoicemailSmsFilterConfig.getVisualVoicemailSmsFilterSettings(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002589 mApp, callingPackage, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002590 } finally {
2591 Binder.restoreCallingIdentity(identity);
2592 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002593 }
2594
2595 @Override
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002596 public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002597 enforceReadPrivilegedPermission("getActiveVisualVoicemailSmsFilterSettings");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002598
2599 final long identity = Binder.clearCallingIdentity();
2600 try {
2601 return VisualVoicemailSmsFilterConfig.getActiveVisualVoicemailSmsFilterSettings(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002602 mApp, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002603 } finally {
2604 Binder.restoreCallingIdentity(identity);
2605 }
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002606 }
2607
2608 @Override
2609 public void sendVisualVoicemailSmsForSubscriber(String callingPackage, int subId,
2610 String number, int port, String text, PendingIntent sentIntent) {
2611 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Ta-wei Yen527a9c02017-01-06 15:29:25 -08002612 enforceVisualVoicemailPackage(callingPackage, subId);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002613 enforceSendSmsPermission();
2614 // Make the calls as the phone process.
2615 final long identity = Binder.clearCallingIdentity();
2616 try {
2617 SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(subId);
2618 if (port == 0) {
2619 smsManager.sendTextMessageWithSelfPermissions(number, null, text,
2620 sentIntent, null, false);
2621 } else {
2622 byte[] data = text.getBytes(StandardCharsets.UTF_8);
2623 smsManager.sendDataMessageWithSelfPermissions(number, null,
2624 (short) port, data, sentIntent, null);
2625 }
2626 } finally {
2627 Binder.restoreCallingIdentity(identity);
2628 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002629 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002630 /**
fionaxu0152e512016-11-14 13:36:14 -08002631 * Sets the voice activation state of a given subId.
2632 */
2633 @Override
2634 public void setVoiceActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002635 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2636 mApp, subId, "setVoiceActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002637
2638 final long identity = Binder.clearCallingIdentity();
2639 try {
2640 final Phone phone = getPhone(subId);
2641 if (phone != null) {
2642 phone.setVoiceActivationState(activationState);
2643 } else {
2644 loge("setVoiceActivationState fails with invalid subId: " + subId);
2645 }
2646 } finally {
2647 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002648 }
2649 }
2650
2651 /**
2652 * Sets the data activation state of a given subId.
2653 */
2654 @Override
2655 public void setDataActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002656 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2657 mApp, subId, "setDataActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002658
2659 final long identity = Binder.clearCallingIdentity();
2660 try {
2661 final Phone phone = getPhone(subId);
2662 if (phone != null) {
2663 phone.setDataActivationState(activationState);
2664 } else {
2665 loge("setVoiceActivationState fails with invalid subId: " + subId);
2666 }
2667 } finally {
2668 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002669 }
2670 }
2671
2672 /**
2673 * Returns the voice activation state of a given subId.
2674 */
2675 @Override
2676 public int getVoiceActivationState(int subId, String callingPackage) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002677 enforceReadPrivilegedPermission("getVoiceActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002678
fionaxu0152e512016-11-14 13:36:14 -08002679 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002680 final long identity = Binder.clearCallingIdentity();
2681 try {
2682 if (phone != null) {
2683 return phone.getVoiceActivationState();
2684 } else {
2685 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2686 }
2687 } finally {
2688 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002689 }
2690 }
2691
2692 /**
2693 * Returns the data activation state of a given subId.
2694 */
2695 @Override
2696 public int getDataActivationState(int subId, String callingPackage) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002697 enforceReadPrivilegedPermission("getDataActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002698
fionaxu0152e512016-11-14 13:36:14 -08002699 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002700 final long identity = Binder.clearCallingIdentity();
2701 try {
2702 if (phone != null) {
2703 return phone.getDataActivationState();
2704 } else {
2705 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2706 }
2707 } finally {
2708 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002709 }
2710 }
2711
2712 /**
Wink Saville36469e72014-06-11 15:17:00 -07002713 * Returns the unread count of voicemails for a subId
2714 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002715 @Override
Brad Ebingerf7664ba2018-11-29 12:43:38 -08002716 public int getVoiceMessageCountForSubscriber(int subId, String callingPackage) {
2717 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2718 mApp, subId, callingPackage, "getVoiceMessageCountForSubscriber")) {
2719 return 0;
2720 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002721 final long identity = Binder.clearCallingIdentity();
2722 try {
2723 final Phone phone = getPhone(subId);
2724 if (phone != null) {
2725 return phone.getVoiceMessageCount();
2726 } else {
2727 return 0;
2728 }
2729 } finally {
2730 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002731 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002732 }
2733
2734 /**
pkanwar8a4dcfb2017-01-19 13:43:16 -08002735 * returns true, if the device is in a state where both voice and data
2736 * are supported simultaneously. This can change based on location or network condition.
2737 */
2738 @Override
2739 public boolean isConcurrentVoiceAndDataAllowed(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002740 final long identity = Binder.clearCallingIdentity();
2741 try {
2742 final Phone phone = getPhone(subId);
2743 return (phone == null ? false : phone.isConcurrentVoiceAndDataAllowed());
2744 } finally {
2745 Binder.restoreCallingIdentity(identity);
2746 }
pkanwar8a4dcfb2017-01-19 13:43:16 -08002747 }
2748
2749 /**
fionaxu235cc5e2017-03-06 22:25:57 -08002750 * Send the dialer code if called from the current default dialer or the caller has
2751 * carrier privilege.
2752 * @param inputCode The dialer code to send
2753 */
2754 @Override
2755 public void sendDialerSpecialCode(String callingPackage, String inputCode) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002756 final Phone defaultPhone = getDefaultPhone();
fionaxu235cc5e2017-03-06 22:25:57 -08002757 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002758 String defaultDialer = TelecomManager.from(defaultPhone.getContext())
2759 .getDefaultDialerPackage();
fionaxu235cc5e2017-03-06 22:25:57 -08002760 if (!TextUtils.equals(callingPackage, defaultDialer)) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002761 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
2762 getDefaultSubscription(), "sendDialerSpecialCode");
fionaxu235cc5e2017-03-06 22:25:57 -08002763 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002764
2765 final long identity = Binder.clearCallingIdentity();
2766 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002767 defaultPhone.sendDialerSpecialCode(inputCode);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002768 } finally {
2769 Binder.restoreCallingIdentity(identity);
2770 }
fionaxu235cc5e2017-03-06 22:25:57 -08002771 }
2772
2773 /**
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002774 * Returns the data network type.
2775 * Legacy call, permission-free.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002776 *
2777 * @Deprecated to be removed Q3 2013 use {@link #getDataNetworkType}.
2778 */
2779 @Override
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002780 public int getNetworkType() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002781 final long identity = Binder.clearCallingIdentity();
2782 try {
2783 final Phone phone = getPhone(getDefaultSubscription());
2784 if (phone != null) {
2785 return phone.getServiceState().getDataNetworkType();
2786 } else {
2787 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2788 }
2789 } finally {
2790 Binder.restoreCallingIdentity(identity);
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002791 }
Wink Saville36469e72014-06-11 15:17:00 -07002792 }
2793
Pengquan Menga1bb6272018-09-06 09:59:22 -07002794 @Override
2795 public int getNetworkSelectionMode(int subId) {
Pengquan Menge92a50d2018-09-21 15:54:48 -07002796 if (!isActiveSubscription(subId)) {
2797 return TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
2798 }
2799
Pengquan Menga1bb6272018-09-06 09:59:22 -07002800 return (int) sendRequest(CMD_GET_NETWORK_SELECTION_MODE, null /* argument */, subId);
2801 }
2802
Brad Ebinger35c841c2018-10-01 10:40:55 -07002803 @Override
Brad Ebingerb2b65522019-03-15 13:48:47 -07002804 public boolean isInEmergencySmsMode() {
2805 enforceReadPrivilegedPermission("isInEmergencySmsMode");
2806 final long identity = Binder.clearCallingIdentity();
2807 try {
2808 for (Phone phone : PhoneFactory.getPhones()) {
2809 if (phone.isInEmergencySmsMode()) {
2810 return true;
2811 }
2812 }
2813 } finally {
2814 Binder.restoreCallingIdentity(identity);
2815 }
2816 return false;
2817 }
2818
2819 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08002820 public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback c)
2821 throws RemoteException {
2822 enforceReadPrivilegedPermission("registerImsRegistrationCallback");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002823 final long token = Binder.clearCallingIdentity();
2824 try {
Brad Ebinger4ae57f92019-01-09 16:51:30 -08002825 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002826 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger35c841c2018-10-01 10:40:55 -07002827 .addRegistrationCallbackForSubscription(c, subId);
2828 } finally {
2829 Binder.restoreCallingIdentity(token);
2830 }
2831 }
2832
2833 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08002834 public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c) {
2835 enforceReadPrivilegedPermission("unregisterImsRegistrationCallback");
Brad Ebinger4ae57f92019-01-09 16:51:30 -08002836 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2837 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
2838 }
2839 Binder.withCleanCallingIdentity(() -> {
2840 try {
2841 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002842 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08002843 .removeRegistrationCallbackForSubscription(c, subId);
2844 } catch (IllegalArgumentException e) {
2845 Log.i(LOG_TAG, "unregisterImsRegistrationCallback: " + subId
2846 + "is inactive, ignoring unregister.");
2847 // If the subscription is no longer active, just return, since the callback
2848 // will already have been removed internally.
2849 }
2850 });
Brad Ebinger35c841c2018-10-01 10:40:55 -07002851 }
2852
2853 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08002854 public void registerMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)
2855 throws RemoteException {
2856 enforceReadPrivilegedPermission("registerMmTelCapabilityCallback");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002857 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2858 final long token = Binder.clearCallingIdentity();
2859 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002860 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger35c841c2018-10-01 10:40:55 -07002861 .addCapabilitiesCallbackForSubscription(c, subId);
2862 } finally {
2863 Binder.restoreCallingIdentity(token);
2864 }
2865 }
2866
2867 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08002868 public void unregisterMmTelCapabilityCallback(int subId, IImsCapabilityCallback c) {
2869 enforceReadPrivilegedPermission("unregisterMmTelCapabilityCallback");
Brad Ebinger4ae57f92019-01-09 16:51:30 -08002870
2871 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2872 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
2873 }
2874 Binder.withCleanCallingIdentity(() -> {
2875 try {
2876 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002877 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08002878 .removeCapabilitiesCallbackForSubscription(c, subId);
2879 } catch (IllegalArgumentException e) {
2880 Log.i(LOG_TAG, "unregisterMmTelCapabilityCallback: " + subId
2881 + "is inactive, ignoring unregister.");
2882 // If the subscription is no longer active, just return, since the callback
2883 // will already have been removed internally.
2884 }
2885 });
Brad Ebinger35c841c2018-10-01 10:40:55 -07002886 }
2887
2888 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08002889 public boolean isCapable(int subId, int capability, int regTech) {
2890 enforceReadPrivilegedPermission("isCapable");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002891 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2892 final long token = Binder.clearCallingIdentity();
2893 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002894 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07002895 getSlotIndexOrException(subId)).queryMmTelCapability(capability, regTech);
2896 } catch (ImsException e) {
2897 Log.w(LOG_TAG, "IMS isCapable - service unavailable: " + e.getMessage());
2898 return false;
Brad Ebinger6b5ac222019-02-04 14:36:52 -08002899 } catch (IllegalArgumentException e) {
2900 Log.i(LOG_TAG, "isCapable: " + subId + " is inactive, returning false.");
2901 return false;
Brad Ebinger35c841c2018-10-01 10:40:55 -07002902 } finally {
2903 Binder.restoreCallingIdentity(token);
2904 }
2905 }
2906
2907 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08002908 public boolean isAvailable(int subId, int capability, int regTech) {
2909 enforceReadPrivilegedPermission("isAvailable");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002910 final long token = Binder.clearCallingIdentity();
2911 try {
2912 Phone phone = getPhone(subId);
2913 if (phone == null) return false;
2914 return phone.isImsCapabilityAvailable(capability, regTech);
2915 } finally {
2916 Binder.restoreCallingIdentity(token);
2917 }
2918 }
2919
2920 @Override
2921 public boolean isAdvancedCallingSettingEnabled(int subId) {
2922 enforceReadPrivilegedPermission("enforceReadPrivilegedPermission");
2923 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2924 final long token = Binder.clearCallingIdentity();
2925 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002926 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07002927 getSlotIndexOrException(subId)).isEnhanced4gLteModeSettingEnabledByUser();
2928 } finally {
2929 Binder.restoreCallingIdentity(token);
2930 }
2931 }
2932
2933 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08002934 public void setAdvancedCallingSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002935 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08002936 "setAdvancedCallingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002937 final long identity = Binder.clearCallingIdentity();
2938 try {
2939 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002940 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07002941 getSlotIndexOrException(subId)).setEnhanced4gLteModeSetting(isEnabled);
2942 } finally {
2943 Binder.restoreCallingIdentity(identity);
2944 }
2945 }
2946
2947 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08002948 public boolean isVtSettingEnabled(int subId) {
2949 enforceReadPrivilegedPermission("isVtSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002950 final long identity = Binder.clearCallingIdentity();
2951 try {
2952 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002953 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07002954 getSlotIndexOrException(subId)).isVtEnabledByUser();
2955 } finally {
2956 Binder.restoreCallingIdentity(identity);
2957 }
2958 }
2959
2960 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08002961 public void setVtSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002962 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08002963 "setVtSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002964 final long identity = Binder.clearCallingIdentity();
2965 try {
2966 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002967 ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setVtSetting(isEnabled);
Brad Ebinger35c841c2018-10-01 10:40:55 -07002968 } finally {
2969 Binder.restoreCallingIdentity(identity);
2970 }
2971 }
2972
2973 @Override
2974 public boolean isVoWiFiSettingEnabled(int subId) {
2975 enforceReadPrivilegedPermission("isVoWiFiSettingEnabled");
2976 final long identity = Binder.clearCallingIdentity();
2977 try {
2978 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002979 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07002980 getSlotIndexOrException(subId)).isWfcEnabledByUser();
2981 } finally {
2982 Binder.restoreCallingIdentity(identity);
2983 }
2984 }
2985
2986 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08002987 public void setVoWiFiSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002988 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08002989 "setVoWiFiSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002990 final long identity = Binder.clearCallingIdentity();
2991 try {
2992 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002993 ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setWfcSetting(isEnabled);
Brad Ebinger35c841c2018-10-01 10:40:55 -07002994 } finally {
2995 Binder.restoreCallingIdentity(identity);
2996 }
2997 }
2998
2999 @Override
3000 public boolean isVoWiFiRoamingSettingEnabled(int subId) {
3001 enforceReadPrivilegedPermission("isVoWiFiRoamingSettingEnabled");
3002 final long identity = Binder.clearCallingIdentity();
3003 try {
3004 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003005 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003006 getSlotIndexOrException(subId)).isWfcRoamingEnabledByUser();
3007 } finally {
3008 Binder.restoreCallingIdentity(identity);
3009 }
3010 }
3011
3012 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08003013 public void setVoWiFiRoamingSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003014 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08003015 "setVoWiFiRoamingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003016 final long identity = Binder.clearCallingIdentity();
3017 try {
3018 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003019 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003020 getSlotIndexOrException(subId)).setWfcRoamingSetting(isEnabled);
3021 } finally {
3022 Binder.restoreCallingIdentity(identity);
3023 }
3024 }
3025
3026 @Override
3027 public void setVoWiFiNonPersistent(int subId, boolean isCapable, int mode) {
3028 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3029 "setVoWiFiNonPersistent");
3030 final long identity = Binder.clearCallingIdentity();
3031 try {
3032 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger43e66f12019-01-15 12:40:04 -08003033 boolean isRoaming = TelephonyManager.from(
3034 getPhone(subId).getContext()).isNetworkRoaming(subId);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003035 ImsManager.getInstance(mApp,
Brad Ebinger43e66f12019-01-15 12:40:04 -08003036 getSlotIndexOrException(subId)).setWfcNonPersistent(isCapable, mode, isRoaming);
Brad Ebinger35c841c2018-10-01 10:40:55 -07003037 } finally {
3038 Binder.restoreCallingIdentity(identity);
3039 }
3040 }
3041
3042 @Override
3043 public int getVoWiFiModeSetting(int subId) {
3044 enforceReadPrivilegedPermission("getVoWiFiModeSetting");
3045 final long identity = Binder.clearCallingIdentity();
3046 try {
3047 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003048 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003049 getSlotIndexOrException(subId)).getWfcMode(false /*isRoaming*/);
3050 } finally {
3051 Binder.restoreCallingIdentity(identity);
3052 }
3053 }
3054
3055 @Override
3056 public void setVoWiFiModeSetting(int subId, int mode) {
3057 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3058 "setVoWiFiModeSetting");
3059 final long identity = Binder.clearCallingIdentity();
3060 try {
3061 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003062 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003063 getSlotIndexOrException(subId)).setWfcMode(mode, false /*isRoaming*/);
3064 } finally {
3065 Binder.restoreCallingIdentity(identity);
3066 }
3067 }
3068
3069 @Override
3070 public int getVoWiFiRoamingModeSetting(int subId) {
3071 enforceReadPrivilegedPermission("getVoWiFiRoamingModeSetting");
3072 final long identity = Binder.clearCallingIdentity();
3073 try {
3074 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003075 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003076 getSlotIndexOrException(subId)).getWfcMode(true /*isRoaming*/);
3077 } finally {
3078 Binder.restoreCallingIdentity(identity);
3079 }
3080 }
3081
3082 @Override
3083 public void setVoWiFiRoamingModeSetting(int subId, int mode) {
3084 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3085 "setVoWiFiRoamingModeSetting");
3086 final long identity = Binder.clearCallingIdentity();
3087 try {
3088 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003089 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003090 getSlotIndexOrException(subId)).setWfcMode(mode, true /*isRoaming*/);
3091 } finally {
3092 Binder.restoreCallingIdentity(identity);
3093 }
3094 }
3095
3096 @Override
3097 public void setRttCapabilitySetting(int subId, boolean isEnabled) {
3098 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3099 "setRttCapabilityEnabled");
3100 final long identity = Binder.clearCallingIdentity();
3101 try {
3102 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003103 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003104 getSlotIndexOrException(subId)).setRttEnabled(isEnabled);
3105 } finally {
3106 Binder.restoreCallingIdentity(identity);
3107 }
3108 }
3109
3110 @Override
3111 public boolean isTtyOverVolteEnabled(int subId) {
3112 enforceReadPrivilegedPermission("isTtyOverVolteEnabled");
3113 final long identity = Binder.clearCallingIdentity();
3114 try {
3115 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003116 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003117 getSlotIndexOrException(subId)).isTtyOnVoLteCapable();
3118 } finally {
3119 Binder.restoreCallingIdentity(identity);
3120 }
3121 }
3122
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003123 @Override
3124 public void registerImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
3125 enforceReadPrivilegedPermission("registerImsProvisioningChangedCallback");
3126 final long identity = Binder.clearCallingIdentity();
3127 try {
3128 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003129 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003130 .addProvisioningCallbackForSubscription(callback, subId);
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003131 } finally {
3132 Binder.restoreCallingIdentity(identity);
3133 }
3134 }
3135
3136 @Override
3137 public void unregisterImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
3138 enforceReadPrivilegedPermission("unregisterImsProvisioningChangedCallback");
3139 final long identity = Binder.clearCallingIdentity();
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003140 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3141 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
3142 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003143 try {
3144 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003145 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003146 .removeProvisioningCallbackForSubscription(callback, subId);
3147 } catch (IllegalArgumentException e) {
3148 Log.i(LOG_TAG, "unregisterImsProvisioningChangedCallback: " + subId
3149 + "is inactive, ignoring unregister.");
3150 // If the subscription is no longer active, just return, since the callback will already
3151 // have been removed internally.
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003152 } finally {
3153 Binder.restoreCallingIdentity(identity);
3154 }
3155 }
3156
3157 @Override
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003158 public void setImsProvisioningStatusForCapability(int subId, int capability, int tech,
3159 boolean isProvisioned) {
3160 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3161 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3162 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
3163 }
3164 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3165 "setProvisioningStatusForCapability");
3166 final long identity = Binder.clearCallingIdentity();
3167 try {
3168 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3169 Phone phone = getPhone(subId);
3170 if (phone == null) {
3171 loge("setImsProvisioningStatusForCapability: phone instance null for subid "
3172 + subId);
3173 return;
3174 }
3175 if (!doesImsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
3176 return;
3177 }
3178
3179 // this capability requires provisioning, route to the correct API.
3180 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
3181 switch (capability) {
3182 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
3183 if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3184 ims.setVolteProvisioned(isProvisioned);
3185 } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
3186 ims.setWfcProvisioned(isProvisioned);
3187 }
3188 break;
3189 }
3190 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
3191 // There is currently no difference in VT provisioning type.
3192 ims.setVtProvisioned(isProvisioned);
3193 break;
3194 }
3195 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
3196 // There is no "deprecated" UT provisioning mechanism through ImsConfig, so
3197 // change the capability of the feature instead if needed.
3198 if (isMmTelCapabilityProvisionedInCache(subId, capability, tech)
3199 == isProvisioned) {
3200 // No change in provisioning.
3201 return;
3202 }
3203 cacheMmTelCapabilityProvisioning(subId, capability, tech, isProvisioned);
3204 try {
3205 ims.changeMmTelCapability(capability, tech, isProvisioned);
3206 } catch (ImsException e) {
3207 loge("setImsProvisioningStatusForCapability: couldn't change UT capability"
3208 + ", Exception" + e.getMessage());
3209 }
3210 break;
3211 }
3212 default: {
3213 throw new IllegalArgumentException("Tried to set provisioning for capability '"
3214 + capability + "', which does not require provisioning.");
3215 }
3216 }
3217
3218 } finally {
3219 Binder.restoreCallingIdentity(identity);
3220 }
3221 }
3222
3223 @Override
3224 public boolean getImsProvisioningStatusForCapability(int subId, int capability, int tech) {
3225 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3226 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3227 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
3228 }
3229 enforceReadPrivilegedPermission("getProvisioningStatusForCapability");
3230 final long identity = Binder.clearCallingIdentity();
3231 try {
3232 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3233 Phone phone = getPhone(subId);
3234 if (phone == null) {
3235 loge("getImsProvisioningStatusForCapability: phone instance null for subid "
3236 + subId);
3237 // We will fail with "true" as the provisioning status because this is the default
3238 // if we do not require provisioning.
3239 return true;
3240 }
3241
3242 if (!doesImsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
3243 return true;
3244 }
3245
3246 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
3247 switch (capability) {
3248 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
3249 if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3250 return ims.isVolteProvisionedOnDevice();
3251 } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
3252 return ims.isWfcProvisionedOnDevice();
3253 }
3254 // This should never happen, since we are checking tech above to make sure it
3255 // is either LTE or IWLAN.
3256 throw new IllegalArgumentException("Invalid radio technology for voice "
3257 + "capability.");
3258 }
3259 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
3260 // There is currently no difference in VT provisioning type.
3261 return ims.isVtProvisionedOnDevice();
3262 }
3263 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
3264 // There is no "deprecated" UT provisioning mechanism, so get from shared prefs.
3265 return isMmTelCapabilityProvisionedInCache(subId, capability, tech);
3266 }
3267 default: {
3268 throw new IllegalArgumentException("Tried to get provisioning for capability '"
3269 + capability + "', which does not require provisioning.");
3270 }
3271 }
3272
3273 } finally {
3274 Binder.restoreCallingIdentity(identity);
3275 }
3276 }
3277
3278 @Override
3279 public boolean isMmTelCapabilityProvisionedInCache(int subId, int capability, int tech) {
3280 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3281 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3282 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
3283 }
3284 enforceReadPrivilegedPermission("isMmTelCapabilityProvisionedInCache");
3285 int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
3286 return (provisionedBits & capability) > 0;
3287 }
3288
3289 @Override
3290 public void cacheMmTelCapabilityProvisioning(int subId, int capability, int tech,
3291 boolean isProvisioned) {
3292 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3293 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3294 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
3295 }
3296 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3297 "setProvisioningStatusForCapability");
3298 int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
3299 // If the current provisioning status for capability already matches isProvisioned,
3300 // do nothing.
3301 if (((provisionedBits & capability) > 0) == isProvisioned) {
3302 return;
3303 }
3304 if (isProvisioned) {
3305 setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits | capability));
3306 } else {
3307 setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits & ~capability));
3308 }
3309 }
3310
3311 /**
3312 * @return the bitfield containing the MmTel provisioning for the provided subscription and
3313 * technology. The bitfield should mirror the bitfield defined by
3314 * {@link MmTelFeature.MmTelCapabilities.MmTelCapability}.
3315 */
3316 private int getMmTelCapabilityProvisioningBitfield(int subId, int tech) {
3317 String key = getMmTelProvisioningKey(subId, tech);
3318 // Default is no capabilities are provisioned.
3319 return mTelephonySharedPreferences.getInt(key, 0 /*default*/);
3320 }
3321
3322 /**
3323 * Sets the MmTel capability provisioning bitfield (defined by
3324 * {@link MmTelFeature.MmTelCapabilities.MmTelCapability}) for the subscription and
3325 * technology specified.
3326 *
3327 * Note: This is a synchronous command and should not be called on UI thread.
3328 */
3329 private void setMmTelCapabilityProvisioningBitfield(int subId, int tech, int newField) {
3330 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
3331 String key = getMmTelProvisioningKey(subId, tech);
3332 editor.putInt(key, newField);
3333 editor.commit();
3334 }
3335
3336 private static String getMmTelProvisioningKey(int subId, int tech) {
3337 // resulting key is provision_ims_mmtel_{subId}_{tech}
3338 return PREF_PROVISION_IMS_MMTEL_PREFIX + subId + "_" + tech;
3339 }
3340
3341 /**
3342 * Query CarrierConfig to see if the specified capability requires provisioning for the
3343 * carrier associated with the subscription id.
3344 */
3345 private boolean doesImsCapabilityRequireProvisioning(Context context, int subId,
3346 int capability) {
3347 CarrierConfigManager configManager = new CarrierConfigManager(context);
3348 PersistableBundle c = configManager.getConfigForSubId(subId);
3349 boolean requireUtProvisioning = c.getBoolean(
3350 // By default, this config is true (even if there is no SIM). We also check to make
3351 // sure the subscription needs provisioning here, so we do not need to check for
3352 // the no-SIM case, where we would normally shortcut this to false.
3353 CarrierConfigManager.KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL, true)
3354 && c.getBoolean(CarrierConfigManager.KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL,
3355 false);
3356 boolean requireVoiceVtProvisioning = c.getBoolean(
3357 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, false);
3358
3359 // First check to make sure that the capability requires provisioning.
3360 switch (capability) {
3361 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE:
3362 // intentional fallthrough
3363 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
3364 if (requireVoiceVtProvisioning) {
3365 // Voice and Video requires provisioning
3366 return true;
3367 }
3368 break;
3369 }
3370 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
3371 if (requireUtProvisioning) {
3372 // UT requires provisioning
3373 return true;
3374 }
3375 break;
3376 }
3377 }
3378 return false;
3379 }
3380
3381 @Override
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003382 public int getImsProvisioningInt(int subId, int key) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003383 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3384 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
3385 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003386 enforceReadPrivilegedPermission("getImsProvisioningInt");
3387 final long identity = Binder.clearCallingIdentity();
3388 try {
3389 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003390 int slotId = getSlotIndex(subId);
3391 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
3392 Log.w(LOG_TAG, "getImsProvisioningInt: called with an inactive subscription '"
3393 + subId + "' for key:" + key);
3394 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
3395 }
3396 return ImsManager.getInstance(mApp, slotId).getConfigInterface().getConfigInt(key);
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003397 } catch (ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003398 Log.w(LOG_TAG, "getImsProvisioningInt: ImsService is not available for subscription '"
3399 + subId + "' for key:" + key);
3400 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003401 } finally {
3402 Binder.restoreCallingIdentity(identity);
3403 }
3404 }
3405
3406 @Override
3407 public String getImsProvisioningString(int subId, int key) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003408 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3409 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
3410 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003411 enforceReadPrivilegedPermission("getImsProvisioningString");
3412 final long identity = Binder.clearCallingIdentity();
3413 try {
3414 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003415 int slotId = getSlotIndex(subId);
3416 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
3417 Log.w(LOG_TAG, "getImsProvisioningString: called for an inactive subscription id '"
3418 + subId + "' for key:" + key);
3419 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_GENERIC;
3420 }
3421 return ImsManager.getInstance(mApp, slotId).getConfigInterface().getConfigString(key);
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003422 } catch (ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003423 Log.w(LOG_TAG, "getImsProvisioningString: ImsService is not available for sub '"
3424 + subId + "' for key:" + key);
3425 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_NOT_READY;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003426 } finally {
3427 Binder.restoreCallingIdentity(identity);
3428 }
3429 }
3430
3431 @Override
3432 public int setImsProvisioningInt(int subId, int key, int value) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003433 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3434 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
3435 }
Brad Ebinger3d0b34e2018-11-15 14:13:12 -08003436 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3437 "setImsProvisioningInt");
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003438 final long identity = Binder.clearCallingIdentity();
3439 try {
3440 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003441 int slotId = getSlotIndex(subId);
3442 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
3443 Log.w(LOG_TAG, "setImsProvisioningInt: called with an inactive subscription id '"
3444 + subId + "' for key:" + key);
3445 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
3446 }
3447 return ImsManager.getInstance(mApp, slotId).getConfigInterface().setConfig(key, value);
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003448 } catch (ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003449 Log.w(LOG_TAG, "setImsProvisioningInt: ImsService unavailable for sub '" + subId
3450 + "' for key:" + key);
3451 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003452 } finally {
3453 Binder.restoreCallingIdentity(identity);
3454 }
3455 }
3456
3457 @Override
3458 public int setImsProvisioningString(int subId, int key, String value) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003459 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3460 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
3461 }
Brad Ebinger3d0b34e2018-11-15 14:13:12 -08003462 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3463 "setImsProvisioningString");
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003464 final long identity = Binder.clearCallingIdentity();
3465 try {
3466 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003467 int slotId = getSlotIndex(subId);
3468 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
3469 Log.w(LOG_TAG, "setImsProvisioningString: called with an inactive subscription id '"
3470 + subId + "' for key:" + key);
3471 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
3472 }
3473 return ImsManager.getInstance(mApp, slotId).getConfigInterface().setConfig(key, value);
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003474 } catch (ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003475 Log.w(LOG_TAG, "setImsProvisioningString: ImsService unavailable for sub '" + subId
3476 + "' for key:" + key);
3477 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003478 } finally {
3479 Binder.restoreCallingIdentity(identity);
3480 }
3481 }
3482
Brad Ebinger35c841c2018-10-01 10:40:55 -07003483 private int getSlotIndexOrException(int subId) throws IllegalArgumentException {
3484 int slotId = SubscriptionManager.getSlotIndex(subId);
3485 if (!SubscriptionManager.isValidSlotIndex(slotId)) {
Brad Ebinger6b5ac222019-02-04 14:36:52 -08003486 throw new IllegalArgumentException("Invalid Subscription Id, subId=" + subId);
Brad Ebinger35c841c2018-10-01 10:40:55 -07003487 }
3488 return slotId;
3489 }
3490
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003491 private int getSlotIndex(int subId) {
3492 int slotId = SubscriptionManager.getSlotIndex(subId);
3493 if (!SubscriptionManager.isValidSlotIndex(slotId)) {
3494 return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
3495 }
3496 return slotId;
3497 }
3498
Wink Saville36469e72014-06-11 15:17:00 -07003499 /**
3500 * Returns the network type for a subId
3501 */
3502 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003503 public int getNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003504 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003505 mApp, subId, callingPackage, "getNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003506 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3507 }
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07003508
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003509 final long identity = Binder.clearCallingIdentity();
3510 try {
3511 final Phone phone = getPhone(subId);
3512 if (phone != null) {
3513 return phone.getServiceState().getDataNetworkType();
3514 } else {
3515 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3516 }
3517 } finally {
3518 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003519 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003520 }
3521
3522 /**
3523 * Returns the data network type
3524 */
3525 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003526 public int getDataNetworkType(String callingPackage) {
3527 return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07003528 }
3529
3530 /**
3531 * Returns the data network type for a subId
3532 */
3533 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003534 public int getDataNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003535 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003536 mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003537 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3538 }
3539
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003540 final long identity = Binder.clearCallingIdentity();
3541 try {
3542 final Phone phone = getPhone(subId);
3543 if (phone != null) {
3544 return phone.getServiceState().getDataNetworkType();
3545 } else {
3546 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3547 }
3548 } finally {
3549 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003550 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003551 }
3552
3553 /**
Wink Saville36469e72014-06-11 15:17:00 -07003554 * Returns the Voice network type for a subId
3555 */
3556 @Override
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07003557 public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003558 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003559 mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07003560 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3561 }
3562
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003563 final long identity = Binder.clearCallingIdentity();
3564 try {
3565 final Phone phone = getPhone(subId);
3566 if (phone != null) {
3567 return phone.getServiceState().getVoiceNetworkType();
3568 } else {
3569 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3570 }
3571 } finally {
3572 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003573 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003574 }
3575
3576 /**
3577 * @return true if a ICC card is present
3578 */
3579 public boolean hasIccCard() {
Wink Saville36469e72014-06-11 15:17:00 -07003580 // FIXME Make changes to pass defaultSimId of type int
Sanket Padawe13bac7b2017-03-20 15:04:47 -07003581 return hasIccCardUsingSlotIndex(mSubscriptionController.getSlotIndex(
3582 getDefaultSubscription()));
Wink Saville36469e72014-06-11 15:17:00 -07003583 }
3584
3585 /**
Sanket Padawe13bac7b2017-03-20 15:04:47 -07003586 * @return true if a ICC card is present for a slotIndex
Wink Saville36469e72014-06-11 15:17:00 -07003587 */
Sanket Padawe356d7632015-06-22 14:03:32 -07003588 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07003589 public boolean hasIccCardUsingSlotIndex(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003590 final long identity = Binder.clearCallingIdentity();
3591 try {
3592 final Phone phone = PhoneFactory.getPhone(slotIndex);
3593 if (phone != null) {
3594 return phone.getIccCard().hasIccCard();
3595 } else {
3596 return false;
3597 }
3598 } finally {
3599 Binder.restoreCallingIdentity(identity);
Amit Mahajana6fc2a82015-01-06 11:53:51 -08003600 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003601 }
3602
3603 /**
3604 * Return if the current radio is LTE on CDMA. This
3605 * is a tri-state return value as for a period of time
3606 * the mode may be unknown.
3607 *
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003608 * @param callingPackage the name of the package making the call.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003609 * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
Jake Hambye994d462014-02-03 13:10:13 -08003610 * or {@link Phone#LTE_ON_CDMA_TRUE}
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003611 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003612 @Override
3613 public int getLteOnCdmaMode(String callingPackage) {
3614 return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07003615 }
3616
Sanket Padawe356d7632015-06-22 14:03:32 -07003617 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003618 public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003619 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003620 mApp, subId, callingPackage, "getLteOnCdmaModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003621 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
3622 }
3623
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003624 final long identity = Binder.clearCallingIdentity();
3625 try {
3626 final Phone phone = getPhone(subId);
3627 if (phone == null) {
3628 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
3629 } else {
3630 return phone.getLteOnCdmaMode();
3631 }
3632 } finally {
3633 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003634 }
Wink Saville36469e72014-06-11 15:17:00 -07003635 }
3636
Wink Saville36469e72014-06-11 15:17:00 -07003637 /**
3638 * {@hide}
3639 * Returns Default subId, 0 in the case of single standby.
3640 */
Wink Savilleb564aae2014-10-23 10:18:09 -07003641 private int getDefaultSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08003642 return mSubscriptionController.getDefaultSubId();
Wink Saville36469e72014-06-11 15:17:00 -07003643 }
3644
Shishir Agrawala9f32182016-04-12 12:00:16 -07003645 private int getSlotForDefaultSubscription() {
3646 return mSubscriptionController.getPhoneId(getDefaultSubscription());
3647 }
3648
Wink Savilleb564aae2014-10-23 10:18:09 -07003649 private int getPreferredVoiceSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08003650 return mSubscriptionController.getDefaultVoiceSubId();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003651 }
Ihab Awadf2177b72013-11-25 13:33:23 -08003652
Pengquan Menge92a50d2018-09-21 15:54:48 -07003653 private boolean isActiveSubscription(int subId) {
3654 return mSubscriptionController.isActiveSubId(subId);
3655 }
3656
Ihab Awadf2177b72013-11-25 13:33:23 -08003657 /**
3658 * @see android.telephony.TelephonyManager.WifiCallingChoices
3659 */
3660 public int getWhenToMakeWifiCalls() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003661 final long identity = Binder.clearCallingIdentity();
3662 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003663 return Settings.System.getInt(mApp.getContentResolver(),
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003664 Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
3665 getWhenToMakeWifiCallsDefaultPreference());
3666 } finally {
3667 Binder.restoreCallingIdentity(identity);
3668 }
Ihab Awadf2177b72013-11-25 13:33:23 -08003669 }
3670
3671 /**
3672 * @see android.telephony.TelephonyManager.WifiCallingChoices
3673 */
3674 public void setWhenToMakeWifiCalls(int preference) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003675 final long identity = Binder.clearCallingIdentity();
3676 try {
3677 if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003678 Settings.System.putInt(mApp.getContentResolver(),
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003679 Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference);
3680 } finally {
3681 Binder.restoreCallingIdentity(identity);
3682 }
Ihab Awadf9e92732013-12-05 18:02:52 -08003683 }
3684
Sailesh Nepald1e68152013-12-12 19:08:02 -08003685 private static int getWhenToMakeWifiCallsDefaultPreference() {
Santos Cordonda120f42014-08-06 04:44:34 -07003686 // TODO: Use a build property to choose this value.
Evan Charlton9829e882013-12-19 15:30:38 -08003687 return TelephonyManager.WifiCallingChoices.ALWAYS_USE;
Ihab Awadf2177b72013-11-25 13:33:23 -08003688 }
Shishir Agrawal69f68122013-12-16 17:25:49 -08003689
Jordan Liu4c733742019-02-28 12:03:40 -08003690 private Phone getPhoneFromSlotIdOrThrowException(int slotIndex) {
3691 int phoneId = UiccController.getInstance().getPhoneIdFromSlotId(slotIndex);
3692 if (phoneId == -1) {
3693 throw new IllegalArgumentException("Given slot index: " + slotIndex
3694 + " does not correspond to an active phone");
3695 }
3696 return PhoneFactory.getPhone(phoneId);
3697 }
3698
Shishir Agrawal566b7612013-10-28 14:41:00 -07003699 @Override
Derek Tan740e1672017-06-27 14:56:27 -07003700 public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
3701 int subId, String callingPackage, String aid, int p2) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003702 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3703 mApp, subId, "iccOpenLogicalChannel");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003704 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jordan Liu4c733742019-02-28 12:03:40 -08003705 if (DBG) {
3706 log("iccOpenLogicalChannel: subId=" + subId + " aid=" + aid + " p2=" + p2);
3707 }
3708 return iccOpenLogicalChannelWithPermission(getPhoneFromSubId(subId), callingPackage, aid,
3709 p2);
3710 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003711
Jordan Liu4c733742019-02-28 12:03:40 -08003712
3713 @Override
3714 public IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(
3715 int slotIndex, String callingPackage, String aid, int p2) {
3716 enforceModifyPermission();
3717 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3718 if (DBG) {
3719 log("iccOpenLogicalChannelBySlot: slot=" + slotIndex + " aid=" + aid + " p2=" + p2);
3720 }
3721 return iccOpenLogicalChannelWithPermission(getPhoneFromSlotIdOrThrowException(slotIndex),
3722 callingPackage, aid, p2);
3723 }
3724
3725 private IccOpenLogicalChannelResponse iccOpenLogicalChannelWithPermission(Phone phone,
3726 String callingPackage, String aid, int p2) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003727 final long identity = Binder.clearCallingIdentity();
3728 try {
3729 if (TextUtils.equals(ISDR_AID, aid)) {
3730 // Only allows LPA to open logical channel to ISD-R.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003731 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
3732 .getContext().getPackageManager());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003733 if (bestComponent == null
3734 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
3735 loge("The calling package is not allowed to access ISD-R.");
3736 throw new SecurityException(
3737 "The calling package is not allowed to access ISD-R.");
3738 }
Derek Tan740e1672017-06-27 14:56:27 -07003739 }
Derek Tan740e1672017-06-27 14:56:27 -07003740
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003741 IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse) sendRequest(
Jordan Liu4c733742019-02-28 12:03:40 -08003742 CMD_OPEN_CHANNEL, new Pair<String, Integer>(aid, p2), phone,
3743 null /* workSource */);
3744 if (DBG) log("iccOpenLogicalChannelWithPermission: " + response);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003745 return response;
3746 } finally {
3747 Binder.restoreCallingIdentity(identity);
3748 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003749 }
3750
3751 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003752 public boolean iccCloseLogicalChannel(int subId, int channel) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003753 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3754 mApp, subId, "iccCloseLogicalChannel");
Jordan Liu4c733742019-02-28 12:03:40 -08003755 if (DBG) log("iccCloseLogicalChannel: subId=" + subId + " chnl=" + channel);
3756 return iccCloseLogicalChannelWithPermission(getPhoneFromSubId(subId), channel);
3757 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003758
Jordan Liu4c733742019-02-28 12:03:40 -08003759 @Override
3760 public boolean iccCloseLogicalChannelBySlot(int slotIndex, int channel) {
3761 enforceModifyPermission();
3762 if (DBG) log("iccCloseLogicalChannelBySlot: slotIndex=" + slotIndex + " chnl=" + channel);
3763 return iccCloseLogicalChannelWithPermission(getPhoneFromSlotIdOrThrowException(slotIndex),
3764 channel);
3765 }
3766
3767 private boolean iccCloseLogicalChannelWithPermission(Phone phone, int channel) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003768 final long identity = Binder.clearCallingIdentity();
3769 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003770 if (channel < 0) {
3771 return false;
3772 }
Jordan Liu4c733742019-02-28 12:03:40 -08003773 Boolean success = (Boolean) sendRequest(CMD_CLOSE_CHANNEL, channel, phone,
3774 null /* workSource */);
3775 if (DBG) log("iccCloseLogicalChannelWithPermission: " + success);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003776 return success;
3777 } finally {
3778 Binder.restoreCallingIdentity(identity);
Shishir Agrawal566b7612013-10-28 14:41:00 -07003779 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003780 }
3781
3782 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003783 public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
Shishir Agrawal566b7612013-10-28 14:41:00 -07003784 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003785 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3786 mApp, subId, "iccTransmitApduLogicalChannel");
Jordan Liu4c733742019-02-28 12:03:40 -08003787 if (DBG) {
3788 log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel
3789 + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
3790 + p3 + " data=" + data);
3791 }
3792 return iccTransmitApduLogicalChannelWithPermission(getPhoneFromSubId(subId), channel, cla,
3793 command, p1, p2, p3, data);
3794 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003795
Jordan Liu4c733742019-02-28 12:03:40 -08003796 @Override
3797 public String iccTransmitApduLogicalChannelBySlot(int slotIndex, int channel, int cla,
3798 int command, int p1, int p2, int p3, String data) {
3799 enforceModifyPermission();
3800 if (DBG) {
3801 log("iccTransmitApduLogicalChannelBySlot: slotIndex=" + slotIndex + " chnl=" + channel
3802 + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
3803 + p3 + " data=" + data);
3804 }
3805 return iccTransmitApduLogicalChannelWithPermission(
3806 getPhoneFromSlotIdOrThrowException(slotIndex), channel, cla, command, p1, p2, p3,
3807 data);
3808 }
3809
3810 private String iccTransmitApduLogicalChannelWithPermission(Phone phone, int channel, int cla,
3811 int command, int p1, int p2, int p3, String data) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003812 final long identity = Binder.clearCallingIdentity();
3813 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003814 if (channel < 0) {
3815 return "";
3816 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003817
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003818 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL,
Jordan Liu4c733742019-02-28 12:03:40 -08003819 new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), phone,
3820 null /* workSource */);
3821 if (DBG) log("iccTransmitApduLogicalChannelWithPermission: " + response);
Shishir Agrawal566b7612013-10-28 14:41:00 -07003822
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003823 // Append the returned status code to the end of the response payload.
3824 String s = Integer.toHexString(
3825 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
3826 if (response.payload != null) {
3827 s = IccUtils.bytesToHexString(response.payload) + s;
3828 }
3829 return s;
3830 } finally {
3831 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07003832 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003833 }
Jake Hambye994d462014-02-03 13:10:13 -08003834
Evan Charltonc66da362014-05-16 14:06:40 -07003835 @Override
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08003836 public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
3837 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003838 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3839 mApp, subId, "iccTransmitApduBasicChannel");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003840 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jordan Liu4c733742019-02-28 12:03:40 -08003841 if (DBG) {
3842 log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd="
3843 + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
3844 }
3845 return iccTransmitApduBasicChannelWithPermission(getPhoneFromSubId(subId), callingPackage,
3846 cla, command, p1, p2, p3, data);
3847 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003848
Jordan Liu4c733742019-02-28 12:03:40 -08003849 @Override
3850 public String iccTransmitApduBasicChannelBySlot(int slotIndex, String callingPackage, int cla,
3851 int command, int p1, int p2, int p3, String data) {
3852 enforceModifyPermission();
3853 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3854 if (DBG) {
3855 log("iccTransmitApduBasicChannelBySlot: slotIndex=" + slotIndex + " cla=" + cla
3856 + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3
3857 + " data=" + data);
3858 }
3859
3860 return iccTransmitApduBasicChannelWithPermission(
3861 getPhoneFromSlotIdOrThrowException(slotIndex), callingPackage, cla, command, p1,
3862 p2, p3, data);
3863 }
3864
3865 // open APDU basic channel assuming the caller has sufficient permissions
3866 private String iccTransmitApduBasicChannelWithPermission(Phone phone, String callingPackage,
3867 int cla, int command, int p1, int p2, int p3, String data) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003868 final long identity = Binder.clearCallingIdentity();
3869 try {
3870 if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
3871 && TextUtils.equals(ISDR_AID, data)) {
3872 // Only allows LPA to select ISD-R.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003873 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
3874 .getContext().getPackageManager());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003875 if (bestComponent == null
3876 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
3877 loge("The calling package is not allowed to select ISD-R.");
3878 throw new SecurityException(
3879 "The calling package is not allowed to select ISD-R.");
3880 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08003881 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08003882
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003883 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL,
Jordan Liu4c733742019-02-28 12:03:40 -08003884 new IccAPDUArgument(0, cla, command, p1, p2, p3, data), phone,
3885 null /* workSource */);
3886 if (DBG) log("iccTransmitApduBasicChannelWithPermission: " + response);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003887
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003888 // Append the returned status code to the end of the response payload.
3889 String s = Integer.toHexString(
3890 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
3891 if (response.payload != null) {
3892 s = IccUtils.bytesToHexString(response.payload) + s;
3893 }
3894 return s;
3895 } finally {
3896 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07003897 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003898 }
3899
3900 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003901 public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003902 String filePath) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003903 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3904 mApp, subId, "iccExchangeSimIO");
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003905
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003906 final long identity = Binder.clearCallingIdentity();
3907 try {
3908 if (DBG) {
3909 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " "
3910 + p1 + " " + p2 + " " + p3 + ":" + filePath);
3911 }
3912
3913 IccIoResult response =
3914 (IccIoResult) sendRequest(CMD_EXCHANGE_SIM_IO,
3915 new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath),
3916 subId);
3917
3918 if (DBG) {
3919 log("Exchange SIM_IO [R]" + response);
3920 }
3921
3922 byte[] result = null;
3923 int length = 2;
3924 if (response.payload != null) {
3925 length = 2 + response.payload.length;
3926 result = new byte[length];
3927 System.arraycopy(response.payload, 0, result, 0, response.payload.length);
3928 } else {
3929 result = new byte[length];
3930 }
3931
3932 result[length - 1] = (byte) response.sw2;
3933 result[length - 2] = (byte) response.sw1;
3934 return result;
3935 } finally {
3936 Binder.restoreCallingIdentity(identity);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003937 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003938 }
3939
Nathan Haroldb3014052017-01-25 15:57:32 -08003940 /**
3941 * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
3942 * on a particular subscription
3943 */
sqianb6e41952018-03-12 14:54:01 -07003944 public String[] getForbiddenPlmns(int subId, int appType, String callingPackage) {
3945 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
3946 mApp, subId, callingPackage, "getForbiddenPlmns")) {
3947 return null;
3948 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003949
3950 final long identity = Binder.clearCallingIdentity();
3951 try {
3952 if (appType != TelephonyManager.APPTYPE_USIM
3953 && appType != TelephonyManager.APPTYPE_SIM) {
3954 loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
3955 return null;
3956 }
3957 Object response = sendRequest(
3958 CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
3959 if (response instanceof String[]) {
3960 return (String[]) response;
3961 }
3962 // Response is an Exception of some kind,
3963 // which is signalled to the user as a NULL retval
Nathan Haroldb3014052017-01-25 15:57:32 -08003964 return null;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003965 } finally {
3966 Binder.restoreCallingIdentity(identity);
Nathan Haroldb3014052017-01-25 15:57:32 -08003967 }
Nathan Haroldb3014052017-01-25 15:57:32 -08003968 }
3969
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003970 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003971 public String sendEnvelopeWithStatus(int subId, String content) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003972 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3973 mApp, subId, "sendEnvelopeWithStatus");
Evan Charltonc66da362014-05-16 14:06:40 -07003974
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003975 final long identity = Binder.clearCallingIdentity();
3976 try {
3977 IccIoResult response = (IccIoResult) sendRequest(CMD_SEND_ENVELOPE, content, subId);
3978 if (response.payload == null) {
3979 return "";
3980 }
Evan Charltonc66da362014-05-16 14:06:40 -07003981
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003982 // Append the returned status code to the end of the response payload.
3983 String s = Integer.toHexString(
3984 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
3985 s = IccUtils.bytesToHexString(response.payload) + s;
3986 return s;
3987 } finally {
3988 Binder.restoreCallingIdentity(identity);
3989 }
Evan Charltonc66da362014-05-16 14:06:40 -07003990 }
3991
Jake Hambye994d462014-02-03 13:10:13 -08003992 /**
3993 * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
3994 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
3995 *
3996 * @param itemID the ID of the item to read
3997 * @return the NV item as a String, or null on error.
3998 */
3999 @Override
4000 public String nvReadItem(int itemID) {
vagdeviaf9a5b92018-08-15 16:01:53 -07004001 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08004002 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4003 mApp, getDefaultSubscription(), "nvReadItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004004
4005 final long identity = Binder.clearCallingIdentity();
4006 try {
4007 if (DBG) log("nvReadItem: item " + itemID);
vagdeviaf9a5b92018-08-15 16:01:53 -07004008 String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004009 if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
4010 return value;
4011 } finally {
4012 Binder.restoreCallingIdentity(identity);
4013 }
Jake Hambye994d462014-02-03 13:10:13 -08004014 }
4015
4016 /**
4017 * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
4018 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
4019 *
4020 * @param itemID the ID of the item to read
4021 * @param itemValue the value to write, as a String
4022 * @return true on success; false on any failure
4023 */
4024 @Override
4025 public boolean nvWriteItem(int itemID, String itemValue) {
vagdeviaf9a5b92018-08-15 16:01:53 -07004026 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08004027 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4028 mApp, getDefaultSubscription(), "nvWriteItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004029
4030 final long identity = Binder.clearCallingIdentity();
4031 try {
4032 if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
4033 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
vagdeviaf9a5b92018-08-15 16:01:53 -07004034 new Pair<Integer, String>(itemID, itemValue), workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004035 if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
4036 return success;
4037 } finally {
4038 Binder.restoreCallingIdentity(identity);
4039 }
Jake Hambye994d462014-02-03 13:10:13 -08004040 }
4041
4042 /**
4043 * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
4044 * Used for device configuration by some CDMA operators.
4045 *
4046 * @param preferredRoamingList byte array containing the new PRL
4047 * @return true on success; false on any failure
4048 */
4049 @Override
4050 public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004051 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4052 mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004053
4054 final long identity = Binder.clearCallingIdentity();
4055 try {
4056 if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
4057 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
4058 if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
4059 return success;
4060 } finally {
4061 Binder.restoreCallingIdentity(identity);
4062 }
Jake Hambye994d462014-02-03 13:10:13 -08004063 }
4064
4065 /**
chen xu6dac5ab2018-10-26 17:39:23 -07004066 * Rollback modem configurations to factory default except some config which are in whitelist.
Jake Hambye994d462014-02-03 13:10:13 -08004067 * Used for device configuration by some CDMA operators.
4068 *
chen xu6dac5ab2018-10-26 17:39:23 -07004069 * @param slotIndex - device slot.
4070 *
Jake Hambye994d462014-02-03 13:10:13 -08004071 * @return true on success; false on any failure
4072 */
4073 @Override
chen xu6dac5ab2018-10-26 17:39:23 -07004074 public boolean resetModemConfig(int slotIndex) {
4075 Phone phone = PhoneFactory.getPhone(slotIndex);
4076 if (phone != null) {
4077 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4078 mApp, phone.getSubId(), "resetModemConfig");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004079
chen xu6dac5ab2018-10-26 17:39:23 -07004080 final long identity = Binder.clearCallingIdentity();
4081 try {
4082 Boolean success = (Boolean) sendRequest(CMD_RESET_MODEM_CONFIG, null);
4083 if (DBG) log("resetModemConfig:" + ' ' + (success ? "ok" : "fail"));
4084 return success;
4085 } finally {
4086 Binder.restoreCallingIdentity(identity);
4087 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004088 }
chen xu6dac5ab2018-10-26 17:39:23 -07004089 return false;
4090 }
4091
4092 /**
4093 * Generate a radio modem reset. Used for device configuration by some CDMA operators.
4094 *
4095 * @param slotIndex - device slot.
4096 *
4097 * @return true on success; false on any failure
4098 */
4099 @Override
4100 public boolean rebootModem(int slotIndex) {
4101 Phone phone = PhoneFactory.getPhone(slotIndex);
4102 if (phone != null) {
4103 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4104 mApp, phone.getSubId(), "rebootModem");
4105
4106 final long identity = Binder.clearCallingIdentity();
4107 try {
4108 Boolean success = (Boolean) sendRequest(CMD_MODEM_REBOOT, null);
4109 if (DBG) log("rebootModem:" + ' ' + (success ? "ok" : "fail"));
4110 return success;
4111 } finally {
4112 Binder.restoreCallingIdentity(identity);
4113 }
4114 }
4115 return false;
Jake Hambye994d462014-02-03 13:10:13 -08004116 }
Jake Hamby7c27be32014-03-03 13:25:59 -08004117
Svet Ganovb320e182015-04-16 12:30:10 -07004118 public String[] getPcscfAddress(String apnType, String callingPackage) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004119 final Phone defaultPhone = getDefaultPhone();
Jeff Davidson7e17e312018-02-13 18:17:36 -08004120 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004121 mApp, defaultPhone.getSubId(), callingPackage, "getPcscfAddress")) {
Svet Ganovb320e182015-04-16 12:30:10 -07004122 return new String[0];
4123 }
4124
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004125 final long identity = Binder.clearCallingIdentity();
4126 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004127 return defaultPhone.getPcscfAddress(apnType);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004128 } finally {
4129 Binder.restoreCallingIdentity(identity);
4130 }
Wink Saville36469e72014-06-11 15:17:00 -07004131 }
4132
Brad Ebinger51f743a2017-01-23 13:50:20 -08004133 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004134 * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
4135 * status updates, if not already enabled.
Brad Ebinger51f743a2017-01-23 13:50:20 -08004136 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004137 public void enableIms(int slotId) {
Brad Ebinger51f743a2017-01-23 13:50:20 -08004138 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004139
4140 final long identity = Binder.clearCallingIdentity();
4141 try {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004142 ImsResolver resolver = PhoneFactory.getImsResolver();
4143 if (resolver == null) {
4144 // may happen if the device does not support IMS.
4145 return;
4146 }
4147 resolver.enableIms(slotId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004148 } finally {
4149 Binder.restoreCallingIdentity(identity);
4150 }
Brad Ebinger34bef922017-11-09 10:27:08 -08004151 }
4152
4153 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004154 * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
4155 * status updates to disabled.
Brad Ebinger34bef922017-11-09 10:27:08 -08004156 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004157 public void disableIms(int slotId) {
4158 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004159
4160 final long identity = Binder.clearCallingIdentity();
4161 try {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004162 ImsResolver resolver = PhoneFactory.getImsResolver();
4163 if (resolver == null) {
4164 // may happen if the device does not support IMS.
4165 return;
4166 }
4167 resolver.disableIms(slotId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004168 } finally {
4169 Binder.restoreCallingIdentity(identity);
4170 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004171 }
4172
4173 /**
4174 * Returns the {@link IImsMmTelFeature} that corresponds to the given slot Id for the MMTel
4175 * feature or {@link null} if the service is not available. If the feature is available, the
4176 * {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates.
4177 */
4178 public IImsMmTelFeature getMmTelFeatureAndListen(int slotId,
Brad Ebinger34bef922017-11-09 10:27:08 -08004179 IImsServiceFeatureCallback callback) {
4180 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004181
4182 final long identity = Binder.clearCallingIdentity();
4183 try {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004184 ImsResolver resolver = PhoneFactory.getImsResolver();
4185 if (resolver == null) {
4186 // may happen if the device does not support IMS.
4187 return null;
4188 }
4189 return resolver.getMmTelFeatureAndListen(slotId, callback);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004190 } finally {
4191 Binder.restoreCallingIdentity(identity);
4192 }
Brad Ebinger34bef922017-11-09 10:27:08 -08004193 }
4194
4195 /**
4196 * Returns the {@link IImsRcsFeature} that corresponds to the given slot Id for the RCS
4197 * feature during emergency calling or {@link null} if the service is not available. If the
4198 * feature is available, the {@link IImsServiceFeatureCallback} callback is registered as a
4199 * listener for feature updates.
4200 */
4201 public IImsRcsFeature getRcsFeatureAndListen(int slotId, IImsServiceFeatureCallback callback) {
4202 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004203
4204 final long identity = Binder.clearCallingIdentity();
4205 try {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004206 ImsResolver resolver = PhoneFactory.getImsResolver();
4207 if (resolver == null) {
4208 // may happen if the device does not support IMS.
4209 return null;
4210 }
4211 return resolver.getRcsFeatureAndListen(slotId, callback);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004212 } finally {
4213 Binder.restoreCallingIdentity(identity);
4214 }
Brad Ebinger51f743a2017-01-23 13:50:20 -08004215 }
4216
Brad Ebinger5f64b052017-12-14 14:26:15 -08004217 /**
4218 * Returns the {@link IImsRegistration} structure associated with the slotId and feature
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004219 * specified or null if IMS is not supported on the slot specified.
Brad Ebinger5f64b052017-12-14 14:26:15 -08004220 */
4221 public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
4222 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004223
4224 final long identity = Binder.clearCallingIdentity();
4225 try {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004226 ImsResolver resolver = PhoneFactory.getImsResolver();
4227 if (resolver == null) {
4228 // may happen if the device does not support IMS.
4229 return null;
4230 }
4231 return resolver.getImsRegistration(slotId, feature);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004232 } finally {
4233 Binder.restoreCallingIdentity(identity);
4234 }
Brad Ebinger5f64b052017-12-14 14:26:15 -08004235 }
4236
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004237 /**
4238 * Returns the {@link IImsConfig} structure associated with the slotId and feature
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004239 * specified or null if IMS is not supported on the slot specified.
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004240 */
4241 public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
4242 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004243
4244 final long identity = Binder.clearCallingIdentity();
4245 try {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004246 ImsResolver resolver = PhoneFactory.getImsResolver();
4247 if (resolver == null) {
4248 // may happen if the device does not support IMS.
4249 return null;
4250 }
4251 return resolver.getImsConfig(slotId, feature);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004252 } finally {
4253 Binder.restoreCallingIdentity(identity);
4254 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004255 }
4256
Brad Ebinger884c07b2018-02-15 16:17:40 -08004257 /**
Brad Ebingerdac2f002018-04-03 15:17:52 -07004258 * Sets the ImsService Package Name that Telephony will bind to.
4259 *
4260 * @param slotId the slot ID that the ImsService should bind for.
4261 * @param isCarrierImsService true if the ImsService is the carrier override, false if the
4262 * ImsService is the device default ImsService.
4263 * @param packageName The package name of the application that contains the ImsService to bind
4264 * to.
4265 * @return true if setting the ImsService to bind to succeeded, false if it did not.
4266 * @hide
4267 */
4268 public boolean setImsService(int slotId, boolean isCarrierImsService, String packageName) {
Brad Ebingerde696de2018-04-06 09:56:40 -07004269 int[] subIds = SubscriptionManager.getSubId(slotId);
4270 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
4271 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
4272 "setImsService");
4273
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004274 final long identity = Binder.clearCallingIdentity();
4275 try {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004276 ImsResolver resolver = PhoneFactory.getImsResolver();
4277 if (resolver == null) {
4278 // may happen if the device does not support IMS.
4279 return false;
4280 }
4281 return resolver.overrideImsServiceConfiguration(slotId, isCarrierImsService,
4282 packageName);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004283 } finally {
4284 Binder.restoreCallingIdentity(identity);
4285 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07004286 }
4287
4288 /**
4289 * Return the ImsService configuration.
4290 *
4291 * @param slotId The slot that the ImsService is associated with.
4292 * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
4293 * the device default.
4294 * @return the package name of the ImsService configuration.
4295 */
4296 public String getImsService(int slotId, boolean isCarrierImsService) {
Brad Ebingerde696de2018-04-06 09:56:40 -07004297 int[] subIds = SubscriptionManager.getSubId(slotId);
4298 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
4299 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
4300 "getImsService");
4301
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004302 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 "";
4308 }
4309 return resolver.getImsServiceConfiguration(slotId, isCarrierImsService);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004310 } finally {
4311 Binder.restoreCallingIdentity(identity);
4312 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07004313 }
4314
Wink Saville36469e72014-06-11 15:17:00 -07004315 public void setImsRegistrationState(boolean registered) {
4316 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004317
4318 final long identity = Binder.clearCallingIdentity();
4319 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004320 getDefaultPhone().setImsRegistrationState(registered);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004321 } finally {
4322 Binder.restoreCallingIdentity(identity);
4323 }
Wink Saville36469e72014-06-11 15:17:00 -07004324 }
4325
4326 /**
Stuart Scott54788802015-03-30 13:18:01 -07004327 * Set the network selection mode to automatic.
4328 *
4329 */
4330 @Override
4331 public void setNetworkSelectionModeAutomatic(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004332 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4333 mApp, subId, "setNetworkSelectionModeAutomatic");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004334
Pengquan Menge92a50d2018-09-21 15:54:48 -07004335 if (!isActiveSubscription(subId)) {
4336 return;
4337 }
4338
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004339 final long identity = Binder.clearCallingIdentity();
4340 try {
4341 if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
4342 sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId);
4343 } finally {
4344 Binder.restoreCallingIdentity(identity);
4345 }
Stuart Scott54788802015-03-30 13:18:01 -07004346 }
4347
Pengquan Mengea84e042018-09-20 14:57:26 -07004348 /**
4349 * Ask the radio to connect to the input network and change selection mode to manual.
4350 *
4351 * @param subId the id of the subscription.
4352 * @param operatorInfo the operator information, included the PLMN, long name and short name of
4353 * the operator to attach to.
4354 * @param persistSelection whether the selection will persist until reboot. If true, only allows
4355 * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
4356 * normal network selection next time.
4357 * @return {@code true} on success; {@code true} on any failure.
Shishir Agrawal302c8692015-06-19 13:49:39 -07004358 */
4359 @Override
Pengquan Mengea84e042018-09-20 14:57:26 -07004360 public boolean setNetworkSelectionModeManual(
4361 int subId, OperatorInfo operatorInfo, boolean persistSelection) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004362 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4363 mApp, subId, "setNetworkSelectionModeManual");
Pengquan Menge92a50d2018-09-21 15:54:48 -07004364
4365 if (!isActiveSubscription(subId)) {
4366 return false;
4367 }
4368
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004369 final long identity = Binder.clearCallingIdentity();
4370 try {
Pengquan Mengea84e042018-09-20 14:57:26 -07004371 ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operatorInfo,
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004372 persistSelection);
Pengquan Mengea84e042018-09-20 14:57:26 -07004373 if (DBG) {
4374 log("setNetworkSelectionModeManual: subId: " + subId
4375 + " operator: " + operatorInfo);
4376 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004377 return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
4378 } finally {
4379 Binder.restoreCallingIdentity(identity);
4380 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07004381 }
4382
4383 /**
4384 * Scans for available networks.
4385 */
4386 @Override
Hall Liuf19c44f2018-11-27 14:38:17 -08004387 public CellNetworkScanResult getCellNetworkScanResults(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004388 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4389 mApp, subId, "getCellNetworkScanResults");
Hall Liuf19c44f2018-11-27 14:38:17 -08004390 LocationAccessPolicy.LocationPermissionResult locationResult =
4391 LocationAccessPolicy.checkLocationPermission(mApp,
4392 new LocationAccessPolicy.LocationPermissionQuery.Builder()
4393 .setCallingPackage(callingPackage)
4394 .setCallingPid(Binder.getCallingPid())
4395 .setCallingUid(Binder.getCallingUid())
4396 .setMethod("getCellNetworkScanResults")
4397 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
4398 .build());
4399 switch (locationResult) {
4400 case DENIED_HARD:
4401 throw new SecurityException("Not allowed to access scan results -- location");
4402 case DENIED_SOFT:
4403 return null;
4404 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004405
Pengquan Menga1bb6272018-09-06 09:59:22 -07004406 long identity = Binder.clearCallingIdentity();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004407 try {
4408 if (DBG) log("getCellNetworkScanResults: subId " + subId);
Pengquan Menga1bb6272018-09-06 09:59:22 -07004409 return (CellNetworkScanResult) sendRequest(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004410 CMD_PERFORM_NETWORK_SCAN, null, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004411 } finally {
4412 Binder.restoreCallingIdentity(identity);
4413 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07004414 }
4415
4416 /**
yinxub1bed742017-04-17 11:45:04 -07004417 * Starts a new network scan and returns the id of this scan.
yinxu504e1392017-04-12 16:03:22 -07004418 *
yinxub1bed742017-04-17 11:45:04 -07004419 * @param subId id of the subscription
4420 * @param request contains the radio access networks with bands/channels to scan
4421 * @param messenger callback messenger for scan results or errors
4422 * @param binder for the purpose of auto clean when the user thread crashes
yinxu504e1392017-04-12 16:03:22 -07004423 * @return the id of the requested scan which can be used to stop the scan.
4424 */
4425 @Override
4426 public int requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger,
Hall Liuf19c44f2018-11-27 14:38:17 -08004427 IBinder binder, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004428 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4429 mApp, subId, "requestNetworkScan");
Hall Liuf19c44f2018-11-27 14:38:17 -08004430 LocationAccessPolicy.LocationPermissionResult locationResult =
4431 LocationAccessPolicy.checkLocationPermission(mApp,
4432 new LocationAccessPolicy.LocationPermissionQuery.Builder()
4433 .setCallingPackage(callingPackage)
4434 .setCallingPid(Binder.getCallingPid())
4435 .setCallingUid(Binder.getCallingUid())
4436 .setMethod("requestNetworkScan")
4437 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
4438 .build());
Hall Liub2ac8ef2019-02-28 15:56:23 -08004439 if (locationResult != LocationAccessPolicy.LocationPermissionResult.ALLOWED) {
4440 SecurityException e = checkNetworkRequestForSanitizedLocationAccess(request);
4441 if (e != null) {
4442 if (locationResult == LocationAccessPolicy.LocationPermissionResult.DENIED_HARD) {
4443 throw e;
4444 } else {
4445 return TelephonyScanManager.INVALID_SCAN_ID;
4446 }
4447 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004448 }
Hall Liuf19c44f2018-11-27 14:38:17 -08004449 return mNetworkScanRequestTracker.startNetworkScan(
4450 request, messenger, binder, getPhone(subId),
4451 callingPackage);
yinxu504e1392017-04-12 16:03:22 -07004452 }
4453
Hall Liub2ac8ef2019-02-28 15:56:23 -08004454 private SecurityException checkNetworkRequestForSanitizedLocationAccess(
4455 NetworkScanRequest request) {
4456 if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_SCAN)
4457 != PERMISSION_GRANTED) {
4458 return new SecurityException("permission.NETWORK_SCAN is needed for network scans"
4459 + " without location access.");
4460 }
4461
4462 if (request.getSpecifiers() != null && request.getSpecifiers().length > 0) {
4463 for (RadioAccessSpecifier ras : request.getSpecifiers()) {
4464 if (ras.getBands() != null && ras.getBands().length > 0) {
4465 return new SecurityException("Specific bands must not be"
4466 + " scanned without location access.");
4467 }
4468 if (ras.getChannels() != null && ras.getChannels().length > 0) {
4469 return new SecurityException("Specific channels must not be"
4470 + " scanned without location access.");
4471 }
4472 }
4473 }
4474
4475 List<String> allowedMccMncs =
4476 NetworkScanRequestTracker.getAllowedMccMncsForLocationRestrictedScan(mApp);
4477 for (String mccmnc : request.getPlmns()) {
4478 if (!allowedMccMncs.contains(mccmnc)) {
4479 return new SecurityException("Requested mccmnc " + mccmnc + " is not known to the"
4480 + " device and cannot be scanned for without location access.");
4481 }
4482 }
4483
4484 return null;
4485 }
4486
yinxu504e1392017-04-12 16:03:22 -07004487 /**
4488 * Stops an existing network scan with the given scanId.
yinxub1bed742017-04-17 11:45:04 -07004489 *
4490 * @param subId id of the subscription
4491 * @param scanId id of the scan that needs to be stopped
yinxu504e1392017-04-12 16:03:22 -07004492 */
4493 @Override
4494 public void stopNetworkScan(int subId, int scanId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004495 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4496 mApp, subId, "stopNetworkScan");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004497
4498 final long identity = Binder.clearCallingIdentity();
4499 try {
4500 mNetworkScanRequestTracker.stopNetworkScan(scanId);
4501 } finally {
4502 Binder.restoreCallingIdentity(identity);
4503 }
yinxu504e1392017-04-12 16:03:22 -07004504 }
4505
4506 /**
Junda Liu84d15a22014-07-02 11:21:04 -07004507 * Get the calculated preferred network type.
4508 * Used for debugging incorrect network type.
4509 *
4510 * @return the preferred network type, defined in RILConstants.java.
4511 */
4512 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004513 public int getCalculatedPreferredNetworkType(String callingPackage) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004514 final Phone defaultPhone = getDefaultPhone();
4515 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
4516 callingPackage, "getCalculatedPreferredNetworkType")) {
Svet Ganovb320e182015-04-16 12:30:10 -07004517 return RILConstants.PREFERRED_NETWORK_MODE;
4518 }
4519
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004520 final long identity = Binder.clearCallingIdentity();
4521 try {
4522 // FIXME: need to get SubId from somewhere.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004523 return PhoneFactory.calculatePreferredNetworkType(defaultPhone.getContext(), 0);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004524 } finally {
4525 Binder.restoreCallingIdentity(identity);
4526 }
Junda Liu84d15a22014-07-02 11:21:04 -07004527 }
4528
4529 /**
Jake Hamby7c27be32014-03-03 13:25:59 -08004530 * Get the preferred network type.
4531 * Used for device configuration by some CDMA operators.
4532 *
4533 * @return the preferred network type, defined in RILConstants.java.
4534 */
4535 @Override
Stuart Scott54788802015-03-30 13:18:01 -07004536 public int getPreferredNetworkType(int subId) {
Pengquan Menga4009cb2018-12-20 11:00:24 -08004537 TelephonyPermissions
4538 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
4539 mApp, subId, "getPreferredNetworkType");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004540
4541 final long identity = Binder.clearCallingIdentity();
4542 try {
4543 if (DBG) log("getPreferredNetworkType");
4544 int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null, subId);
4545 int networkType = (result != null ? result[0] : -1);
4546 if (DBG) log("getPreferredNetworkType: " + networkType);
4547 return networkType;
4548 } finally {
4549 Binder.restoreCallingIdentity(identity);
4550 }
Jake Hamby7c27be32014-03-03 13:25:59 -08004551 }
4552
4553 /**
4554 * Set the preferred network type.
4555 * Used for device configuration by some CDMA operators.
4556 *
4557 * @param networkType the preferred network type, defined in RILConstants.java.
4558 * @return true on success; false on any failure.
4559 */
4560 @Override
Stuart Scott54788802015-03-30 13:18:01 -07004561 public boolean setPreferredNetworkType(int subId, int networkType) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004562 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4563 mApp, subId, "setPreferredNetworkType");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004564
4565 final long identity = Binder.clearCallingIdentity();
4566 try {
4567 if (DBG) log("setPreferredNetworkType: subId " + subId + " type " + networkType);
4568 Boolean success = (Boolean) sendRequest(
4569 CMD_SET_PREFERRED_NETWORK_TYPE, networkType, subId);
4570 if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail"));
4571 if (success) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004572 Settings.Global.putInt(mApp.getContentResolver(),
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004573 Settings.Global.PREFERRED_NETWORK_MODE + subId, networkType);
4574 }
4575 return success;
4576 } finally {
4577 Binder.restoreCallingIdentity(identity);
Junda Liu80bc0d12014-07-14 16:36:44 -07004578 }
Jake Hamby7c27be32014-03-03 13:25:59 -08004579 }
Robert Greenwalted86e582014-05-21 20:03:20 -07004580
4581 /**
Miaoa84611c2019-03-15 09:21:10 +08004582 * Check whether DUN APN is required for tethering with subId.
Junda Liu475951f2014-11-07 16:45:03 -08004583 *
Miaoa84611c2019-03-15 09:21:10 +08004584 * @param subId the id of the subscription to require tethering.
Amit Mahajanfe58cdf2017-07-11 12:01:53 -07004585 * @return {@code true} if DUN APN is required for tethering.
Junda Liu475951f2014-11-07 16:45:03 -08004586 * @hide
4587 */
4588 @Override
Miaoa84611c2019-03-15 09:21:10 +08004589 public boolean getTetherApnRequiredForSubscriber(int subId) {
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004590 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004591 final long identity = Binder.clearCallingIdentity();
Miaoa84611c2019-03-15 09:21:10 +08004592 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004593 try {
Miaoa84611c2019-03-15 09:21:10 +08004594 if (phone != null) {
4595 return phone.hasMatchedTetherApnSetting();
4596 } else {
4597 return false;
4598 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004599 } finally {
4600 Binder.restoreCallingIdentity(identity);
Junda Liu475951f2014-11-07 16:45:03 -08004601 }
Junda Liu475951f2014-11-07 16:45:03 -08004602 }
4603
4604 /**
Robert Greenwalted86e582014-05-21 20:03:20 -07004605 * Set mobile data enabled
4606 * Used by the user through settings etc to turn on/off mobile data
4607 *
4608 * @param enable {@code true} turn turn data on, else {@code false}
4609 */
4610 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08004611 public void setUserDataEnabled(int subId, boolean enable) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004612 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4613 mApp, subId, "setUserDataEnabled");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004614
4615 final long identity = Binder.clearCallingIdentity();
4616 try {
4617 int phoneId = mSubscriptionController.getPhoneId(subId);
4618 if (DBG) log("setUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
4619 Phone phone = PhoneFactory.getPhone(phoneId);
4620 if (phone != null) {
4621 if (DBG) log("setUserDataEnabled: subId=" + subId + " enable=" + enable);
Jack Yud79fba22018-12-13 11:51:28 -08004622 phone.getDataEnabledSettings().setUserDataEnabled(enable);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004623 } else {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004624 loge("setUserDataEnabled: no phone found. Invalid subId=" + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004625 }
4626 } finally {
4627 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08004628 }
Robert Greenwalted86e582014-05-21 20:03:20 -07004629 }
4630
4631 /**
Malcolm Chen964682d2017-11-28 16:20:07 -08004632 * Get the user enabled state of Mobile Data.
4633 *
4634 * TODO: remove and use isUserDataEnabled.
4635 * This can't be removed now because some vendor codes
4636 * calls through ITelephony directly while they should
4637 * use TelephonyManager.
4638 *
4639 * @return true on enabled
4640 */
4641 @Override
4642 public boolean getDataEnabled(int subId) {
4643 return isUserDataEnabled(subId);
4644 }
4645
4646 /**
4647 * Get whether mobile data is enabled per user setting.
4648 *
4649 * There are other factors deciding whether mobile data is actually enabled, but they are
4650 * not considered here. See {@link #isDataEnabled(int)} for more details.
Robert Greenwalt646120a2014-05-23 11:54:03 -07004651 *
Jeff Davidsona1920712016-11-18 17:05:56 -08004652 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
Robert Greenwalted86e582014-05-21 20:03:20 -07004653 *
4654 * @return {@code true} if data is enabled else {@code false}
4655 */
4656 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08004657 public boolean isUserDataEnabled(int subId) {
Robert Greenwalt646120a2014-05-23 11:54:03 -07004658 try {
4659 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
4660 null);
4661 } catch (Exception e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004662 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4663 mApp, subId, "isUserDataEnabled");
Robert Greenwalt646120a2014-05-23 11:54:03 -07004664 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004665
4666 final long identity = Binder.clearCallingIdentity();
4667 try {
4668 int phoneId = mSubscriptionController.getPhoneId(subId);
4669 if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
4670 Phone phone = PhoneFactory.getPhone(phoneId);
4671 if (phone != null) {
4672 boolean retVal = phone.isUserDataEnabled();
4673 if (DBG) log("isUserDataEnabled: subId=" + subId + " retVal=" + retVal);
4674 return retVal;
4675 } else {
4676 if (DBG) loge("isUserDataEnabled: no phone subId=" + subId + " retVal=false");
4677 return false;
4678 }
4679 } finally {
4680 Binder.restoreCallingIdentity(identity);
Malcolm Chen964682d2017-11-28 16:20:07 -08004681 }
4682 }
4683
4684 /**
4685 * Get whether mobile data is enabled.
4686 *
4687 * Comparable to {@link #isUserDataEnabled(int)}, this considers all factors deciding
4688 * whether mobile data is actually enabled.
4689 *
4690 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
4691 *
4692 * @return {@code true} if data is enabled else {@code false}
4693 */
4694 @Override
4695 public boolean isDataEnabled(int subId) {
4696 try {
4697 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
4698 null);
4699 } catch (Exception e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004700 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4701 mApp, subId, "isDataEnabled");
Malcolm Chen964682d2017-11-28 16:20:07 -08004702 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004703
4704 final long identity = Binder.clearCallingIdentity();
4705 try {
4706 int phoneId = mSubscriptionController.getPhoneId(subId);
4707 if (DBG) log("isDataEnabled: subId=" + subId + " phoneId=" + phoneId);
4708 Phone phone = PhoneFactory.getPhone(phoneId);
4709 if (phone != null) {
Jack Yud79fba22018-12-13 11:51:28 -08004710 boolean retVal = phone.getDataEnabledSettings().isDataEnabled();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004711 if (DBG) log("isDataEnabled: subId=" + subId + " retVal=" + retVal);
4712 return retVal;
4713 } else {
4714 if (DBG) loge("isDataEnabled: no phone subId=" + subId + " retVal=false");
4715 return false;
4716 }
4717 } finally {
4718 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08004719 }
Robert Greenwalted86e582014-05-21 20:03:20 -07004720 }
Shishir Agrawal60f9c952014-06-23 12:00:43 -07004721
4722 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004723 public int getCarrierPrivilegeStatus(int subId) {
4724 final Phone phone = getPhone(subId);
4725 if (phone == null) {
4726 loge("getCarrierPrivilegeStatus: Invalid subId");
4727 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
4728 }
4729 UiccCard card = UiccController.getInstance().getUiccCard(phone.getPhoneId());
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07004730 if (card == null) {
Shishir Agrawal5e5becd2014-11-18 11:38:23 -08004731 loge("getCarrierPrivilegeStatus: No UICC");
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07004732 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
4733 }
4734 return card.getCarrierPrivilegeStatusForCurrentTransaction(
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004735 phone.getContext().getPackageManager());
Shishir Agrawal60f9c952014-06-23 12:00:43 -07004736 }
Junda Liu29340342014-07-10 15:23:27 -07004737
4738 @Override
Jeff Davidson7e17e312018-02-13 18:17:36 -08004739 public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
4740 final Phone phone = getPhone(subId);
4741 if (phone == null) {
4742 loge("getCarrierPrivilegeStatus: Invalid subId");
4743 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
4744 }
4745 UiccProfile profile =
4746 UiccController.getInstance().getUiccProfileForPhone(phone.getPhoneId());
4747 if (profile == null) {
4748 loge("getCarrierPrivilegeStatus: No UICC");
4749 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
4750 }
4751 return profile.getCarrierPrivilegeStatusForUid(phone.getContext().getPackageManager(), uid);
4752 }
4753
4754 @Override
Zach Johnson50ecba32015-05-19 00:24:21 -07004755 public int checkCarrierPrivilegesForPackage(String pkgName) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004756 final Phone defaultPhone = getDefaultPhone();
Junda Liu317d70b2016-03-08 09:33:53 -08004757 if (TextUtils.isEmpty(pkgName))
4758 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004759 UiccCard card = UiccController.getInstance().getUiccCard(defaultPhone.getPhoneId());
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07004760 if (card == null) {
4761 loge("checkCarrierPrivilegesForPackage: No UICC");
4762 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
4763 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004764 return card.getCarrierPrivilegeStatus(defaultPhone.getContext().getPackageManager(),
4765 pkgName);
Zach Johnson50ecba32015-05-19 00:24:21 -07004766 }
4767
4768 @Override
4769 public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
Junda Liu317d70b2016-03-08 09:33:53 -08004770 if (TextUtils.isEmpty(pkgName))
4771 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Zach Johnson50ecba32015-05-19 00:24:21 -07004772 int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
4773 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
4774 UiccCard card = UiccController.getInstance().getUiccCard(i);
4775 if (card == null) {
Jonathan Basseri7d320df2015-06-16 12:17:08 -07004776 // No UICC in that slot.
Zach Johnson50ecba32015-05-19 00:24:21 -07004777 continue;
4778 }
4779
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004780 result = card.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName);
Zach Johnson50ecba32015-05-19 00:24:21 -07004781 if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
4782 break;
4783 }
4784 }
4785
4786 return result;
Junda Liu29340342014-07-10 15:23:27 -07004787 }
Derek Tan89e89d42014-07-08 17:00:10 -07004788
4789 @Override
Junda Liue64de782015-04-16 17:19:16 -07004790 public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
4791 if (!SubscriptionManager.isValidPhoneId(phoneId)) {
4792 loge("phoneId " + phoneId + " is not valid.");
4793 return null;
4794 }
4795 UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07004796 if (card == null) {
Diego Pontorieroaf74c862014-08-28 11:51:16 -07004797 loge("getCarrierPackageNamesForIntent: No UICC");
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07004798 return null ;
4799 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004800 return card.getCarrierPackageNamesForIntent(mApp.getPackageManager(), intent);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07004801 }
4802
Amith Yamasani6e118872016-02-19 12:53:51 -08004803 @Override
4804 public List<String> getPackagesWithCarrierPrivileges() {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004805 PackageManager pm = mApp.getPackageManager();
Amith Yamasani6e118872016-02-19 12:53:51 -08004806 List<String> privilegedPackages = new ArrayList<>();
4807 List<PackageInfo> packages = null;
4808 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
4809 UiccCard card = UiccController.getInstance().getUiccCard(i);
4810 if (card == null) {
4811 // No UICC in that slot.
4812 continue;
4813 }
4814 if (card.hasCarrierPrivilegeRules()) {
4815 if (packages == null) {
4816 // Only check packages in user 0 for now
4817 packages = pm.getInstalledPackagesAsUser(
4818 PackageManager.MATCH_DISABLED_COMPONENTS
4819 | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
4820 | PackageManager.GET_SIGNATURES, UserHandle.USER_SYSTEM);
4821 }
4822 for (int p = packages.size() - 1; p >= 0; p--) {
4823 PackageInfo pkgInfo = packages.get(p);
4824 if (pkgInfo != null && pkgInfo.packageName != null
4825 && card.getCarrierPrivilegeStatus(pkgInfo)
4826 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
4827 privilegedPackages.add(pkgInfo.packageName);
4828 }
4829 }
4830 }
4831 }
4832 return privilegedPackages;
4833 }
4834
Wink Savilleb564aae2014-10-23 10:18:09 -07004835 private String getIccId(int subId) {
Sanket Padawe356d7632015-06-22 14:03:32 -07004836 final Phone phone = getPhone(subId);
4837 UiccCard card = phone == null ? null : phone.getUiccCard();
Derek Tan97ebb422014-09-05 16:55:38 -07004838 if (card == null) {
4839 loge("getIccId: No UICC");
4840 return null;
4841 }
4842 String iccId = card.getIccId();
4843 if (TextUtils.isEmpty(iccId)) {
4844 loge("getIccId: ICC ID is null or empty.");
4845 return null;
4846 }
4847 return iccId;
4848 }
4849
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07004850 @Override
Jeff Sharkey85190e62014-12-05 09:40:12 -08004851 public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
4852 String number) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004853 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
4854 subId, "setLine1NumberForDisplayForSubscriber");
Derek Tan97ebb422014-09-05 16:55:38 -07004855
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004856 final long identity = Binder.clearCallingIdentity();
4857 try {
4858 final String iccId = getIccId(subId);
4859 final Phone phone = getPhone(subId);
4860 if (phone == null) {
4861 return false;
4862 }
4863 final String subscriberId = phone.getSubscriberId();
4864
4865 if (DBG_MERGE) {
4866 Slog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId="
4867 + subscriberId + " to " + number);
4868 }
4869
4870 if (TextUtils.isEmpty(iccId)) {
4871 return false;
4872 }
4873
4874 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
4875
4876 final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
4877 if (alphaTag == null) {
4878 editor.remove(alphaTagPrefKey);
4879 } else {
4880 editor.putString(alphaTagPrefKey, alphaTag);
4881 }
4882
4883 // Record both the line number and IMSI for this ICCID, since we need to
4884 // track all merged IMSIs based on line number
4885 final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
4886 final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
4887 if (number == null) {
4888 editor.remove(numberPrefKey);
4889 editor.remove(subscriberPrefKey);
4890 } else {
4891 editor.putString(numberPrefKey, number);
4892 editor.putString(subscriberPrefKey, subscriberId);
4893 }
4894
4895 editor.commit();
4896 return true;
4897 } finally {
4898 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004899 }
Derek Tan7226c842014-07-02 17:42:23 -07004900 }
4901
4902 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004903 public String getLine1NumberForDisplay(int subId, String callingPackage) {
Makoto Onukifee69342015-06-29 14:44:50 -07004904 // This is open to apps with WRITE_SMS.
Jeff Davidson7e17e312018-02-13 18:17:36 -08004905 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
Jeff Davidson913390f2018-02-23 17:11:49 -08004906 mApp, subId, callingPackage, "getLine1NumberForDisplay")) {
Amit Mahajan9cf11512015-11-09 11:40:48 -08004907 if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
Svet Ganovb320e182015-04-16 12:30:10 -07004908 return null;
4909 }
Derek Tan97ebb422014-09-05 16:55:38 -07004910
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004911 final long identity = Binder.clearCallingIdentity();
4912 try {
4913 String iccId = getIccId(subId);
4914 if (iccId != null) {
4915 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
4916 if (DBG_MERGE) {
4917 log("getLine1NumberForDisplay returning "
4918 + mTelephonySharedPreferences.getString(numberPrefKey, null));
4919 }
4920 return mTelephonySharedPreferences.getString(numberPrefKey, null);
Amit Mahajan9cf11512015-11-09 11:40:48 -08004921 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004922 if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null");
4923 return null;
4924 } finally {
4925 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07004926 }
Derek Tan7226c842014-07-02 17:42:23 -07004927 }
4928
4929 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004930 public String getLine1AlphaTagForDisplay(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004931 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08004932 mApp, subId, callingPackage, "getLine1AlphaTagForDisplay")) {
Svet Ganovb320e182015-04-16 12:30:10 -07004933 return null;
4934 }
Derek Tan97ebb422014-09-05 16:55:38 -07004935
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004936 final long identity = Binder.clearCallingIdentity();
4937 try {
4938 String iccId = getIccId(subId);
4939 if (iccId != null) {
4940 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
4941 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null);
4942 }
4943 return null;
4944 } finally {
4945 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07004946 }
Derek Tan7226c842014-07-02 17:42:23 -07004947 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07004948
4949 @Override
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07004950 public String[] getMergedSubscriberIds(String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08004951 // This API isn't public, so no need to provide a valid subscription ID - we're not worried
4952 // about carrier-privileged callers not having access.
Jeff Davidson7e17e312018-02-13 18:17:36 -08004953 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08004954 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
4955 "getMergedSubscriberIds")) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07004956 return null;
4957 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08004958
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07004959 final long identity = Binder.clearCallingIdentity();
4960 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004961 final Context context = mApp;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004962 final TelephonyManager tele = TelephonyManager.from(context);
4963 final SubscriptionManager sub = SubscriptionManager.from(context);
4964
4965 // Figure out what subscribers are currently active
4966 final ArraySet<String> activeSubscriberIds = new ArraySet<>();
4967 // Clear calling identity, when calling TelephonyManager, because callerUid must be
4968 // the process, where TelephonyManager was instantiated.
4969 // Otherwise AppOps check will fail.
4970
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07004971 final int[] subIds = sub.getActiveSubscriptionIdList();
4972 for (int subId : subIds) {
4973 activeSubscriberIds.add(tele.getSubscriberId(subId));
4974 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004975
4976 // First pass, find a number override for an active subscriber
4977 String mergeNumber = null;
4978 final Map<String, ?> prefs = mTelephonySharedPreferences.getAll();
4979 for (String key : prefs.keySet()) {
4980 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) {
4981 final String subscriberId = (String) prefs.get(key);
4982 if (activeSubscriberIds.contains(subscriberId)) {
4983 final String iccId = key.substring(
4984 PREF_CARRIERS_SUBSCRIBER_PREFIX.length());
4985 final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
4986 mergeNumber = (String) prefs.get(numberKey);
4987 if (DBG_MERGE) {
4988 Slog.d(LOG_TAG, "Found line number " + mergeNumber
4989 + " for active subscriber " + subscriberId);
4990 }
4991 if (!TextUtils.isEmpty(mergeNumber)) {
4992 break;
4993 }
4994 }
4995 }
4996 }
4997
4998 // Shortcut when no active merged subscribers
4999 if (TextUtils.isEmpty(mergeNumber)) {
5000 return null;
5001 }
5002
5003 // Second pass, find all subscribers under that line override
5004 final ArraySet<String> result = new ArraySet<>();
5005 for (String key : prefs.keySet()) {
5006 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) {
5007 final String number = (String) prefs.get(key);
5008 if (mergeNumber.equals(number)) {
5009 final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length());
5010 final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
5011 final String subscriberId = (String) prefs.get(subscriberKey);
5012 if (!TextUtils.isEmpty(subscriberId)) {
5013 result.add(subscriberId);
5014 }
5015 }
5016 }
5017 }
5018
5019 final String[] resultArray = result.toArray(new String[result.size()]);
5020 Arrays.sort(resultArray);
5021 if (DBG_MERGE) {
5022 Slog.d(LOG_TAG,
5023 "Found subscribers " + Arrays.toString(resultArray) + " after merge");
5024 }
5025 return resultArray;
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07005026 } finally {
5027 Binder.restoreCallingIdentity(identity);
Jeff Sharkey85190e62014-12-05 09:40:12 -08005028 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08005029 }
5030
5031 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08005032 public boolean setOperatorBrandOverride(int subId, String brand) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005033 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
5034 subId, "setOperatorBrandOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005035
5036 final long identity = Binder.clearCallingIdentity();
5037 try {
5038 final Phone phone = getPhone(subId);
5039 return phone == null ? false : phone.setOperatorBrandOverride(brand);
5040 } finally {
5041 Binder.restoreCallingIdentity(identity);
5042 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07005043 }
Steven Liu4bf01bc2014-07-17 11:05:29 -05005044
5045 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08005046 public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
Shishir Agrawal621a47c2014-12-01 10:25:09 -08005047 List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
5048 List<String> cdmaNonRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005049 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setRoamingOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005050
5051 final long identity = Binder.clearCallingIdentity();
5052 try {
5053 final Phone phone = getPhone(subId);
5054 if (phone == null) {
5055 return false;
5056 }
5057 return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList,
5058 cdmaNonRoamingList);
5059 } finally {
5060 Binder.restoreCallingIdentity(identity);
Shishir Agrawalc04d9752016-02-19 10:41:00 -08005061 }
Shishir Agrawal621a47c2014-12-01 10:25:09 -08005062 }
5063
5064 @Override
Shuo Qian850e4d6a2018-04-25 21:02:08 +00005065 @Deprecated
5066 public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
5067 enforceModifyPermission();
5068
5069 int returnValue = 0;
5070 try {
vagdeviaf9a5b92018-08-15 16:01:53 -07005071 AsyncResult result = (AsyncResult) sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
Shuo Qian850e4d6a2018-04-25 21:02:08 +00005072 if(result.exception == null) {
5073 if (result.result != null) {
5074 byte[] responseData = (byte[])(result.result);
5075 if(responseData.length > oemResp.length) {
5076 Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +
5077 responseData.length + "bytes. Buffer Size is " +
5078 oemResp.length + "bytes.");
5079 }
5080 System.arraycopy(responseData, 0, oemResp, 0, responseData.length);
5081 returnValue = responseData.length;
5082 }
5083 } else {
5084 CommandException ex = (CommandException) result.exception;
5085 returnValue = ex.getCommandError().ordinal();
5086 if(returnValue > 0) returnValue *= -1;
5087 }
5088 } catch (RuntimeException e) {
5089 Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");
5090 returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());
5091 if(returnValue > 0) returnValue *= -1;
5092 }
5093
5094 return returnValue;
5095 }
5096
5097 @Override
Wink Saville5d475dd2014-10-17 15:00:58 -07005098 public void setRadioCapability(RadioAccessFamily[] rafs) {
5099 try {
5100 ProxyController.getInstance().setRadioCapability(rafs);
5101 } catch (RuntimeException e) {
5102 Log.w(LOG_TAG, "setRadioCapability: Runtime Exception");
5103 }
5104 }
5105
5106 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07005107 public int getRadioAccessFamily(int phoneId, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08005108 Phone phone = PhoneFactory.getPhone(phoneId);
chen xub97461a2018-10-26 14:17:57 -07005109 int raf = RadioAccessFamily.RAF_UNKNOWN;
Jeff Davidson913390f2018-02-23 17:11:49 -08005110 if (phone == null) {
chen xub97461a2018-10-26 14:17:57 -07005111 return raf;
Jeff Davidson913390f2018-02-23 17:11:49 -08005112 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005113 final long identity = Binder.clearCallingIdentity();
5114 try {
chen xub97461a2018-10-26 14:17:57 -07005115 TelephonyPermissions
5116 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5117 mApp, phone.getSubId(), "getRadioAccessFamily");
5118 raf = ProxyController.getInstance().getRadioAccessFamily(phoneId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005119 } finally {
5120 Binder.restoreCallingIdentity(identity);
5121 }
chen xub97461a2018-10-26 14:17:57 -07005122 return raf;
Wink Saville5d475dd2014-10-17 15:00:58 -07005123 }
Andrew Leedf14ead2014-10-17 14:22:52 -07005124
5125 @Override
5126 public void enableVideoCalling(boolean enable) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005127 final Phone defaultPhone = getDefaultPhone();
Andrew Leedf14ead2014-10-17 14:22:52 -07005128 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005129
5130 final long identity = Binder.clearCallingIdentity();
5131 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005132 ImsManager.getInstance(defaultPhone.getContext(),
5133 defaultPhone.getPhoneId()).setVtSetting(enable);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005134 } finally {
5135 Binder.restoreCallingIdentity(identity);
5136 }
Andrew Leedf14ead2014-10-17 14:22:52 -07005137 }
5138
5139 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07005140 public boolean isVideoCallingEnabled(String callingPackage) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005141 final Phone defaultPhone = getDefaultPhone();
Amit Mahajan578e53d2018-03-20 16:18:38 +00005142 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005143 mApp, defaultPhone.getSubId(), callingPackage, "isVideoCallingEnabled")) {
Amit Mahajan578e53d2018-03-20 16:18:38 +00005144 return false;
5145 }
Svet Ganovb320e182015-04-16 12:30:10 -07005146
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005147 final long identity = Binder.clearCallingIdentity();
5148 try {
5149 // Check the user preference and the system-level IMS setting. Even if the user has
5150 // enabled video calling, if IMS is disabled we aren't able to support video calling.
5151 // In the long run, we may instead need to check if there exists a connection service
5152 // which can support video calling.
5153 ImsManager imsManager =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005154 ImsManager.getInstance(defaultPhone.getContext(), defaultPhone.getPhoneId());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005155 return imsManager.isVtEnabledByPlatform()
5156 && imsManager.isEnhanced4gLteModeSettingEnabledByUser()
5157 && imsManager.isVtEnabledByUser();
5158 } finally {
5159 Binder.restoreCallingIdentity(identity);
5160 }
Andrew Leedf14ead2014-10-17 14:22:52 -07005161 }
Libin.Tang@motorola.comafe82642014-12-18 13:27:53 -06005162
Andrew Leea1239f22015-03-02 17:44:07 -08005163 @Override
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005164 public boolean canChangeDtmfToneLength(int subId, String callingPackage) {
5165 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5166 mApp, subId, callingPackage, "isVideoCallingEnabled")) {
5167 return false;
5168 }
5169
5170 final long identity = Binder.clearCallingIdentity();
5171 try {
5172 CarrierConfigManager configManager =
5173 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005174 return configManager.getConfigForSubId(subId)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005175 .getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL);
5176 } finally {
5177 Binder.restoreCallingIdentity(identity);
5178 }
Andrew Leea1239f22015-03-02 17:44:07 -08005179 }
5180
5181 @Override
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005182 public boolean isWorldPhone(int subId, String callingPackage) {
5183 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5184 mApp, subId, callingPackage, "isVideoCallingEnabled")) {
5185 return false;
5186 }
5187
5188 final long identity = Binder.clearCallingIdentity();
5189 try {
5190 CarrierConfigManager configManager =
5191 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005192 return configManager.getConfigForSubId(subId)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005193 .getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL);
5194 } finally {
5195 Binder.restoreCallingIdentity(identity);
5196 }
Andrew Leea1239f22015-03-02 17:44:07 -08005197 }
5198
Andrew Lee9431b832015-03-09 18:46:45 -07005199 @Override
5200 public boolean isTtyModeSupported() {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005201 TelecomManager telecomManager = TelecomManager.from(mApp);
Wooki Wu1f82f7a2016-02-15 15:59:58 +08005202 return telecomManager.isTtySupported();
Andrew Lee9431b832015-03-09 18:46:45 -07005203 }
5204
5205 @Override
5206 public boolean isHearingAidCompatibilitySupported() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005207 final long identity = Binder.clearCallingIdentity();
5208 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005209 return mApp.getResources().getBoolean(R.bool.hac_enabled);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005210 } finally {
5211 Binder.restoreCallingIdentity(identity);
5212 }
Andrew Lee9431b832015-03-09 18:46:45 -07005213 }
5214
Hall Liuf6668912018-10-31 17:05:23 -07005215 /**
5216 * Determines whether the device currently supports RTT (Real-time text). Based both on carrier
5217 * support for the feature and device firmware support.
5218 *
5219 * @return {@code true} if the device and carrier both support RTT, {@code false} otherwise.
5220 */
5221 @Override
5222 public boolean isRttSupported(int subscriptionId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005223 final long identity = Binder.clearCallingIdentity();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005224 final Phone phone = getPhone(subscriptionId);
5225 if (phone == null) {
5226 loge("isRttSupported: no Phone found. Invalid subId:" + subscriptionId);
5227 return false;
5228 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005229 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005230 boolean isCarrierSupported = mApp.getCarrierConfigForSubId(subscriptionId).getBoolean(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005231 CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
5232 boolean isDeviceSupported =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005233 phone.getContext().getResources().getBoolean(R.bool.config_support_rtt);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005234 return isCarrierSupported && isDeviceSupported;
5235 } finally {
5236 Binder.restoreCallingIdentity(identity);
5237 }
Hall Liu98187582018-01-22 19:15:32 -08005238 }
5239
Hall Liuf6668912018-10-31 17:05:23 -07005240 /**
5241 * Determines whether the user has turned on RTT. Only returns true if the device and carrier
5242 * both also support RTT.
5243 */
5244 public boolean isRttEnabled(int subscriptionId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005245 final long identity = Binder.clearCallingIdentity();
5246 try {
Hall Liuf6668912018-10-31 17:05:23 -07005247 return isRttSupported(subscriptionId) && Settings.Secure.getInt(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005248 mApp.getContentResolver(), Settings.Secure.RTT_CALLING_MODE, 0) != 0;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005249 } finally {
5250 Binder.restoreCallingIdentity(identity);
5251 }
Hall Liu3ad5f012018-04-06 16:23:39 -07005252 }
5253
Sanket Padawe7310cc72015-01-14 09:53:20 -08005254 /**
5255 * Returns the unique device ID of phone, for example, the IMEI for
5256 * GSM and the MEID for CDMA phones. Return null if device ID is not available.
5257 *
5258 * <p>Requires Permission:
5259 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
5260 */
5261 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07005262 public String getDeviceId(String callingPackage) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08005263 final Phone phone = PhoneFactory.getPhone(0);
Jeff Davidson913390f2018-02-23 17:11:49 -08005264 if (phone == null) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08005265 return null;
5266 }
Jeff Davidson913390f2018-02-23 17:11:49 -08005267 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07005268 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
5269 callingPackage, "getDeviceId")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08005270 return null;
5271 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005272
5273 final long identity = Binder.clearCallingIdentity();
5274 try {
5275 return phone.getDeviceId();
5276 } finally {
5277 Binder.restoreCallingIdentity(identity);
5278 }
Sanket Padawe7310cc72015-01-14 09:53:20 -08005279 }
5280
Ping Sunc67b7c22016-03-02 19:16:45 +08005281 /**
5282 * {@hide}
5283 * Returns the IMS Registration Status on a particular subid
5284 *
5285 * @param subId
5286 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005287 public boolean isImsRegistered(int subId) {
Ping Sunc67b7c22016-03-02 19:16:45 +08005288 Phone phone = getPhone(subId);
5289 if (phone != null) {
5290 return phone.isImsRegistered();
5291 } else {
5292 return false;
5293 }
5294 }
5295
Santos Cordon7a1885b2015-02-03 11:15:19 -08005296 @Override
5297 public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005298 final long identity = Binder.clearCallingIdentity();
5299 try {
5300 return PhoneUtils.getSubIdForPhoneAccount(phoneAccount);
5301 } finally {
5302 Binder.restoreCallingIdentity(identity);
5303 }
Santos Cordon7a1885b2015-02-03 11:15:19 -08005304 }
Nathan Harolddcfc7932015-03-18 10:01:20 -07005305
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005306 /**
5307 * @return the VoWiFi calling availability.
Nathan Haroldc55097a2015-03-11 18:14:50 -07005308 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005309 public boolean isWifiCallingAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005310 final long identity = Binder.clearCallingIdentity();
5311 try {
5312 Phone phone = getPhone(subId);
5313 if (phone != null) {
5314 return phone.isWifiCallingEnabled();
5315 } else {
5316 return false;
5317 }
5318 } finally {
5319 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005320 }
Nathan Haroldc55097a2015-03-11 18:14:50 -07005321 }
5322
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005323 /**
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005324 * @return the VT calling availability.
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07005325 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005326 public boolean isVideoTelephonyAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005327 final long identity = Binder.clearCallingIdentity();
5328 try {
5329 Phone phone = getPhone(subId);
5330 if (phone != null) {
5331 return phone.isVideoEnabled();
5332 } else {
5333 return false;
5334 }
5335 } finally {
5336 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005337 }
5338 }
5339
5340 /**
5341 * @return the IMS registration technology for the MMTEL feature. Valid return values are
5342 * defined in {@link ImsRegistrationImplBase}.
5343 */
5344 public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005345 final long identity = Binder.clearCallingIdentity();
5346 try {
5347 Phone phone = getPhone(subId);
5348 if (phone != null) {
5349 return phone.getImsRegistrationTech();
5350 } else {
5351 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
5352 }
5353 } finally {
5354 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005355 }
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07005356 }
5357
Stuart Scott8eef64f2015-04-08 15:13:54 -07005358 @Override
5359 public void factoryReset(int subId) {
5360 enforceConnectivityInternalPermission();
Stuart Scott981d8582015-04-21 14:09:50 -07005361 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
5362 return;
5363 }
5364
Svet Ganovcc087f82015-05-12 20:35:54 -07005365 final long identity = Binder.clearCallingIdentity();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005366
Svet Ganovcc087f82015-05-12 20:35:54 -07005367 try {
Stuart Scott981d8582015-04-21 14:09:50 -07005368 if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
5369 UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
Pengquan Meng85728fb2018-03-12 16:31:21 -07005370 setUserDataEnabled(subId, getDefaultDataEnabled());
Svet Ganovcc087f82015-05-12 20:35:54 -07005371 setNetworkSelectionModeAutomatic(subId);
Pengquan Meng85728fb2018-03-12 16:31:21 -07005372 setPreferredNetworkType(subId, getDefaultNetworkType(subId));
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005373 setDataRoamingEnabled(subId, getDefaultDataRoamingEnabled(subId));
5374 CarrierInfoManager.deleteAllCarrierKeysForImsiEncryption(mApp);
Svet Ganovcc087f82015-05-12 20:35:54 -07005375 }
Amit Mahajan7dbbd822019-03-13 17:33:47 -07005376 // There has been issues when Sms raw table somehow stores orphan
5377 // fragments. They lead to garbled message when new fragments come
5378 // in and combined with those stale ones. In case this happens again,
5379 // user can reset all network settings which will clean up this table.
5380 cleanUpSmsRawTable(getDefaultPhone().getContext());
Svet Ganovcc087f82015-05-12 20:35:54 -07005381 } finally {
5382 Binder.restoreCallingIdentity(identity);
Stuart Scott8eef64f2015-04-08 15:13:54 -07005383 }
5384 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01005385
Amit Mahajan7dbbd822019-03-13 17:33:47 -07005386 private void cleanUpSmsRawTable(Context context) {
5387 ContentResolver resolver = context.getContentResolver();
5388 Uri uri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete");
5389 resolver.delete(uri, null, null);
5390 }
5391
Narayan Kamath1c496c22015-04-16 14:40:19 +01005392 @Override
chen xu5d3637b2019-01-21 23:31:38 -08005393 public String getSimLocaleForSubscriber(int subId) {
5394 enforceReadPrivilegedPermission("getSimLocaleForSubscriber, subId: " + subId);
5395 final Phone phone = getPhone(subId);
5396 if (phone == null) {
5397 log("getSimLocaleForSubscriber, invalid subId");
chen xu2bb91e42019-01-24 14:35:54 -08005398 return null;
chen xu5d3637b2019-01-21 23:31:38 -08005399 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005400 final long identity = Binder.clearCallingIdentity();
5401 try {
chen xu5d3637b2019-01-21 23:31:38 -08005402 final SubscriptionInfo info = mSubscriptionController.getActiveSubscriptionInfo(subId,
5403 phone.getContext().getOpPackageName());
chen xu6291c472019-02-04 12:55:53 -08005404 if (info == null) {
5405 log("getSimLocaleForSubscriber, inactive subId: " + subId);
5406 return null;
5407 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005408 // Try and fetch the locale from the carrier properties or from the SIM language
5409 // preferences (EF-PL and EF-LI)...
5410 final int mcc = info.getMcc();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005411 String simLanguage = null;
chen xu5d3637b2019-01-21 23:31:38 -08005412 final Locale localeFromDefaultSim = phone.getLocaleFromSimAndCarrierPrefs();
5413 if (localeFromDefaultSim != null) {
5414 if (!localeFromDefaultSim.getCountry().isEmpty()) {
5415 if (DBG) log("Using locale from subId: " + subId + " locale: "
5416 + localeFromDefaultSim);
5417 return localeFromDefaultSim.toLanguageTag();
5418 } else {
5419 simLanguage = localeFromDefaultSim.getLanguage();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005420 }
5421 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01005422
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005423 // The SIM language preferences only store a language (e.g. fr = French), not an
5424 // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
5425 // the SIM and carrier preferences does not include a country we add the country
5426 // determined from the SIM MCC to provide an exact locale.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005427 final Locale mccLocale = MccTable.getLocaleFromMcc(mApp, mcc, simLanguage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005428 if (mccLocale != null) {
chen xu5d3637b2019-01-21 23:31:38 -08005429 if (DBG) log("No locale from SIM, using mcc locale:" + mccLocale);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005430 return mccLocale.toLanguageTag();
5431 }
5432
5433 if (DBG) log("No locale found - returning null");
5434 return null;
5435 } finally {
5436 Binder.restoreCallingIdentity(identity);
5437 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01005438 }
5439
5440 private List<SubscriptionInfo> getAllSubscriptionInfoList() {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005441 return mSubscriptionController.getAllSubInfoList(mApp.getOpPackageName());
Narayan Kamath1c496c22015-04-16 14:40:19 +01005442 }
5443
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005444 /**
5445 * NOTE: this method assumes permission checks are done and caller identity has been cleared.
5446 */
5447 private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005448 return mSubscriptionController.getActiveSubscriptionInfoList(mApp.getOpPackageName());
Narayan Kamath1c496c22015-04-16 14:40:19 +01005449 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07005450
Chenjie Yu1ba97252018-01-11 18:16:20 -08005451 private final ModemActivityInfo mLastModemActivityInfo =
5452 new ModemActivityInfo(0, 0, 0, new int[0], 0, 0);
5453
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07005454 /**
Adam Lesinski903a54c2016-04-11 14:49:52 -07005455 * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
5456 * representing the state of the modem.
5457 *
Chenjie Yu1ba97252018-01-11 18:16:20 -08005458 * NOTE: The underlying implementation clears the modem state, so there should only ever be one
5459 * caller to it. Everyone should call this class to get cumulative data.
Adam Lesinski903a54c2016-04-11 14:49:52 -07005460 * @hide
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07005461 */
5462 @Override
Adam Lesinski903a54c2016-04-11 14:49:52 -07005463 public void requestModemActivityInfo(ResultReceiver result) {
5464 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07005465 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005466
5467 final long identity = Binder.clearCallingIdentity();
5468 try {
5469 ModemActivityInfo ret = null;
5470 synchronized (mLastModemActivityInfo) {
5471 ModemActivityInfo info = (ModemActivityInfo) sendRequest(
5472 CMD_GET_MODEM_ACTIVITY_INFO,
vagdeviaf9a5b92018-08-15 16:01:53 -07005473 null, workSource);
Siddharth Rayb8114062018-06-17 15:02:38 -07005474 if (isModemActivityInfoValid(info)) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005475 int[] mergedTxTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
5476 for (int i = 0; i < mergedTxTimeMs.length; i++) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005477 mergedTxTimeMs[i] = info.getTxTimeMillis()[i]
5478 + mLastModemActivityInfo.getTxTimeMillis()[i];
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005479 }
5480 mLastModemActivityInfo.setTimestamp(info.getTimestamp());
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005481 mLastModemActivityInfo.setSleepTimeMillis(info.getSleepTimeMillis()
5482 + mLastModemActivityInfo.getSleepTimeMillis());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005483 mLastModemActivityInfo.setIdleTimeMillis(
5484 info.getIdleTimeMillis() + mLastModemActivityInfo.getIdleTimeMillis());
5485 mLastModemActivityInfo.setTxTimeMillis(mergedTxTimeMs);
5486 mLastModemActivityInfo.setRxTimeMillis(
5487 info.getRxTimeMillis() + mLastModemActivityInfo.getRxTimeMillis());
5488 mLastModemActivityInfo.setEnergyUsed(
5489 info.getEnergyUsed() + mLastModemActivityInfo.getEnergyUsed());
Chenjie Yu1ba97252018-01-11 18:16:20 -08005490 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005491 ret = new ModemActivityInfo(mLastModemActivityInfo.getTimestamp(),
5492 mLastModemActivityInfo.getSleepTimeMillis(),
5493 mLastModemActivityInfo.getIdleTimeMillis(),
5494 mLastModemActivityInfo.getTxTimeMillis(),
5495 mLastModemActivityInfo.getRxTimeMillis(),
5496 mLastModemActivityInfo.getEnergyUsed());
Chenjie Yu1ba97252018-01-11 18:16:20 -08005497 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005498 Bundle bundle = new Bundle();
5499 bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, ret);
5500 result.send(0, bundle);
5501 } finally {
5502 Binder.restoreCallingIdentity(identity);
Chenjie Yu1ba97252018-01-11 18:16:20 -08005503 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07005504 }
Jack Yu85bd38a2015-11-09 11:34:32 -08005505
Siddharth Rayb8114062018-06-17 15:02:38 -07005506 // Checks that ModemActivityInfo is valid. Sleep time, Idle time, Rx time and Tx time should be
5507 // less than total activity duration.
5508 private boolean isModemActivityInfoValid(ModemActivityInfo info) {
5509 if (info == null) {
5510 return false;
5511 }
5512 int activityDurationMs =
5513 (int) (info.getTimestamp() - mLastModemActivityInfo.getTimestamp());
5514 int totalTxTimeMs = 0;
5515 for (int i = 0; i < info.getTxTimeMillis().length; i++) {
5516 totalTxTimeMs += info.getTxTimeMillis()[i];
5517 }
5518 return (info.isValid()
5519 && (info.getSleepTimeMillis() <= activityDurationMs)
5520 && (info.getIdleTimeMillis() <= activityDurationMs)
5521 && (info.getRxTimeMillis() <= activityDurationMs)
5522 && (totalTxTimeMs <= activityDurationMs));
5523 }
5524
Jack Yu85bd38a2015-11-09 11:34:32 -08005525 /**
5526 * {@hide}
5527 * Returns the service state information on specified subscription.
5528 */
5529 @Override
5530 public ServiceState getServiceStateForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005531 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08005532 mApp, subId, callingPackage, "getServiceStateForSubscriber")) {
Jack Yu85bd38a2015-11-09 11:34:32 -08005533 return null;
5534 }
5535
Hall Liuf19c44f2018-11-27 14:38:17 -08005536 LocationAccessPolicy.LocationPermissionResult fineLocationResult =
5537 LocationAccessPolicy.checkLocationPermission(mApp,
5538 new LocationAccessPolicy.LocationPermissionQuery.Builder()
5539 .setCallingPackage(callingPackage)
5540 .setCallingPid(Binder.getCallingPid())
5541 .setCallingUid(Binder.getCallingUid())
5542 .setMethod("getServiceStateForSubscriber")
5543 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
5544 .build());
5545
5546 LocationAccessPolicy.LocationPermissionResult coarseLocationResult =
5547 LocationAccessPolicy.checkLocationPermission(mApp,
5548 new LocationAccessPolicy.LocationPermissionQuery.Builder()
5549 .setCallingPackage(callingPackage)
5550 .setCallingPid(Binder.getCallingPid())
5551 .setCallingUid(Binder.getCallingUid())
5552 .setMethod("getServiceStateForSubscriber")
5553 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
5554 .build());
5555 // We don't care about hard or soft here -- all we need to know is how much info to scrub.
5556 boolean hasFinePermission =
5557 fineLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
5558 boolean hasCoarsePermission =
5559 coarseLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
5560
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005561 final long identity = Binder.clearCallingIdentity();
5562 try {
5563 final Phone phone = getPhone(subId);
5564 if (phone == null) {
5565 return null;
5566 }
Jack Yu85bd38a2015-11-09 11:34:32 -08005567
Hall Liuf19c44f2018-11-27 14:38:17 -08005568 ServiceState ss = phone.getServiceState();
5569
5570 // Scrub out the location info in ServiceState depending on what level of access
5571 // the caller has.
5572 if (hasFinePermission) return ss;
5573 if (hasCoarsePermission) return ss.sanitizeLocationInfo(false);
5574 return ss.sanitizeLocationInfo(true);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005575 } finally {
5576 Binder.restoreCallingIdentity(identity);
5577 }
Jack Yu85bd38a2015-11-09 11:34:32 -08005578 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08005579
5580 /**
5581 * Returns the URI for the per-account voicemail ringtone set in Phone settings.
5582 *
5583 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
5584 * voicemail ringtone.
5585 * @return The URI for the ringtone to play when receiving a voicemail from a specific
5586 * PhoneAccount.
5587 */
5588 @Override
5589 public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005590 final long identity = Binder.clearCallingIdentity();
5591 try {
5592 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
5593 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005594 phone = getDefaultPhone();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005595 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08005596
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005597 return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext());
5598 } finally {
5599 Binder.restoreCallingIdentity(identity);
5600 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08005601 }
5602
5603 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005604 * Sets the per-account voicemail ringtone.
5605 *
5606 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
5607 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
5608 *
5609 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
5610 * voicemail ringtone.
5611 * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
5612 * PhoneAccount.
5613 */
5614 @Override
5615 public void setVoicemailRingtoneUri(String callingPackage,
5616 PhoneAccountHandle phoneAccountHandle, Uri uri) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005617 final Phone defaultPhone = getDefaultPhone();
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005618 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
5619 if (!TextUtils.equals(callingPackage,
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005620 TelecomManager.from(defaultPhone.getContext()).getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005621 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5622 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
5623 "setVoicemailRingtoneUri");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005624 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005625
5626 final long identity = Binder.clearCallingIdentity();
5627 try {
5628 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
5629 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005630 phone = defaultPhone;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005631 }
5632 VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri);
5633 } finally {
5634 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005635 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005636 }
5637
5638 /**
Nancy Chen31f9ba12016-01-06 11:42:12 -08005639 * Returns whether vibration is set for voicemail notification in Phone settings.
5640 *
5641 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
5642 * voicemail vibration setting.
5643 * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
5644 */
5645 @Override
5646 public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005647 final long identity = Binder.clearCallingIdentity();
5648 try {
5649 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
5650 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005651 phone = getDefaultPhone();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005652 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08005653
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005654 return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext());
5655 } finally {
5656 Binder.restoreCallingIdentity(identity);
5657 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08005658 }
5659
Youhan Wange64578a2016-05-02 15:32:42 -07005660 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005661 * Sets the per-account voicemail vibration.
5662 *
5663 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
5664 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
5665 *
5666 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
5667 * voicemail vibration setting.
5668 * @param enabled Whether to enable or disable vibration for voicemail notifications from a
5669 * specific PhoneAccount.
5670 */
5671 @Override
5672 public void setVoicemailVibrationEnabled(String callingPackage,
5673 PhoneAccountHandle phoneAccountHandle, boolean enabled) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005674 final Phone defaultPhone = getDefaultPhone();
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005675 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
5676 if (!TextUtils.equals(callingPackage,
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005677 TelecomManager.from(defaultPhone.getContext()).getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005678 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5679 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
5680 "setVoicemailVibrationEnabled");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005681 }
5682
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005683 final long identity = Binder.clearCallingIdentity();
5684 try {
5685 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
5686 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005687 phone = defaultPhone;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005688 }
5689 VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled);
5690 } finally {
5691 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005692 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005693 }
5694
5695 /**
Youhan Wange64578a2016-05-02 15:32:42 -07005696 * Make sure either called from same process as self (phone) or IPC caller has read privilege.
5697 *
5698 * @throws SecurityException if the caller does not have the required permission
5699 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07005700 private void enforceReadPrivilegedPermission(String message) {
Youhan Wange64578a2016-05-02 15:32:42 -07005701 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
Brad Ebinger35c841c2018-10-01 10:40:55 -07005702 message);
Youhan Wange64578a2016-05-02 15:32:42 -07005703 }
5704
5705 /**
Ta-wei Yen30a69c82016-12-27 14:52:32 -08005706 * Make sure either called from same process as self (phone) or IPC caller has send SMS
5707 * permission.
5708 *
5709 * @throws SecurityException if the caller does not have the required permission
5710 */
5711 private void enforceSendSmsPermission() {
5712 mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null);
5713 }
5714
5715 /**
Ta-wei Yen527a9c02017-01-06 15:29:25 -08005716 * Make sure called from the package in charge of visual voicemail.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08005717 *
Ta-wei Yen527a9c02017-01-06 15:29:25 -08005718 * @throws SecurityException if the caller is not the visual voicemail package.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08005719 */
Ta-wei Yen527a9c02017-01-06 15:29:25 -08005720 private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005721 final long identity = Binder.clearCallingIdentity();
5722 try {
5723 ComponentName componentName =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005724 RemoteVvmTaskManager.getRemotePackage(mApp, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005725 if (componentName == null) {
5726 throw new SecurityException(
5727 "Caller not current active visual voicemail package[null]");
5728 }
5729 String vvmPackage = componentName.getPackageName();
5730 if (!callingPackage.equals(vvmPackage)) {
5731 throw new SecurityException("Caller not current active visual voicemail package["
5732 + vvmPackage + "]");
5733 }
5734 } finally {
5735 Binder.restoreCallingIdentity(identity);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08005736 }
5737 }
5738
5739 /**
Youhan Wange64578a2016-05-02 15:32:42 -07005740 * Return the application ID for the app type.
5741 *
5742 * @param subId the subscription ID that this request applies to.
5743 * @param appType the uicc app type.
5744 * @return Application ID for specificied app type, or null if no uicc.
5745 */
5746 @Override
5747 public String getAidForAppType(int subId, int appType) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005748 enforceReadPrivilegedPermission("getAidForAppType");
Youhan Wange64578a2016-05-02 15:32:42 -07005749 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005750
5751 final long identity = Binder.clearCallingIdentity();
Youhan Wange64578a2016-05-02 15:32:42 -07005752 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005753 if (phone == null) {
5754 return null;
5755 }
5756 String aid = null;
5757 try {
5758 aid = UiccController.getInstance().getUiccCard(phone.getPhoneId())
5759 .getApplicationByType(appType).getAid();
5760 } catch (Exception e) {
5761 Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e);
5762 }
5763 return aid;
5764 } finally {
5765 Binder.restoreCallingIdentity(identity);
Youhan Wange64578a2016-05-02 15:32:42 -07005766 }
Youhan Wange64578a2016-05-02 15:32:42 -07005767 }
5768
Youhan Wang4001d252016-05-11 10:29:41 -07005769 /**
5770 * Return the Electronic Serial Number.
5771 *
5772 * @param subId the subscription ID that this request applies to.
5773 * @return ESN or null if error.
5774 */
5775 @Override
5776 public String getEsn(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005777 enforceReadPrivilegedPermission("getEsn");
Youhan Wang4001d252016-05-11 10:29:41 -07005778 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005779
5780 final long identity = Binder.clearCallingIdentity();
Youhan Wang4001d252016-05-11 10:29:41 -07005781 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005782 if (phone == null) {
5783 return null;
5784 }
5785 String esn = null;
5786 try {
5787 esn = phone.getEsn();
5788 } catch (Exception e) {
5789 Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e);
5790 }
5791 return esn;
5792 } finally {
5793 Binder.restoreCallingIdentity(identity);
Youhan Wang4001d252016-05-11 10:29:41 -07005794 }
Youhan Wang4001d252016-05-11 10:29:41 -07005795 }
5796
Sanket Padawe99ef1e32016-05-18 16:12:33 -07005797 /**
Youhan Wang66ad5d72016-07-18 17:56:58 -07005798 * Return the Preferred Roaming List Version.
5799 *
5800 * @param subId the subscription ID that this request applies to.
5801 * @return PRLVersion or null if error.
5802 */
5803 @Override
5804 public String getCdmaPrlVersion(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005805 enforceReadPrivilegedPermission("getCdmaPrlVersion");
Youhan Wang66ad5d72016-07-18 17:56:58 -07005806 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005807
5808 final long identity = Binder.clearCallingIdentity();
Youhan Wang66ad5d72016-07-18 17:56:58 -07005809 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005810 if (phone == null) {
5811 return null;
5812 }
5813 String cdmaPrlVersion = null;
5814 try {
5815 cdmaPrlVersion = phone.getCdmaPrlVersion();
5816 } catch (Exception e) {
5817 Log.e(LOG_TAG, "Not getting PRLVersion", e);
5818 }
5819 return cdmaPrlVersion;
5820 } finally {
5821 Binder.restoreCallingIdentity(identity);
Youhan Wang66ad5d72016-07-18 17:56:58 -07005822 }
Youhan Wang66ad5d72016-07-18 17:56:58 -07005823 }
5824
5825 /**
Sanket Padawe99ef1e32016-05-18 16:12:33 -07005826 * Get snapshot of Telephony histograms
5827 * @return List of Telephony histograms
5828 * @hide
5829 */
5830 @Override
5831 public List<TelephonyHistogram> getTelephonyHistograms() {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005832 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5833 mApp, getDefaultSubscription(), "getTelephonyHistograms");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005834
5835 final long identity = Binder.clearCallingIdentity();
5836 try {
5837 return RIL.getTelephonyRILTimingHistograms();
5838 } finally {
5839 Binder.restoreCallingIdentity(identity);
5840 }
Sanket Padawe99ef1e32016-05-18 16:12:33 -07005841 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07005842
5843 /**
5844 * {@hide}
Michele Berionne482f8202018-11-27 18:57:59 -08005845 * Set the allowed carrier list and the excluded carrier list, indicating the priority between
5846 * the two lists.
Meng Wang1a7c35a2016-05-05 20:56:15 -07005847 * Require system privileges. In the future we may add this to carrier APIs.
5848 *
Michele Berionne482f8202018-11-27 18:57:59 -08005849 * @return Integer with the result of the operation, as defined in {@link TelephonyManager}.
Meng Wang1a7c35a2016-05-05 20:56:15 -07005850 */
5851 @Override
Michele Berionne482f8202018-11-27 18:57:59 -08005852 @TelephonyManager.SetCarrierRestrictionResult
5853 public int setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules) {
Meng Wang1a7c35a2016-05-05 20:56:15 -07005854 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07005855 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005856
Michele Berionne482f8202018-11-27 18:57:59 -08005857 if (carrierRestrictionRules == null) {
5858 throw new NullPointerException("carrier restriction cannot be null");
Meng Wang9b7c4e92017-02-17 11:41:27 -08005859 }
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005860
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005861 final long identity = Binder.clearCallingIdentity();
5862 try {
Michele Berionne482f8202018-11-27 18:57:59 -08005863 return (int) sendRequest(CMD_SET_ALLOWED_CARRIERS, carrierRestrictionRules,
vagdeviaf9a5b92018-08-15 16:01:53 -07005864 workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005865 } finally {
5866 Binder.restoreCallingIdentity(identity);
5867 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07005868 }
5869
5870 /**
5871 * {@hide}
Michele Berionne482f8202018-11-27 18:57:59 -08005872 * Get the allowed carrier list and the excluded carrier list, including the priority between
5873 * the two lists.
Meng Wang1a7c35a2016-05-05 20:56:15 -07005874 * Require system privileges. In the future we may add this to carrier APIs.
5875 *
Michele Berionne482f8202018-11-27 18:57:59 -08005876 * @return {@link android.telephony.CarrierRestrictionRules}
Meng Wang1a7c35a2016-05-05 20:56:15 -07005877 */
5878 @Override
Michele Berionne482f8202018-11-27 18:57:59 -08005879 public CarrierRestrictionRules getAllowedCarriers() {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005880 enforceReadPrivilegedPermission("getAllowedCarriers");
vagdeviaf9a5b92018-08-15 16:01:53 -07005881 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005882
5883 final long identity = Binder.clearCallingIdentity();
5884 try {
Michele Berionne482f8202018-11-27 18:57:59 -08005885 Object response = sendRequest(CMD_GET_ALLOWED_CARRIERS, null, workSource);
5886 if (response instanceof CarrierRestrictionRules) {
5887 return (CarrierRestrictionRules) response;
5888 }
5889 // Response is an Exception of some kind,
5890 // which is signalled to the user as a NULL retval
5891 return null;
5892 } catch (Exception e) {
5893 Log.e(LOG_TAG, "getAllowedCarriers. Exception ex=" + e);
5894 return null;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005895 } finally {
5896 Binder.restoreCallingIdentity(identity);
5897 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07005898 }
5899
fionaxu59545b42016-05-25 15:53:37 -07005900 /**
5901 * Action set from carrier signalling broadcast receivers to enable/disable metered apns
5902 * @param subId the subscription ID that this action applies to.
5903 * @param enabled control enable or disable metered apns.
5904 * {@hide}
5905 */
5906 @Override
5907 public void carrierActionSetMeteredApnsEnabled(int subId, boolean enabled) {
5908 enforceModifyPermission();
5909 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005910
5911 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07005912 if (phone == null) {
5913 loge("carrierAction: SetMeteredApnsEnabled fails with invalid subId: " + subId);
5914 return;
5915 }
5916 try {
5917 phone.carrierActionSetMeteredApnsEnabled(enabled);
5918 } catch (Exception e) {
5919 Log.e(LOG_TAG, "carrierAction: SetMeteredApnsEnabled fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005920 } finally {
5921 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07005922 }
5923 }
5924
5925 /**
5926 * Action set from carrier signalling broadcast receivers to enable/disable radio
5927 * @param subId the subscription ID that this action applies to.
5928 * @param enabled control enable or disable radio.
5929 * {@hide}
5930 */
5931 @Override
5932 public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
5933 enforceModifyPermission();
5934 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005935
5936 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07005937 if (phone == null) {
5938 loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
5939 return;
5940 }
5941 try {
5942 phone.carrierActionSetRadioEnabled(enabled);
5943 } catch (Exception e) {
5944 Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005945 } finally {
5946 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07005947 }
5948 }
5949
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07005950 /**
fionaxu8da9cb12017-05-23 15:02:46 -07005951 * Action set from carrier signalling broadcast receivers to start/stop reporting the default
5952 * network status based on which carrier apps could apply actions accordingly,
5953 * enable/disable default url handler for example.
5954 *
5955 * @param subId the subscription ID that this action applies to.
5956 * @param report control start/stop reporting the default network status.
5957 * {@hide}
5958 */
5959 @Override
5960 public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
5961 enforceModifyPermission();
5962 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005963
5964 final long identity = Binder.clearCallingIdentity();
fionaxu8da9cb12017-05-23 15:02:46 -07005965 if (phone == null) {
5966 loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId);
5967 return;
5968 }
5969 try {
5970 phone.carrierActionReportDefaultNetworkStatus(report);
5971 } catch (Exception e) {
5972 Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005973 } finally {
5974 Binder.restoreCallingIdentity(identity);
fionaxu8da9cb12017-05-23 15:02:46 -07005975 }
5976 }
5977
5978 /**
fionaxud9622282017-07-17 17:51:30 -07005979 * Action set from carrier signalling broadcast receivers to reset all carrier actions
5980 * @param subId the subscription ID that this action applies to.
5981 * {@hide}
5982 */
5983 @Override
5984 public void carrierActionResetAll(int subId) {
5985 enforceModifyPermission();
5986 final Phone phone = getPhone(subId);
5987 if (phone == null) {
5988 loge("carrierAction: ResetAll fails with invalid sibId: " + subId);
5989 return;
5990 }
5991 try {
5992 phone.carrierActionResetAll();
5993 } catch (Exception e) {
5994 Log.e(LOG_TAG, "carrierAction: ResetAll fails. Exception ex=" + e);
5995 }
5996 }
5997
5998 /**
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07005999 * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a
6000 * bug report is being generated.
6001 */
6002 @Override
Ta-wei Yen99282e02016-06-21 18:19:35 -07006003 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006004 if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
6005 != PackageManager.PERMISSION_GRANTED) {
dcashman22b950d2016-06-27 11:39:02 -07006006 writer.println("Permission Denial: can't dump Phone from pid="
6007 + Binder.getCallingPid()
6008 + ", uid=" + Binder.getCallingUid()
6009 + "without permission "
6010 + android.Manifest.permission.DUMP);
6011 return;
6012 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006013 DumpsysHandler.dump(mApp, fd, writer, args);
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07006014 }
Jack Yueb89b242016-06-22 13:27:47 -07006015
Brad Ebingerdac2f002018-04-03 15:17:52 -07006016 @Override
6017 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
6018 String[] args, ShellCallback callback, ResultReceiver resultReceiver)
6019 throws RemoteException {
6020 (new TelephonyShellCommand(this)).exec(this, in, out, err, args, callback, resultReceiver);
6021 }
6022
Jack Yueb89b242016-06-22 13:27:47 -07006023 /**
Jack Yu84291ec2017-05-26 16:07:50 -07006024 * Get aggregated video call data usage since boot.
6025 *
6026 * @param perUidStats True if requesting data usage per uid, otherwise overall usage.
6027 * @return Snapshot of video call data usage
Jack Yueb89b242016-06-22 13:27:47 -07006028 * {@hide}
6029 */
6030 @Override
Jack Yu84291ec2017-05-26 16:07:50 -07006031 public NetworkStats getVtDataUsage(int subId, boolean perUidStats) {
Jack Yueb89b242016-06-22 13:27:47 -07006032 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_NETWORK_USAGE_HISTORY,
6033 null);
6034
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006035 final long identity = Binder.clearCallingIdentity();
6036 try {
6037 // NetworkStatsService keeps tracking the active network interface and identity. It
6038 // records the delta with the corresponding network identity.
6039 // We just return the total video call data usage snapshot since boot.
6040 Phone phone = getPhone(subId);
6041 if (phone != null) {
6042 return phone.getVtDataUsage(perUidStats);
6043 }
6044 return null;
6045 } finally {
6046 Binder.restoreCallingIdentity(identity);
Jack Yueb89b242016-06-22 13:27:47 -07006047 }
Jack Yueb89b242016-06-22 13:27:47 -07006048 }
Jack Yu75ab2952016-07-08 14:29:33 -07006049
6050 /**
6051 * Policy control of data connection. Usually used when data limit is passed.
6052 * @param enabled True if enabling the data, otherwise disabling.
6053 * @param subId Subscription index
6054 * {@hide}
6055 */
6056 @Override
6057 public void setPolicyDataEnabled(boolean enabled, int subId) {
6058 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006059
6060 final long identity = Binder.clearCallingIdentity();
6061 try {
6062 Phone phone = getPhone(subId);
6063 if (phone != null) {
Jack Yud79fba22018-12-13 11:51:28 -08006064 phone.getDataEnabledSettings().setPolicyDataEnabled(enabled);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006065 }
6066 } finally {
6067 Binder.restoreCallingIdentity(identity);
Jack Yu75ab2952016-07-08 14:29:33 -07006068 }
6069 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07006070
6071 /**
6072 * Get Client request stats
6073 * @return List of Client Request Stats
6074 * @hide
6075 */
6076 @Override
6077 public List<ClientRequestStats> getClientRequestStats(String callingPackage, int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006078 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08006079 mApp, subId, callingPackage, "getClientRequestStats")) {
Sooraj Sasindran9a909312016-07-18 11:57:25 -07006080 return null;
6081 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07006082 Phone phone = getPhone(subId);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07006083
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006084 final long identity = Binder.clearCallingIdentity();
6085 try {
6086 if (phone != null) {
6087 return phone.getClientRequestStats();
6088 }
6089
6090 return null;
6091 } finally {
6092 Binder.restoreCallingIdentity(identity);
6093 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07006094 }
6095
Narayan Kamathf04b5a12018-01-09 11:47:15 +00006096 private WorkSource getWorkSource(int uid) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006097 String packageName = mApp.getPackageManager().getNameForUid(uid);
Narayan Kamathf04b5a12018-01-09 11:47:15 +00006098 return new WorkSource(uid, packageName);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07006099 }
Jack Yueb4124c2017-02-16 15:32:43 -08006100
6101 /**
Grace Chen70990072017-03-24 17:21:30 -07006102 * Set SIM card power state.
Jack Yueb4124c2017-02-16 15:32:43 -08006103 *
Sanket Padawe13bac7b2017-03-20 15:04:47 -07006104 * @param slotIndex SIM slot id.
Grace Chen70990072017-03-24 17:21:30 -07006105 * @param state State of SIM (power down, power up, pass through)
6106 * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
6107 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
6108 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
Jack Yueb4124c2017-02-16 15:32:43 -08006109 *
6110 **/
6111 @Override
Grace Chen70990072017-03-24 17:21:30 -07006112 public void setSimPowerStateForSlot(int slotIndex, int state) {
Jack Yueb4124c2017-02-16 15:32:43 -08006113 enforceModifyPermission();
Sanket Padawe13bac7b2017-03-20 15:04:47 -07006114 Phone phone = PhoneFactory.getPhone(slotIndex);
6115
vagdeviaf9a5b92018-08-15 16:01:53 -07006116 WorkSource workSource = getWorkSource(Binder.getCallingUid());
6117
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006118 final long identity = Binder.clearCallingIdentity();
6119 try {
6120 if (phone != null) {
vagdeviaf9a5b92018-08-15 16:01:53 -07006121 phone.setSimPowerState(state, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006122 }
6123 } finally {
6124 Binder.restoreCallingIdentity(identity);
Jack Yueb4124c2017-02-16 15:32:43 -08006125 }
6126 }
Shuo Qiandd210312017-04-12 22:11:33 +00006127
Tyler Gunn65d45c22017-06-05 11:22:26 -07006128 private boolean isUssdApiAllowed(int subId) {
6129 CarrierConfigManager configManager =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006130 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Tyler Gunn65d45c22017-06-05 11:22:26 -07006131 if (configManager == null) {
6132 return false;
6133 }
6134 PersistableBundle pb = configManager.getConfigForSubId(subId);
6135 if (pb == null) {
6136 return false;
6137 }
6138 return pb.getBoolean(
6139 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL);
6140 }
6141
Shuo Qiandd210312017-04-12 22:11:33 +00006142 /**
6143 * Check if phone is in emergency callback mode
6144 * @return true if phone is in emergency callback mode
6145 * @param subId sub id
6146 */
goneil9c5f4872017-12-05 14:07:56 -08006147 @Override
Shuo Qiandd210312017-04-12 22:11:33 +00006148 public boolean getEmergencyCallbackMode(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07006149 enforceReadPrivilegedPermission("getEmergencyCallbackMode");
Shuo Qiandd210312017-04-12 22:11:33 +00006150 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006151
6152 final long identity = Binder.clearCallingIdentity();
6153 try {
6154 if (phone != null) {
6155 return phone.isInEcm();
6156 } else {
6157 return false;
6158 }
6159 } finally {
6160 Binder.restoreCallingIdentity(identity);
Shuo Qiandd210312017-04-12 22:11:33 +00006161 }
6162 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08006163
6164 /**
6165 * Get the current signal strength information for the given subscription.
6166 * Because this information is not updated when the device is in a low power state
6167 * it should not be relied-upon to be current.
6168 * @param subId Subscription index
6169 * @return the most recent cached signal strength info from the modem
6170 */
6171 @Override
6172 public SignalStrength getSignalStrength(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006173 final long identity = Binder.clearCallingIdentity();
6174 try {
6175 Phone p = getPhone(subId);
6176 if (p == null) {
6177 return null;
6178 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08006179
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006180 return p.getSignalStrength();
6181 } finally {
6182 Binder.restoreCallingIdentity(identity);
6183 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08006184 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00006185
Pengquan Meng77b7f132018-08-22 14:49:57 -07006186 /**
Chen Xuf792fd62018-10-17 17:54:36 +00006187 * Get the current modem radio state for the given slot.
6188 * @param slotIndex slot index.
6189 * @param callingPackage the name of the package making the call.
6190 * @return the current radio power state from the modem
6191 */
6192 @Override
6193 public int getRadioPowerState(int slotIndex, String callingPackage) {
6194 Phone phone = PhoneFactory.getPhone(slotIndex);
6195 if (phone != null) {
6196 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
6197 mApp, phone.getSubId(), callingPackage, "getRadioPowerState")) {
6198 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
6199 }
6200
6201 final long identity = Binder.clearCallingIdentity();
6202 try {
6203 return phone.getRadioPowerState();
6204 } finally {
6205 Binder.restoreCallingIdentity(identity);
6206 }
6207 }
6208 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
6209 }
6210
6211 /**
Pengquan Meng77b7f132018-08-22 14:49:57 -07006212 * Checks if data roaming is enabled on the subscription with id {@code subId}.
6213 *
6214 * <p>Requires one of the following permissions:
6215 * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
6216 * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
6217 * privileges.
6218 *
6219 * @param subId subscription id
6220 * @return {@code true} if data roaming is enabled on this subscription, otherwise return
6221 * {@code false}.
6222 */
6223 @Override
6224 public boolean isDataRoamingEnabled(int subId) {
Pengquan Meng44e66f12019-04-01 10:48:20 -07006225 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
6226 null /* message */);
6227
Pengquan Menga1bb6272018-09-06 09:59:22 -07006228 boolean isEnabled = false;
6229 final long identity = Binder.clearCallingIdentity();
Pengquan Meng77b7f132018-08-22 14:49:57 -07006230 try {
Pengquan Menga1bb6272018-09-06 09:59:22 -07006231 Phone phone = getPhone(subId);
6232 isEnabled = phone != null ? phone.getDataRoamingEnabled() : false;
Pengquan Meng77b7f132018-08-22 14:49:57 -07006233 } catch (Exception e) {
6234 TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
6235 mApp, subId, "isDataRoamingEnabled");
Pengquan Menga1bb6272018-09-06 09:59:22 -07006236 } finally {
6237 Binder.restoreCallingIdentity(identity);
Pengquan Meng77b7f132018-08-22 14:49:57 -07006238 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07006239 return isEnabled;
Pengquan Meng77b7f132018-08-22 14:49:57 -07006240 }
6241
6242
6243 /**
6244 * Enables/Disables the data roaming on the subscription with id {@code subId}.
6245 *
6246 * <p> Requires permission:
6247 * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier
6248 * privileges.
6249 *
6250 * @param subId subscription id
6251 * @param isEnabled {@code true} means enable, {@code false} means disable.
6252 */
6253 @Override
6254 public void setDataRoamingEnabled(int subId, boolean isEnabled) {
Pengquan Meng44e66f12019-04-01 10:48:20 -07006255 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6256 mApp, subId, "setDataRoamingEnabled");
6257
Pengquan Menga1bb6272018-09-06 09:59:22 -07006258 final long identity = Binder.clearCallingIdentity();
6259 try {
Pengquan Menga1bb6272018-09-06 09:59:22 -07006260 Phone phone = getPhone(subId);
6261 if (phone != null) {
6262 phone.setDataRoamingEnabled(isEnabled);
6263 }
6264 } finally {
6265 Binder.restoreCallingIdentity(identity);
Pengquan Meng77b7f132018-08-22 14:49:57 -07006266 }
6267 }
6268
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00006269 @Override
Pengquan Meng6884a2c2018-10-03 12:19:13 -07006270 public boolean isManualNetworkSelectionAllowed(int subId) {
Pengquan Meng44e66f12019-04-01 10:48:20 -07006271 TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
6272 mApp, subId, "isManualNetworkSelectionAllowed");
6273
Pengquan Meng6884a2c2018-10-03 12:19:13 -07006274 boolean isAllowed = true;
6275 final long identity = Binder.clearCallingIdentity();
6276 try {
Pengquan Meng6884a2c2018-10-03 12:19:13 -07006277 Phone phone = getPhone(subId);
6278 if (phone != null) {
6279 isAllowed = phone.isCspPlmnEnabled();
6280 }
6281 } finally {
6282 Binder.restoreCallingIdentity(identity);
6283 }
6284 return isAllowed;
6285 }
6286
6287 @Override
Jordan Liu75f43ea2019-01-17 16:56:37 -08006288 public List<UiccCardInfo> getUiccCardsInfo(String callingPackage) {
Jordan Liuc65bc952019-02-12 17:54:02 -08006289 try {
6290 enforceReadPrivilegedPermission("getUiccCardsInfo");
6291 } catch (SecurityException e) {
6292 // even without READ_PRIVILEGED_PHONE_STATE, we allow the call to continue if the caller
6293 // has carrier privileges on an active UICC
6294 if (checkCarrierPrivilegesForPackageAnyPhone(callingPackage)
6295 != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
6296 throw new SecurityException("Caller does not have carrier privileges on any UICC");
6297 }
Jordan Liu75f43ea2019-01-17 16:56:37 -08006298 }
Jordan Liu5aa07002018-12-18 15:44:48 -08006299
6300 final long identity = Binder.clearCallingIdentity();
6301 try {
Jordan Liu75f43ea2019-01-17 16:56:37 -08006302 UiccController uiccController = UiccController.getInstance();
6303 ArrayList<UiccCardInfo> cardInfos = uiccController.getAllUiccCardInfos();
6304
6305 ApplicationInfo ai = mApp.getPackageManager().getApplicationInfo(callingPackage, 0);
6306 if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6307 // Remove private info if the caller doesn't have access
6308 ArrayList<UiccCardInfo> filteredInfos = new ArrayList<>();
6309 for (UiccCardInfo cardInfo : cardInfos) {
6310 UiccCard card = uiccController.getUiccCard(cardInfo.getSlotIndex());
6311 UiccProfile profile = card.getUiccProfile();
6312 if (profile.getCarrierPrivilegeStatus(mApp.getPackageManager(), callingPackage)
6313 != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
6314 filteredInfos.add(cardInfo.getUnprivileged());
6315 } else {
6316 filteredInfos.add(cardInfo);
6317 }
6318 }
6319 return filteredInfos;
6320 }
6321 return cardInfos;
6322 } catch (PackageManager.NameNotFoundException e) {
6323 // This should not happen since we pass the package info in from TelephonyManager
6324 throw new SecurityException("Invalid calling package.");
Jordan Liu5aa07002018-12-18 15:44:48 -08006325 } finally {
6326 Binder.restoreCallingIdentity(identity);
6327 }
6328 }
6329
6330 @Override
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00006331 public UiccSlotInfo[] getUiccSlotsInfo() {
Brad Ebinger35c841c2018-10-01 10:40:55 -07006332 enforceReadPrivilegedPermission("getUiccSlotsInfo");
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00006333
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006334 final long identity = Binder.clearCallingIdentity();
6335 try {
6336 UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
6337 if (slots == null) {
6338 Rlog.i(LOG_TAG, "slots is null.");
6339 return null;
6340 }
6341
6342 UiccSlotInfo[] infos = new UiccSlotInfo[slots.length];
6343 for (int i = 0; i < slots.length; i++) {
6344 UiccSlot slot = slots[i];
6345 if (slot == null) {
6346 continue;
6347 }
6348
6349 String cardId;
6350 UiccCard card = slot.getUiccCard();
6351 if (card != null) {
6352 cardId = card.getCardId();
6353 } else {
6354 cardId = slot.getIccId();
6355 }
6356
6357 int cardState = 0;
6358 switch (slot.getCardState()) {
6359 case CARDSTATE_ABSENT:
6360 cardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
6361 break;
6362 case CARDSTATE_PRESENT:
6363 cardState = UiccSlotInfo.CARD_STATE_INFO_PRESENT;
6364 break;
6365 case CARDSTATE_ERROR:
6366 cardState = UiccSlotInfo.CARD_STATE_INFO_ERROR;
6367 break;
6368 case CARDSTATE_RESTRICTED:
6369 cardState = UiccSlotInfo.CARD_STATE_INFO_RESTRICTED;
6370 break;
6371 default:
6372 break;
6373
6374 }
6375
6376 infos[i] = new UiccSlotInfo(
6377 slot.isActive(),
6378 slot.isEuicc(),
6379 cardId,
6380 cardState,
6381 slot.getPhoneId(),
Jordan Liua2619582019-02-14 12:56:40 -08006382 slot.isExtendedApduSupported(),
6383 slot.isRemovable());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006384 }
6385 return infos;
6386 } finally {
6387 Binder.restoreCallingIdentity(identity);
Holly Jiuyu Sun1d957c52018-04-04 13:52:42 -07006388 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00006389 }
6390
6391 @Override
6392 public boolean switchSlots(int[] physicalSlots) {
6393 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006394
6395 final long identity = Binder.clearCallingIdentity();
6396 try {
6397 return (Boolean) sendRequest(CMD_SWITCH_SLOTS, physicalSlots);
6398 } finally {
6399 Binder.restoreCallingIdentity(identity);
6400 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00006401 }
Jack Yu4c988042018-02-27 15:30:01 -08006402
6403 @Override
Jordan Liu7de49fa2018-12-06 14:48:49 -08006404 public int getCardIdForDefaultEuicc(int subId, String callingPackage) {
Jordan Liu7de49fa2018-12-06 14:48:49 -08006405 final long identity = Binder.clearCallingIdentity();
6406 try {
6407 return UiccController.getInstance().getCardIdForDefaultEuicc();
6408 } finally {
6409 Binder.restoreCallingIdentity(identity);
6410 }
6411 }
6412
6413 @Override
Jack Yu4c988042018-02-27 15:30:01 -08006414 public void setRadioIndicationUpdateMode(int subId, int filters, int mode) {
6415 enforceModifyPermission();
6416 final Phone phone = getPhone(subId);
6417 if (phone == null) {
6418 loge("setRadioIndicationUpdateMode fails with invalid subId: " + subId);
6419 return;
6420 }
6421
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006422 final long identity = Binder.clearCallingIdentity();
6423 try {
6424 phone.setRadioIndicationUpdateMode(filters, mode);
6425 } finally {
6426 Binder.restoreCallingIdentity(identity);
6427 }
Jack Yu4c988042018-02-27 15:30:01 -08006428 }
Pengquan Meng85728fb2018-03-12 16:31:21 -07006429
6430 /**
goneil47ffb6e2018-04-06 15:40:58 -07006431 * A test API to reload the UICC profile.
6432 *
6433 * <p>Requires that the calling app has permission
6434 * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
6435 * @hide
6436 */
6437 @Override
6438 public void refreshUiccProfile(int subId) {
6439 enforceModifyPermission();
6440
6441 final long identity = Binder.clearCallingIdentity();
6442 try {
6443 Phone phone = getPhone(subId);
6444 if (phone == null) {
6445 return;
6446 }
6447 UiccCard uiccCard = phone.getUiccCard();
6448 if (uiccCard == null) {
6449 return;
6450 }
6451 UiccProfile uiccProfile = uiccCard.getUiccProfile();
6452 if (uiccProfile == null) {
6453 return;
6454 }
6455 uiccProfile.refresh();
6456 } finally {
6457 Binder.restoreCallingIdentity(identity);
6458 }
6459 }
6460
6461 /**
Pengquan Meng85728fb2018-03-12 16:31:21 -07006462 * Returns false if the mobile data is disabled by default, otherwise return true.
6463 */
6464 private boolean getDefaultDataEnabled() {
6465 return "true".equalsIgnoreCase(
6466 SystemProperties.get(DEFAULT_MOBILE_DATA_PROPERTY_NAME, "true"));
6467 }
6468
6469 /**
6470 * Returns true if the data roaming is enabled by default, i.e the system property
6471 * of {@link #DEFAULT_DATA_ROAMING_PROPERTY_NAME} is true or the config of
6472 * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} is true.
6473 */
6474 private boolean getDefaultDataRoamingEnabled(int subId) {
6475 final CarrierConfigManager configMgr = (CarrierConfigManager)
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006476 mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Pengquan Meng85728fb2018-03-12 16:31:21 -07006477 boolean isDataRoamingEnabled = "true".equalsIgnoreCase(
6478 SystemProperties.get(DEFAULT_DATA_ROAMING_PROPERTY_NAME, "false"));
6479 isDataRoamingEnabled |= configMgr.getConfigForSubId(subId).getBoolean(
6480 CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
6481 return isDataRoamingEnabled;
6482 }
6483
6484 /**
6485 * Returns the default network type for the given {@code subId}, if the default network type is
6486 * not set, return {@link Phone#PREFERRED_NT_MODE}.
6487 */
6488 private int getDefaultNetworkType(int subId) {
6489 return Integer.parseInt(
6490 TelephonyManager.getTelephonyProperty(
6491 mSubscriptionController.getPhoneId(subId),
6492 DEFAULT_NETWORK_MODE_PROPERTY_NAME,
6493 String.valueOf(Phone.PREFERRED_NT_MODE)));
6494 }
fionaxua13278b2018-03-21 00:08:13 -07006495
6496 @Override
6497 public void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String
chen xueaba88a2019-03-15 13:15:10 -07006498 gid1, String gid2, String plmn, String spn, String carrierPrivilegeRules, String apn) {
fionaxua13278b2018-03-21 00:08:13 -07006499 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006500
6501 final long identity = Binder.clearCallingIdentity();
6502 try {
6503 final Phone phone = getPhone(subId);
6504 if (phone == null) {
6505 loge("setCarrierTestOverride fails with invalid subId: " + subId);
6506 return;
6507 }
chen xueaba88a2019-03-15 13:15:10 -07006508 phone.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, plmn, spn,
6509 carrierPrivilegeRules, apn);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006510 } finally {
6511 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07006512 }
fionaxua13278b2018-03-21 00:08:13 -07006513 }
6514
6515 @Override
6516 public int getCarrierIdListVersion(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07006517 enforceReadPrivilegedPermission("getCarrierIdListVersion");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006518
6519 final long identity = Binder.clearCallingIdentity();
6520 try {
6521 final Phone phone = getPhone(subId);
6522 if (phone == null) {
6523 loge("getCarrierIdListVersion fails with invalid subId: " + subId);
6524 return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
6525 }
6526 return phone.getCarrierIdListVersion();
6527 } finally {
6528 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07006529 }
fionaxua13278b2018-03-21 00:08:13 -07006530 }
Malcolm Chen2c63d402018-08-14 16:00:53 -07006531
6532 @Override
6533 public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage) {
6534 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
6535 mApp, subId, callingPackage, "getNumberOfModemsWithSimultaneousDataConnections")) {
6536 return -1;
6537 }
6538
6539 final long identity = Binder.clearCallingIdentity();
6540 try {
6541 return mPhoneConfigurationManager.getNumberOfModemsWithSimultaneousDataConnections();
6542 } finally {
6543 Binder.restoreCallingIdentity(identity);
6544 }
6545 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07006546
6547 @Override
6548 public int getCdmaRoamingMode(int subId) {
6549 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6550 mApp, subId, "getCdmaRoamingMode");
6551
6552 final long identity = Binder.clearCallingIdentity();
6553 try {
6554 return (int) sendRequest(CMD_GET_CDMA_ROAMING_MODE, null /* argument */, subId);
6555 } finally {
6556 Binder.restoreCallingIdentity(identity);
6557 }
6558 }
6559
6560 @Override
6561 public boolean setCdmaRoamingMode(int subId, int mode) {
6562 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6563 mApp, subId, "setCdmaRoamingMode");
6564
6565 final long identity = Binder.clearCallingIdentity();
6566 try {
6567 return (boolean) sendRequest(CMD_SET_CDMA_ROAMING_MODE, mode, subId);
6568 } finally {
6569 Binder.restoreCallingIdentity(identity);
6570 }
6571 }
6572
6573 @Override
6574 public boolean setCdmaSubscriptionMode(int subId, int mode) {
6575 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6576 mApp, subId, "setCdmaSubscriptionMode");
6577
6578 final long identity = Binder.clearCallingIdentity();
6579 try {
6580 return (boolean) sendRequest(CMD_SET_CDMA_SUBSCRIPTION_MODE, mode, subId);
6581 } finally {
6582 Binder.restoreCallingIdentity(identity);
6583 }
6584 }
Makoto Onukida3bf792018-09-18 16:06:29 -07006585
6586 private void ensureUserRunning(int userId) {
6587 if (!mUserManager.isUserRunning(userId)) {
6588 throw new IllegalStateException("User " + userId + " does not exist or not running");
6589 }
6590 }
6591
6592 /**
6593 * Returns a list of SMS apps on a given user.
6594 *
6595 * Only the shell user (UID 2000 or 0) can call it.
6596 * Target user must be running.
6597 */
6598 @Override
6599 public String[] getSmsApps(int userId) {
6600 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getSmsApps");
6601 ensureUserRunning(userId);
6602
6603 final Collection<SmsApplicationData> apps =
6604 SmsApplication.getApplicationCollectionAsUser(mApp, userId);
6605
6606 String[] ret = new String[apps.size()];
6607 int i = 0;
6608 for (SmsApplicationData app : apps) {
6609 ret[i++] = app.mPackageName;
6610 }
6611 return ret;
6612 }
6613
6614 /**
6615 * Returns the default SMS app package name on a given user.
6616 *
6617 * Only the shell user (UID 2000 or 0) can call it.
6618 * Target user must be running.
6619 */
6620 @Override
6621 public String getDefaultSmsApp(int userId) {
6622 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getDefaultSmsApp");
6623 ensureUserRunning(userId);
6624
6625 final ComponentName cn = SmsApplication.getDefaultSmsApplicationAsUser(mApp,
6626 /* updateIfNeeded= */ true, userId);
6627 return cn == null ? null : cn.getPackageName();
6628 }
6629
6630 /**
6631 * Set a package as the default SMS app on a given user.
6632 *
6633 * Only the shell user (UID 2000 or 0) can call it.
6634 * Target user must be running.
6635 */
6636 @Override
6637 public void setDefaultSmsApp(int userId, String packageName) {
6638 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setDefaultSmsApp");
6639 ensureUserRunning(userId);
6640
6641 boolean found = false;
6642 for (String pkg : getSmsApps(userId)) {
6643 if (TextUtils.equals(packageName, pkg)) {
6644 found = true;
6645 break;
6646 }
6647 }
6648 if (!found) {
6649 throw new IllegalArgumentException("Package " + packageName + " is not an SMS app");
6650 }
6651
6652 SmsApplication.setDefaultApplicationAsUser(packageName, mApp, userId);
6653 }
sqianc5eccab2018-10-19 18:46:41 -07006654
6655 @Override
sqian8c685422019-02-22 15:55:18 -08006656 public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList(
sqianc5eccab2018-10-19 18:46:41 -07006657 String callingPackage) {
sqian11b7a0e2018-12-05 18:48:28 -08006658 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
sqian8c685422019-02-22 15:55:18 -08006659 mApp, getDefaultSubscription(), callingPackage, "getEmergencyNumberList")) {
sqian11b7a0e2018-12-05 18:48:28 -08006660 throw new SecurityException("Requires READ_PHONE_STATE permission.");
6661 }
6662 final long identity = Binder.clearCallingIdentity();
6663 try {
sqian854d44b2018-12-12 16:48:18 -08006664 Map<Integer, List<EmergencyNumber>> emergencyNumberListInternal = new HashMap<>();
6665 for (Phone phone: PhoneFactory.getPhones()) {
6666 if (phone.getEmergencyNumberTracker() != null
6667 && phone.getEmergencyNumberTracker().getEmergencyNumberList() != null) {
6668 emergencyNumberListInternal.put(
6669 phone.getSubId(),
6670 phone.getEmergencyNumberTracker().getEmergencyNumberList());
6671 }
sqian11b7a0e2018-12-05 18:48:28 -08006672 }
sqian854d44b2018-12-12 16:48:18 -08006673 return emergencyNumberListInternal;
sqian11b7a0e2018-12-05 18:48:28 -08006674 } finally {
6675 Binder.restoreCallingIdentity(identity);
6676 }
sqianc5eccab2018-10-19 18:46:41 -07006677 }
6678
6679 @Override
sqian8c685422019-02-22 15:55:18 -08006680 public boolean isEmergencyNumber(String number, boolean exactMatch) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006681 final Phone defaultPhone = getDefaultPhone();
sqian11b7a0e2018-12-05 18:48:28 -08006682 if (!exactMatch) {
6683 TelephonyPermissions
6684 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
sqian8c685422019-02-22 15:55:18 -08006685 mApp, defaultPhone.getSubId(), "isEmergencyNumber(Potential)");
sqian11b7a0e2018-12-05 18:48:28 -08006686 }
6687 final long identity = Binder.clearCallingIdentity();
6688 try {
sqian854d44b2018-12-12 16:48:18 -08006689 for (Phone phone: PhoneFactory.getPhones()) {
6690 if (phone.getEmergencyNumberTracker() != null
6691 && phone.getEmergencyNumberTracker() != null) {
6692 if (phone.getEmergencyNumberTracker().isEmergencyNumber(
6693 number, exactMatch)) {
6694 return true;
sqian11b7a0e2018-12-05 18:48:28 -08006695 }
6696 }
sqian11b7a0e2018-12-05 18:48:28 -08006697 }
6698 return false;
6699 } finally {
6700 Binder.restoreCallingIdentity(identity);
6701 }
6702 }
6703
sqianf4ca7ed2019-01-15 18:32:07 -08006704 /**
6705 * Update emergency number list for test mode.
6706 */
6707 @Override
6708 public void updateEmergencyNumberListTestMode(int action, EmergencyNumber num) {
6709 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
6710 "updateEmergencyNumberListTestMode");
6711
6712 final long identity = Binder.clearCallingIdentity();
6713 try {
6714 for (Phone phone: PhoneFactory.getPhones()) {
6715 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
6716 if (tracker != null) {
6717 tracker.executeEmergencyNumberTestModeCommand(action, num);
6718 }
6719 }
6720 } finally {
6721 Binder.restoreCallingIdentity(identity);
6722 }
6723 }
6724
6725 /**
6726 * Get the full emergency number list for test mode.
6727 */
6728 @Override
6729 public List<String> getEmergencyNumberListTestMode() {
6730 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
6731 "getEmergencyNumberListTestMode");
6732
6733 final long identity = Binder.clearCallingIdentity();
6734 try {
6735 Set<String> emergencyNumbers = new HashSet<>();
6736 for (Phone phone: PhoneFactory.getPhones()) {
6737 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
6738 if (tracker != null) {
6739 for (EmergencyNumber num : tracker.getEmergencyNumberList()) {
6740 emergencyNumbers.add(num.getNumber());
6741 }
6742 }
6743 }
6744 return new ArrayList<>(emergencyNumbers);
6745 } finally {
6746 Binder.restoreCallingIdentity(identity);
6747 }
6748 }
6749
chen xud6b45bd2018-10-30 22:27:10 -07006750 @Override
6751 public List<String> getCertsFromCarrierPrivilegeAccessRules(int subId) {
6752 enforceReadPrivilegedPermission("getCertsFromCarrierPrivilegeAccessRules");
6753 Phone phone = getPhone(subId);
6754 if (phone == null) {
6755 return null;
6756 }
6757 final long identity = Binder.clearCallingIdentity();
6758 try {
6759 UiccProfile profile = UiccController.getInstance()
6760 .getUiccProfileForPhone(phone.getPhoneId());
6761 if (profile != null) {
6762 return profile.getCertsFromCarrierPrivilegeAccessRules();
6763 }
6764 } finally {
6765 Binder.restoreCallingIdentity(identity);
6766 }
6767 return null;
6768 }
Malcolm Chen8e4ed912019-01-15 20:22:16 -08006769
6770 /**
6771 * Enable or disable a modem stack.
6772 */
6773 @Override
6774 public boolean enableModemForSlot(int slotIndex, boolean enable) {
6775 enforceModifyPermission();
6776
6777 final long identity = Binder.clearCallingIdentity();
6778 try {
6779 Phone phone = PhoneFactory.getPhone(slotIndex);
6780 if (phone == null) {
6781 return false;
6782 } else {
6783 return (Boolean) sendRequest(CMD_REQUEST_ENABLE_MODEM, enable, phone, null);
6784 }
6785 } finally {
6786 Binder.restoreCallingIdentity(identity);
6787 }
6788 }
Michelecea4cf22018-12-21 15:00:11 -08006789
Malcolm Chen4bcd9822019-03-27 18:34:05 -07006790 /**
6791 * Whether a modem stack is enabled or not.
6792 */
6793 @Override
6794 public boolean isModemEnabledForSlot(int slotIndex, String callingPackage) {
6795 Phone phone = PhoneFactory.getPhone(slotIndex);
6796 if (phone == null) return false;
6797
6798 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
6799 mApp, phone.getSubId(), callingPackage, "isModemEnabledForSlot")) {
6800 throw new SecurityException("Requires READ_PHONE_STATE permission.");
6801 }
6802
6803 final long identity = Binder.clearCallingIdentity();
6804 try {
6805 return PhoneConfigurationManager.getInstance().getPhoneStatus(phone);
6806 } finally {
6807 Binder.restoreCallingIdentity(identity);
6808 }
6809 }
6810
Michelecea4cf22018-12-21 15:00:11 -08006811 @Override
Michele0ea7d782019-03-19 14:58:42 -07006812 public void setMultiSimCarrierRestriction(boolean isMultiSimCarrierRestricted) {
Michelecea4cf22018-12-21 15:00:11 -08006813 enforceModifyPermission();
6814
6815 final long identity = Binder.clearCallingIdentity();
6816 try {
6817 mTelephonySharedPreferences.edit()
Michele0ea7d782019-03-19 14:58:42 -07006818 .putBoolean(PREF_MULTI_SIM_RESTRICTED, isMultiSimCarrierRestricted)
Michelecea4cf22018-12-21 15:00:11 -08006819 .commit();
6820 } finally {
6821 Binder.restoreCallingIdentity(identity);
6822 }
6823 }
6824
6825 @Override
Michele0ea7d782019-03-19 14:58:42 -07006826 @TelephonyManager.IsMultiSimSupportedResult
6827 public int isMultiSimSupported(String callingPackage) {
Michele4245e952019-02-04 11:36:23 -08006828 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp,
Michele0ea7d782019-03-19 14:58:42 -07006829 getDefaultPhone().getSubId(), callingPackage, "isMultiSimSupported")) {
6830 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele4245e952019-02-04 11:36:23 -08006831 }
Michelecea4cf22018-12-21 15:00:11 -08006832
6833 final long identity = Binder.clearCallingIdentity();
6834 try {
Michele0ea7d782019-03-19 14:58:42 -07006835 return isMultiSimSupportedInternal();
Michelecea4cf22018-12-21 15:00:11 -08006836 } finally {
6837 Binder.restoreCallingIdentity(identity);
6838 }
6839 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08006840
Michele0ea7d782019-03-19 14:58:42 -07006841 @TelephonyManager.IsMultiSimSupportedResult
6842 private int isMultiSimSupportedInternal() {
Michele30b57b22019-03-01 12:01:14 -08006843 // If the device has less than 2 SIM cards, indicate that multisim is restricted.
6844 int numPhysicalSlots = UiccController.getInstance().getUiccSlots().length;
6845 if (numPhysicalSlots < 2) {
Michele0ea7d782019-03-19 14:58:42 -07006846 loge("isMultiSimSupportedInternal: requires at least 2 cards");
6847 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -08006848 }
6849 // Check if the hardware supports multisim functionality. If usage of multisim is not
6850 // supported by the modem, indicate that it is restricted.
6851 PhoneCapability staticCapability =
6852 mPhoneConfigurationManager.getStaticPhoneCapability();
6853 if (staticCapability == null) {
Michele0ea7d782019-03-19 14:58:42 -07006854 loge("isMultiSimSupportedInternal: no static configuration available");
6855 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -08006856 }
6857 if (staticCapability.logicalModemList.size() < 2) {
Michele0ea7d782019-03-19 14:58:42 -07006858 loge("isMultiSimSupportedInternal: maximum number of modem is < 2");
6859 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -08006860 }
6861 // Check if support of multiple SIMs is restricted by carrier
6862 if (mTelephonySharedPreferences.getBoolean(PREF_MULTI_SIM_RESTRICTED, false)) {
Michele0ea7d782019-03-19 14:58:42 -07006863 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_CARRIER;
Michele30b57b22019-03-01 12:01:14 -08006864 }
6865
Michele0ea7d782019-03-19 14:58:42 -07006866 return TelephonyManager.MULTISIM_ALLOWED;
Michele30b57b22019-03-01 12:01:14 -08006867 }
6868
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08006869 /**
6870 * Switch configs to enable multi-sim or switch back to single-sim
Nazanin Bakhshi17318782019-03-01 11:56:08 -08006871 * Note: Switch from multi-sim to single-sim is only possible with MODIFY_PHONE_STATE
6872 * permission, but the other way around is possible with either MODIFY_PHONE_STATE
6873 * or carrier privileges
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08006874 * @param numOfSims number of active sims we want to switch to
6875 */
6876 @Override
6877 public void switchMultiSimConfig(int numOfSims) {
Nazanin Bakhshi17318782019-03-01 11:56:08 -08006878 if (numOfSims == 1) {
6879 enforceModifyPermission();
6880 } else {
6881 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6882 mApp, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, "switchMultiSimConfig");
6883 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08006884 final long identity = Binder.clearCallingIdentity();
Michele30b57b22019-03-01 12:01:14 -08006885
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08006886 try {
Michele30b57b22019-03-01 12:01:14 -08006887 //only proceed if multi-sim is not restricted
Michele0ea7d782019-03-19 14:58:42 -07006888 if (isMultiSimSupportedInternal() != TelephonyManager.MULTISIM_ALLOWED) {
Michele30b57b22019-03-01 12:01:14 -08006889 loge("switchMultiSimConfig not possible. It is restricted or not supported.");
6890 return;
6891 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08006892 mPhoneConfigurationManager.switchMultiSimConfig(numOfSims);
6893 } finally {
6894 Binder.restoreCallingIdentity(identity);
6895 }
6896 }
6897
6898 /**
chen xub4baa772019-04-03 10:23:41 -07006899 * Get whether making changes to modem configurations will trigger reboot.
6900 * Return value defaults to true.
Nazanin Bakhshi5fe5ef22019-01-30 10:52:09 -08006901 */
6902 @Override
chen xub4baa772019-04-03 10:23:41 -07006903 public boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage) {
6904 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
6905 mApp, subId, callingPackage, "doesSwitchMultiSimConfigTriggerReboot")) {
6906 return false;
6907 }
Nazanin Bakhshi5fe5ef22019-01-30 10:52:09 -08006908 final long identity = Binder.clearCallingIdentity();
6909 try {
6910 return mPhoneConfigurationManager.isRebootRequiredForModemConfigChange();
6911 } finally {
6912 Binder.restoreCallingIdentity(identity);
6913 }
6914 }
6915
Nathan Harold29f5f052019-02-15 13:41:57 -08006916 private void updateModemStateMetrics() {
6917 TelephonyMetrics metrics = TelephonyMetrics.getInstance();
6918 // TODO: check the state for each modem if the api is ready.
6919 metrics.updateEnabledModemBitmap((1 << TelephonyManager.from(mApp).getPhoneCount()) - 1);
6920 }
6921
Pengquan Meng3889a572019-01-23 11:16:29 -08006922 @Override
6923 public int[] getSlotsMapping() {
6924 enforceReadPrivilegedPermission("getSlotsMapping");
6925
6926 final long identity = Binder.clearCallingIdentity();
6927 try {
6928 int phoneCount = TelephonyManager.getDefault().getPhoneCount();
6929 // All logical slots should have a mapping to a physical slot.
6930 int[] logicalSlotsMapping = new int[phoneCount];
6931 UiccSlotInfo[] slotInfos = getUiccSlotsInfo();
6932 for (int i = 0; i < slotInfos.length; i++) {
6933 if (SubscriptionManager.isValidPhoneId(slotInfos[i].getLogicalSlotIdx())) {
6934 logicalSlotsMapping[slotInfos[i].getLogicalSlotIdx()] = i;
6935 }
6936 }
6937 return logicalSlotsMapping;
6938 } finally {
6939 Binder.restoreCallingIdentity(identity);
6940 }
6941 }
Nathan Harold48d6fd52019-02-06 19:01:40 -08006942
6943 /**
6944 * Get the IRadio HAL Version
6945 */
6946 @Override
6947 public int getRadioHalVersion() {
6948 Phone phone = getDefaultPhone();
6949 if (phone == null) return -1;
6950 HalVersion hv = phone.getHalVersion();
6951 if (hv.equals(HalVersion.UNKNOWN)) return -1;
6952 return hv.major * 100 + hv.minor;
6953 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07006954}