blob: e4bc48533625019d9a9108e268cdfaadd85b2b27 [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;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070027import android.content.Context;
28import android.content.Intent;
Derek Tan97ebb422014-09-05 16:55:38 -070029import android.content.SharedPreferences;
Nathan Harold31d7ff32018-10-15 20:20:30 -070030import android.content.pm.ApplicationInfo;
Derek Tan740e1672017-06-27 14:56:27 -070031import android.content.pm.ComponentInfo;
Amith Yamasani6e118872016-02-19 12:53:51 -080032import android.content.pm.PackageInfo;
Shishir Agrawal60f9c952014-06-23 12:00:43 -070033import android.content.pm.PackageManager;
Jack Yu84291ec2017-05-26 16:07:50 -070034import android.net.NetworkStats;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070035import android.net.Uri;
36import android.os.AsyncResult;
37import android.os.Binder;
Hall Liuf19c44f2018-11-27 14:38:17 -080038import android.os.Build;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070039import android.os.Bundle;
40import android.os.Handler;
yinxu504e1392017-04-12 16:03:22 -070041import android.os.IBinder;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070042import android.os.Looper;
43import android.os.Message;
yinxu504e1392017-04-12 16:03:22 -070044import android.os.Messenger;
Tyler Gunn65d45c22017-06-05 11:22:26 -070045import android.os.PersistableBundle;
Brad Ebinger5f64b052017-12-14 14:26:15 -080046import android.os.RemoteException;
Adam Lesinski903a54c2016-04-11 14:49:52 -070047import android.os.ResultReceiver;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070048import android.os.ServiceManager;
Brad Ebingerdac2f002018-04-03 15:17:52 -070049import android.os.ShellCallback;
Pengquan Meng85728fb2018-03-12 16:31:21 -070050import android.os.SystemProperties;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070051import android.os.UserHandle;
Stuart Scott981d8582015-04-21 14:09:50 -070052import android.os.UserManager;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070053import android.os.WorkSource;
Derek Tan97ebb422014-09-05 16:55:38 -070054import android.preference.PreferenceManager;
Ihab Awadf2177b72013-11-25 13:33:23 -080055import android.provider.Settings;
Santos Cordon7a1885b2015-02-03 11:15:19 -080056import android.telecom.PhoneAccount;
Nancy Chen31f9ba12016-01-06 11:42:12 -080057import android.telecom.PhoneAccountHandle;
Andrew Lee9431b832015-03-09 18:46:45 -070058import android.telecom.TelecomManager;
Junda Liu12f7d802015-05-01 12:06:44 -070059import android.telephony.CarrierConfigManager;
Michele Berionne482f8202018-11-27 18:57:59 -080060import android.telephony.CarrierRestrictionRules;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070061import android.telephony.CellInfo;
Nathan Haroldf180aac2018-06-01 18:43:55 -070062import android.telephony.CellInfoGsm;
63import android.telephony.CellInfoWcdma;
Nathan Harold3ff88932018-08-14 10:19:49 -070064import android.telephony.CellLocation;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070065import android.telephony.ClientRequestStats;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -070066import android.telephony.ICellInfoCallback;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -070067import android.telephony.IccOpenLogicalChannelResponse;
Hall Liu1aa510f2017-11-22 17:40:08 -080068import android.telephony.LocationAccessPolicy;
Ta-wei Yen87c49842016-05-13 21:19:52 -070069import android.telephony.ModemActivityInfo;
Jake Hambye994d462014-02-03 13:10:13 -080070import android.telephony.NeighboringCellInfo;
yinxu504e1392017-04-12 16:03:22 -070071import android.telephony.NetworkScanRequest;
Michele4245e952019-02-04 11:36:23 -080072import android.telephony.PhoneCapability;
Hall Liud892bec2018-11-30 14:51:45 -080073import android.telephony.PhoneNumberRange;
Wink Saville5d475dd2014-10-17 15:00:58 -070074import android.telephony.RadioAccessFamily;
Tyler Gunn65d45c22017-06-05 11:22:26 -070075import android.telephony.Rlog;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070076import android.telephony.ServiceState;
Nathan Harold46b42aa2017-03-10 19:38:22 -080077import android.telephony.SignalStrength;
Jack Yu84291ec2017-05-26 16:07:50 -070078import android.telephony.SmsManager;
Wink Saville0f3b5fc2014-11-11 08:40:49 -080079import android.telephony.SubscriptionInfo;
Jeff Sharkey85190e62014-12-05 09:40:12 -080080import android.telephony.SubscriptionManager;
Sanket Padawe99ef1e32016-05-18 16:12:33 -070081import android.telephony.TelephonyHistogram;
Ta-wei Yenb6929602016-05-24 15:48:27 -070082import android.telephony.TelephonyManager;
Jordan Liu5aa07002018-12-18 15:44:48 -080083import android.telephony.UiccCardInfo;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +000084import android.telephony.UiccSlotInfo;
Tyler Gunn65d45c22017-06-05 11:22:26 -070085import android.telephony.UssdResponse;
Ta-wei Yenb6929602016-05-24 15:48:27 -070086import android.telephony.VisualVoicemailSmsFilterSettings;
Nathan Harold3ff88932018-08-14 10:19:49 -070087import android.telephony.cdma.CdmaCellLocation;
Jack Yub5d8f642018-11-26 11:20:48 -080088import android.telephony.data.ApnSetting;
89import android.telephony.emergency.EmergencyNumber;
Nathan Harold3ff88932018-08-14 10:19:49 -070090import android.telephony.gsm.GsmCellLocation;
Brad Ebinger1c8542e2019-01-14 13:43:14 -080091import android.telephony.ims.ProvisioningManager;
Brad Ebinger35c841c2018-10-01 10:40:55 -070092import android.telephony.ims.aidl.IImsCapabilityCallback;
Brad Ebinger22bc3e42018-01-16 09:39:35 -080093import android.telephony.ims.aidl.IImsConfig;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -070094import android.telephony.ims.aidl.IImsConfigCallback;
Brad Ebinger22bc3e42018-01-16 09:39:35 -080095import android.telephony.ims.aidl.IImsMmTelFeature;
96import android.telephony.ims.aidl.IImsRcsFeature;
97import android.telephony.ims.aidl.IImsRegistration;
Brad Ebinger35c841c2018-10-01 10:40:55 -070098import android.telephony.ims.aidl.IImsRegistrationCallback;
Brad Ebinger1c8542e2019-01-14 13:43:14 -080099import android.telephony.ims.feature.MmTelFeature;
100import android.telephony.ims.stub.ImsConfigImplBase;
Brad Ebinger1f2b5082018-02-08 16:11:32 -0800101import android.telephony.ims.stub.ImsRegistrationImplBase;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700102import android.text.TextUtils;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800103import android.util.ArraySet;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700104import android.util.Log;
Jake Hambye994d462014-02-03 13:10:13 -0800105import android.util.Pair;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800106import android.util.Slog;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800107
Brad Ebinger35c841c2018-10-01 10:40:55 -0700108import com.android.ims.ImsException;
Andrew Lee312e8172014-10-23 17:01:36 -0700109import com.android.ims.ImsManager;
Brad Ebinger34bef922017-11-09 10:27:08 -0800110import com.android.ims.internal.IImsServiceFeatureCallback;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700111import com.android.internal.telephony.CallManager;
Tyler Gunn52dcf772017-04-26 11:30:31 -0700112import com.android.internal.telephony.CallStateException;
pkanwar79ec0542017-07-31 14:10:01 -0700113import com.android.internal.telephony.CarrierInfoManager;
chen xu651eec72018-11-11 19:03:44 -0800114import com.android.internal.telephony.CarrierResolver;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700115import com.android.internal.telephony.CellNetworkScanResult;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700116import com.android.internal.telephony.CommandException;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700117import com.android.internal.telephony.DefaultPhoneNotifier;
Nathan Harold48d6fd52019-02-06 19:01:40 -0800118import com.android.internal.telephony.HalVersion;
Hall Liud892bec2018-11-30 14:51:45 -0800119import com.android.internal.telephony.INumberVerificationCallback;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700120import com.android.internal.telephony.ITelephony;
Jake Hambye994d462014-02-03 13:10:13 -0800121import com.android.internal.telephony.IccCard;
Jack Yu5f7092c2018-04-13 14:05:37 -0700122import com.android.internal.telephony.LocaleTracker;
Narayan Kamath1c496c22015-04-16 14:40:19 +0100123import com.android.internal.telephony.MccTable;
yinxub1bed742017-04-17 11:45:04 -0700124import com.android.internal.telephony.NetworkScanRequestTracker;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700125import com.android.internal.telephony.OperatorInfo;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700126import com.android.internal.telephony.Phone;
Malcolm Chen2c63d402018-08-14 16:00:53 -0700127import com.android.internal.telephony.PhoneConfigurationManager;
Nathan Harolda667c152016-12-14 11:27:20 -0800128import com.android.internal.telephony.PhoneConstantConversions;
Ta-wei Yen87c49842016-05-13 21:19:52 -0700129import com.android.internal.telephony.PhoneConstants;
Wink Saville36469e72014-06-11 15:17:00 -0700130import com.android.internal.telephony.PhoneFactory;
Wink Saville5d475dd2014-10-17 15:00:58 -0700131import com.android.internal.telephony.ProxyController;
Sanket Padawe99ef1e32016-05-18 16:12:33 -0700132import com.android.internal.telephony.RIL;
Svet Ganovb320e182015-04-16 12:30:10 -0700133import com.android.internal.telephony.RILConstants;
Jack Yu5f7092c2018-04-13 14:05:37 -0700134import com.android.internal.telephony.ServiceStateTracker;
Makoto Onukida3bf792018-09-18 16:06:29 -0700135import com.android.internal.telephony.SmsApplication;
136import com.android.internal.telephony.SmsApplication.SmsApplicationData;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800137import com.android.internal.telephony.SubscriptionController;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800138import com.android.internal.telephony.TelephonyPermissions;
sqianf4ca7ed2019-01-15 18:32:07 -0800139import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Derek Tan740e1672017-06-27 14:56:27 -0700140import com.android.internal.telephony.euicc.EuiccConnector;
Pengquan Meng6c2dc9f2019-02-06 11:12:53 -0800141import com.android.internal.telephony.metrics.TelephonyMetrics;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700142import com.android.internal.telephony.uicc.IccIoResult;
143import com.android.internal.telephony.uicc.IccUtils;
Nathan Haroldb3014052017-01-25 15:57:32 -0800144import com.android.internal.telephony.uicc.SIMRecords;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700145import com.android.internal.telephony.uicc.UiccCard;
Nathan Haroldb3014052017-01-25 15:57:32 -0800146import com.android.internal.telephony.uicc.UiccCardApplication;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700147import com.android.internal.telephony.uicc.UiccController;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800148import com.android.internal.telephony.uicc.UiccProfile;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000149import com.android.internal.telephony.uicc.UiccSlot;
fionaxu7ed723d2017-05-30 18:58:54 -0700150import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
Jake Hambye994d462014-02-03 13:10:13 -0800151import com.android.internal.util.HexDump;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700152import com.android.phone.vvm.PhoneAccountHandleConverter;
Ta-wei Yen527a9c02017-01-06 15:29:25 -0800153import com.android.phone.vvm.RemoteVvmTaskManager;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700154import com.android.phone.vvm.VisualVoicemailSettingsUtil;
Ta-wei Yenc8905312017-03-28 11:14:45 -0700155import com.android.phone.vvm.VisualVoicemailSmsFilterConfig;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800156
Ta-wei Yenc236d6b2016-06-21 13:33:12 -0700157import java.io.FileDescriptor;
158import java.io.PrintWriter;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800159import java.nio.charset.StandardCharsets;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700160import java.util.ArrayList;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800161import java.util.Arrays;
Makoto Onukida3bf792018-09-18 16:06:29 -0700162import java.util.Collection;
sqian11b7a0e2018-12-05 18:48:28 -0800163import java.util.HashMap;
sqianf4ca7ed2019-01-15 18:32:07 -0800164import java.util.HashSet;
Jake Hambye994d462014-02-03 13:10:13 -0800165import java.util.List;
Narayan Kamath1c496c22015-04-16 14:40:19 +0100166import java.util.Locale;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800167import java.util.Map;
sqianf4ca7ed2019-01-15 18:32:07 -0800168import java.util.Set;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700169
170/**
171 * Implementation of the ITelephony interface.
172 */
Santos Cordon117fee72014-05-16 17:56:12 -0700173public class PhoneInterfaceManager extends ITelephony.Stub {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700174 private static final String LOG_TAG = "PhoneInterfaceManager";
175 private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
176 private static final boolean DBG_LOC = false;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800177 private static final boolean DBG_MERGE = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700178
179 // Message codes used with mMainThreadHandler
180 private static final int CMD_HANDLE_PIN_MMI = 1;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700181 private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7;
182 private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700183 private static final int CMD_OPEN_CHANNEL = 9;
184 private static final int EVENT_OPEN_CHANNEL_DONE = 10;
185 private static final int CMD_CLOSE_CHANNEL = 11;
186 private static final int EVENT_CLOSE_CHANNEL_DONE = 12;
Jake Hambye994d462014-02-03 13:10:13 -0800187 private static final int CMD_NV_READ_ITEM = 13;
188 private static final int EVENT_NV_READ_ITEM_DONE = 14;
189 private static final int CMD_NV_WRITE_ITEM = 15;
190 private static final int EVENT_NV_WRITE_ITEM_DONE = 16;
191 private static final int CMD_NV_WRITE_CDMA_PRL = 17;
192 private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18;
chen xu6dac5ab2018-10-26 17:39:23 -0700193 private static final int CMD_RESET_MODEM_CONFIG = 19;
194 private static final int EVENT_RESET_MODEM_CONFIG_DONE = 20;
Jake Hamby7c27be32014-03-03 13:25:59 -0800195 private static final int CMD_GET_PREFERRED_NETWORK_TYPE = 21;
196 private static final int EVENT_GET_PREFERRED_NETWORK_TYPE_DONE = 22;
197 private static final int CMD_SET_PREFERRED_NETWORK_TYPE = 23;
198 private static final int EVENT_SET_PREFERRED_NETWORK_TYPE_DONE = 24;
Sailesh Nepal35b59452014-03-06 09:26:56 -0800199 private static final int CMD_SEND_ENVELOPE = 25;
200 private static final int EVENT_SEND_ENVELOPE_DONE = 26;
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000201 private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27;
202 private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28;
Derek Tan6b088ee2014-09-05 14:15:18 -0700203 private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29;
204 private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30;
205 private static final int CMD_EXCHANGE_SIM_IO = 31;
206 private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800207 private static final int CMD_SET_VOICEMAIL_NUMBER = 33;
208 private static final int EVENT_SET_VOICEMAIL_NUMBER_DONE = 34;
Stuart Scott54788802015-03-30 13:18:01 -0700209 private static final int CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC = 35;
210 private static final int EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE = 36;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700211 private static final int CMD_GET_MODEM_ACTIVITY_INFO = 37;
212 private static final int EVENT_GET_MODEM_ACTIVITY_INFO_DONE = 38;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700213 private static final int CMD_PERFORM_NETWORK_SCAN = 39;
214 private static final int EVENT_PERFORM_NETWORK_SCAN_DONE = 40;
215 private static final int CMD_SET_NETWORK_SELECTION_MODE_MANUAL = 41;
216 private static final int EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE = 42;
Meng Wang1a7c35a2016-05-05 20:56:15 -0700217 private static final int CMD_SET_ALLOWED_CARRIERS = 43;
218 private static final int EVENT_SET_ALLOWED_CARRIERS_DONE = 44;
219 private static final int CMD_GET_ALLOWED_CARRIERS = 45;
220 private static final int EVENT_GET_ALLOWED_CARRIERS_DONE = 46;
pkanwar32d516d2016-10-14 19:37:38 -0700221 private static final int CMD_HANDLE_USSD_REQUEST = 47;
Nathan Haroldb3014052017-01-25 15:57:32 -0800222 private static final int CMD_GET_FORBIDDEN_PLMNS = 48;
223 private static final int EVENT_GET_FORBIDDEN_PLMNS_DONE = 49;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000224 private static final int CMD_SWITCH_SLOTS = 50;
225 private static final int EVENT_SWITCH_SLOTS_DONE = 51;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700226 private static final int CMD_GET_NETWORK_SELECTION_MODE = 52;
227 private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 53;
228 private static final int CMD_GET_CDMA_ROAMING_MODE = 54;
229 private static final int EVENT_GET_CDMA_ROAMING_MODE_DONE = 55;
230 private static final int CMD_SET_CDMA_ROAMING_MODE = 56;
231 private static final int EVENT_SET_CDMA_ROAMING_MODE_DONE = 57;
232 private static final int CMD_SET_CDMA_SUBSCRIPTION_MODE = 58;
233 private static final int EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE = 59;
Nathan Harold3ff88932018-08-14 10:19:49 -0700234 private static final int CMD_GET_ALL_CELL_INFO = 60;
235 private static final int EVENT_GET_ALL_CELL_INFO_DONE = 61;
236 private static final int CMD_GET_CELL_LOCATION = 62;
237 private static final int EVENT_GET_CELL_LOCATION_DONE = 63;
chen xu6dac5ab2018-10-26 17:39:23 -0700238 private static final int CMD_MODEM_REBOOT = 64;
239 private static final int EVENT_CMD_MODEM_REBOOT_DONE = 65;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -0700240 private static final int CMD_REQUEST_CELL_INFO_UPDATE = 66;
241 private static final int EVENT_REQUEST_CELL_INFO_UPDATE_DONE = 67;
Malcolm Chen8e4ed912019-01-15 20:22:16 -0800242 private static final int CMD_REQUEST_ENABLE_MODEM = 68;
243 private static final int EVENT_ENABLE_MODEM_DONE = 69;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700244
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -0800245 // Parameters of select command.
246 private static final int SELECT_COMMAND = 0xA4;
247 private static final int SELECT_P1 = 0x04;
248 private static final int SELECT_P2 = 0;
249 private static final int SELECT_P3 = 0x10;
250
Pengquan Meng85728fb2018-03-12 16:31:21 -0700251 private static final String DEFAULT_NETWORK_MODE_PROPERTY_NAME = "ro.telephony.default_network";
252 private static final String DEFAULT_DATA_ROAMING_PROPERTY_NAME = "ro.com.android.dataroaming";
253 private static final String DEFAULT_MOBILE_DATA_PROPERTY_NAME = "ro.com.android.mobiledata";
254
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700255 /** The singleton instance. */
256 private static PhoneInterfaceManager sInstance;
257
Wink Saville3ab207e2014-11-20 13:07:20 -0800258 private PhoneGlobals mApp;
Wink Saville3ab207e2014-11-20 13:07:20 -0800259 private CallManager mCM;
Stuart Scott981d8582015-04-21 14:09:50 -0700260 private UserManager mUserManager;
Wink Saville3ab207e2014-11-20 13:07:20 -0800261 private AppOpsManager mAppOps;
262 private MainThreadHandler mMainThreadHandler;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800263 private SubscriptionController mSubscriptionController;
Wink Saville3ab207e2014-11-20 13:07:20 -0800264 private SharedPreferences mTelephonySharedPreferences;
Malcolm Chen2c63d402018-08-14 16:00:53 -0700265 private PhoneConfigurationManager mPhoneConfigurationManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700266
Derek Tan97ebb422014-09-05 16:55:38 -0700267 private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
268 private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
Jeff Sharkey85190e62014-12-05 09:40:12 -0800269 private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800270 private static final String PREF_PROVISION_IMS_MMTEL_PREFIX = "provision_ims_mmtel_";
Derek Tan89e89d42014-07-08 17:00:10 -0700271
Michelecea4cf22018-12-21 15:00:11 -0800272 // String to store multi SIM allowed
273 private static final String PREF_MULTI_SIM_RESTRICTED = "multisim_restricted";
274
Derek Tan740e1672017-06-27 14:56:27 -0700275 // The AID of ISD-R.
276 private static final String ISDR_AID = "A0000005591010FFFFFFFF8900000100";
277
yinxub1bed742017-04-17 11:45:04 -0700278 private NetworkScanRequestTracker mNetworkScanRequestTracker;
279
David Kelly5e06a7f2018-03-12 14:10:59 +0000280 private static final int TYPE_ALLOCATION_CODE_LENGTH = 8;
281 private static final int MANUFACTURER_CODE_LENGTH = 8;
282
Derek Tan89e89d42014-07-08 17:00:10 -0700283 /**
Shishir Agrawal566b7612013-10-28 14:41:00 -0700284 * A request object to use for transmitting data to an ICC.
285 */
286 private static final class IccAPDUArgument {
287 public int channel, cla, command, p1, p2, p3;
288 public String data;
289
290 public IccAPDUArgument(int channel, int cla, int command,
291 int p1, int p2, int p3, String data) {
292 this.channel = channel;
293 this.cla = cla;
294 this.command = command;
295 this.p1 = p1;
296 this.p2 = p2;
297 this.p3 = p3;
298 this.data = data;
299 }
300 }
301
302 /**
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700303 * A request object to use for transmitting data to an ICC.
304 */
305 private static final class ManualNetworkSelectionArgument {
306 public OperatorInfo operatorInfo;
307 public boolean persistSelection;
308
309 public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) {
310 this.operatorInfo = operatorInfo;
311 this.persistSelection = persistSelection;
312 }
313 }
314
315 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700316 * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
317 * request after sending. The main thread will notify the request when it is complete.
318 */
319 private static final class MainThreadRequest {
320 /** The argument to use for the request */
321 public Object argument;
322 /** The result of the request that is run on the main thread */
323 public Object result;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800324 // The subscriber id that this request applies to. Defaults to
325 // SubscriptionManager.INVALID_SUBSCRIPTION_ID
326 public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700327
Nathan Harold92bed182018-10-12 18:16:49 -0700328 // In cases where subId is unavailable, the caller needs to specify the phone.
329 public Phone phone;
330
vagdeviaf9a5b92018-08-15 16:01:53 -0700331 public WorkSource workSource;
332
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700333 public MainThreadRequest(Object argument) {
334 this.argument = argument;
335 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800336
Nathan Harold92bed182018-10-12 18:16:49 -0700337 MainThreadRequest(Object argument, Phone phone, WorkSource workSource) {
338 this.argument = argument;
339 if (phone != null) {
340 this.phone = phone;
341 }
342 this.workSource = workSource;
343 }
344
vagdeviaf9a5b92018-08-15 16:01:53 -0700345 MainThreadRequest(Object argument, Integer subId, WorkSource workSource) {
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800346 this.argument = argument;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800347 if (subId != null) {
348 this.subId = subId;
349 }
vagdeviaf9a5b92018-08-15 16:01:53 -0700350 this.workSource = workSource;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800351 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700352 }
353
Sailesh Nepalcc0375f2013-11-13 09:15:18 -0800354 private static final class IncomingThirdPartyCallArgs {
355 public final ComponentName component;
356 public final String callId;
357 public final String callerDisplayName;
358
359 public IncomingThirdPartyCallArgs(ComponentName component, String callId,
360 String callerDisplayName) {
361 this.component = component;
362 this.callId = callId;
363 this.callerDisplayName = callerDisplayName;
364 }
365 }
366
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700367 /**
368 * A handler that processes messages on the main thread in the phone process. Since many
369 * of the Phone calls are not thread safe this is needed to shuttle the requests from the
370 * inbound binder threads to the main thread in the phone process. The Binder thread
371 * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
372 * on, which will be notified when the operation completes and will contain the result of the
373 * request.
374 *
375 * <p>If a MainThreadRequest object is provided in the msg.obj field,
376 * note that request.result must be set to something non-null for the calling thread to
377 * unblock.
378 */
379 private final class MainThreadHandler extends Handler {
380 @Override
381 public void handleMessage(Message msg) {
382 MainThreadRequest request;
383 Message onCompleted;
384 AsyncResult ar;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800385 UiccCard uiccCard;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700386 IccAPDUArgument iccArgument;
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800387 final Phone defaultPhone = getDefaultPhone();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700388
389 switch (msg.what) {
Pengquan Menga1bb6272018-09-06 09:59:22 -0700390 case CMD_HANDLE_USSD_REQUEST: {
391 request = (MainThreadRequest) msg.obj;
392 final Phone phone = getPhoneFromRequest(request);
393 Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
394 String ussdRequest = ussdObject.first;
395 ResultReceiver wrappedCallback = ussdObject.second;
Tyler Gunn65d45c22017-06-05 11:22:26 -0700396
Pengquan Menga1bb6272018-09-06 09:59:22 -0700397 if (!isUssdApiAllowed(request.subId)) {
398 // Carrier does not support use of this API, return failure.
399 Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
400 UssdResponse response = new UssdResponse(ussdRequest, null);
401 Bundle returnData = new Bundle();
402 returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
403 wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
Tyler Gunn65d45c22017-06-05 11:22:26 -0700404
Pengquan Menga1bb6272018-09-06 09:59:22 -0700405 request.result = true;
406 notifyRequester(request);
407 return;
408 }
Tyler Gunn65d45c22017-06-05 11:22:26 -0700409
Pengquan Menga1bb6272018-09-06 09:59:22 -0700410 try {
411 request.result = phone != null
412 ? phone.handleUssdRequest(ussdRequest, wrappedCallback) : false;
413 } catch (CallStateException cse) {
414 request.result = false;
415 }
416 // Wake up the requesting thread
417 notifyRequester(request);
418 break;
pkanwar32d516d2016-10-14 19:37:38 -0700419 }
420
Yorke Lee716f67e2015-06-17 15:39:16 -0700421 case CMD_HANDLE_PIN_MMI: {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700422 request = (MainThreadRequest) msg.obj;
Yorke Lee716f67e2015-06-17 15:39:16 -0700423 final Phone phone = getPhoneFromRequest(request);
424 request.result = phone != null ?
425 getPhoneFromRequest(request).handlePinMmi((String) request.argument)
426 : false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700427 // Wake up the requesting thread
Pengquan Menga1bb6272018-09-06 09:59:22 -0700428 notifyRequester(request);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700429 break;
Yorke Lee716f67e2015-06-17 15:39:16 -0700430 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700431
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700432 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700433 request = (MainThreadRequest) msg.obj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700434 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800435 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700436 if (uiccCard == null) {
437 loge("iccTransmitApduLogicalChannel: No UICC");
438 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700439 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700440 } else {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700441 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
442 request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700443 uiccCard.iccTransmitApduLogicalChannel(
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700444 iccArgument.channel, iccArgument.cla, iccArgument.command,
445 iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data,
Shishir Agrawal566b7612013-10-28 14:41:00 -0700446 onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700447 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700448 break;
449
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700450 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700451 ar = (AsyncResult) msg.obj;
452 request = (MainThreadRequest) ar.userObj;
453 if (ar.exception == null && ar.result != null) {
454 request.result = ar.result;
455 } else {
456 request.result = new IccIoResult(0x6F, 0, (byte[])null);
457 if (ar.result == null) {
458 loge("iccTransmitApduLogicalChannel: Empty response");
Jake Hambye994d462014-02-03 13:10:13 -0800459 } else if (ar.exception instanceof CommandException) {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700460 loge("iccTransmitApduLogicalChannel: CommandException: " +
Jake Hambye994d462014-02-03 13:10:13 -0800461 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700462 } else {
463 loge("iccTransmitApduLogicalChannel: Unknown exception");
464 }
465 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700466 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700467 break;
468
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700469 case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
470 request = (MainThreadRequest) msg.obj;
471 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800472 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700473 if (uiccCard == null) {
474 loge("iccTransmitApduBasicChannel: No UICC");
475 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700476 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700477 } else {
478 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
479 request);
480 uiccCard.iccTransmitApduBasicChannel(
481 iccArgument.cla, iccArgument.command, iccArgument.p1, iccArgument.p2,
482 iccArgument.p3, iccArgument.data, onCompleted);
483 }
484 break;
485
486 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
487 ar = (AsyncResult) msg.obj;
488 request = (MainThreadRequest) ar.userObj;
489 if (ar.exception == null && ar.result != null) {
490 request.result = ar.result;
491 } else {
492 request.result = new IccIoResult(0x6F, 0, (byte[])null);
493 if (ar.result == null) {
494 loge("iccTransmitApduBasicChannel: Empty response");
495 } else if (ar.exception instanceof CommandException) {
496 loge("iccTransmitApduBasicChannel: CommandException: " +
497 ar.exception);
498 } else {
499 loge("iccTransmitApduBasicChannel: Unknown exception");
500 }
501 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700502 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700503 break;
504
505 case CMD_EXCHANGE_SIM_IO:
506 request = (MainThreadRequest) msg.obj;
507 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800508 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700509 if (uiccCard == null) {
510 loge("iccExchangeSimIO: No UICC");
511 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700512 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700513 } else {
514 onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
515 request);
516 uiccCard.iccExchangeSimIO(iccArgument.cla, /* fileID */
517 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3,
518 iccArgument.data, onCompleted);
519 }
520 break;
521
522 case EVENT_EXCHANGE_SIM_IO_DONE:
523 ar = (AsyncResult) msg.obj;
524 request = (MainThreadRequest) ar.userObj;
525 if (ar.exception == null && ar.result != null) {
526 request.result = ar.result;
527 } else {
528 request.result = new IccIoResult(0x6f, 0, (byte[])null);
529 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700530 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700531 break;
532
Derek Tan4d5e5c12014-02-04 11:54:58 -0800533 case CMD_SEND_ENVELOPE:
534 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800535 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700536 if (uiccCard == null) {
537 loge("sendEnvelopeWithStatus: No UICC");
538 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700539 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700540 } else {
541 onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
542 uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted);
543 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800544 break;
545
546 case EVENT_SEND_ENVELOPE_DONE:
547 ar = (AsyncResult) msg.obj;
548 request = (MainThreadRequest) ar.userObj;
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700549 if (ar.exception == null && ar.result != null) {
550 request.result = ar.result;
Derek Tan4d5e5c12014-02-04 11:54:58 -0800551 } else {
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700552 request.result = new IccIoResult(0x6F, 0, (byte[])null);
553 if (ar.result == null) {
554 loge("sendEnvelopeWithStatus: Empty response");
555 } else if (ar.exception instanceof CommandException) {
556 loge("sendEnvelopeWithStatus: CommandException: " +
557 ar.exception);
558 } else {
559 loge("sendEnvelopeWithStatus: exception:" + ar.exception);
560 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800561 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700562 notifyRequester(request);
Derek Tan4d5e5c12014-02-04 11:54:58 -0800563 break;
564
Shishir Agrawal566b7612013-10-28 14:41:00 -0700565 case CMD_OPEN_CHANNEL:
566 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800567 uiccCard = getUiccCardFromRequest(request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800568 Pair<String, Integer> openChannelArgs = (Pair<String, Integer>) request.argument;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700569 if (uiccCard == null) {
570 loge("iccOpenLogicalChannel: No UICC");
Shishir Agrawalfc0492a2016-02-17 11:15:33 -0800571 request.result = new IccOpenLogicalChannelResponse(-1,
572 IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700573 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700574 } else {
575 onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800576 uiccCard.iccOpenLogicalChannel(openChannelArgs.first,
577 openChannelArgs.second, onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700578 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700579 break;
580
581 case EVENT_OPEN_CHANNEL_DONE:
582 ar = (AsyncResult) msg.obj;
583 request = (MainThreadRequest) ar.userObj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700584 IccOpenLogicalChannelResponse openChannelResp;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700585 if (ar.exception == null && ar.result != null) {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700586 int[] result = (int[]) ar.result;
587 int channelId = result[0];
588 byte[] selectResponse = null;
589 if (result.length > 1) {
590 selectResponse = new byte[result.length - 1];
591 for (int i = 1; i < result.length; ++i) {
592 selectResponse[i - 1] = (byte) result[i];
593 }
594 }
595 openChannelResp = new IccOpenLogicalChannelResponse(channelId,
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700596 IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700597 } else {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700598 if (ar.result == null) {
599 loge("iccOpenLogicalChannel: Empty response");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700600 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700601 if (ar.exception != null) {
602 loge("iccOpenLogicalChannel: Exception: " + ar.exception);
603 }
604
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700605 int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR;
Junda Liua754ba12015-05-20 01:17:52 -0700606 if (ar.exception instanceof CommandException) {
607 CommandException.Error error =
608 ((CommandException) (ar.exception)).getCommandError();
609 if (error == CommandException.Error.MISSING_RESOURCE) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700610 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE;
Junda Liua754ba12015-05-20 01:17:52 -0700611 } else if (error == CommandException.Error.NO_SUCH_ELEMENT) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700612 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700613 }
614 }
615 openChannelResp = new IccOpenLogicalChannelResponse(
616 IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700617 }
Shishir Agrawal82c8a462014-07-31 18:13:17 -0700618 request.result = openChannelResp;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700619 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700620 break;
621
622 case CMD_CLOSE_CHANNEL:
623 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800624 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700625 if (uiccCard == null) {
626 loge("iccCloseLogicalChannel: No UICC");
Yoshiaki Naka2e29d822016-09-02 19:27:39 +0900627 request.result = false;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700628 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700629 } else {
630 onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
631 uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
632 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700633 break;
634
635 case EVENT_CLOSE_CHANNEL_DONE:
Jake Hambye994d462014-02-03 13:10:13 -0800636 handleNullReturnEvent(msg, "iccCloseLogicalChannel");
637 break;
638
639 case CMD_NV_READ_ITEM:
640 request = (MainThreadRequest) msg.obj;
641 onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800642 defaultPhone.nvReadItem((Integer) request.argument, onCompleted,
643 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800644 break;
645
646 case EVENT_NV_READ_ITEM_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700647 ar = (AsyncResult) msg.obj;
648 request = (MainThreadRequest) ar.userObj;
Jake Hambye994d462014-02-03 13:10:13 -0800649 if (ar.exception == null && ar.result != null) {
650 request.result = ar.result; // String
Shishir Agrawal566b7612013-10-28 14:41:00 -0700651 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800652 request.result = "";
653 if (ar.result == null) {
654 loge("nvReadItem: Empty response");
655 } else if (ar.exception instanceof CommandException) {
656 loge("nvReadItem: CommandException: " +
657 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700658 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800659 loge("nvReadItem: Unknown exception");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700660 }
661 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700662 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700663 break;
664
Jake Hambye994d462014-02-03 13:10:13 -0800665 case CMD_NV_WRITE_ITEM:
666 request = (MainThreadRequest) msg.obj;
667 onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
668 Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800669 defaultPhone.nvWriteItem(idValue.first, idValue.second, onCompleted,
vagdeviaf9a5b92018-08-15 16:01:53 -0700670 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800671 break;
672
673 case EVENT_NV_WRITE_ITEM_DONE:
674 handleNullReturnEvent(msg, "nvWriteItem");
675 break;
676
677 case CMD_NV_WRITE_CDMA_PRL:
678 request = (MainThreadRequest) msg.obj;
679 onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800680 defaultPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
Jake Hambye994d462014-02-03 13:10:13 -0800681 break;
682
683 case EVENT_NV_WRITE_CDMA_PRL_DONE:
684 handleNullReturnEvent(msg, "nvWriteCdmaPrl");
685 break;
686
chen xu6dac5ab2018-10-26 17:39:23 -0700687 case CMD_RESET_MODEM_CONFIG:
Jake Hambye994d462014-02-03 13:10:13 -0800688 request = (MainThreadRequest) msg.obj;
chen xu6dac5ab2018-10-26 17:39:23 -0700689 onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800690 defaultPhone.resetModemConfig(onCompleted);
Jake Hambye994d462014-02-03 13:10:13 -0800691 break;
692
chen xu6dac5ab2018-10-26 17:39:23 -0700693 case EVENT_RESET_MODEM_CONFIG_DONE:
694 handleNullReturnEvent(msg, "resetModemConfig");
Jake Hambye994d462014-02-03 13:10:13 -0800695 break;
696
Jake Hamby7c27be32014-03-03 13:25:59 -0800697 case CMD_GET_PREFERRED_NETWORK_TYPE:
698 request = (MainThreadRequest) msg.obj;
699 onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request);
Stuart Scott54788802015-03-30 13:18:01 -0700700 getPhoneFromRequest(request).getPreferredNetworkType(onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800701 break;
702
703 case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE:
704 ar = (AsyncResult) msg.obj;
705 request = (MainThreadRequest) ar.userObj;
706 if (ar.exception == null && ar.result != null) {
707 request.result = ar.result; // Integer
708 } else {
Sanket Padawecfc2d352016-01-05 19:52:14 -0800709 request.result = null;
Jake Hamby7c27be32014-03-03 13:25:59 -0800710 if (ar.result == null) {
711 loge("getPreferredNetworkType: Empty response");
712 } else if (ar.exception instanceof CommandException) {
713 loge("getPreferredNetworkType: CommandException: " +
714 ar.exception);
715 } else {
716 loge("getPreferredNetworkType: Unknown exception");
717 }
718 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700719 notifyRequester(request);
Jake Hamby7c27be32014-03-03 13:25:59 -0800720 break;
721
722 case CMD_SET_PREFERRED_NETWORK_TYPE:
723 request = (MainThreadRequest) msg.obj;
724 onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request);
725 int networkType = (Integer) request.argument;
Stuart Scott54788802015-03-30 13:18:01 -0700726 getPhoneFromRequest(request).setPreferredNetworkType(networkType, onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800727 break;
728
729 case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE:
730 handleNullReturnEvent(msg, "setPreferredNetworkType");
731 break;
732
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000733 case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
734 request = (MainThreadRequest)msg.obj;
735 onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800736 defaultPhone.invokeOemRilRequestRaw((byte[]) request.argument, onCompleted);
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000737 break;
738
739 case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
740 ar = (AsyncResult)msg.obj;
741 request = (MainThreadRequest)ar.userObj;
742 request.result = ar;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700743 notifyRequester(request);
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000744 break;
745
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800746 case CMD_SET_VOICEMAIL_NUMBER:
747 request = (MainThreadRequest) msg.obj;
748 onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
749 Pair<String, String> tagNum = (Pair<String, String>) request.argument;
Stuart Scott584921c2015-01-15 17:10:34 -0800750 getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
751 onCompleted);
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800752 break;
753
754 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
755 handleNullReturnEvent(msg, "setVoicemailNumber");
756 break;
757
Stuart Scott54788802015-03-30 13:18:01 -0700758 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC:
759 request = (MainThreadRequest) msg.obj;
760 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE,
761 request);
762 getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted);
763 break;
764
765 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE:
766 handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic");
767 break;
768
Shishir Agrawal302c8692015-06-19 13:49:39 -0700769 case CMD_PERFORM_NETWORK_SCAN:
770 request = (MainThreadRequest) msg.obj;
771 onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request);
772 getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
773 break;
774
775 case EVENT_PERFORM_NETWORK_SCAN_DONE:
776 ar = (AsyncResult) msg.obj;
777 request = (MainThreadRequest) ar.userObj;
778 CellNetworkScanResult cellScanResult;
779 if (ar.exception == null && ar.result != null) {
780 cellScanResult = new CellNetworkScanResult(
781 CellNetworkScanResult.STATUS_SUCCESS,
782 (List<OperatorInfo>) ar.result);
783 } else {
784 if (ar.result == null) {
785 loge("getCellNetworkScanResults: Empty response");
786 }
787 if (ar.exception != null) {
788 loge("getCellNetworkScanResults: Exception: " + ar.exception);
789 }
790 int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR;
791 if (ar.exception instanceof CommandException) {
792 CommandException.Error error =
793 ((CommandException) (ar.exception)).getCommandError();
794 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
795 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE;
796 } else if (error == CommandException.Error.GENERIC_FAILURE) {
797 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE;
798 }
799 }
800 cellScanResult = new CellNetworkScanResult(errorCode, null);
801 }
802 request.result = cellScanResult;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700803 notifyRequester(request);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700804 break;
805
806 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
807 request = (MainThreadRequest) msg.obj;
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700808 ManualNetworkSelectionArgument selArg =
809 (ManualNetworkSelectionArgument) request.argument;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700810 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE,
811 request);
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700812 getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo,
813 selArg.persistSelection, onCompleted);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700814 break;
815
816 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
Pengquan Menge3d01e22018-09-20 15:25:35 -0700817 ar = (AsyncResult) msg.obj;
818 request = (MainThreadRequest) ar.userObj;
819 if (ar.exception == null) {
820 request.result = true;
821 } else {
822 request.result = false;
823 loge("setNetworkSelectionModeManual " + ar.exception);
824 }
825 notifyRequester(request);
826 mApp.onNetworkSelectionChanged(request.subId);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700827 break;
828
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700829 case CMD_GET_MODEM_ACTIVITY_INFO:
830 request = (MainThreadRequest) msg.obj;
831 onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800832 defaultPhone.getModemActivityInfo(onCompleted, request.workSource);
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700833 break;
834
835 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE:
836 ar = (AsyncResult) msg.obj;
837 request = (MainThreadRequest) ar.userObj;
838 if (ar.exception == null && ar.result != null) {
839 request.result = ar.result;
840 } else {
841 if (ar.result == null) {
842 loge("queryModemActivityInfo: Empty response");
843 } else if (ar.exception instanceof CommandException) {
844 loge("queryModemActivityInfo: CommandException: " +
845 ar.exception);
846 } else {
847 loge("queryModemActivityInfo: Unknown exception");
848 }
849 }
Amit Mahajand4766222016-01-28 15:28:28 -0800850 // Result cannot be null. Return ModemActivityInfo with all fields set to 0.
851 if (request.result == null) {
852 request.result = new ModemActivityInfo(0, 0, 0, null, 0, 0);
853 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700854 notifyRequester(request);
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700855 break;
856
Meng Wang1a7c35a2016-05-05 20:56:15 -0700857 case CMD_SET_ALLOWED_CARRIERS:
858 request = (MainThreadRequest) msg.obj;
Michele Berionne482f8202018-11-27 18:57:59 -0800859 CarrierRestrictionRules argument =
860 (CarrierRestrictionRules) request.argument;
Meng Wang1a7c35a2016-05-05 20:56:15 -0700861 onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
Michele Berionne482f8202018-11-27 18:57:59 -0800862 defaultPhone.setAllowedCarriers(argument, onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700863 break;
864
865 case EVENT_SET_ALLOWED_CARRIERS_DONE:
866 ar = (AsyncResult) msg.obj;
867 request = (MainThreadRequest) ar.userObj;
868 if (ar.exception == null && ar.result != null) {
869 request.result = ar.result;
870 } else {
Michele Berionne482f8202018-11-27 18:57:59 -0800871 request.result = TelephonyManager.SET_CARRIER_RESTRICTION_ERROR;
872 if (ar.exception instanceof CommandException) {
873 loge("setAllowedCarriers: CommandException: " + ar.exception);
874 CommandException.Error error =
875 ((CommandException) (ar.exception)).getCommandError();
876 if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
877 request.result =
878 TelephonyManager.SET_CARRIER_RESTRICTION_NOT_SUPPORTED;
879 }
Meng Wang1a7c35a2016-05-05 20:56:15 -0700880 } else {
881 loge("setAllowedCarriers: Unknown exception");
882 }
883 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700884 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700885 break;
886
887 case CMD_GET_ALLOWED_CARRIERS:
888 request = (MainThreadRequest) msg.obj;
889 onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800890 defaultPhone.getAllowedCarriers(onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700891 break;
892
893 case EVENT_GET_ALLOWED_CARRIERS_DONE:
894 ar = (AsyncResult) msg.obj;
895 request = (MainThreadRequest) ar.userObj;
896 if (ar.exception == null && ar.result != null) {
897 request.result = ar.result;
898 } else {
Michele Berionne482f8202018-11-27 18:57:59 -0800899 request.result = new IllegalStateException(
900 "Failed to get carrier restrictions");
Meng Wang1a7c35a2016-05-05 20:56:15 -0700901 if (ar.result == null) {
902 loge("getAllowedCarriers: Empty response");
903 } else if (ar.exception instanceof CommandException) {
904 loge("getAllowedCarriers: CommandException: " +
905 ar.exception);
906 } else {
907 loge("getAllowedCarriers: Unknown exception");
908 }
909 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700910 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700911 break;
912
Nathan Haroldb3014052017-01-25 15:57:32 -0800913 case EVENT_GET_FORBIDDEN_PLMNS_DONE:
914 ar = (AsyncResult) msg.obj;
915 request = (MainThreadRequest) ar.userObj;
916 if (ar.exception == null && ar.result != null) {
917 request.result = ar.result;
918 } else {
919 request.result = new IllegalArgumentException(
920 "Failed to retrieve Forbidden Plmns");
921 if (ar.result == null) {
922 loge("getForbiddenPlmns: Empty response");
923 } else {
924 loge("getForbiddenPlmns: Unknown exception");
925 }
926 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700927 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -0800928 break;
929
930 case CMD_GET_FORBIDDEN_PLMNS:
931 request = (MainThreadRequest) msg.obj;
932 uiccCard = getUiccCardFromRequest(request);
933 if (uiccCard == null) {
934 loge("getForbiddenPlmns() UiccCard is null");
935 request.result = new IllegalArgumentException(
936 "getForbiddenPlmns() UiccCard is null");
Pengquan Menga1bb6272018-09-06 09:59:22 -0700937 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -0800938 break;
939 }
940 Integer appType = (Integer) request.argument;
941 UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType);
942 if (uiccApp == null) {
943 loge("getForbiddenPlmns() no app with specified type -- "
944 + appType);
945 request.result = new IllegalArgumentException("Failed to get UICC App");
Pengquan Menga1bb6272018-09-06 09:59:22 -0700946 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -0800947 break;
948 } else {
949 if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
950 + " specified type -- " + appType);
951 }
952 onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
953 ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
954 onCompleted);
955 break;
956
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000957 case CMD_SWITCH_SLOTS:
958 request = (MainThreadRequest) msg.obj;
959 int[] physicalSlots = (int[]) request.argument;
960 onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
961 UiccController.getInstance().switchSlots(physicalSlots, onCompleted);
962 break;
963
964 case EVENT_SWITCH_SLOTS_DONE:
965 ar = (AsyncResult) msg.obj;
966 request = (MainThreadRequest) ar.userObj;
967 request.result = (ar.exception == null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700968 notifyRequester(request);
969 break;
970 case CMD_GET_NETWORK_SELECTION_MODE:
971 request = (MainThreadRequest) msg.obj;
972 onCompleted = obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE, request);
973 getPhoneFromRequest(request).getNetworkSelectionMode(onCompleted);
974 break;
975
976 case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
977 ar = (AsyncResult) msg.obj;
978 request = (MainThreadRequest) ar.userObj;
979 if (ar.exception != null) {
980 request.result = TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
981 } else {
982 int mode = ((int[]) ar.result)[0];
983 if (mode == 0) {
984 request.result = TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
985 } else {
986 request.result = TelephonyManager.NETWORK_SELECTION_MODE_MANUAL;
987 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000988 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700989 notifyRequester(request);
990 break;
991 case CMD_GET_CDMA_ROAMING_MODE:
992 request = (MainThreadRequest) msg.obj;
993 onCompleted = obtainMessage(EVENT_GET_CDMA_ROAMING_MODE_DONE, request);
994 getPhoneFromRequest(request).queryCdmaRoamingPreference(onCompleted);
995 break;
996 case EVENT_GET_CDMA_ROAMING_MODE_DONE:
997 ar = (AsyncResult) msg.obj;
998 request = (MainThreadRequest) ar.userObj;
999 if (ar.exception != null) {
1000 request.result = TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT;
1001 } else {
1002 request.result = ((int[]) ar.result)[0];
1003 }
1004 notifyRequester(request);
1005 break;
1006 case CMD_SET_CDMA_ROAMING_MODE:
1007 request = (MainThreadRequest) msg.obj;
1008 onCompleted = obtainMessage(EVENT_SET_CDMA_ROAMING_MODE_DONE, request);
1009 int mode = (int) request.argument;
1010 getPhoneFromRequest(request).setCdmaRoamingPreference(mode, onCompleted);
1011 break;
1012 case EVENT_SET_CDMA_ROAMING_MODE_DONE:
1013 ar = (AsyncResult) msg.obj;
1014 request = (MainThreadRequest) ar.userObj;
1015 request.result = ar.exception == null;
1016 notifyRequester(request);
1017 break;
1018 case CMD_SET_CDMA_SUBSCRIPTION_MODE:
1019 request = (MainThreadRequest) msg.obj;
1020 onCompleted = obtainMessage(EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1021 int subscriptionMode = (int) request.argument;
1022 getPhoneFromRequest(request).setCdmaSubscription(subscriptionMode, onCompleted);
1023 break;
1024 case EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE:
1025 ar = (AsyncResult) msg.obj;
1026 request = (MainThreadRequest) ar.userObj;
1027 request.result = ar.exception == null;
1028 notifyRequester(request);
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001029 break;
Nathan Harold3ff88932018-08-14 10:19:49 -07001030 case CMD_GET_ALL_CELL_INFO:
1031 request = (MainThreadRequest) msg.obj;
Nathan Harold3ff88932018-08-14 10:19:49 -07001032 onCompleted = obtainMessage(EVENT_GET_ALL_CELL_INFO_DONE, request);
Nathan Harold92bed182018-10-12 18:16:49 -07001033 request.phone.requestCellInfoUpdate(request.workSource, onCompleted);
Nathan Harold3ff88932018-08-14 10:19:49 -07001034 break;
Nathan Harold3ff88932018-08-14 10:19:49 -07001035 case EVENT_GET_ALL_CELL_INFO_DONE:
1036 ar = (AsyncResult) msg.obj;
1037 request = (MainThreadRequest) ar.userObj;
Nathan Harold8d0f1742018-10-02 12:14:47 -07001038 // If a timeout occurs, the response will be null
1039 request.result = (ar.exception == null && ar.result != null)
1040 ? ar.result : new ArrayList<CellInfo>();
Nathan Harold3ff88932018-08-14 10:19:49 -07001041 synchronized (request) {
1042 request.notifyAll();
1043 }
1044 break;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001045 case CMD_REQUEST_CELL_INFO_UPDATE:
1046 request = (MainThreadRequest) msg.obj;
1047 request.phone.requestCellInfoUpdate(request.workSource,
1048 obtainMessage(EVENT_REQUEST_CELL_INFO_UPDATE_DONE, request));
1049 break;
1050 case EVENT_REQUEST_CELL_INFO_UPDATE_DONE:
1051 ar = (AsyncResult) msg.obj;
1052 request = (MainThreadRequest) ar.userObj;
1053 ICellInfoCallback cb = (ICellInfoCallback) request.argument;
1054 try {
1055 if (ar.exception != null) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001056 Log.e(LOG_TAG, "Exception retrieving CellInfo=" + ar.exception);
Nathan Harolde82c4b82018-12-18 19:40:37 -08001057 cb.onError(TelephonyManager.CellInfoCallback.ERROR_MODEM_ERROR,
1058 new android.os.ParcelableException(ar.exception));
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001059 } else if (ar.result == null) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001060 Log.w(LOG_TAG, "Timeout Waiting for CellInfo!");
Nathan Harolde82c4b82018-12-18 19:40:37 -08001061 cb.onError(TelephonyManager.CellInfoCallback.ERROR_TIMEOUT, null);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001062 } else {
1063 // use the result as returned
1064 cb.onCellInfo((List<CellInfo>) ar.result);
1065 }
1066 } catch (RemoteException re) {
1067 Log.w(LOG_TAG, "Discarded CellInfo due to Callback RemoteException");
1068 }
1069 break;
1070 case CMD_GET_CELL_LOCATION:
Nathan Harold3ff88932018-08-14 10:19:49 -07001071 request = (MainThreadRequest) msg.obj;
1072 WorkSource ws = (WorkSource) request.argument;
1073 Phone phone = getPhoneFromRequest(request);
1074 phone.getCellLocation(ws, obtainMessage(EVENT_GET_CELL_LOCATION_DONE, request));
1075 break;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001076 case EVENT_GET_CELL_LOCATION_DONE:
Nathan Harold3ff88932018-08-14 10:19:49 -07001077 ar = (AsyncResult) msg.obj;
1078 request = (MainThreadRequest) ar.userObj;
1079 if (ar.exception == null) {
1080 request.result = ar.result;
1081 } else {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001082 phone = getPhoneFromRequest(request);
Nathan Harold3ff88932018-08-14 10:19:49 -07001083 request.result = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
1084 ? new CdmaCellLocation() : new GsmCellLocation();
1085 }
1086
1087 synchronized (request) {
1088 request.notifyAll();
1089 }
1090 break;
chen xu6dac5ab2018-10-26 17:39:23 -07001091 case CMD_MODEM_REBOOT:
1092 request = (MainThreadRequest) msg.obj;
1093 onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001094 defaultPhone.rebootModem(onCompleted);
chen xu6dac5ab2018-10-26 17:39:23 -07001095 break;
chen xu6dac5ab2018-10-26 17:39:23 -07001096 case EVENT_CMD_MODEM_REBOOT_DONE:
1097 handleNullReturnEvent(msg, "rebootModem");
1098 break;
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001099 case CMD_REQUEST_ENABLE_MODEM:
1100 request = (MainThreadRequest) msg.obj;
1101 boolean enable = (boolean) request.argument;
1102 onCompleted = obtainMessage(EVENT_ENABLE_MODEM_DONE, request);
Nazanin Bakhshi33d584b2019-02-27 10:44:32 -08001103 onCompleted.arg1 = enable ? 1 : 0;
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001104 PhoneConfigurationManager.getInstance()
1105 .enablePhone(request.phone, enable, onCompleted);
1106 break;
1107 case EVENT_ENABLE_MODEM_DONE:
1108 ar = (AsyncResult) msg.obj;
1109 request = (MainThreadRequest) ar.userObj;
1110 request.result = (ar.exception == null);
Nazanin Bakhshi33d584b2019-02-27 10:44:32 -08001111 //update the cache as modem status has changed
1112 mPhoneConfigurationManager.addToPhoneStatusCache(
1113 request.phone.getPhoneId(), msg.arg1 == 1);
Pengquan Meng6c2dc9f2019-02-06 11:12:53 -08001114 updateModemStateMetrics();
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001115 notifyRequester(request);
1116 break;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001117 default:
1118 Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
1119 break;
1120 }
1121 }
Jake Hambye994d462014-02-03 13:10:13 -08001122
Pengquan Menga1bb6272018-09-06 09:59:22 -07001123 private void notifyRequester(MainThreadRequest request) {
1124 synchronized (request) {
1125 request.notifyAll();
1126 }
1127 }
1128
Jake Hambye994d462014-02-03 13:10:13 -08001129 private void handleNullReturnEvent(Message msg, String command) {
1130 AsyncResult ar = (AsyncResult) msg.obj;
1131 MainThreadRequest request = (MainThreadRequest) ar.userObj;
1132 if (ar.exception == null) {
1133 request.result = true;
1134 } else {
1135 request.result = false;
1136 if (ar.exception instanceof CommandException) {
1137 loge(command + ": CommandException: " + ar.exception);
1138 } else {
1139 loge(command + ": Unknown exception");
1140 }
1141 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001142 notifyRequester(request);
Jake Hambye994d462014-02-03 13:10:13 -08001143 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001144 }
1145
1146 /**
1147 * Posts the specified command to be executed on the main thread,
1148 * waits for the request to complete, and returns the result.
1149 * @see #sendRequestAsync
1150 */
1151 private Object sendRequest(int command, Object argument) {
Nathan Harold92bed182018-10-12 18:16:49 -07001152 return sendRequest(
1153 command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, null, null);
vagdeviaf9a5b92018-08-15 16:01:53 -07001154 }
1155
1156 /**
1157 * Posts the specified command to be executed on the main thread,
1158 * waits for the request to complete, and returns the result.
1159 * @see #sendRequestAsync
1160 */
1161 private Object sendRequest(int command, Object argument, WorkSource workSource) {
1162 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
Nathan Harold92bed182018-10-12 18:16:49 -07001163 null, workSource);
Wink Saville36469e72014-06-11 15:17:00 -07001164 }
1165
1166 /**
1167 * Posts the specified command to be executed on the main thread,
1168 * waits for the request to complete, and returns the result.
1169 * @see #sendRequestAsync
1170 */
Shishir Agrawal76d5da92014-11-09 16:17:25 -08001171 private Object sendRequest(int command, Object argument, Integer subId) {
Nathan Harold92bed182018-10-12 18:16:49 -07001172 return sendRequest(command, argument, subId, null, null);
vagdeviaf9a5b92018-08-15 16:01:53 -07001173 }
1174
1175 /**
1176 * Posts the specified command to be executed on the main thread,
1177 * waits for the request to complete, and returns the result.
1178 * @see #sendRequestAsync
1179 */
Nathan Harold92bed182018-10-12 18:16:49 -07001180 private Object sendRequest(int command, Object argument, int subId, WorkSource workSource) {
1181 return sendRequest(command, argument, subId, null, workSource);
1182 }
1183
1184 /**
1185 * Posts the specified command to be executed on the main thread,
1186 * waits for the request to complete, and returns the result.
1187 * @see #sendRequestAsync
1188 */
1189 private Object sendRequest(int command, Object argument, Phone phone, WorkSource workSource) {
1190 return sendRequest(
1191 command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phone, workSource);
1192 }
1193
1194 /**
1195 * Posts the specified command to be executed on the main thread,
1196 * waits for the request to complete, and returns the result.
1197 * @see #sendRequestAsync
1198 */
1199 private Object sendRequest(
1200 int command, Object argument, Integer subId, Phone phone, WorkSource workSource) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001201 if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
1202 throw new RuntimeException("This method will deadlock if called from the main thread.");
1203 }
1204
Nathan Harold92bed182018-10-12 18:16:49 -07001205 MainThreadRequest request = null;
1206 if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && phone != null) {
1207 throw new IllegalArgumentException("subId and phone cannot both be specified!");
1208 } else if (phone != null) {
1209 request = new MainThreadRequest(argument, phone, workSource);
1210 } else {
1211 request = new MainThreadRequest(argument, subId, workSource);
1212 }
1213
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001214 Message msg = mMainThreadHandler.obtainMessage(command, request);
1215 msg.sendToTarget();
1216
1217 // Wait for the request to complete
1218 synchronized (request) {
1219 while (request.result == null) {
1220 try {
1221 request.wait();
1222 } catch (InterruptedException e) {
1223 // Do nothing, go back and wait until the request is complete
1224 }
1225 }
1226 }
1227 return request.result;
1228 }
1229
1230 /**
1231 * Asynchronous ("fire and forget") version of sendRequest():
1232 * Posts the specified command to be executed on the main thread, and
1233 * returns immediately.
1234 * @see #sendRequest
1235 */
1236 private void sendRequestAsync(int command) {
1237 mMainThreadHandler.sendEmptyMessage(command);
1238 }
1239
1240 /**
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001241 * Same as {@link #sendRequestAsync(int)} except it takes an argument.
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001242 * @see {@link #sendRequest(int)}
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001243 */
1244 private void sendRequestAsync(int command, Object argument) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001245 sendRequestAsync(command, argument, null, null);
1246 }
1247
1248 /**
1249 * Same as {@link #sendRequestAsync(int,Object)} except it takes a Phone and WorkSource.
1250 * @see {@link #sendRequest(int,Object)}
1251 */
1252 private void sendRequestAsync(
1253 int command, Object argument, Phone phone, WorkSource workSource) {
1254 MainThreadRequest request = new MainThreadRequest(argument, phone, workSource);
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001255 Message msg = mMainThreadHandler.obtainMessage(command, request);
1256 msg.sendToTarget();
1257 }
1258
1259 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001260 * Initialize the singleton PhoneInterfaceManager instance.
1261 * This is only done once, at startup, from PhoneApp.onCreate().
1262 */
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001263 /* package */ static PhoneInterfaceManager init(PhoneGlobals app) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001264 synchronized (PhoneInterfaceManager.class) {
1265 if (sInstance == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001266 sInstance = new PhoneInterfaceManager(app);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001267 } else {
1268 Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
1269 }
1270 return sInstance;
1271 }
1272 }
1273
1274 /** Private constructor; @see init() */
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001275 private PhoneInterfaceManager(PhoneGlobals app) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001276 mApp = app;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001277 mCM = PhoneGlobals.getInstance().mCM;
Stuart Scott981d8582015-04-21 14:09:50 -07001278 mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001279 mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
1280 mMainThreadHandler = new MainThreadHandler();
Tobias Thiererb19e1f12018-12-11 17:54:03 +00001281 mSubscriptionController = SubscriptionController.getInstance();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001282 mTelephonySharedPreferences =
1283 PreferenceManager.getDefaultSharedPreferences(mApp);
yinxub1bed742017-04-17 11:45:04 -07001284 mNetworkScanRequestTracker = new NetworkScanRequestTracker();
Malcolm Chen2c63d402018-08-14 16:00:53 -07001285 mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
Wink Saville3ab207e2014-11-20 13:07:20 -08001286
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001287 publish();
1288 }
1289
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001290 private Phone getDefaultPhone() {
1291 Phone thePhone = getPhone(getDefaultSubscription());
1292 return (thePhone != null) ? thePhone : PhoneFactory.getDefaultPhone();
1293 }
1294
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001295 private void publish() {
1296 if (DBG) log("publish: " + this);
1297
1298 ServiceManager.addService("phone", this);
1299 }
1300
Stuart Scott584921c2015-01-15 17:10:34 -08001301 private Phone getPhoneFromRequest(MainThreadRequest request) {
Jordan Liu4c733742019-02-28 12:03:40 -08001302 if (request.phone != null) {
1303 return request.phone;
1304 } else {
1305 return getPhoneFromSubId(request.subId);
1306 }
1307 }
1308
1309 private Phone getPhoneFromSubId(int subId) {
1310 return (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
1311 ? getDefaultPhone() : getPhone(subId);
Stuart Scott584921c2015-01-15 17:10:34 -08001312 }
1313
Shishir Agrawalc04d9752016-02-19 10:41:00 -08001314 private UiccCard getUiccCardFromRequest(MainThreadRequest request) {
1315 Phone phone = getPhoneFromRequest(request);
1316 return phone == null ? null :
1317 UiccController.getInstance().getUiccCard(phone.getPhoneId());
1318 }
1319
Wink Saville36469e72014-06-11 15:17:00 -07001320 // returns phone associated with the subId.
Wink Savilleb564aae2014-10-23 10:18:09 -07001321 private Phone getPhone(int subId) {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08001322 return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId));
Wink Saville36469e72014-06-11 15:17:00 -07001323 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001324
1325 public void dial(String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001326 dialForSubscriber(getPreferredVoiceSubscription(), number);
Wink Saville36469e72014-06-11 15:17:00 -07001327 }
1328
Wink Savilleb564aae2014-10-23 10:18:09 -07001329 public void dialForSubscriber(int subId, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001330 if (DBG) log("dial: " + number);
1331 // No permission check needed here: This is just a wrapper around the
1332 // ACTION_DIAL intent, which is available to any app since it puts up
1333 // the UI before it does anything.
1334
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001335 final long identity = Binder.clearCallingIdentity();
1336 try {
1337 String url = createTelUrl(number);
1338 if (url == null) {
1339 return;
1340 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001341
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001342 // PENDING: should we just silently fail if phone is offhook or ringing?
1343 PhoneConstants.State state = mCM.getState(subId);
1344 if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
1345 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
1346 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1347 mApp.startActivity(intent);
1348 }
1349 } finally {
1350 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001351 }
1352 }
1353
1354 public void call(String callingPackage, String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001355 callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number);
Wink Saville36469e72014-06-11 15:17:00 -07001356 }
1357
Wink Savilleb564aae2014-10-23 10:18:09 -07001358 public void callForSubscriber(int subId, String callingPackage, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001359 if (DBG) log("call: " + number);
1360
1361 // This is just a wrapper around the ACTION_CALL intent, but we still
1362 // need to do a permission check since we're calling startActivity()
1363 // from the context of the phone app.
1364 enforceCallPermission();
1365
1366 if (mAppOps.noteOp(AppOpsManager.OP_CALL_PHONE, Binder.getCallingUid(), callingPackage)
1367 != AppOpsManager.MODE_ALLOWED) {
1368 return;
1369 }
1370
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001371 final long identity = Binder.clearCallingIdentity();
1372 try {
1373 String url = createTelUrl(number);
1374 if (url == null) {
1375 return;
1376 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001377
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001378 boolean isValid = false;
1379 final List<SubscriptionInfo> slist = getActiveSubscriptionInfoListPrivileged();
1380 if (slist != null) {
1381 for (SubscriptionInfo subInfoRecord : slist) {
1382 if (subInfoRecord.getSubscriptionId() == subId) {
1383 isValid = true;
1384 break;
1385 }
Wink Saville3ab207e2014-11-20 13:07:20 -08001386 }
Wink Saville08874612014-08-31 19:19:58 -07001387 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001388 if (!isValid) {
1389 return;
1390 }
Wink Saville08874612014-08-31 19:19:58 -07001391
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001392 Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
1393 intent.putExtra(SUBSCRIPTION_KEY, subId);
1394 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1395 mApp.startActivity(intent);
1396 } finally {
1397 Binder.restoreCallingIdentity(identity);
1398 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001399 }
1400
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001401 public boolean supplyPin(String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001402 return supplyPinForSubscriber(getDefaultSubscription(), pin);
Wink Saville36469e72014-06-11 15:17:00 -07001403 }
1404
Wink Savilleb564aae2014-10-23 10:18:09 -07001405 public boolean supplyPinForSubscriber(int subId, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001406 int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07001407 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1408 }
1409
1410 public boolean supplyPuk(String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001411 return supplyPukForSubscriber(getDefaultSubscription(), puk, pin);
Wink Saville36469e72014-06-11 15:17:00 -07001412 }
1413
Wink Savilleb564aae2014-10-23 10:18:09 -07001414 public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001415 int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07001416 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1417 }
1418
1419 /** {@hide} */
1420 public int[] supplyPinReportResult(String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001421 return supplyPinReportResultForSubscriber(getDefaultSubscription(), pin);
Wink Saville36469e72014-06-11 15:17:00 -07001422 }
1423
Wink Savilleb564aae2014-10-23 10:18:09 -07001424 public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001425 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001426
1427 final long identity = Binder.clearCallingIdentity();
1428 try {
1429 final UnlockSim checkSimPin = new UnlockSim(getPhone(subId).getIccCard());
1430 checkSimPin.start();
1431 return checkSimPin.unlockSim(null, pin);
1432 } finally {
1433 Binder.restoreCallingIdentity(identity);
1434 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001435 }
1436
Wink Saville9de0f752013-10-22 19:04:03 -07001437 /** {@hide} */
1438 public int[] supplyPukReportResult(String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001439 return supplyPukReportResultForSubscriber(getDefaultSubscription(), puk, pin);
Wink Saville36469e72014-06-11 15:17:00 -07001440 }
1441
Wink Savilleb564aae2014-10-23 10:18:09 -07001442 public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001443 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001444
1445 final long identity = Binder.clearCallingIdentity();
1446 try {
1447 final UnlockSim checkSimPuk = new UnlockSim(getPhone(subId).getIccCard());
1448 checkSimPuk.start();
1449 return checkSimPuk.unlockSim(puk, pin);
1450 } finally {
1451 Binder.restoreCallingIdentity(identity);
1452 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001453 }
1454
1455 /**
Wink Saville9de0f752013-10-22 19:04:03 -07001456 * Helper thread to turn async call to SimCard#supplyPin into
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001457 * a synchronous one.
1458 */
1459 private static class UnlockSim extends Thread {
1460
1461 private final IccCard mSimCard;
1462
1463 private boolean mDone = false;
Wink Saville9de0f752013-10-22 19:04:03 -07001464 private int mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1465 private int mRetryCount = -1;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001466
1467 // For replies from SimCard interface
1468 private Handler mHandler;
1469
1470 // For async handler to identify request type
1471 private static final int SUPPLY_PIN_COMPLETE = 100;
1472
1473 public UnlockSim(IccCard simCard) {
1474 mSimCard = simCard;
1475 }
1476
1477 @Override
1478 public void run() {
1479 Looper.prepare();
1480 synchronized (UnlockSim.this) {
1481 mHandler = new Handler() {
1482 @Override
1483 public void handleMessage(Message msg) {
1484 AsyncResult ar = (AsyncResult) msg.obj;
1485 switch (msg.what) {
1486 case SUPPLY_PIN_COMPLETE:
1487 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
1488 synchronized (UnlockSim.this) {
Wink Saville9de0f752013-10-22 19:04:03 -07001489 mRetryCount = msg.arg1;
1490 if (ar.exception != null) {
1491 if (ar.exception instanceof CommandException &&
1492 ((CommandException)(ar.exception)).getCommandError()
1493 == CommandException.Error.PASSWORD_INCORRECT) {
1494 mResult = PhoneConstants.PIN_PASSWORD_INCORRECT;
1495 } else {
1496 mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1497 }
1498 } else {
1499 mResult = PhoneConstants.PIN_RESULT_SUCCESS;
1500 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001501 mDone = true;
1502 UnlockSim.this.notifyAll();
1503 }
1504 break;
1505 }
1506 }
1507 };
1508 UnlockSim.this.notifyAll();
1509 }
1510 Looper.loop();
1511 }
1512
1513 /*
1514 * Use PIN or PUK to unlock SIM card
1515 *
1516 * If PUK is null, unlock SIM card with PIN
1517 *
1518 * If PUK is not null, unlock SIM card with PUK and set PIN code
1519 */
Wink Saville9de0f752013-10-22 19:04:03 -07001520 synchronized int[] unlockSim(String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001521
1522 while (mHandler == null) {
1523 try {
1524 wait();
1525 } catch (InterruptedException e) {
1526 Thread.currentThread().interrupt();
1527 }
1528 }
1529 Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
1530
1531 if (puk == null) {
1532 mSimCard.supplyPin(pin, callback);
1533 } else {
1534 mSimCard.supplyPuk(puk, pin, callback);
1535 }
1536
1537 while (!mDone) {
1538 try {
1539 Log.d(LOG_TAG, "wait for done");
1540 wait();
1541 } catch (InterruptedException e) {
1542 // Restore the interrupted status
1543 Thread.currentThread().interrupt();
1544 }
1545 }
1546 Log.d(LOG_TAG, "done");
Wink Saville9de0f752013-10-22 19:04:03 -07001547 int[] resultArray = new int[2];
1548 resultArray[0] = mResult;
1549 resultArray[1] = mRetryCount;
1550 return resultArray;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001551 }
1552 }
1553
1554 public void updateServiceLocation() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001555 updateServiceLocationForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001556
1557 }
1558
Wink Savilleb564aae2014-10-23 10:18:09 -07001559 public void updateServiceLocationForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001560 // No permission check needed here: this call is harmless, and it's
1561 // needed for the ServiceState.requestStateUpdate() call (which is
1562 // already intentionally exposed to 3rd parties.)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001563 final long identity = Binder.clearCallingIdentity();
1564 try {
1565 final Phone phone = getPhone(subId);
1566 if (phone != null) {
1567 phone.updateServiceLocation();
1568 }
1569 } finally {
1570 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001571 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001572 }
1573
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001574 @Override
1575 public boolean isRadioOn(String callingPackage) {
1576 return isRadioOnForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07001577 }
1578
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001579 @Override
1580 public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08001581 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08001582 mApp, subId, callingPackage, "isRadioOnForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001583 return false;
1584 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001585
1586 final long identity = Binder.clearCallingIdentity();
1587 try {
1588 return isRadioOnForSubscriber(subId);
1589 } finally {
1590 Binder.restoreCallingIdentity(identity);
1591 }
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001592 }
1593
1594 private boolean isRadioOnForSubscriber(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001595 final long identity = Binder.clearCallingIdentity();
1596 try {
1597 final Phone phone = getPhone(subId);
1598 if (phone != null) {
1599 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
1600 } else {
1601 return false;
1602 }
1603 } finally {
1604 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001605 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001606 }
1607
1608 public void toggleRadioOnOff() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001609 toggleRadioOnOffForSubscriber(getDefaultSubscription());
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001610 }
Wink Saville36469e72014-06-11 15:17:00 -07001611
Wink Savilleb564aae2014-10-23 10:18:09 -07001612 public void toggleRadioOnOffForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001613 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001614
1615 final long identity = Binder.clearCallingIdentity();
1616 try {
1617 final Phone phone = getPhone(subId);
1618 if (phone != null) {
1619 phone.setRadioPower(!isRadioOnForSubscriber(subId));
1620 }
1621 } finally {
1622 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001623 }
Wink Saville36469e72014-06-11 15:17:00 -07001624 }
1625
1626 public boolean setRadio(boolean turnOn) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001627 return setRadioForSubscriber(getDefaultSubscription(), turnOn);
Wink Saville36469e72014-06-11 15:17:00 -07001628 }
1629
Wink Savilleb564aae2014-10-23 10:18:09 -07001630 public boolean setRadioForSubscriber(int subId, boolean turnOn) {
Wink Saville36469e72014-06-11 15:17:00 -07001631 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001632
1633 final long identity = Binder.clearCallingIdentity();
1634 try {
1635 final Phone phone = getPhone(subId);
1636 if (phone == null) {
1637 return false;
1638 }
1639 if ((phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF) != turnOn) {
1640 toggleRadioOnOffForSubscriber(subId);
1641 }
1642 return true;
1643 } finally {
1644 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001645 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001646 }
Wink Saville36469e72014-06-11 15:17:00 -07001647
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001648 public boolean needMobileRadioShutdown() {
1649 /*
1650 * If any of the Radios are available, it will need to be
1651 * shutdown. So return true if any Radio is available.
1652 */
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001653 final long identity = Binder.clearCallingIdentity();
1654 try {
1655 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1656 Phone phone = PhoneFactory.getPhone(i);
1657 if (phone != null && phone.isRadioAvailable()) return true;
1658 }
1659 logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown.");
1660 return false;
1661 } finally {
1662 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001663 }
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001664 }
1665
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001666 @Override
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001667 public void shutdownMobileRadios() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001668 enforceModifyPermission();
1669
1670 final long identity = Binder.clearCallingIdentity();
1671 try {
1672 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1673 logv("Shutting down Phone " + i);
1674 shutdownRadioUsingPhoneId(i);
1675 }
1676 } finally {
1677 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001678 }
1679 }
1680
1681 private void shutdownRadioUsingPhoneId(int phoneId) {
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001682 Phone phone = PhoneFactory.getPhone(phoneId);
1683 if (phone != null && phone.isRadioAvailable()) {
1684 phone.shutdownRadio();
1685 }
1686 }
1687
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001688 public boolean setRadioPower(boolean turnOn) {
Jack Yub4e16162017-05-15 12:48:40 -07001689 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001690
1691 final long identity = Binder.clearCallingIdentity();
1692 try {
1693 final Phone defaultPhone = PhoneFactory.getDefaultPhone();
1694 if (defaultPhone != null) {
1695 defaultPhone.setRadioPower(turnOn);
1696 return true;
1697 } else {
1698 loge("There's no default phone.");
1699 return false;
1700 }
1701 } finally {
1702 Binder.restoreCallingIdentity(identity);
Wei Liu9ae2a062016-08-08 11:09:34 -07001703 }
Wink Saville36469e72014-06-11 15:17:00 -07001704 }
1705
Wink Savilleb564aae2014-10-23 10:18:09 -07001706 public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001707 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001708
1709 final long identity = Binder.clearCallingIdentity();
1710 try {
1711 final Phone phone = getPhone(subId);
1712 if (phone != null) {
1713 phone.setRadioPower(turnOn);
1714 return true;
1715 } else {
1716 return false;
1717 }
1718 } finally {
1719 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001720 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001721 }
1722
Wink Saville36469e72014-06-11 15:17:00 -07001723 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07001724 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001725 public boolean enableDataConnectivity() {
1726 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001727
1728 final long identity = Binder.clearCallingIdentity();
1729 try {
1730 int subId = mSubscriptionController.getDefaultDataSubId();
1731 final Phone phone = getPhone(subId);
1732 if (phone != null) {
Jack Yud79fba22018-12-13 11:51:28 -08001733 phone.getDataEnabledSettings().setUserDataEnabled(true);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001734 return true;
1735 } else {
1736 return false;
1737 }
1738 } finally {
1739 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001740 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001741 }
1742
Wink Saville36469e72014-06-11 15:17:00 -07001743 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07001744 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001745 public boolean disableDataConnectivity() {
1746 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001747
1748 final long identity = Binder.clearCallingIdentity();
1749 try {
1750 int subId = mSubscriptionController.getDefaultDataSubId();
1751 final Phone phone = getPhone(subId);
1752 if (phone != null) {
Jack Yud79fba22018-12-13 11:51:28 -08001753 phone.getDataEnabledSettings().setUserDataEnabled(false);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001754 return true;
1755 } else {
1756 return false;
1757 }
1758 } finally {
1759 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001760 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001761 }
1762
Sanket Padawe356d7632015-06-22 14:03:32 -07001763 @Override
Jack Yuacf8a132017-05-01 17:00:48 -07001764 public boolean isDataConnectivityPossible(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001765 final long identity = Binder.clearCallingIdentity();
1766 try {
1767 final Phone phone = getPhone(subId);
1768 if (phone != null) {
Jack Yub5d8f642018-11-26 11:20:48 -08001769 return phone.isDataAllowed(ApnSetting.TYPE_DEFAULT);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001770 } else {
1771 return false;
1772 }
1773 } finally {
1774 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001775 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001776 }
1777
1778 public boolean handlePinMmi(String dialString) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001779 return handlePinMmiForSubscriber(getDefaultSubscription(), dialString);
Wink Saville36469e72014-06-11 15:17:00 -07001780 }
1781
pkanwarae03a6b2016-11-06 20:37:09 -08001782 public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001783 enforceCallPermission();
1784
1785 final long identity = Binder.clearCallingIdentity();
1786 try {
1787 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1788 return;
1789 }
1790 Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback);
1791 sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId);
1792 } finally {
1793 Binder.restoreCallingIdentity(identity);
1794 }
pkanwar32d516d2016-10-14 19:37:38 -07001795 };
1796
Wink Savilleb564aae2014-10-23 10:18:09 -07001797 public boolean handlePinMmiForSubscriber(int subId, String dialString) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001798 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001799
1800 final long identity = Binder.clearCallingIdentity();
1801 try {
1802 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1803 return false;
1804 }
1805 return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
1806 } finally {
1807 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001808 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001809 }
1810
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001811 public int getCallState() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07001812 return getCallStateForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001813 }
1814
Sanket Padawe13bac7b2017-03-20 15:04:47 -07001815 public int getCallStateForSlot(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001816 final long identity = Binder.clearCallingIdentity();
1817 try {
1818 Phone phone = PhoneFactory.getPhone(slotIndex);
1819 return phone == null ? TelephonyManager.CALL_STATE_IDLE :
1820 PhoneConstantConversions.convertCallState(phone.getState());
1821 } finally {
1822 Binder.restoreCallingIdentity(identity);
1823 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001824 }
1825
Sanket Padawe356d7632015-06-22 14:03:32 -07001826 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001827 public int getDataState() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001828 final long identity = Binder.clearCallingIdentity();
1829 try {
1830 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1831 if (phone != null) {
1832 return PhoneConstantConversions.convertDataState(phone.getDataConnectionState());
1833 } else {
1834 return PhoneConstantConversions.convertDataState(
1835 PhoneConstants.DataState.DISCONNECTED);
1836 }
1837 } finally {
1838 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001839 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001840 }
1841
Sanket Padawe356d7632015-06-22 14:03:32 -07001842 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001843 public int getDataActivity() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001844 final long identity = Binder.clearCallingIdentity();
1845 try {
1846 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1847 if (phone != null) {
1848 return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState());
1849 } else {
1850 return TelephonyManager.DATA_ACTIVITY_NONE;
1851 }
1852 } finally {
1853 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001854 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001855 }
1856
1857 @Override
Svetoslav64fad262015-04-14 14:35:21 -07001858 public Bundle getCellLocation(String callingPackage) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001859 mApp.getSystemService(AppOpsManager.class)
Hall Liu1aa510f2017-11-22 17:40:08 -08001860 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08001861
1862 LocationAccessPolicy.LocationPermissionResult locationResult =
1863 LocationAccessPolicy.checkLocationPermission(mApp,
1864 new LocationAccessPolicy.LocationPermissionQuery.Builder()
1865 .setCallingPackage(callingPackage)
1866 .setCallingPid(Binder.getCallingPid())
1867 .setCallingUid(Binder.getCallingUid())
1868 .setMethod("getCellLocation")
1869 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
1870 .build());
1871 switch (locationResult) {
1872 case DENIED_HARD:
1873 throw new SecurityException("Not allowed to access cell location");
1874 case DENIED_SOFT:
1875 return new Bundle();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001876 }
1877
Narayan Kamathf04b5a12018-01-09 11:47:15 +00001878 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001879 final long identity = Binder.clearCallingIdentity();
1880 try {
1881 if (DBG_LOC) log("getCellLocation: is active user");
1882 Bundle data = new Bundle();
Nathan Harold3ff88932018-08-14 10:19:49 -07001883 int subId = mSubscriptionController.getDefaultDataSubId();
1884 CellLocation cl = (CellLocation) sendRequest(CMD_GET_CELL_LOCATION, workSource, subId);
1885 cl.fillInNotifierBundle(data);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001886 return data;
1887 } finally {
1888 Binder.restoreCallingIdentity(identity);
1889 }
Svetoslav64fad262015-04-14 14:35:21 -07001890 }
1891
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001892 @Override
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001893 public String getNetworkCountryIsoForPhone(int phoneId) {
1894 // Reporting the correct network country is ambiguous when IWLAN could conflict with
1895 // registered cell info, so return a NULL country instead.
1896 final long identity = Binder.clearCallingIdentity();
1897 try {
Malcolm Chen3732c2b2018-07-18 20:15:24 -07001898 if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
1899 // Get default phone in this case.
1900 phoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
1901 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001902 final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
Jack Yu5f7092c2018-04-13 14:05:37 -07001903 // Todo: fix this when we can get the actual cellular network info when the device
1904 // is on IWLAN.
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001905 if (TelephonyManager.NETWORK_TYPE_IWLAN
1906 == getVoiceNetworkTypeForSubscriber(subId, mApp.getPackageName())) {
1907 return "";
1908 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001909 Phone phone = PhoneFactory.getPhone(phoneId);
1910 if (phone != null) {
1911 ServiceStateTracker sst = phone.getServiceStateTracker();
1912 if (sst != null) {
1913 LocaleTracker lt = sst.getLocaleTracker();
1914 if (lt != null) {
1915 return lt.getCurrentCountry();
1916 }
1917 }
1918 }
1919 return "";
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001920 } finally {
1921 Binder.restoreCallingIdentity(identity);
1922 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001923 }
1924
1925 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001926 public void enableLocationUpdates() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001927 enableLocationUpdatesForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001928 }
1929
Sanket Padawe356d7632015-06-22 14:03:32 -07001930 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07001931 public void enableLocationUpdatesForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001932 mApp.enforceCallingOrSelfPermission(
1933 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001934
1935 final long identity = Binder.clearCallingIdentity();
1936 try {
1937 final Phone phone = getPhone(subId);
1938 if (phone != null) {
1939 phone.enableLocationUpdates();
1940 }
1941 } finally {
1942 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001943 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001944 }
1945
1946 @Override
1947 public void disableLocationUpdates() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001948 disableLocationUpdatesForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001949 }
1950
Sanket Padawe356d7632015-06-22 14:03:32 -07001951 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07001952 public void disableLocationUpdatesForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001953 mApp.enforceCallingOrSelfPermission(
1954 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001955
1956 final long identity = Binder.clearCallingIdentity();
1957 try {
1958 final Phone phone = getPhone(subId);
1959 if (phone != null) {
1960 phone.disableLocationUpdates();
1961 }
1962 } finally {
1963 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001964 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001965 }
1966
Nathan Harold31d7ff32018-10-15 20:20:30 -07001967 /**
1968 * Returns the target SDK version number for a given package name.
1969 *
1970 * @return target SDK if the package is found or INT_MAX.
1971 */
1972 private int getTargetSdk(String packageName) {
1973 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001974 final ApplicationInfo ai = mApp.getPackageManager().getApplicationInfo(
1975 packageName, 0);
Nathan Harold31d7ff32018-10-15 20:20:30 -07001976 if (ai != null) return ai.targetSdkVersion;
1977 } catch (PackageManager.NameNotFoundException unexpected) {
1978 }
1979 return Integer.MAX_VALUE;
1980 }
1981
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001982 @Override
1983 @SuppressWarnings("unchecked")
Nathan Harold31d7ff32018-10-15 20:20:30 -07001984 public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage) {
1985 final int targetSdk = getTargetSdk(callingPackage);
Nathan Harolddbea45a2018-08-30 14:35:07 -07001986 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
1987 throw new SecurityException(
1988 "getNeighboringCellInfo() is unavailable to callers targeting Q+ SDK levels.");
1989 }
Nathan Haroldb4d55612018-07-20 13:13:08 -07001990
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001991 if (mAppOps.noteOp(AppOpsManager.OP_NEIGHBORING_CELLS, Binder.getCallingUid(),
1992 callingPackage) != AppOpsManager.MODE_ALLOWED) {
1993 return null;
1994 }
Svetoslav64fad262015-04-14 14:35:21 -07001995
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001996 if (DBG_LOC) log("getNeighboringCellInfo: is active user");
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001997
Nathan Haroldf180aac2018-06-01 18:43:55 -07001998 List<CellInfo> info = getAllCellInfo(callingPackage);
1999 if (info == null) return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002000
Nathan Haroldf180aac2018-06-01 18:43:55 -07002001 List<NeighboringCellInfo> neighbors = new ArrayList<NeighboringCellInfo>();
2002 for (CellInfo ci : info) {
2003 if (ci instanceof CellInfoGsm) {
2004 neighbors.add(new NeighboringCellInfo((CellInfoGsm) ci));
2005 } else if (ci instanceof CellInfoWcdma) {
2006 neighbors.add(new NeighboringCellInfo((CellInfoWcdma) ci));
2007 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002008 }
Nathan Haroldf180aac2018-06-01 18:43:55 -07002009 return (neighbors.size()) > 0 ? neighbors : null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002010 }
2011
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002012 private List<CellInfo> getCachedCellInfo() {
2013 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
2014 for (Phone phone : PhoneFactory.getPhones()) {
2015 List<CellInfo> info = phone.getAllCellInfo();
2016 if (info != null) cellInfos.addAll(info);
2017 }
2018 return cellInfos;
2019 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002020
2021 @Override
Svetoslav64fad262015-04-14 14:35:21 -07002022 public List<CellInfo> getAllCellInfo(String callingPackage) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002023 mApp.getSystemService(AppOpsManager.class)
Hall Liu1aa510f2017-11-22 17:40:08 -08002024 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08002025
2026 LocationAccessPolicy.LocationPermissionResult locationResult =
2027 LocationAccessPolicy.checkLocationPermission(mApp,
2028 new LocationAccessPolicy.LocationPermissionQuery.Builder()
2029 .setCallingPackage(callingPackage)
2030 .setCallingPid(Binder.getCallingPid())
2031 .setCallingUid(Binder.getCallingUid())
2032 .setMethod("getAllCellInfo")
Nathan Harold5ae50b52019-02-20 15:46:36 -08002033 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
Hall Liuf19c44f2018-11-27 14:38:17 -08002034 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2035 .build());
2036 switch (locationResult) {
2037 case DENIED_HARD:
2038 throw new SecurityException("Not allowed to access cell info");
2039 case DENIED_SOFT:
2040 return new ArrayList<>();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002041 }
2042
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002043 final int targetSdk = getTargetSdk(callingPackage);
2044 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
2045 return getCachedCellInfo();
2046 }
2047
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07002048 if (DBG_LOC) log("getAllCellInfo: is active user");
Narayan Kamathf04b5a12018-01-09 11:47:15 +00002049 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002050 final long identity = Binder.clearCallingIdentity();
2051 try {
2052 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
2053 for (Phone phone : PhoneFactory.getPhones()) {
Nathan Harold3ff88932018-08-14 10:19:49 -07002054 final List<CellInfo> info = (List<CellInfo>) sendRequest(
Nathan Harold92bed182018-10-12 18:16:49 -07002055 CMD_GET_ALL_CELL_INFO, null, phone, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002056 if (info != null) cellInfos.addAll(info);
2057 }
2058 return cellInfos;
2059 } finally {
2060 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002061 }
2062 }
2063
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07002064 @Override
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002065 public void requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage) {
2066 requestCellInfoUpdateInternal(
2067 subId, cb, callingPackage, getWorkSource(Binder.getCallingUid()));
2068 }
2069
2070 @Override
2071 public void requestCellInfoUpdateWithWorkSource(
2072 int subId, ICellInfoCallback cb, String callingPackage, WorkSource workSource) {
2073 enforceModifyPermission();
2074 requestCellInfoUpdateInternal(subId, cb, callingPackage, workSource);
2075 }
2076
2077 private void requestCellInfoUpdateInternal(
2078 int subId, ICellInfoCallback cb, String callingPackage, WorkSource workSource) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002079 mApp.getSystemService(AppOpsManager.class)
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002080 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08002081
2082 LocationAccessPolicy.LocationPermissionResult locationResult =
2083 LocationAccessPolicy.checkLocationPermission(mApp,
2084 new LocationAccessPolicy.LocationPermissionQuery.Builder()
2085 .setCallingPackage(callingPackage)
2086 .setCallingPid(Binder.getCallingPid())
2087 .setCallingUid(Binder.getCallingUid())
2088 .setMethod("requestCellInfoUpdate")
2089 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2090 .build());
2091 switch (locationResult) {
2092 case DENIED_HARD:
2093 throw new SecurityException("Not allowed to access cell info");
2094 case DENIED_SOFT:
2095 return;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002096 }
2097
2098 final Phone phone = getPhone(subId);
2099 if (phone == null) throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
2100
2101 sendRequestAsync(CMD_REQUEST_CELL_INFO_UPDATE, cb, phone, workSource);
2102 }
2103
2104 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002105 public void setCellInfoListRate(int rateInMillis) {
Jack Yua8d8cb82017-01-16 10:15:34 -08002106 enforceModifyPermission();
Narayan Kamathf04b5a12018-01-09 11:47:15 +00002107 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002108
2109 final long identity = Binder.clearCallingIdentity();
2110 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002111 getDefaultPhone().setCellInfoListRate(rateInMillis, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002112 } finally {
2113 Binder.restoreCallingIdentity(identity);
2114 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002115 }
2116
Shishir Agrawala9f32182016-04-12 12:00:16 -07002117 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002118 public String getImeiForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002119 Phone phone = PhoneFactory.getPhone(slotIndex);
2120 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002121 return null;
2122 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002123 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07002124 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
2125 callingPackage, "getImeiForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002126 return null;
2127 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002128
2129 final long identity = Binder.clearCallingIdentity();
2130 try {
2131 return phone.getImei();
2132 } finally {
2133 Binder.restoreCallingIdentity(identity);
2134 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002135 }
2136
2137 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002138 public String getTypeAllocationCodeForSlot(int slotIndex) {
2139 Phone phone = PhoneFactory.getPhone(slotIndex);
2140 String tac = null;
2141 if (phone != null) {
2142 String imei = phone.getImei();
2143 tac = imei == null ? null : imei.substring(0, TYPE_ALLOCATION_CODE_LENGTH);
2144 }
2145 return tac;
2146 }
2147
2148 @Override
Jack Yu2af8d712017-03-15 17:14:14 -07002149 public String getMeidForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002150 Phone phone = PhoneFactory.getPhone(slotIndex);
2151 if (phone == null) {
Jack Yu2af8d712017-03-15 17:14:14 -07002152 return null;
2153 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002154
Jeff Davidson913390f2018-02-23 17:11:49 -08002155 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07002156 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
2157 callingPackage, "getMeidForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002158 return null;
2159 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002160
2161 final long identity = Binder.clearCallingIdentity();
2162 try {
2163 return phone.getMeid();
2164 } finally {
2165 Binder.restoreCallingIdentity(identity);
2166 }
Jack Yu2af8d712017-03-15 17:14:14 -07002167 }
2168
2169 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002170 public String getManufacturerCodeForSlot(int slotIndex) {
2171 Phone phone = PhoneFactory.getPhone(slotIndex);
2172 String manufacturerCode = null;
2173 if (phone != null) {
2174 String meid = phone.getMeid();
2175 manufacturerCode = meid == null ? null : meid.substring(0, MANUFACTURER_CODE_LENGTH);
2176 }
2177 return manufacturerCode;
2178 }
2179
2180 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002181 public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002182 Phone phone = PhoneFactory.getPhone(slotIndex);
2183 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002184 return null;
2185 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002186 int subId = phone.getSubId();
2187 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2188 mApp, subId, callingPackage, "getDeviceSoftwareVersionForSlot")) {
2189 return null;
2190 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002191
2192 final long identity = Binder.clearCallingIdentity();
2193 try {
2194 return phone.getDeviceSvn();
2195 } finally {
2196 Binder.restoreCallingIdentity(identity);
2197 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002198 }
2199
fionaxu43304da2017-11-27 22:51:16 -08002200 @Override
2201 public int getSubscriptionCarrierId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002202 final long identity = Binder.clearCallingIdentity();
2203 try {
2204 final Phone phone = getPhone(subId);
2205 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getCarrierId();
2206 } finally {
2207 Binder.restoreCallingIdentity(identity);
2208 }
fionaxu43304da2017-11-27 22:51:16 -08002209 }
2210
2211 @Override
2212 public String getSubscriptionCarrierName(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002213 final long identity = Binder.clearCallingIdentity();
2214 try {
2215 final Phone phone = getPhone(subId);
2216 return phone == null ? null : phone.getCarrierName();
2217 } finally {
2218 Binder.restoreCallingIdentity(identity);
2219 }
fionaxu43304da2017-11-27 22:51:16 -08002220 }
2221
calvinpanffe225e2018-11-01 19:43:06 +08002222 @Override
chen xu0026ca62019-03-06 15:28:50 -08002223 public int getSubscriptionSpecificCarrierId(int subId) {
chen xu25637222018-11-04 17:17:00 -08002224 final long identity = Binder.clearCallingIdentity();
2225 try {
2226 final Phone phone = getPhone(subId);
2227 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID
chen xu0026ca62019-03-06 15:28:50 -08002228 : phone.getSpecificCarrierId();
chen xu25637222018-11-04 17:17:00 -08002229 } finally {
2230 Binder.restoreCallingIdentity(identity);
2231 }
2232 }
2233
2234 @Override
chen xu0026ca62019-03-06 15:28:50 -08002235 public String getSubscriptionSpecificCarrierName(int subId) {
chen xu25637222018-11-04 17:17:00 -08002236 final long identity = Binder.clearCallingIdentity();
2237 try {
2238 final Phone phone = getPhone(subId);
chen xu0026ca62019-03-06 15:28:50 -08002239 return phone == null ? null : phone.getSpecificCarrierName();
chen xu25637222018-11-04 17:17:00 -08002240 } finally {
2241 Binder.restoreCallingIdentity(identity);
2242 }
2243 }
2244
chen xu651eec72018-11-11 19:03:44 -08002245 @Override
chen xu864e11c2018-12-06 22:10:03 -08002246 public int getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc) {
2247 if (!isSubscriptionMccMnc) {
2248 enforceReadPrivilegedPermission("getCarrierIdFromMccMnc");
2249 }
chen xu651eec72018-11-11 19:03:44 -08002250 final Phone phone = PhoneFactory.getPhone(slotIndex);
2251 if (phone == null) {
2252 return TelephonyManager.UNKNOWN_CARRIER_ID;
2253 }
2254 final long identity = Binder.clearCallingIdentity();
2255 try {
2256 return CarrierResolver.getCarrierIdFromMccMnc(phone.getContext(), mccmnc);
2257 } finally {
2258 Binder.restoreCallingIdentity(identity);
2259 }
2260 }
2261
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002262 //
2263 // Internal helper methods.
2264 //
2265
Sanket Padaweee13a9b2016-03-08 17:30:28 -08002266 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002267 * Make sure the caller has the MODIFY_PHONE_STATE permission.
2268 *
2269 * @throws SecurityException if the caller does not have the required permission
2270 */
2271 private void enforceModifyPermission() {
2272 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
2273 }
2274
2275 /**
2276 * Make sure the caller has the CALL_PHONE permission.
2277 *
2278 * @throws SecurityException if the caller does not have the required permission
2279 */
2280 private void enforceCallPermission() {
2281 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
2282 }
2283
Stuart Scott8eef64f2015-04-08 15:13:54 -07002284 private void enforceConnectivityInternalPermission() {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002285 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL,
Stuart Scott8eef64f2015-04-08 15:13:54 -07002286 "ConnectivityService");
2287 }
2288
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002289 private String createTelUrl(String number) {
2290 if (TextUtils.isEmpty(number)) {
2291 return null;
2292 }
2293
Jake Hambye994d462014-02-03 13:10:13 -08002294 return "tel:" + number;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002295 }
2296
Ihab Awadf9e92732013-12-05 18:02:52 -08002297 private static void log(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002298 Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg);
2299 }
2300
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002301 private static void logv(String msg) {
2302 Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg);
2303 }
2304
Ihab Awadf9e92732013-12-05 18:02:52 -08002305 private static void loge(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002306 Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg);
2307 }
2308
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002309 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002310 public int getActivePhoneType() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07002311 return getActivePhoneTypeForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002312 }
2313
Sanket Padawe356d7632015-06-22 14:03:32 -07002314 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002315 public int getActivePhoneTypeForSlot(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002316 final long identity = Binder.clearCallingIdentity();
2317 try {
2318 final Phone phone = PhoneFactory.getPhone(slotIndex);
2319 if (phone == null) {
2320 return PhoneConstants.PHONE_TYPE_NONE;
2321 } else {
2322 return phone.getPhoneType();
2323 }
2324 } finally {
2325 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002326 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002327 }
2328
2329 /**
2330 * Returns the CDMA ERI icon index to display
2331 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002332 @Override
2333 public int getCdmaEriIconIndex(String callingPackage) {
2334 return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002335 }
2336
Sanket Padawe356d7632015-06-22 14:03:32 -07002337 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002338 public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002339 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002340 mApp, subId, callingPackage, "getCdmaEriIconIndexForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002341 return -1;
2342 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002343
2344 final long identity = Binder.clearCallingIdentity();
2345 try {
2346 final Phone phone = getPhone(subId);
2347 if (phone != null) {
2348 return phone.getCdmaEriIconIndex();
2349 } else {
2350 return -1;
2351 }
2352 } finally {
2353 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002354 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002355 }
2356
2357 /**
2358 * Returns the CDMA ERI icon mode,
2359 * 0 - ON
2360 * 1 - FLASHING
2361 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002362 @Override
2363 public int getCdmaEriIconMode(String callingPackage) {
2364 return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002365 }
2366
Sanket Padawe356d7632015-06-22 14:03:32 -07002367 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002368 public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002369 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002370 mApp, subId, callingPackage, "getCdmaEriIconModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002371 return -1;
2372 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002373
2374 final long identity = Binder.clearCallingIdentity();
2375 try {
2376 final Phone phone = getPhone(subId);
2377 if (phone != null) {
2378 return phone.getCdmaEriIconMode();
2379 } else {
2380 return -1;
2381 }
2382 } finally {
2383 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002384 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002385 }
2386
2387 /**
2388 * Returns the CDMA ERI text,
2389 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002390 @Override
2391 public String getCdmaEriText(String callingPackage) {
2392 return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002393 }
2394
Sanket Padawe356d7632015-06-22 14:03:32 -07002395 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002396 public String getCdmaEriTextForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002397 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002398 mApp, subId, callingPackage, "getCdmaEriIconTextForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002399 return null;
2400 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002401
2402 final long identity = Binder.clearCallingIdentity();
2403 try {
2404 final Phone phone = getPhone(subId);
2405 if (phone != null) {
2406 return phone.getCdmaEriText();
2407 } else {
2408 return null;
2409 }
2410 } finally {
2411 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002412 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002413 }
2414
2415 /**
Junda Liuca05d5d2014-08-14 22:36:34 -07002416 * Returns the CDMA MDN.
2417 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002418 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002419 public String getCdmaMdn(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002420 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2421 mApp, subId, "getCdmaMdn");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002422
2423 final long identity = Binder.clearCallingIdentity();
2424 try {
2425 final Phone phone = getPhone(subId);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002426 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002427 return phone.getLine1Number();
2428 } else {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002429 loge("getCdmaMdn: no phone found. Invalid subId: " + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002430 return null;
2431 }
2432 } finally {
2433 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07002434 }
2435 }
2436
2437 /**
2438 * Returns the CDMA MIN.
2439 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002440 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002441 public String getCdmaMin(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002442 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2443 mApp, subId, "getCdmaMin");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002444
2445 final long identity = Binder.clearCallingIdentity();
2446 try {
2447 final Phone phone = getPhone(subId);
2448 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
2449 return phone.getCdmaMin();
2450 } else {
2451 return null;
2452 }
2453 } finally {
2454 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07002455 }
2456 }
2457
Hall Liud892bec2018-11-30 14:51:45 -08002458 @Override
2459 public void requestNumberVerification(PhoneNumberRange range, long timeoutMillis,
2460 INumberVerificationCallback callback, String callingPackage) {
2461 if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
2462 != PERMISSION_GRANTED) {
2463 throw new SecurityException("Caller must hold the MODIFY_PHONE_STATE permission");
2464 }
2465 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2466
2467 String authorizedPackage = NumberVerificationManager.getAuthorizedPackage(mApp);
2468 if (!TextUtils.equals(callingPackage, authorizedPackage)) {
2469 throw new SecurityException("Calling package must be configured in the device config");
2470 }
2471
2472 if (range == null) {
2473 throw new NullPointerException("Range must be non-null");
2474 }
2475
2476 timeoutMillis = Math.min(timeoutMillis,
Hall Liubd069e32019-02-28 18:56:30 -08002477 TelephonyManager.getMaxNumberVerificationTimeoutMillis());
Hall Liud892bec2018-11-30 14:51:45 -08002478
2479 NumberVerificationManager.getInstance().requestVerification(range, callback, timeoutMillis);
2480 }
2481
Junda Liuca05d5d2014-08-14 22:36:34 -07002482 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002483 * Returns true if CDMA provisioning needs to run.
2484 */
2485 public boolean needsOtaServiceProvisioning() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002486 final long identity = Binder.clearCallingIdentity();
2487 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002488 return getDefaultPhone().needsOtaServiceProvisioning();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002489 } finally {
2490 Binder.restoreCallingIdentity(identity);
2491 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002492 }
2493
2494 /**
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002495 * Sets the voice mail number of a given subId.
2496 */
2497 @Override
2498 public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002499 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setVoiceMailNumber");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002500
2501 final long identity = Binder.clearCallingIdentity();
2502 try {
2503 Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
2504 new Pair<String, String>(alphaTag, number), new Integer(subId));
2505 return success;
2506 } finally {
2507 Binder.restoreCallingIdentity(identity);
2508 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002509 }
2510
Ta-wei Yen87c49842016-05-13 21:19:52 -07002511 @Override
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002512 public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
2513 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002514 String systemDialer = TelecomManager.from(mApp).getSystemDialerPackage();
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002515 if (!TextUtils.equals(callingPackage, systemDialer)) {
2516 throw new SecurityException("caller must be system dialer");
2517 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002518
2519 final long identity = Binder.clearCallingIdentity();
2520 try {
2521 PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
2522 if (phoneAccountHandle == null) {
2523 return null;
2524 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002525 return VisualVoicemailSettingsUtil.dump(mApp, phoneAccountHandle);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002526 } finally {
2527 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002528 }
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002529 }
2530
2531 @Override
Ta-wei Yen409ac562017-03-06 16:00:44 -08002532 public String getVisualVoicemailPackageName(String callingPackage, int subId) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08002533 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jeff Davidson7e17e312018-02-13 18:17:36 -08002534 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002535 mApp, subId, callingPackage, "getVisualVoicemailPackageName")) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08002536 return null;
2537 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002538
Jeff Davidsona8e4e242018-03-15 17:16:18 -07002539 final long identity = Binder.clearCallingIdentity();
2540 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002541 return RemoteVvmTaskManager.getRemotePackage(mApp, subId).getPackageName();
Jeff Davidsona8e4e242018-03-15 17:16:18 -07002542 } finally {
2543 Binder.restoreCallingIdentity(identity);
2544 }
Ta-wei Yendca928f2017-01-10 16:17:08 -08002545 }
2546
2547 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002548 public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
2549 VisualVoicemailSmsFilterSettings settings) {
2550 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002551
2552 final long identity = Binder.clearCallingIdentity();
2553 try {
2554 VisualVoicemailSmsFilterConfig.enableVisualVoicemailSmsFilter(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002555 mApp, callingPackage, subId, settings);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002556 } finally {
2557 Binder.restoreCallingIdentity(identity);
2558 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002559 }
2560
2561 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002562 public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
2563 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002564
2565 final long identity = Binder.clearCallingIdentity();
2566 try {
2567 VisualVoicemailSmsFilterConfig.disableVisualVoicemailSmsFilter(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002568 mApp, callingPackage, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002569 } finally {
2570 Binder.restoreCallingIdentity(identity);
2571 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002572 }
2573
2574 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002575 public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
2576 String callingPackage, int subId) {
2577 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002578
2579 final long identity = Binder.clearCallingIdentity();
2580 try {
2581 return VisualVoicemailSmsFilterConfig.getVisualVoicemailSmsFilterSettings(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002582 mApp, callingPackage, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002583 } finally {
2584 Binder.restoreCallingIdentity(identity);
2585 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002586 }
2587
2588 @Override
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002589 public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002590 enforceReadPrivilegedPermission("getActiveVisualVoicemailSmsFilterSettings");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002591
2592 final long identity = Binder.clearCallingIdentity();
2593 try {
2594 return VisualVoicemailSmsFilterConfig.getActiveVisualVoicemailSmsFilterSettings(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002595 mApp, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002596 } finally {
2597 Binder.restoreCallingIdentity(identity);
2598 }
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002599 }
2600
2601 @Override
2602 public void sendVisualVoicemailSmsForSubscriber(String callingPackage, int subId,
2603 String number, int port, String text, PendingIntent sentIntent) {
2604 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Ta-wei Yen527a9c02017-01-06 15:29:25 -08002605 enforceVisualVoicemailPackage(callingPackage, subId);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002606 enforceSendSmsPermission();
2607 // Make the calls as the phone process.
2608 final long identity = Binder.clearCallingIdentity();
2609 try {
2610 SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(subId);
2611 if (port == 0) {
2612 smsManager.sendTextMessageWithSelfPermissions(number, null, text,
2613 sentIntent, null, false);
2614 } else {
2615 byte[] data = text.getBytes(StandardCharsets.UTF_8);
2616 smsManager.sendDataMessageWithSelfPermissions(number, null,
2617 (short) port, data, sentIntent, null);
2618 }
2619 } finally {
2620 Binder.restoreCallingIdentity(identity);
2621 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002622 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002623 /**
fionaxu0152e512016-11-14 13:36:14 -08002624 * Sets the voice activation state of a given subId.
2625 */
2626 @Override
2627 public void setVoiceActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002628 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2629 mApp, subId, "setVoiceActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002630
2631 final long identity = Binder.clearCallingIdentity();
2632 try {
2633 final Phone phone = getPhone(subId);
2634 if (phone != null) {
2635 phone.setVoiceActivationState(activationState);
2636 } else {
2637 loge("setVoiceActivationState fails with invalid subId: " + subId);
2638 }
2639 } finally {
2640 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002641 }
2642 }
2643
2644 /**
2645 * Sets the data activation state of a given subId.
2646 */
2647 @Override
2648 public void setDataActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002649 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2650 mApp, subId, "setDataActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002651
2652 final long identity = Binder.clearCallingIdentity();
2653 try {
2654 final Phone phone = getPhone(subId);
2655 if (phone != null) {
2656 phone.setDataActivationState(activationState);
2657 } else {
2658 loge("setVoiceActivationState fails with invalid subId: " + subId);
2659 }
2660 } finally {
2661 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002662 }
2663 }
2664
2665 /**
2666 * Returns the voice activation state of a given subId.
2667 */
2668 @Override
2669 public int getVoiceActivationState(int subId, String callingPackage) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002670 enforceReadPrivilegedPermission("getVoiceActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002671
fionaxu0152e512016-11-14 13:36:14 -08002672 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002673 final long identity = Binder.clearCallingIdentity();
2674 try {
2675 if (phone != null) {
2676 return phone.getVoiceActivationState();
2677 } else {
2678 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2679 }
2680 } finally {
2681 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002682 }
2683 }
2684
2685 /**
2686 * Returns the data activation state of a given subId.
2687 */
2688 @Override
2689 public int getDataActivationState(int subId, String callingPackage) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002690 enforceReadPrivilegedPermission("getDataActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002691
fionaxu0152e512016-11-14 13:36:14 -08002692 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002693 final long identity = Binder.clearCallingIdentity();
2694 try {
2695 if (phone != null) {
2696 return phone.getDataActivationState();
2697 } else {
2698 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2699 }
2700 } finally {
2701 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002702 }
2703 }
2704
2705 /**
Wink Saville36469e72014-06-11 15:17:00 -07002706 * Returns the unread count of voicemails for a subId
2707 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002708 @Override
Brad Ebingerf7664ba2018-11-29 12:43:38 -08002709 public int getVoiceMessageCountForSubscriber(int subId, String callingPackage) {
2710 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2711 mApp, subId, callingPackage, "getVoiceMessageCountForSubscriber")) {
2712 return 0;
2713 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002714 final long identity = Binder.clearCallingIdentity();
2715 try {
2716 final Phone phone = getPhone(subId);
2717 if (phone != null) {
2718 return phone.getVoiceMessageCount();
2719 } else {
2720 return 0;
2721 }
2722 } finally {
2723 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002724 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002725 }
2726
2727 /**
pkanwar8a4dcfb2017-01-19 13:43:16 -08002728 * returns true, if the device is in a state where both voice and data
2729 * are supported simultaneously. This can change based on location or network condition.
2730 */
2731 @Override
2732 public boolean isConcurrentVoiceAndDataAllowed(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002733 final long identity = Binder.clearCallingIdentity();
2734 try {
2735 final Phone phone = getPhone(subId);
2736 return (phone == null ? false : phone.isConcurrentVoiceAndDataAllowed());
2737 } finally {
2738 Binder.restoreCallingIdentity(identity);
2739 }
pkanwar8a4dcfb2017-01-19 13:43:16 -08002740 }
2741
2742 /**
fionaxu235cc5e2017-03-06 22:25:57 -08002743 * Send the dialer code if called from the current default dialer or the caller has
2744 * carrier privilege.
2745 * @param inputCode The dialer code to send
2746 */
2747 @Override
2748 public void sendDialerSpecialCode(String callingPackage, String inputCode) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002749 final Phone defaultPhone = getDefaultPhone();
fionaxu235cc5e2017-03-06 22:25:57 -08002750 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002751 String defaultDialer = TelecomManager.from(defaultPhone.getContext())
2752 .getDefaultDialerPackage();
fionaxu235cc5e2017-03-06 22:25:57 -08002753 if (!TextUtils.equals(callingPackage, defaultDialer)) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002754 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
2755 getDefaultSubscription(), "sendDialerSpecialCode");
fionaxu235cc5e2017-03-06 22:25:57 -08002756 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002757
2758 final long identity = Binder.clearCallingIdentity();
2759 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002760 defaultPhone.sendDialerSpecialCode(inputCode);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002761 } finally {
2762 Binder.restoreCallingIdentity(identity);
2763 }
fionaxu235cc5e2017-03-06 22:25:57 -08002764 }
2765
2766 /**
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002767 * Returns the data network type.
2768 * Legacy call, permission-free.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002769 *
2770 * @Deprecated to be removed Q3 2013 use {@link #getDataNetworkType}.
2771 */
2772 @Override
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002773 public int getNetworkType() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002774 final long identity = Binder.clearCallingIdentity();
2775 try {
2776 final Phone phone = getPhone(getDefaultSubscription());
2777 if (phone != null) {
2778 return phone.getServiceState().getDataNetworkType();
2779 } else {
2780 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2781 }
2782 } finally {
2783 Binder.restoreCallingIdentity(identity);
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002784 }
Wink Saville36469e72014-06-11 15:17:00 -07002785 }
2786
Pengquan Menga1bb6272018-09-06 09:59:22 -07002787 @Override
2788 public int getNetworkSelectionMode(int subId) {
Pengquan Menge92a50d2018-09-21 15:54:48 -07002789 if (!isActiveSubscription(subId)) {
2790 return TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
2791 }
2792
Pengquan Menga1bb6272018-09-06 09:59:22 -07002793 return (int) sendRequest(CMD_GET_NETWORK_SELECTION_MODE, null /* argument */, subId);
2794 }
2795
Brad Ebinger35c841c2018-10-01 10:40:55 -07002796 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08002797 public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback c)
2798 throws RemoteException {
2799 enforceReadPrivilegedPermission("registerImsRegistrationCallback");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002800 final long token = Binder.clearCallingIdentity();
2801 try {
Brad Ebinger4ae57f92019-01-09 16:51:30 -08002802 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002803 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger35c841c2018-10-01 10:40:55 -07002804 .addRegistrationCallbackForSubscription(c, subId);
2805 } finally {
2806 Binder.restoreCallingIdentity(token);
2807 }
2808 }
2809
2810 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08002811 public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c) {
2812 enforceReadPrivilegedPermission("unregisterImsRegistrationCallback");
Brad Ebinger4ae57f92019-01-09 16:51:30 -08002813 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2814 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
2815 }
2816 Binder.withCleanCallingIdentity(() -> {
2817 try {
2818 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002819 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08002820 .removeRegistrationCallbackForSubscription(c, subId);
2821 } catch (IllegalArgumentException e) {
2822 Log.i(LOG_TAG, "unregisterImsRegistrationCallback: " + subId
2823 + "is inactive, ignoring unregister.");
2824 // If the subscription is no longer active, just return, since the callback
2825 // will already have been removed internally.
2826 }
2827 });
Brad Ebinger35c841c2018-10-01 10:40:55 -07002828 }
2829
2830 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08002831 public void registerMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)
2832 throws RemoteException {
2833 enforceReadPrivilegedPermission("registerMmTelCapabilityCallback");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002834 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2835 final long token = Binder.clearCallingIdentity();
2836 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002837 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger35c841c2018-10-01 10:40:55 -07002838 .addCapabilitiesCallbackForSubscription(c, subId);
2839 } finally {
2840 Binder.restoreCallingIdentity(token);
2841 }
2842 }
2843
2844 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08002845 public void unregisterMmTelCapabilityCallback(int subId, IImsCapabilityCallback c) {
2846 enforceReadPrivilegedPermission("unregisterMmTelCapabilityCallback");
Brad Ebinger4ae57f92019-01-09 16:51:30 -08002847
2848 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2849 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
2850 }
2851 Binder.withCleanCallingIdentity(() -> {
2852 try {
2853 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002854 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08002855 .removeCapabilitiesCallbackForSubscription(c, subId);
2856 } catch (IllegalArgumentException e) {
2857 Log.i(LOG_TAG, "unregisterMmTelCapabilityCallback: " + subId
2858 + "is inactive, ignoring unregister.");
2859 // If the subscription is no longer active, just return, since the callback
2860 // will already have been removed internally.
2861 }
2862 });
Brad Ebinger35c841c2018-10-01 10:40:55 -07002863 }
2864
2865 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08002866 public boolean isCapable(int subId, int capability, int regTech) {
2867 enforceReadPrivilegedPermission("isCapable");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002868 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2869 final long token = Binder.clearCallingIdentity();
2870 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002871 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07002872 getSlotIndexOrException(subId)).queryMmTelCapability(capability, regTech);
2873 } catch (ImsException e) {
2874 Log.w(LOG_TAG, "IMS isCapable - service unavailable: " + e.getMessage());
2875 return false;
Brad Ebinger6b5ac222019-02-04 14:36:52 -08002876 } catch (IllegalArgumentException e) {
2877 Log.i(LOG_TAG, "isCapable: " + subId + " is inactive, returning false.");
2878 return false;
Brad Ebinger35c841c2018-10-01 10:40:55 -07002879 } finally {
2880 Binder.restoreCallingIdentity(token);
2881 }
2882 }
2883
2884 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08002885 public boolean isAvailable(int subId, int capability, int regTech) {
2886 enforceReadPrivilegedPermission("isAvailable");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002887 final long token = Binder.clearCallingIdentity();
2888 try {
2889 Phone phone = getPhone(subId);
2890 if (phone == null) return false;
2891 return phone.isImsCapabilityAvailable(capability, regTech);
2892 } finally {
2893 Binder.restoreCallingIdentity(token);
2894 }
2895 }
2896
2897 @Override
2898 public boolean isAdvancedCallingSettingEnabled(int subId) {
2899 enforceReadPrivilegedPermission("enforceReadPrivilegedPermission");
2900 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2901 final long token = Binder.clearCallingIdentity();
2902 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002903 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07002904 getSlotIndexOrException(subId)).isEnhanced4gLteModeSettingEnabledByUser();
2905 } finally {
2906 Binder.restoreCallingIdentity(token);
2907 }
2908 }
2909
2910 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08002911 public void setAdvancedCallingSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002912 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08002913 "setAdvancedCallingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002914 final long identity = Binder.clearCallingIdentity();
2915 try {
2916 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002917 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07002918 getSlotIndexOrException(subId)).setEnhanced4gLteModeSetting(isEnabled);
2919 } finally {
2920 Binder.restoreCallingIdentity(identity);
2921 }
2922 }
2923
2924 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08002925 public boolean isVtSettingEnabled(int subId) {
2926 enforceReadPrivilegedPermission("isVtSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002927 final long identity = Binder.clearCallingIdentity();
2928 try {
2929 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002930 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07002931 getSlotIndexOrException(subId)).isVtEnabledByUser();
2932 } finally {
2933 Binder.restoreCallingIdentity(identity);
2934 }
2935 }
2936
2937 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08002938 public void setVtSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002939 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08002940 "setVtSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002941 final long identity = Binder.clearCallingIdentity();
2942 try {
2943 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002944 ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setVtSetting(isEnabled);
Brad Ebinger35c841c2018-10-01 10:40:55 -07002945 } finally {
2946 Binder.restoreCallingIdentity(identity);
2947 }
2948 }
2949
2950 @Override
2951 public boolean isVoWiFiSettingEnabled(int subId) {
2952 enforceReadPrivilegedPermission("isVoWiFiSettingEnabled");
2953 final long identity = Binder.clearCallingIdentity();
2954 try {
2955 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002956 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07002957 getSlotIndexOrException(subId)).isWfcEnabledByUser();
2958 } finally {
2959 Binder.restoreCallingIdentity(identity);
2960 }
2961 }
2962
2963 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08002964 public void setVoWiFiSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002965 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08002966 "setVoWiFiSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002967 final long identity = Binder.clearCallingIdentity();
2968 try {
2969 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002970 ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setWfcSetting(isEnabled);
Brad Ebinger35c841c2018-10-01 10:40:55 -07002971 } finally {
2972 Binder.restoreCallingIdentity(identity);
2973 }
2974 }
2975
2976 @Override
2977 public boolean isVoWiFiRoamingSettingEnabled(int subId) {
2978 enforceReadPrivilegedPermission("isVoWiFiRoamingSettingEnabled");
2979 final long identity = Binder.clearCallingIdentity();
2980 try {
2981 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002982 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07002983 getSlotIndexOrException(subId)).isWfcRoamingEnabledByUser();
2984 } finally {
2985 Binder.restoreCallingIdentity(identity);
2986 }
2987 }
2988
2989 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08002990 public void setVoWiFiRoamingSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002991 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08002992 "setVoWiFiRoamingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07002993 final long identity = Binder.clearCallingIdentity();
2994 try {
2995 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002996 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07002997 getSlotIndexOrException(subId)).setWfcRoamingSetting(isEnabled);
2998 } finally {
2999 Binder.restoreCallingIdentity(identity);
3000 }
3001 }
3002
3003 @Override
3004 public void setVoWiFiNonPersistent(int subId, boolean isCapable, int mode) {
3005 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3006 "setVoWiFiNonPersistent");
3007 final long identity = Binder.clearCallingIdentity();
3008 try {
3009 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger43e66f12019-01-15 12:40:04 -08003010 boolean isRoaming = TelephonyManager.from(
3011 getPhone(subId).getContext()).isNetworkRoaming(subId);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003012 ImsManager.getInstance(mApp,
Brad Ebinger43e66f12019-01-15 12:40:04 -08003013 getSlotIndexOrException(subId)).setWfcNonPersistent(isCapable, mode, isRoaming);
Brad Ebinger35c841c2018-10-01 10:40:55 -07003014 } finally {
3015 Binder.restoreCallingIdentity(identity);
3016 }
3017 }
3018
3019 @Override
3020 public int getVoWiFiModeSetting(int subId) {
3021 enforceReadPrivilegedPermission("getVoWiFiModeSetting");
3022 final long identity = Binder.clearCallingIdentity();
3023 try {
3024 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003025 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003026 getSlotIndexOrException(subId)).getWfcMode(false /*isRoaming*/);
3027 } finally {
3028 Binder.restoreCallingIdentity(identity);
3029 }
3030 }
3031
3032 @Override
3033 public void setVoWiFiModeSetting(int subId, int mode) {
3034 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3035 "setVoWiFiModeSetting");
3036 final long identity = Binder.clearCallingIdentity();
3037 try {
3038 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003039 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003040 getSlotIndexOrException(subId)).setWfcMode(mode, false /*isRoaming*/);
3041 } finally {
3042 Binder.restoreCallingIdentity(identity);
3043 }
3044 }
3045
3046 @Override
3047 public int getVoWiFiRoamingModeSetting(int subId) {
3048 enforceReadPrivilegedPermission("getVoWiFiRoamingModeSetting");
3049 final long identity = Binder.clearCallingIdentity();
3050 try {
3051 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003052 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003053 getSlotIndexOrException(subId)).getWfcMode(true /*isRoaming*/);
3054 } finally {
3055 Binder.restoreCallingIdentity(identity);
3056 }
3057 }
3058
3059 @Override
3060 public void setVoWiFiRoamingModeSetting(int subId, int mode) {
3061 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3062 "setVoWiFiRoamingModeSetting");
3063 final long identity = Binder.clearCallingIdentity();
3064 try {
3065 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003066 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003067 getSlotIndexOrException(subId)).setWfcMode(mode, true /*isRoaming*/);
3068 } finally {
3069 Binder.restoreCallingIdentity(identity);
3070 }
3071 }
3072
3073 @Override
3074 public void setRttCapabilitySetting(int subId, boolean isEnabled) {
3075 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3076 "setRttCapabilityEnabled");
3077 final long identity = Binder.clearCallingIdentity();
3078 try {
3079 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003080 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003081 getSlotIndexOrException(subId)).setRttEnabled(isEnabled);
3082 } finally {
3083 Binder.restoreCallingIdentity(identity);
3084 }
3085 }
3086
3087 @Override
3088 public boolean isTtyOverVolteEnabled(int subId) {
3089 enforceReadPrivilegedPermission("isTtyOverVolteEnabled");
3090 final long identity = Binder.clearCallingIdentity();
3091 try {
3092 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003093 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003094 getSlotIndexOrException(subId)).isTtyOnVoLteCapable();
3095 } finally {
3096 Binder.restoreCallingIdentity(identity);
3097 }
3098 }
3099
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003100 @Override
3101 public void registerImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
3102 enforceReadPrivilegedPermission("registerImsProvisioningChangedCallback");
3103 final long identity = Binder.clearCallingIdentity();
3104 try {
3105 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003106 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003107 .addProvisioningCallbackForSubscription(callback, subId);
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003108 } finally {
3109 Binder.restoreCallingIdentity(identity);
3110 }
3111 }
3112
3113 @Override
3114 public void unregisterImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
3115 enforceReadPrivilegedPermission("unregisterImsProvisioningChangedCallback");
3116 final long identity = Binder.clearCallingIdentity();
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003117 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3118 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
3119 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003120 try {
3121 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003122 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003123 .removeProvisioningCallbackForSubscription(callback, subId);
3124 } catch (IllegalArgumentException e) {
3125 Log.i(LOG_TAG, "unregisterImsProvisioningChangedCallback: " + subId
3126 + "is inactive, ignoring unregister.");
3127 // If the subscription is no longer active, just return, since the callback will already
3128 // have been removed internally.
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003129 } finally {
3130 Binder.restoreCallingIdentity(identity);
3131 }
3132 }
3133
3134 @Override
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003135 public void setImsProvisioningStatusForCapability(int subId, int capability, int tech,
3136 boolean isProvisioned) {
3137 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3138 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3139 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
3140 }
3141 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3142 "setProvisioningStatusForCapability");
3143 final long identity = Binder.clearCallingIdentity();
3144 try {
3145 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3146 Phone phone = getPhone(subId);
3147 if (phone == null) {
3148 loge("setImsProvisioningStatusForCapability: phone instance null for subid "
3149 + subId);
3150 return;
3151 }
3152 if (!doesImsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
3153 return;
3154 }
3155
3156 // this capability requires provisioning, route to the correct API.
3157 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
3158 switch (capability) {
3159 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
3160 if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3161 ims.setVolteProvisioned(isProvisioned);
3162 } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
3163 ims.setWfcProvisioned(isProvisioned);
3164 }
3165 break;
3166 }
3167 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
3168 // There is currently no difference in VT provisioning type.
3169 ims.setVtProvisioned(isProvisioned);
3170 break;
3171 }
3172 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
3173 // There is no "deprecated" UT provisioning mechanism through ImsConfig, so
3174 // change the capability of the feature instead if needed.
3175 if (isMmTelCapabilityProvisionedInCache(subId, capability, tech)
3176 == isProvisioned) {
3177 // No change in provisioning.
3178 return;
3179 }
3180 cacheMmTelCapabilityProvisioning(subId, capability, tech, isProvisioned);
3181 try {
3182 ims.changeMmTelCapability(capability, tech, isProvisioned);
3183 } catch (ImsException e) {
3184 loge("setImsProvisioningStatusForCapability: couldn't change UT capability"
3185 + ", Exception" + e.getMessage());
3186 }
3187 break;
3188 }
3189 default: {
3190 throw new IllegalArgumentException("Tried to set provisioning for capability '"
3191 + capability + "', which does not require provisioning.");
3192 }
3193 }
3194
3195 } finally {
3196 Binder.restoreCallingIdentity(identity);
3197 }
3198 }
3199
3200 @Override
3201 public boolean getImsProvisioningStatusForCapability(int subId, int capability, int tech) {
3202 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3203 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3204 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
3205 }
3206 enforceReadPrivilegedPermission("getProvisioningStatusForCapability");
3207 final long identity = Binder.clearCallingIdentity();
3208 try {
3209 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3210 Phone phone = getPhone(subId);
3211 if (phone == null) {
3212 loge("getImsProvisioningStatusForCapability: phone instance null for subid "
3213 + subId);
3214 // We will fail with "true" as the provisioning status because this is the default
3215 // if we do not require provisioning.
3216 return true;
3217 }
3218
3219 if (!doesImsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
3220 return true;
3221 }
3222
3223 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
3224 switch (capability) {
3225 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
3226 if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3227 return ims.isVolteProvisionedOnDevice();
3228 } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
3229 return ims.isWfcProvisionedOnDevice();
3230 }
3231 // This should never happen, since we are checking tech above to make sure it
3232 // is either LTE or IWLAN.
3233 throw new IllegalArgumentException("Invalid radio technology for voice "
3234 + "capability.");
3235 }
3236 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
3237 // There is currently no difference in VT provisioning type.
3238 return ims.isVtProvisionedOnDevice();
3239 }
3240 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
3241 // There is no "deprecated" UT provisioning mechanism, so get from shared prefs.
3242 return isMmTelCapabilityProvisionedInCache(subId, capability, tech);
3243 }
3244 default: {
3245 throw new IllegalArgumentException("Tried to get provisioning for capability '"
3246 + capability + "', which does not require provisioning.");
3247 }
3248 }
3249
3250 } finally {
3251 Binder.restoreCallingIdentity(identity);
3252 }
3253 }
3254
3255 @Override
3256 public boolean isMmTelCapabilityProvisionedInCache(int subId, int capability, int tech) {
3257 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3258 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3259 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
3260 }
3261 enforceReadPrivilegedPermission("isMmTelCapabilityProvisionedInCache");
3262 int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
3263 return (provisionedBits & capability) > 0;
3264 }
3265
3266 @Override
3267 public void cacheMmTelCapabilityProvisioning(int subId, int capability, int tech,
3268 boolean isProvisioned) {
3269 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3270 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3271 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
3272 }
3273 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3274 "setProvisioningStatusForCapability");
3275 int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
3276 // If the current provisioning status for capability already matches isProvisioned,
3277 // do nothing.
3278 if (((provisionedBits & capability) > 0) == isProvisioned) {
3279 return;
3280 }
3281 if (isProvisioned) {
3282 setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits | capability));
3283 } else {
3284 setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits & ~capability));
3285 }
3286 }
3287
3288 /**
3289 * @return the bitfield containing the MmTel provisioning for the provided subscription and
3290 * technology. The bitfield should mirror the bitfield defined by
3291 * {@link MmTelFeature.MmTelCapabilities.MmTelCapability}.
3292 */
3293 private int getMmTelCapabilityProvisioningBitfield(int subId, int tech) {
3294 String key = getMmTelProvisioningKey(subId, tech);
3295 // Default is no capabilities are provisioned.
3296 return mTelephonySharedPreferences.getInt(key, 0 /*default*/);
3297 }
3298
3299 /**
3300 * Sets the MmTel capability provisioning bitfield (defined by
3301 * {@link MmTelFeature.MmTelCapabilities.MmTelCapability}) for the subscription and
3302 * technology specified.
3303 *
3304 * Note: This is a synchronous command and should not be called on UI thread.
3305 */
3306 private void setMmTelCapabilityProvisioningBitfield(int subId, int tech, int newField) {
3307 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
3308 String key = getMmTelProvisioningKey(subId, tech);
3309 editor.putInt(key, newField);
3310 editor.commit();
3311 }
3312
3313 private static String getMmTelProvisioningKey(int subId, int tech) {
3314 // resulting key is provision_ims_mmtel_{subId}_{tech}
3315 return PREF_PROVISION_IMS_MMTEL_PREFIX + subId + "_" + tech;
3316 }
3317
3318 /**
3319 * Query CarrierConfig to see if the specified capability requires provisioning for the
3320 * carrier associated with the subscription id.
3321 */
3322 private boolean doesImsCapabilityRequireProvisioning(Context context, int subId,
3323 int capability) {
3324 CarrierConfigManager configManager = new CarrierConfigManager(context);
3325 PersistableBundle c = configManager.getConfigForSubId(subId);
3326 boolean requireUtProvisioning = c.getBoolean(
3327 // By default, this config is true (even if there is no SIM). We also check to make
3328 // sure the subscription needs provisioning here, so we do not need to check for
3329 // the no-SIM case, where we would normally shortcut this to false.
3330 CarrierConfigManager.KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL, true)
3331 && c.getBoolean(CarrierConfigManager.KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL,
3332 false);
3333 boolean requireVoiceVtProvisioning = c.getBoolean(
3334 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, false);
3335
3336 // First check to make sure that the capability requires provisioning.
3337 switch (capability) {
3338 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE:
3339 // intentional fallthrough
3340 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
3341 if (requireVoiceVtProvisioning) {
3342 // Voice and Video requires provisioning
3343 return true;
3344 }
3345 break;
3346 }
3347 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
3348 if (requireUtProvisioning) {
3349 // UT requires provisioning
3350 return true;
3351 }
3352 break;
3353 }
3354 }
3355 return false;
3356 }
3357
3358 @Override
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003359 public int getImsProvisioningInt(int subId, int key) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003360 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3361 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
3362 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003363 enforceReadPrivilegedPermission("getImsProvisioningInt");
3364 final long identity = Binder.clearCallingIdentity();
3365 try {
3366 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003367 int slotId = getSlotIndex(subId);
3368 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
3369 Log.w(LOG_TAG, "getImsProvisioningInt: called with an inactive subscription '"
3370 + subId + "' for key:" + key);
3371 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
3372 }
3373 return ImsManager.getInstance(mApp, slotId).getConfigInterface().getConfigInt(key);
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003374 } catch (ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003375 Log.w(LOG_TAG, "getImsProvisioningInt: ImsService is not available for subscription '"
3376 + subId + "' for key:" + key);
3377 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003378 } finally {
3379 Binder.restoreCallingIdentity(identity);
3380 }
3381 }
3382
3383 @Override
3384 public String getImsProvisioningString(int subId, int key) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003385 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3386 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
3387 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003388 enforceReadPrivilegedPermission("getImsProvisioningString");
3389 final long identity = Binder.clearCallingIdentity();
3390 try {
3391 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003392 int slotId = getSlotIndex(subId);
3393 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
3394 Log.w(LOG_TAG, "getImsProvisioningString: called for an inactive subscription id '"
3395 + subId + "' for key:" + key);
3396 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_GENERIC;
3397 }
3398 return ImsManager.getInstance(mApp, slotId).getConfigInterface().getConfigString(key);
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003399 } catch (ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003400 Log.w(LOG_TAG, "getImsProvisioningString: ImsService is not available for sub '"
3401 + subId + "' for key:" + key);
3402 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_NOT_READY;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003403 } finally {
3404 Binder.restoreCallingIdentity(identity);
3405 }
3406 }
3407
3408 @Override
3409 public int setImsProvisioningInt(int subId, int key, int value) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003410 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3411 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
3412 }
Brad Ebinger3d0b34e2018-11-15 14:13:12 -08003413 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3414 "setImsProvisioningInt");
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003415 final long identity = Binder.clearCallingIdentity();
3416 try {
3417 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003418 int slotId = getSlotIndex(subId);
3419 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
3420 Log.w(LOG_TAG, "setImsProvisioningInt: called with an inactive subscription id '"
3421 + subId + "' for key:" + key);
3422 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
3423 }
3424 return ImsManager.getInstance(mApp, slotId).getConfigInterface().setConfig(key, value);
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003425 } catch (ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003426 Log.w(LOG_TAG, "setImsProvisioningInt: ImsService unavailable for sub '" + subId
3427 + "' for key:" + key);
3428 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003429 } finally {
3430 Binder.restoreCallingIdentity(identity);
3431 }
3432 }
3433
3434 @Override
3435 public int setImsProvisioningString(int subId, int key, String value) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003436 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3437 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
3438 }
Brad Ebinger3d0b34e2018-11-15 14:13:12 -08003439 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3440 "setImsProvisioningString");
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003441 final long identity = Binder.clearCallingIdentity();
3442 try {
3443 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003444 int slotId = getSlotIndex(subId);
3445 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
3446 Log.w(LOG_TAG, "setImsProvisioningString: called with an inactive subscription id '"
3447 + subId + "' for key:" + key);
3448 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
3449 }
3450 return ImsManager.getInstance(mApp, slotId).getConfigInterface().setConfig(key, value);
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003451 } catch (ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003452 Log.w(LOG_TAG, "setImsProvisioningString: ImsService unavailable for sub '" + subId
3453 + "' for key:" + key);
3454 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003455 } finally {
3456 Binder.restoreCallingIdentity(identity);
3457 }
3458 }
3459
Brad Ebinger35c841c2018-10-01 10:40:55 -07003460 private int getSlotIndexOrException(int subId) throws IllegalArgumentException {
3461 int slotId = SubscriptionManager.getSlotIndex(subId);
3462 if (!SubscriptionManager.isValidSlotIndex(slotId)) {
Brad Ebinger6b5ac222019-02-04 14:36:52 -08003463 throw new IllegalArgumentException("Invalid Subscription Id, subId=" + subId);
Brad Ebinger35c841c2018-10-01 10:40:55 -07003464 }
3465 return slotId;
3466 }
3467
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003468 private int getSlotIndex(int subId) {
3469 int slotId = SubscriptionManager.getSlotIndex(subId);
3470 if (!SubscriptionManager.isValidSlotIndex(slotId)) {
3471 return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
3472 }
3473 return slotId;
3474 }
3475
Wink Saville36469e72014-06-11 15:17:00 -07003476 /**
3477 * Returns the network type for a subId
3478 */
3479 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003480 public int getNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003481 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003482 mApp, subId, callingPackage, "getNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003483 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3484 }
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07003485
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003486 final long identity = Binder.clearCallingIdentity();
3487 try {
3488 final Phone phone = getPhone(subId);
3489 if (phone != null) {
3490 return phone.getServiceState().getDataNetworkType();
3491 } else {
3492 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3493 }
3494 } finally {
3495 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003496 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003497 }
3498
3499 /**
3500 * Returns the data network type
3501 */
3502 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003503 public int getDataNetworkType(String callingPackage) {
3504 return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07003505 }
3506
3507 /**
3508 * Returns the data network type for a subId
3509 */
3510 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003511 public int getDataNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003512 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003513 mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003514 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3515 }
3516
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003517 final long identity = Binder.clearCallingIdentity();
3518 try {
3519 final Phone phone = getPhone(subId);
3520 if (phone != null) {
3521 return phone.getServiceState().getDataNetworkType();
3522 } else {
3523 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3524 }
3525 } finally {
3526 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003527 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003528 }
3529
3530 /**
Wink Saville36469e72014-06-11 15:17:00 -07003531 * Returns the Voice network type for a subId
3532 */
3533 @Override
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07003534 public int getVoiceNetworkTypeForSubscriber(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 Greenwalta5dcfcb2015-07-10 09:06:29 -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().getVoiceNetworkType();
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 /**
3554 * @return true if a ICC card is present
3555 */
3556 public boolean hasIccCard() {
Wink Saville36469e72014-06-11 15:17:00 -07003557 // FIXME Make changes to pass defaultSimId of type int
Sanket Padawe13bac7b2017-03-20 15:04:47 -07003558 return hasIccCardUsingSlotIndex(mSubscriptionController.getSlotIndex(
3559 getDefaultSubscription()));
Wink Saville36469e72014-06-11 15:17:00 -07003560 }
3561
3562 /**
Sanket Padawe13bac7b2017-03-20 15:04:47 -07003563 * @return true if a ICC card is present for a slotIndex
Wink Saville36469e72014-06-11 15:17:00 -07003564 */
Sanket Padawe356d7632015-06-22 14:03:32 -07003565 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07003566 public boolean hasIccCardUsingSlotIndex(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003567 final long identity = Binder.clearCallingIdentity();
3568 try {
3569 final Phone phone = PhoneFactory.getPhone(slotIndex);
3570 if (phone != null) {
3571 return phone.getIccCard().hasIccCard();
3572 } else {
3573 return false;
3574 }
3575 } finally {
3576 Binder.restoreCallingIdentity(identity);
Amit Mahajana6fc2a82015-01-06 11:53:51 -08003577 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003578 }
3579
3580 /**
3581 * Return if the current radio is LTE on CDMA. This
3582 * is a tri-state return value as for a period of time
3583 * the mode may be unknown.
3584 *
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003585 * @param callingPackage the name of the package making the call.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003586 * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
Jake Hambye994d462014-02-03 13:10:13 -08003587 * or {@link Phone#LTE_ON_CDMA_TRUE}
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003588 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003589 @Override
3590 public int getLteOnCdmaMode(String callingPackage) {
3591 return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07003592 }
3593
Sanket Padawe356d7632015-06-22 14:03:32 -07003594 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003595 public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003596 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003597 mApp, subId, callingPackage, "getLteOnCdmaModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003598 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
3599 }
3600
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003601 final long identity = Binder.clearCallingIdentity();
3602 try {
3603 final Phone phone = getPhone(subId);
3604 if (phone == null) {
3605 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
3606 } else {
3607 return phone.getLteOnCdmaMode();
3608 }
3609 } finally {
3610 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003611 }
Wink Saville36469e72014-06-11 15:17:00 -07003612 }
3613
Wink Saville36469e72014-06-11 15:17:00 -07003614 /**
3615 * {@hide}
3616 * Returns Default subId, 0 in the case of single standby.
3617 */
Wink Savilleb564aae2014-10-23 10:18:09 -07003618 private int getDefaultSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08003619 return mSubscriptionController.getDefaultSubId();
Wink Saville36469e72014-06-11 15:17:00 -07003620 }
3621
Shishir Agrawala9f32182016-04-12 12:00:16 -07003622 private int getSlotForDefaultSubscription() {
3623 return mSubscriptionController.getPhoneId(getDefaultSubscription());
3624 }
3625
Wink Savilleb564aae2014-10-23 10:18:09 -07003626 private int getPreferredVoiceSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08003627 return mSubscriptionController.getDefaultVoiceSubId();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003628 }
Ihab Awadf2177b72013-11-25 13:33:23 -08003629
Pengquan Menge92a50d2018-09-21 15:54:48 -07003630 private boolean isActiveSubscription(int subId) {
3631 return mSubscriptionController.isActiveSubId(subId);
3632 }
3633
Ihab Awadf2177b72013-11-25 13:33:23 -08003634 /**
3635 * @see android.telephony.TelephonyManager.WifiCallingChoices
3636 */
3637 public int getWhenToMakeWifiCalls() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003638 final long identity = Binder.clearCallingIdentity();
3639 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003640 return Settings.System.getInt(mApp.getContentResolver(),
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003641 Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
3642 getWhenToMakeWifiCallsDefaultPreference());
3643 } finally {
3644 Binder.restoreCallingIdentity(identity);
3645 }
Ihab Awadf2177b72013-11-25 13:33:23 -08003646 }
3647
3648 /**
3649 * @see android.telephony.TelephonyManager.WifiCallingChoices
3650 */
3651 public void setWhenToMakeWifiCalls(int preference) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003652 final long identity = Binder.clearCallingIdentity();
3653 try {
3654 if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003655 Settings.System.putInt(mApp.getContentResolver(),
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003656 Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference);
3657 } finally {
3658 Binder.restoreCallingIdentity(identity);
3659 }
Ihab Awadf9e92732013-12-05 18:02:52 -08003660 }
3661
Sailesh Nepald1e68152013-12-12 19:08:02 -08003662 private static int getWhenToMakeWifiCallsDefaultPreference() {
Santos Cordonda120f42014-08-06 04:44:34 -07003663 // TODO: Use a build property to choose this value.
Evan Charlton9829e882013-12-19 15:30:38 -08003664 return TelephonyManager.WifiCallingChoices.ALWAYS_USE;
Ihab Awadf2177b72013-11-25 13:33:23 -08003665 }
Shishir Agrawal69f68122013-12-16 17:25:49 -08003666
Jordan Liu4c733742019-02-28 12:03:40 -08003667 private Phone getPhoneFromSlotIdOrThrowException(int slotIndex) {
3668 int phoneId = UiccController.getInstance().getPhoneIdFromSlotId(slotIndex);
3669 if (phoneId == -1) {
3670 throw new IllegalArgumentException("Given slot index: " + slotIndex
3671 + " does not correspond to an active phone");
3672 }
3673 return PhoneFactory.getPhone(phoneId);
3674 }
3675
Shishir Agrawal566b7612013-10-28 14:41:00 -07003676 @Override
Derek Tan740e1672017-06-27 14:56:27 -07003677 public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
3678 int subId, String callingPackage, String aid, int p2) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003679 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3680 mApp, subId, "iccOpenLogicalChannel");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003681 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jordan Liu4c733742019-02-28 12:03:40 -08003682 if (DBG) {
3683 log("iccOpenLogicalChannel: subId=" + subId + " aid=" + aid + " p2=" + p2);
3684 }
3685 return iccOpenLogicalChannelWithPermission(getPhoneFromSubId(subId), callingPackage, aid,
3686 p2);
3687 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003688
Jordan Liu4c733742019-02-28 12:03:40 -08003689
3690 @Override
3691 public IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(
3692 int slotIndex, String callingPackage, String aid, int p2) {
3693 enforceModifyPermission();
3694 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3695 if (DBG) {
3696 log("iccOpenLogicalChannelBySlot: slot=" + slotIndex + " aid=" + aid + " p2=" + p2);
3697 }
3698 return iccOpenLogicalChannelWithPermission(getPhoneFromSlotIdOrThrowException(slotIndex),
3699 callingPackage, aid, p2);
3700 }
3701
3702 private IccOpenLogicalChannelResponse iccOpenLogicalChannelWithPermission(Phone phone,
3703 String callingPackage, String aid, int p2) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003704 final long identity = Binder.clearCallingIdentity();
3705 try {
3706 if (TextUtils.equals(ISDR_AID, aid)) {
3707 // Only allows LPA to open logical channel to ISD-R.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003708 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
3709 .getContext().getPackageManager());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003710 if (bestComponent == null
3711 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
3712 loge("The calling package is not allowed to access ISD-R.");
3713 throw new SecurityException(
3714 "The calling package is not allowed to access ISD-R.");
3715 }
Derek Tan740e1672017-06-27 14:56:27 -07003716 }
Derek Tan740e1672017-06-27 14:56:27 -07003717
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003718 IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse) sendRequest(
Jordan Liu4c733742019-02-28 12:03:40 -08003719 CMD_OPEN_CHANNEL, new Pair<String, Integer>(aid, p2), phone,
3720 null /* workSource */);
3721 if (DBG) log("iccOpenLogicalChannelWithPermission: " + response);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003722 return response;
3723 } finally {
3724 Binder.restoreCallingIdentity(identity);
3725 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003726 }
3727
3728 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003729 public boolean iccCloseLogicalChannel(int subId, int channel) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003730 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3731 mApp, subId, "iccCloseLogicalChannel");
Jordan Liu4c733742019-02-28 12:03:40 -08003732 if (DBG) log("iccCloseLogicalChannel: subId=" + subId + " chnl=" + channel);
3733 return iccCloseLogicalChannelWithPermission(getPhoneFromSubId(subId), channel);
3734 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003735
Jordan Liu4c733742019-02-28 12:03:40 -08003736 @Override
3737 public boolean iccCloseLogicalChannelBySlot(int slotIndex, int channel) {
3738 enforceModifyPermission();
3739 if (DBG) log("iccCloseLogicalChannelBySlot: slotIndex=" + slotIndex + " chnl=" + channel);
3740 return iccCloseLogicalChannelWithPermission(getPhoneFromSlotIdOrThrowException(slotIndex),
3741 channel);
3742 }
3743
3744 private boolean iccCloseLogicalChannelWithPermission(Phone phone, int channel) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003745 final long identity = Binder.clearCallingIdentity();
3746 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003747 if (channel < 0) {
3748 return false;
3749 }
Jordan Liu4c733742019-02-28 12:03:40 -08003750 Boolean success = (Boolean) sendRequest(CMD_CLOSE_CHANNEL, channel, phone,
3751 null /* workSource */);
3752 if (DBG) log("iccCloseLogicalChannelWithPermission: " + success);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003753 return success;
3754 } finally {
3755 Binder.restoreCallingIdentity(identity);
Shishir Agrawal566b7612013-10-28 14:41:00 -07003756 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003757 }
3758
3759 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003760 public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
Shishir Agrawal566b7612013-10-28 14:41:00 -07003761 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003762 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3763 mApp, subId, "iccTransmitApduLogicalChannel");
Jordan Liu4c733742019-02-28 12:03:40 -08003764 if (DBG) {
3765 log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel
3766 + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
3767 + p3 + " data=" + data);
3768 }
3769 return iccTransmitApduLogicalChannelWithPermission(getPhoneFromSubId(subId), channel, cla,
3770 command, p1, p2, p3, data);
3771 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003772
Jordan Liu4c733742019-02-28 12:03:40 -08003773 @Override
3774 public String iccTransmitApduLogicalChannelBySlot(int slotIndex, int channel, int cla,
3775 int command, int p1, int p2, int p3, String data) {
3776 enforceModifyPermission();
3777 if (DBG) {
3778 log("iccTransmitApduLogicalChannelBySlot: slotIndex=" + slotIndex + " chnl=" + channel
3779 + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
3780 + p3 + " data=" + data);
3781 }
3782 return iccTransmitApduLogicalChannelWithPermission(
3783 getPhoneFromSlotIdOrThrowException(slotIndex), channel, cla, command, p1, p2, p3,
3784 data);
3785 }
3786
3787 private String iccTransmitApduLogicalChannelWithPermission(Phone phone, int channel, int cla,
3788 int command, int p1, int p2, int p3, String data) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003789 final long identity = Binder.clearCallingIdentity();
3790 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003791 if (channel < 0) {
3792 return "";
3793 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003794
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003795 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL,
Jordan Liu4c733742019-02-28 12:03:40 -08003796 new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), phone,
3797 null /* workSource */);
3798 if (DBG) log("iccTransmitApduLogicalChannelWithPermission: " + response);
Shishir Agrawal566b7612013-10-28 14:41:00 -07003799
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003800 // Append the returned status code to the end of the response payload.
3801 String s = Integer.toHexString(
3802 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
3803 if (response.payload != null) {
3804 s = IccUtils.bytesToHexString(response.payload) + s;
3805 }
3806 return s;
3807 } finally {
3808 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07003809 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003810 }
Jake Hambye994d462014-02-03 13:10:13 -08003811
Evan Charltonc66da362014-05-16 14:06:40 -07003812 @Override
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08003813 public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
3814 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003815 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3816 mApp, subId, "iccTransmitApduBasicChannel");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003817 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jordan Liu4c733742019-02-28 12:03:40 -08003818 if (DBG) {
3819 log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd="
3820 + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
3821 }
3822 return iccTransmitApduBasicChannelWithPermission(getPhoneFromSubId(subId), callingPackage,
3823 cla, command, p1, p2, p3, data);
3824 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003825
Jordan Liu4c733742019-02-28 12:03:40 -08003826 @Override
3827 public String iccTransmitApduBasicChannelBySlot(int slotIndex, String callingPackage, int cla,
3828 int command, int p1, int p2, int p3, String data) {
3829 enforceModifyPermission();
3830 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3831 if (DBG) {
3832 log("iccTransmitApduBasicChannelBySlot: slotIndex=" + slotIndex + " cla=" + cla
3833 + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3
3834 + " data=" + data);
3835 }
3836
3837 return iccTransmitApduBasicChannelWithPermission(
3838 getPhoneFromSlotIdOrThrowException(slotIndex), callingPackage, cla, command, p1,
3839 p2, p3, data);
3840 }
3841
3842 // open APDU basic channel assuming the caller has sufficient permissions
3843 private String iccTransmitApduBasicChannelWithPermission(Phone phone, String callingPackage,
3844 int cla, int command, int p1, int p2, int p3, String data) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003845 final long identity = Binder.clearCallingIdentity();
3846 try {
3847 if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
3848 && TextUtils.equals(ISDR_AID, data)) {
3849 // Only allows LPA to select ISD-R.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003850 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
3851 .getContext().getPackageManager());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003852 if (bestComponent == null
3853 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
3854 loge("The calling package is not allowed to select ISD-R.");
3855 throw new SecurityException(
3856 "The calling package is not allowed to select ISD-R.");
3857 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08003858 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08003859
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003860 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL,
Jordan Liu4c733742019-02-28 12:03:40 -08003861 new IccAPDUArgument(0, cla, command, p1, p2, p3, data), phone,
3862 null /* workSource */);
3863 if (DBG) log("iccTransmitApduBasicChannelWithPermission: " + response);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003864
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003865 // Append the returned status code to the end of the response payload.
3866 String s = Integer.toHexString(
3867 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
3868 if (response.payload != null) {
3869 s = IccUtils.bytesToHexString(response.payload) + s;
3870 }
3871 return s;
3872 } finally {
3873 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07003874 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003875 }
3876
3877 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003878 public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003879 String filePath) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003880 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3881 mApp, subId, "iccExchangeSimIO");
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003882
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003883 final long identity = Binder.clearCallingIdentity();
3884 try {
3885 if (DBG) {
3886 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " "
3887 + p1 + " " + p2 + " " + p3 + ":" + filePath);
3888 }
3889
3890 IccIoResult response =
3891 (IccIoResult) sendRequest(CMD_EXCHANGE_SIM_IO,
3892 new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath),
3893 subId);
3894
3895 if (DBG) {
3896 log("Exchange SIM_IO [R]" + response);
3897 }
3898
3899 byte[] result = null;
3900 int length = 2;
3901 if (response.payload != null) {
3902 length = 2 + response.payload.length;
3903 result = new byte[length];
3904 System.arraycopy(response.payload, 0, result, 0, response.payload.length);
3905 } else {
3906 result = new byte[length];
3907 }
3908
3909 result[length - 1] = (byte) response.sw2;
3910 result[length - 2] = (byte) response.sw1;
3911 return result;
3912 } finally {
3913 Binder.restoreCallingIdentity(identity);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003914 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003915 }
3916
Nathan Haroldb3014052017-01-25 15:57:32 -08003917 /**
3918 * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
3919 * on a particular subscription
3920 */
sqianb6e41952018-03-12 14:54:01 -07003921 public String[] getForbiddenPlmns(int subId, int appType, String callingPackage) {
3922 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
3923 mApp, subId, callingPackage, "getForbiddenPlmns")) {
3924 return null;
3925 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003926
3927 final long identity = Binder.clearCallingIdentity();
3928 try {
3929 if (appType != TelephonyManager.APPTYPE_USIM
3930 && appType != TelephonyManager.APPTYPE_SIM) {
3931 loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
3932 return null;
3933 }
3934 Object response = sendRequest(
3935 CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
3936 if (response instanceof String[]) {
3937 return (String[]) response;
3938 }
3939 // Response is an Exception of some kind,
3940 // which is signalled to the user as a NULL retval
Nathan Haroldb3014052017-01-25 15:57:32 -08003941 return null;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003942 } finally {
3943 Binder.restoreCallingIdentity(identity);
Nathan Haroldb3014052017-01-25 15:57:32 -08003944 }
Nathan Haroldb3014052017-01-25 15:57:32 -08003945 }
3946
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003947 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003948 public String sendEnvelopeWithStatus(int subId, String content) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003949 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3950 mApp, subId, "sendEnvelopeWithStatus");
Evan Charltonc66da362014-05-16 14:06:40 -07003951
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003952 final long identity = Binder.clearCallingIdentity();
3953 try {
3954 IccIoResult response = (IccIoResult) sendRequest(CMD_SEND_ENVELOPE, content, subId);
3955 if (response.payload == null) {
3956 return "";
3957 }
Evan Charltonc66da362014-05-16 14:06:40 -07003958
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003959 // Append the returned status code to the end of the response payload.
3960 String s = Integer.toHexString(
3961 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
3962 s = IccUtils.bytesToHexString(response.payload) + s;
3963 return s;
3964 } finally {
3965 Binder.restoreCallingIdentity(identity);
3966 }
Evan Charltonc66da362014-05-16 14:06:40 -07003967 }
3968
Jake Hambye994d462014-02-03 13:10:13 -08003969 /**
3970 * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
3971 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
3972 *
3973 * @param itemID the ID of the item to read
3974 * @return the NV item as a String, or null on error.
3975 */
3976 @Override
3977 public String nvReadItem(int itemID) {
vagdeviaf9a5b92018-08-15 16:01:53 -07003978 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08003979 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3980 mApp, getDefaultSubscription(), "nvReadItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003981
3982 final long identity = Binder.clearCallingIdentity();
3983 try {
3984 if (DBG) log("nvReadItem: item " + itemID);
vagdeviaf9a5b92018-08-15 16:01:53 -07003985 String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003986 if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
3987 return value;
3988 } finally {
3989 Binder.restoreCallingIdentity(identity);
3990 }
Jake Hambye994d462014-02-03 13:10:13 -08003991 }
3992
3993 /**
3994 * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
3995 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
3996 *
3997 * @param itemID the ID of the item to read
3998 * @param itemValue the value to write, as a String
3999 * @return true on success; false on any failure
4000 */
4001 @Override
4002 public boolean nvWriteItem(int itemID, String itemValue) {
vagdeviaf9a5b92018-08-15 16:01:53 -07004003 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08004004 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4005 mApp, getDefaultSubscription(), "nvWriteItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004006
4007 final long identity = Binder.clearCallingIdentity();
4008 try {
4009 if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
4010 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
vagdeviaf9a5b92018-08-15 16:01:53 -07004011 new Pair<Integer, String>(itemID, itemValue), workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004012 if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
4013 return success;
4014 } finally {
4015 Binder.restoreCallingIdentity(identity);
4016 }
Jake Hambye994d462014-02-03 13:10:13 -08004017 }
4018
4019 /**
4020 * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
4021 * Used for device configuration by some CDMA operators.
4022 *
4023 * @param preferredRoamingList byte array containing the new PRL
4024 * @return true on success; false on any failure
4025 */
4026 @Override
4027 public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004028 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4029 mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004030
4031 final long identity = Binder.clearCallingIdentity();
4032 try {
4033 if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
4034 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
4035 if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
4036 return success;
4037 } finally {
4038 Binder.restoreCallingIdentity(identity);
4039 }
Jake Hambye994d462014-02-03 13:10:13 -08004040 }
4041
4042 /**
chen xu6dac5ab2018-10-26 17:39:23 -07004043 * Rollback modem configurations to factory default except some config which are in whitelist.
Jake Hambye994d462014-02-03 13:10:13 -08004044 * Used for device configuration by some CDMA operators.
4045 *
chen xu6dac5ab2018-10-26 17:39:23 -07004046 * @param slotIndex - device slot.
4047 *
Jake Hambye994d462014-02-03 13:10:13 -08004048 * @return true on success; false on any failure
4049 */
4050 @Override
chen xu6dac5ab2018-10-26 17:39:23 -07004051 public boolean resetModemConfig(int slotIndex) {
4052 Phone phone = PhoneFactory.getPhone(slotIndex);
4053 if (phone != null) {
4054 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4055 mApp, phone.getSubId(), "resetModemConfig");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004056
chen xu6dac5ab2018-10-26 17:39:23 -07004057 final long identity = Binder.clearCallingIdentity();
4058 try {
4059 Boolean success = (Boolean) sendRequest(CMD_RESET_MODEM_CONFIG, null);
4060 if (DBG) log("resetModemConfig:" + ' ' + (success ? "ok" : "fail"));
4061 return success;
4062 } finally {
4063 Binder.restoreCallingIdentity(identity);
4064 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004065 }
chen xu6dac5ab2018-10-26 17:39:23 -07004066 return false;
4067 }
4068
4069 /**
4070 * Generate a radio modem reset. Used for device configuration by some CDMA operators.
4071 *
4072 * @param slotIndex - device slot.
4073 *
4074 * @return true on success; false on any failure
4075 */
4076 @Override
4077 public boolean rebootModem(int slotIndex) {
4078 Phone phone = PhoneFactory.getPhone(slotIndex);
4079 if (phone != null) {
4080 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4081 mApp, phone.getSubId(), "rebootModem");
4082
4083 final long identity = Binder.clearCallingIdentity();
4084 try {
4085 Boolean success = (Boolean) sendRequest(CMD_MODEM_REBOOT, null);
4086 if (DBG) log("rebootModem:" + ' ' + (success ? "ok" : "fail"));
4087 return success;
4088 } finally {
4089 Binder.restoreCallingIdentity(identity);
4090 }
4091 }
4092 return false;
Jake Hambye994d462014-02-03 13:10:13 -08004093 }
Jake Hamby7c27be32014-03-03 13:25:59 -08004094
Svet Ganovb320e182015-04-16 12:30:10 -07004095 public String[] getPcscfAddress(String apnType, String callingPackage) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004096 final Phone defaultPhone = getDefaultPhone();
Jeff Davidson7e17e312018-02-13 18:17:36 -08004097 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004098 mApp, defaultPhone.getSubId(), callingPackage, "getPcscfAddress")) {
Svet Ganovb320e182015-04-16 12:30:10 -07004099 return new String[0];
4100 }
4101
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004102 final long identity = Binder.clearCallingIdentity();
4103 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004104 return defaultPhone.getPcscfAddress(apnType);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004105 } finally {
4106 Binder.restoreCallingIdentity(identity);
4107 }
Wink Saville36469e72014-06-11 15:17:00 -07004108 }
4109
Brad Ebinger51f743a2017-01-23 13:50:20 -08004110 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004111 * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
4112 * status updates, if not already enabled.
Brad Ebinger51f743a2017-01-23 13:50:20 -08004113 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004114 public void enableIms(int slotId) {
Brad Ebinger51f743a2017-01-23 13:50:20 -08004115 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004116
4117 final long identity = Binder.clearCallingIdentity();
4118 try {
4119 PhoneFactory.getImsResolver().enableIms(slotId);
4120 } finally {
4121 Binder.restoreCallingIdentity(identity);
4122 }
Brad Ebinger34bef922017-11-09 10:27:08 -08004123 }
4124
4125 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004126 * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
4127 * status updates to disabled.
Brad Ebinger34bef922017-11-09 10:27:08 -08004128 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004129 public void disableIms(int slotId) {
4130 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004131
4132 final long identity = Binder.clearCallingIdentity();
4133 try {
4134 PhoneFactory.getImsResolver().disableIms(slotId);
4135 } finally {
4136 Binder.restoreCallingIdentity(identity);
4137 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004138 }
4139
4140 /**
4141 * Returns the {@link IImsMmTelFeature} that corresponds to the given slot Id for the MMTel
4142 * feature or {@link null} if the service is not available. If the feature is available, the
4143 * {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates.
4144 */
4145 public IImsMmTelFeature getMmTelFeatureAndListen(int slotId,
Brad Ebinger34bef922017-11-09 10:27:08 -08004146 IImsServiceFeatureCallback callback) {
4147 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004148
4149 final long identity = Binder.clearCallingIdentity();
4150 try {
4151 return PhoneFactory.getImsResolver().getMmTelFeatureAndListen(slotId, callback);
4152 } finally {
4153 Binder.restoreCallingIdentity(identity);
4154 }
Brad Ebinger34bef922017-11-09 10:27:08 -08004155 }
4156
4157 /**
4158 * Returns the {@link IImsRcsFeature} that corresponds to the given slot Id for the RCS
4159 * feature during emergency calling or {@link null} if the service is not available. If the
4160 * feature is available, the {@link IImsServiceFeatureCallback} callback is registered as a
4161 * listener for feature updates.
4162 */
4163 public IImsRcsFeature getRcsFeatureAndListen(int slotId, IImsServiceFeatureCallback callback) {
4164 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004165
4166 final long identity = Binder.clearCallingIdentity();
4167 try {
4168 return PhoneFactory.getImsResolver().getRcsFeatureAndListen(slotId, callback);
4169 } finally {
4170 Binder.restoreCallingIdentity(identity);
4171 }
Brad Ebinger51f743a2017-01-23 13:50:20 -08004172 }
4173
Brad Ebinger5f64b052017-12-14 14:26:15 -08004174 /**
4175 * Returns the {@link IImsRegistration} structure associated with the slotId and feature
4176 * specified.
4177 */
4178 public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
4179 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004180
4181 final long identity = Binder.clearCallingIdentity();
4182 try {
4183 return PhoneFactory.getImsResolver().getImsRegistration(slotId, feature);
4184 } finally {
4185 Binder.restoreCallingIdentity(identity);
4186 }
Brad Ebinger5f64b052017-12-14 14:26:15 -08004187 }
4188
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004189 /**
4190 * Returns the {@link IImsConfig} structure associated with the slotId and feature
4191 * specified.
4192 */
4193 public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
4194 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004195
4196 final long identity = Binder.clearCallingIdentity();
4197 try {
4198 return PhoneFactory.getImsResolver().getImsConfig(slotId, feature);
4199 } finally {
4200 Binder.restoreCallingIdentity(identity);
4201 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004202 }
4203
Brad Ebinger884c07b2018-02-15 16:17:40 -08004204 /**
Brad Ebingerdac2f002018-04-03 15:17:52 -07004205 * Sets the ImsService Package Name that Telephony will bind to.
4206 *
4207 * @param slotId the slot ID that the ImsService should bind for.
4208 * @param isCarrierImsService true if the ImsService is the carrier override, false if the
4209 * ImsService is the device default ImsService.
4210 * @param packageName The package name of the application that contains the ImsService to bind
4211 * to.
4212 * @return true if setting the ImsService to bind to succeeded, false if it did not.
4213 * @hide
4214 */
4215 public boolean setImsService(int slotId, boolean isCarrierImsService, String packageName) {
Brad Ebingerde696de2018-04-06 09:56:40 -07004216 int[] subIds = SubscriptionManager.getSubId(slotId);
4217 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
4218 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
4219 "setImsService");
4220
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004221 final long identity = Binder.clearCallingIdentity();
4222 try {
4223 return PhoneFactory.getImsResolver().overrideImsServiceConfiguration(slotId,
4224 isCarrierImsService, packageName);
4225 } finally {
4226 Binder.restoreCallingIdentity(identity);
4227 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07004228 }
4229
4230 /**
4231 * Return the ImsService configuration.
4232 *
4233 * @param slotId The slot that the ImsService is associated with.
4234 * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
4235 * the device default.
4236 * @return the package name of the ImsService configuration.
4237 */
4238 public String getImsService(int slotId, boolean isCarrierImsService) {
Brad Ebingerde696de2018-04-06 09:56:40 -07004239 int[] subIds = SubscriptionManager.getSubId(slotId);
4240 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
4241 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
4242 "getImsService");
4243
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004244 final long identity = Binder.clearCallingIdentity();
4245 try {
4246 return PhoneFactory.getImsResolver().getImsServiceConfiguration(slotId,
4247 isCarrierImsService);
4248 } finally {
4249 Binder.restoreCallingIdentity(identity);
4250 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07004251 }
4252
Wink Saville36469e72014-06-11 15:17:00 -07004253 public void setImsRegistrationState(boolean registered) {
4254 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004255
4256 final long identity = Binder.clearCallingIdentity();
4257 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004258 getDefaultPhone().setImsRegistrationState(registered);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004259 } finally {
4260 Binder.restoreCallingIdentity(identity);
4261 }
Wink Saville36469e72014-06-11 15:17:00 -07004262 }
4263
4264 /**
Stuart Scott54788802015-03-30 13:18:01 -07004265 * Set the network selection mode to automatic.
4266 *
4267 */
4268 @Override
4269 public void setNetworkSelectionModeAutomatic(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004270 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4271 mApp, subId, "setNetworkSelectionModeAutomatic");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004272
Pengquan Menge92a50d2018-09-21 15:54:48 -07004273 if (!isActiveSubscription(subId)) {
4274 return;
4275 }
4276
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004277 final long identity = Binder.clearCallingIdentity();
4278 try {
4279 if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
4280 sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId);
4281 } finally {
4282 Binder.restoreCallingIdentity(identity);
4283 }
Stuart Scott54788802015-03-30 13:18:01 -07004284 }
4285
Pengquan Mengea84e042018-09-20 14:57:26 -07004286 /**
4287 * Ask the radio to connect to the input network and change selection mode to manual.
4288 *
4289 * @param subId the id of the subscription.
4290 * @param operatorInfo the operator information, included the PLMN, long name and short name of
4291 * the operator to attach to.
4292 * @param persistSelection whether the selection will persist until reboot. If true, only allows
4293 * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
4294 * normal network selection next time.
4295 * @return {@code true} on success; {@code true} on any failure.
Shishir Agrawal302c8692015-06-19 13:49:39 -07004296 */
4297 @Override
Pengquan Mengea84e042018-09-20 14:57:26 -07004298 public boolean setNetworkSelectionModeManual(
4299 int subId, OperatorInfo operatorInfo, boolean persistSelection) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004300 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4301 mApp, subId, "setNetworkSelectionModeManual");
Pengquan Menge92a50d2018-09-21 15:54:48 -07004302
4303 if (!isActiveSubscription(subId)) {
4304 return false;
4305 }
4306
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004307 final long identity = Binder.clearCallingIdentity();
4308 try {
Pengquan Mengea84e042018-09-20 14:57:26 -07004309 ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operatorInfo,
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004310 persistSelection);
Pengquan Mengea84e042018-09-20 14:57:26 -07004311 if (DBG) {
4312 log("setNetworkSelectionModeManual: subId: " + subId
4313 + " operator: " + operatorInfo);
4314 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004315 return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
4316 } finally {
4317 Binder.restoreCallingIdentity(identity);
4318 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07004319 }
4320
4321 /**
4322 * Scans for available networks.
4323 */
4324 @Override
Hall Liuf19c44f2018-11-27 14:38:17 -08004325 public CellNetworkScanResult getCellNetworkScanResults(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004326 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4327 mApp, subId, "getCellNetworkScanResults");
Hall Liuf19c44f2018-11-27 14:38:17 -08004328 LocationAccessPolicy.LocationPermissionResult locationResult =
4329 LocationAccessPolicy.checkLocationPermission(mApp,
4330 new LocationAccessPolicy.LocationPermissionQuery.Builder()
4331 .setCallingPackage(callingPackage)
4332 .setCallingPid(Binder.getCallingPid())
4333 .setCallingUid(Binder.getCallingUid())
4334 .setMethod("getCellNetworkScanResults")
4335 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
4336 .build());
4337 switch (locationResult) {
4338 case DENIED_HARD:
4339 throw new SecurityException("Not allowed to access scan results -- location");
4340 case DENIED_SOFT:
4341 return null;
4342 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004343
Pengquan Menga1bb6272018-09-06 09:59:22 -07004344 long identity = Binder.clearCallingIdentity();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004345 try {
4346 if (DBG) log("getCellNetworkScanResults: subId " + subId);
Pengquan Menga1bb6272018-09-06 09:59:22 -07004347 return (CellNetworkScanResult) sendRequest(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004348 CMD_PERFORM_NETWORK_SCAN, null, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004349 } finally {
4350 Binder.restoreCallingIdentity(identity);
4351 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07004352 }
4353
4354 /**
yinxub1bed742017-04-17 11:45:04 -07004355 * Starts a new network scan and returns the id of this scan.
yinxu504e1392017-04-12 16:03:22 -07004356 *
yinxub1bed742017-04-17 11:45:04 -07004357 * @param subId id of the subscription
4358 * @param request contains the radio access networks with bands/channels to scan
4359 * @param messenger callback messenger for scan results or errors
4360 * @param binder for the purpose of auto clean when the user thread crashes
yinxu504e1392017-04-12 16:03:22 -07004361 * @return the id of the requested scan which can be used to stop the scan.
4362 */
4363 @Override
4364 public int requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger,
Hall Liuf19c44f2018-11-27 14:38:17 -08004365 IBinder binder, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004366 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4367 mApp, subId, "requestNetworkScan");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004368
Hall Liuf19c44f2018-11-27 14:38:17 -08004369 LocationAccessPolicy.LocationPermissionResult locationResult =
4370 LocationAccessPolicy.checkLocationPermission(mApp,
4371 new LocationAccessPolicy.LocationPermissionQuery.Builder()
4372 .setCallingPackage(callingPackage)
4373 .setCallingPid(Binder.getCallingPid())
4374 .setCallingUid(Binder.getCallingUid())
4375 .setMethod("requestNetworkScan")
4376 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
4377 .build());
4378 switch (locationResult) {
4379 case DENIED_HARD:
4380 throw new SecurityException("Not allowed to request network scan -- location");
4381 case DENIED_SOFT:
4382 return -1;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004383 }
Hall Liuf19c44f2018-11-27 14:38:17 -08004384
4385 return mNetworkScanRequestTracker.startNetworkScan(
4386 request, messenger, binder, getPhone(subId),
4387 callingPackage);
yinxu504e1392017-04-12 16:03:22 -07004388 }
4389
4390 /**
4391 * Stops an existing network scan with the given scanId.
yinxub1bed742017-04-17 11:45:04 -07004392 *
4393 * @param subId id of the subscription
4394 * @param scanId id of the scan that needs to be stopped
yinxu504e1392017-04-12 16:03:22 -07004395 */
4396 @Override
4397 public void stopNetworkScan(int subId, int scanId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004398 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4399 mApp, subId, "stopNetworkScan");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004400
4401 final long identity = Binder.clearCallingIdentity();
4402 try {
4403 mNetworkScanRequestTracker.stopNetworkScan(scanId);
4404 } finally {
4405 Binder.restoreCallingIdentity(identity);
4406 }
yinxu504e1392017-04-12 16:03:22 -07004407 }
4408
4409 /**
Junda Liu84d15a22014-07-02 11:21:04 -07004410 * Get the calculated preferred network type.
4411 * Used for debugging incorrect network type.
4412 *
4413 * @return the preferred network type, defined in RILConstants.java.
4414 */
4415 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004416 public int getCalculatedPreferredNetworkType(String callingPackage) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004417 final Phone defaultPhone = getDefaultPhone();
4418 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
4419 callingPackage, "getCalculatedPreferredNetworkType")) {
Svet Ganovb320e182015-04-16 12:30:10 -07004420 return RILConstants.PREFERRED_NETWORK_MODE;
4421 }
4422
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004423 final long identity = Binder.clearCallingIdentity();
4424 try {
4425 // FIXME: need to get SubId from somewhere.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004426 return PhoneFactory.calculatePreferredNetworkType(defaultPhone.getContext(), 0);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004427 } finally {
4428 Binder.restoreCallingIdentity(identity);
4429 }
Junda Liu84d15a22014-07-02 11:21:04 -07004430 }
4431
4432 /**
Jake Hamby7c27be32014-03-03 13:25:59 -08004433 * Get the preferred network type.
4434 * Used for device configuration by some CDMA operators.
4435 *
4436 * @return the preferred network type, defined in RILConstants.java.
4437 */
4438 @Override
Stuart Scott54788802015-03-30 13:18:01 -07004439 public int getPreferredNetworkType(int subId) {
Pengquan Menga4009cb2018-12-20 11:00:24 -08004440 TelephonyPermissions
4441 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
4442 mApp, subId, "getPreferredNetworkType");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004443
4444 final long identity = Binder.clearCallingIdentity();
4445 try {
4446 if (DBG) log("getPreferredNetworkType");
4447 int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null, subId);
4448 int networkType = (result != null ? result[0] : -1);
4449 if (DBG) log("getPreferredNetworkType: " + networkType);
4450 return networkType;
4451 } finally {
4452 Binder.restoreCallingIdentity(identity);
4453 }
Jake Hamby7c27be32014-03-03 13:25:59 -08004454 }
4455
4456 /**
4457 * Set the preferred network type.
4458 * Used for device configuration by some CDMA operators.
4459 *
4460 * @param networkType the preferred network type, defined in RILConstants.java.
4461 * @return true on success; false on any failure.
4462 */
4463 @Override
Stuart Scott54788802015-03-30 13:18:01 -07004464 public boolean setPreferredNetworkType(int subId, int networkType) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004465 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4466 mApp, subId, "setPreferredNetworkType");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004467
4468 final long identity = Binder.clearCallingIdentity();
4469 try {
4470 if (DBG) log("setPreferredNetworkType: subId " + subId + " type " + networkType);
4471 Boolean success = (Boolean) sendRequest(
4472 CMD_SET_PREFERRED_NETWORK_TYPE, networkType, subId);
4473 if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail"));
4474 if (success) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004475 Settings.Global.putInt(mApp.getContentResolver(),
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004476 Settings.Global.PREFERRED_NETWORK_MODE + subId, networkType);
4477 }
4478 return success;
4479 } finally {
4480 Binder.restoreCallingIdentity(identity);
Junda Liu80bc0d12014-07-14 16:36:44 -07004481 }
Jake Hamby7c27be32014-03-03 13:25:59 -08004482 }
Robert Greenwalted86e582014-05-21 20:03:20 -07004483
4484 /**
Amit Mahajanfe58cdf2017-07-11 12:01:53 -07004485 * Check whether DUN APN is required for tethering.
Junda Liu475951f2014-11-07 16:45:03 -08004486 *
Amit Mahajanfe58cdf2017-07-11 12:01:53 -07004487 * @return {@code true} if DUN APN is required for tethering.
Junda Liu475951f2014-11-07 16:45:03 -08004488 * @hide
4489 */
4490 @Override
Amit Mahajanfe58cdf2017-07-11 12:01:53 -07004491 public boolean getTetherApnRequired() {
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004492 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004493 final long identity = Binder.clearCallingIdentity();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004494 final Phone defaultPhone = getDefaultPhone();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004495 try {
Amit Mahajanfe58cdf2017-07-11 12:01:53 -07004496 return defaultPhone.hasMatchedTetherApnSetting();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004497 } finally {
4498 Binder.restoreCallingIdentity(identity);
Junda Liu475951f2014-11-07 16:45:03 -08004499 }
Junda Liu475951f2014-11-07 16:45:03 -08004500 }
4501
4502 /**
Robert Greenwalted86e582014-05-21 20:03:20 -07004503 * Set mobile data enabled
4504 * Used by the user through settings etc to turn on/off mobile data
4505 *
4506 * @param enable {@code true} turn turn data on, else {@code false}
4507 */
4508 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08004509 public void setUserDataEnabled(int subId, boolean enable) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004510 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4511 mApp, subId, "setUserDataEnabled");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004512
4513 final long identity = Binder.clearCallingIdentity();
4514 try {
4515 int phoneId = mSubscriptionController.getPhoneId(subId);
4516 if (DBG) log("setUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
4517 Phone phone = PhoneFactory.getPhone(phoneId);
4518 if (phone != null) {
4519 if (DBG) log("setUserDataEnabled: subId=" + subId + " enable=" + enable);
Jack Yud79fba22018-12-13 11:51:28 -08004520 phone.getDataEnabledSettings().setUserDataEnabled(enable);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004521 } else {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004522 loge("setUserDataEnabled: no phone found. Invalid subId=" + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004523 }
4524 } finally {
4525 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08004526 }
Robert Greenwalted86e582014-05-21 20:03:20 -07004527 }
4528
4529 /**
Malcolm Chen964682d2017-11-28 16:20:07 -08004530 * Get the user enabled state of Mobile Data.
4531 *
4532 * TODO: remove and use isUserDataEnabled.
4533 * This can't be removed now because some vendor codes
4534 * calls through ITelephony directly while they should
4535 * use TelephonyManager.
4536 *
4537 * @return true on enabled
4538 */
4539 @Override
4540 public boolean getDataEnabled(int subId) {
4541 return isUserDataEnabled(subId);
4542 }
4543
4544 /**
4545 * Get whether mobile data is enabled per user setting.
4546 *
4547 * There are other factors deciding whether mobile data is actually enabled, but they are
4548 * not considered here. See {@link #isDataEnabled(int)} for more details.
Robert Greenwalt646120a2014-05-23 11:54:03 -07004549 *
Jeff Davidsona1920712016-11-18 17:05:56 -08004550 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
Robert Greenwalted86e582014-05-21 20:03:20 -07004551 *
4552 * @return {@code true} if data is enabled else {@code false}
4553 */
4554 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08004555 public boolean isUserDataEnabled(int subId) {
Robert Greenwalt646120a2014-05-23 11:54:03 -07004556 try {
4557 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
4558 null);
4559 } catch (Exception e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004560 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4561 mApp, subId, "isUserDataEnabled");
Robert Greenwalt646120a2014-05-23 11:54:03 -07004562 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004563
4564 final long identity = Binder.clearCallingIdentity();
4565 try {
4566 int phoneId = mSubscriptionController.getPhoneId(subId);
4567 if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
4568 Phone phone = PhoneFactory.getPhone(phoneId);
4569 if (phone != null) {
4570 boolean retVal = phone.isUserDataEnabled();
4571 if (DBG) log("isUserDataEnabled: subId=" + subId + " retVal=" + retVal);
4572 return retVal;
4573 } else {
4574 if (DBG) loge("isUserDataEnabled: no phone subId=" + subId + " retVal=false");
4575 return false;
4576 }
4577 } finally {
4578 Binder.restoreCallingIdentity(identity);
Malcolm Chen964682d2017-11-28 16:20:07 -08004579 }
4580 }
4581
4582 /**
4583 * Get whether mobile data is enabled.
4584 *
4585 * Comparable to {@link #isUserDataEnabled(int)}, this considers all factors deciding
4586 * whether mobile data is actually enabled.
4587 *
4588 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
4589 *
4590 * @return {@code true} if data is enabled else {@code false}
4591 */
4592 @Override
4593 public boolean isDataEnabled(int subId) {
4594 try {
4595 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
4596 null);
4597 } catch (Exception e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004598 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4599 mApp, subId, "isDataEnabled");
Malcolm Chen964682d2017-11-28 16:20:07 -08004600 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004601
4602 final long identity = Binder.clearCallingIdentity();
4603 try {
4604 int phoneId = mSubscriptionController.getPhoneId(subId);
4605 if (DBG) log("isDataEnabled: subId=" + subId + " phoneId=" + phoneId);
4606 Phone phone = PhoneFactory.getPhone(phoneId);
4607 if (phone != null) {
Jack Yud79fba22018-12-13 11:51:28 -08004608 boolean retVal = phone.getDataEnabledSettings().isDataEnabled();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004609 if (DBG) log("isDataEnabled: subId=" + subId + " retVal=" + retVal);
4610 return retVal;
4611 } else {
4612 if (DBG) loge("isDataEnabled: no phone subId=" + subId + " retVal=false");
4613 return false;
4614 }
4615 } finally {
4616 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08004617 }
Robert Greenwalted86e582014-05-21 20:03:20 -07004618 }
Shishir Agrawal60f9c952014-06-23 12:00:43 -07004619
4620 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004621 public int getCarrierPrivilegeStatus(int subId) {
4622 final Phone phone = getPhone(subId);
4623 if (phone == null) {
4624 loge("getCarrierPrivilegeStatus: Invalid subId");
4625 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
4626 }
4627 UiccCard card = UiccController.getInstance().getUiccCard(phone.getPhoneId());
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07004628 if (card == null) {
Shishir Agrawal5e5becd2014-11-18 11:38:23 -08004629 loge("getCarrierPrivilegeStatus: No UICC");
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07004630 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
4631 }
4632 return card.getCarrierPrivilegeStatusForCurrentTransaction(
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004633 phone.getContext().getPackageManager());
Shishir Agrawal60f9c952014-06-23 12:00:43 -07004634 }
Junda Liu29340342014-07-10 15:23:27 -07004635
4636 @Override
Jeff Davidson7e17e312018-02-13 18:17:36 -08004637 public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
4638 final Phone phone = getPhone(subId);
4639 if (phone == null) {
4640 loge("getCarrierPrivilegeStatus: Invalid subId");
4641 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
4642 }
4643 UiccProfile profile =
4644 UiccController.getInstance().getUiccProfileForPhone(phone.getPhoneId());
4645 if (profile == null) {
4646 loge("getCarrierPrivilegeStatus: No UICC");
4647 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
4648 }
4649 return profile.getCarrierPrivilegeStatusForUid(phone.getContext().getPackageManager(), uid);
4650 }
4651
4652 @Override
Zach Johnson50ecba32015-05-19 00:24:21 -07004653 public int checkCarrierPrivilegesForPackage(String pkgName) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004654 final Phone defaultPhone = getDefaultPhone();
Junda Liu317d70b2016-03-08 09:33:53 -08004655 if (TextUtils.isEmpty(pkgName))
4656 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004657 UiccCard card = UiccController.getInstance().getUiccCard(defaultPhone.getPhoneId());
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07004658 if (card == null) {
4659 loge("checkCarrierPrivilegesForPackage: No UICC");
4660 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
4661 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004662 return card.getCarrierPrivilegeStatus(defaultPhone.getContext().getPackageManager(),
4663 pkgName);
Zach Johnson50ecba32015-05-19 00:24:21 -07004664 }
4665
4666 @Override
4667 public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
Junda Liu317d70b2016-03-08 09:33:53 -08004668 if (TextUtils.isEmpty(pkgName))
4669 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Zach Johnson50ecba32015-05-19 00:24:21 -07004670 int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
4671 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
4672 UiccCard card = UiccController.getInstance().getUiccCard(i);
4673 if (card == null) {
Jonathan Basseri7d320df2015-06-16 12:17:08 -07004674 // No UICC in that slot.
Zach Johnson50ecba32015-05-19 00:24:21 -07004675 continue;
4676 }
4677
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004678 result = card.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName);
Zach Johnson50ecba32015-05-19 00:24:21 -07004679 if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
4680 break;
4681 }
4682 }
4683
4684 return result;
Junda Liu29340342014-07-10 15:23:27 -07004685 }
Derek Tan89e89d42014-07-08 17:00:10 -07004686
4687 @Override
Junda Liue64de782015-04-16 17:19:16 -07004688 public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
4689 if (!SubscriptionManager.isValidPhoneId(phoneId)) {
4690 loge("phoneId " + phoneId + " is not valid.");
4691 return null;
4692 }
4693 UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07004694 if (card == null) {
Diego Pontorieroaf74c862014-08-28 11:51:16 -07004695 loge("getCarrierPackageNamesForIntent: No UICC");
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07004696 return null ;
4697 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004698 return card.getCarrierPackageNamesForIntent(mApp.getPackageManager(), intent);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07004699 }
4700
Amith Yamasani6e118872016-02-19 12:53:51 -08004701 @Override
4702 public List<String> getPackagesWithCarrierPrivileges() {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004703 PackageManager pm = mApp.getPackageManager();
Amith Yamasani6e118872016-02-19 12:53:51 -08004704 List<String> privilegedPackages = new ArrayList<>();
4705 List<PackageInfo> packages = null;
4706 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
4707 UiccCard card = UiccController.getInstance().getUiccCard(i);
4708 if (card == null) {
4709 // No UICC in that slot.
4710 continue;
4711 }
4712 if (card.hasCarrierPrivilegeRules()) {
4713 if (packages == null) {
4714 // Only check packages in user 0 for now
4715 packages = pm.getInstalledPackagesAsUser(
4716 PackageManager.MATCH_DISABLED_COMPONENTS
4717 | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
4718 | PackageManager.GET_SIGNATURES, UserHandle.USER_SYSTEM);
4719 }
4720 for (int p = packages.size() - 1; p >= 0; p--) {
4721 PackageInfo pkgInfo = packages.get(p);
4722 if (pkgInfo != null && pkgInfo.packageName != null
4723 && card.getCarrierPrivilegeStatus(pkgInfo)
4724 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
4725 privilegedPackages.add(pkgInfo.packageName);
4726 }
4727 }
4728 }
4729 }
4730 return privilegedPackages;
4731 }
4732
Wink Savilleb564aae2014-10-23 10:18:09 -07004733 private String getIccId(int subId) {
Sanket Padawe356d7632015-06-22 14:03:32 -07004734 final Phone phone = getPhone(subId);
4735 UiccCard card = phone == null ? null : phone.getUiccCard();
Derek Tan97ebb422014-09-05 16:55:38 -07004736 if (card == null) {
4737 loge("getIccId: No UICC");
4738 return null;
4739 }
4740 String iccId = card.getIccId();
4741 if (TextUtils.isEmpty(iccId)) {
4742 loge("getIccId: ICC ID is null or empty.");
4743 return null;
4744 }
4745 return iccId;
4746 }
4747
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07004748 @Override
Jeff Sharkey85190e62014-12-05 09:40:12 -08004749 public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
4750 String number) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004751 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
4752 subId, "setLine1NumberForDisplayForSubscriber");
Derek Tan97ebb422014-09-05 16:55:38 -07004753
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004754 final long identity = Binder.clearCallingIdentity();
4755 try {
4756 final String iccId = getIccId(subId);
4757 final Phone phone = getPhone(subId);
4758 if (phone == null) {
4759 return false;
4760 }
4761 final String subscriberId = phone.getSubscriberId();
4762
4763 if (DBG_MERGE) {
4764 Slog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId="
4765 + subscriberId + " to " + number);
4766 }
4767
4768 if (TextUtils.isEmpty(iccId)) {
4769 return false;
4770 }
4771
4772 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
4773
4774 final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
4775 if (alphaTag == null) {
4776 editor.remove(alphaTagPrefKey);
4777 } else {
4778 editor.putString(alphaTagPrefKey, alphaTag);
4779 }
4780
4781 // Record both the line number and IMSI for this ICCID, since we need to
4782 // track all merged IMSIs based on line number
4783 final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
4784 final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
4785 if (number == null) {
4786 editor.remove(numberPrefKey);
4787 editor.remove(subscriberPrefKey);
4788 } else {
4789 editor.putString(numberPrefKey, number);
4790 editor.putString(subscriberPrefKey, subscriberId);
4791 }
4792
4793 editor.commit();
4794 return true;
4795 } finally {
4796 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004797 }
Derek Tan7226c842014-07-02 17:42:23 -07004798 }
4799
4800 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004801 public String getLine1NumberForDisplay(int subId, String callingPackage) {
Makoto Onukifee69342015-06-29 14:44:50 -07004802 // This is open to apps with WRITE_SMS.
Jeff Davidson7e17e312018-02-13 18:17:36 -08004803 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
Jeff Davidson913390f2018-02-23 17:11:49 -08004804 mApp, subId, callingPackage, "getLine1NumberForDisplay")) {
Amit Mahajan9cf11512015-11-09 11:40:48 -08004805 if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
Svet Ganovb320e182015-04-16 12:30:10 -07004806 return null;
4807 }
Derek Tan97ebb422014-09-05 16:55:38 -07004808
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004809 final long identity = Binder.clearCallingIdentity();
4810 try {
4811 String iccId = getIccId(subId);
4812 if (iccId != null) {
4813 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
4814 if (DBG_MERGE) {
4815 log("getLine1NumberForDisplay returning "
4816 + mTelephonySharedPreferences.getString(numberPrefKey, null));
4817 }
4818 return mTelephonySharedPreferences.getString(numberPrefKey, null);
Amit Mahajan9cf11512015-11-09 11:40:48 -08004819 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004820 if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null");
4821 return null;
4822 } finally {
4823 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07004824 }
Derek Tan7226c842014-07-02 17:42:23 -07004825 }
4826
4827 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004828 public String getLine1AlphaTagForDisplay(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004829 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08004830 mApp, subId, callingPackage, "getLine1AlphaTagForDisplay")) {
Svet Ganovb320e182015-04-16 12:30:10 -07004831 return null;
4832 }
Derek Tan97ebb422014-09-05 16:55:38 -07004833
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004834 final long identity = Binder.clearCallingIdentity();
4835 try {
4836 String iccId = getIccId(subId);
4837 if (iccId != null) {
4838 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
4839 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null);
4840 }
4841 return null;
4842 } finally {
4843 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07004844 }
Derek Tan7226c842014-07-02 17:42:23 -07004845 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07004846
4847 @Override
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07004848 public String[] getMergedSubscriberIds(String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08004849 // This API isn't public, so no need to provide a valid subscription ID - we're not worried
4850 // about carrier-privileged callers not having access.
Jeff Davidson7e17e312018-02-13 18:17:36 -08004851 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08004852 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
4853 "getMergedSubscriberIds")) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07004854 return null;
4855 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08004856
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07004857 final long identity = Binder.clearCallingIdentity();
4858 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004859 final Context context = mApp;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004860 final TelephonyManager tele = TelephonyManager.from(context);
4861 final SubscriptionManager sub = SubscriptionManager.from(context);
4862
4863 // Figure out what subscribers are currently active
4864 final ArraySet<String> activeSubscriberIds = new ArraySet<>();
4865 // Clear calling identity, when calling TelephonyManager, because callerUid must be
4866 // the process, where TelephonyManager was instantiated.
4867 // Otherwise AppOps check will fail.
4868
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07004869 final int[] subIds = sub.getActiveSubscriptionIdList();
4870 for (int subId : subIds) {
4871 activeSubscriberIds.add(tele.getSubscriberId(subId));
4872 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004873
4874 // First pass, find a number override for an active subscriber
4875 String mergeNumber = null;
4876 final Map<String, ?> prefs = mTelephonySharedPreferences.getAll();
4877 for (String key : prefs.keySet()) {
4878 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) {
4879 final String subscriberId = (String) prefs.get(key);
4880 if (activeSubscriberIds.contains(subscriberId)) {
4881 final String iccId = key.substring(
4882 PREF_CARRIERS_SUBSCRIBER_PREFIX.length());
4883 final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
4884 mergeNumber = (String) prefs.get(numberKey);
4885 if (DBG_MERGE) {
4886 Slog.d(LOG_TAG, "Found line number " + mergeNumber
4887 + " for active subscriber " + subscriberId);
4888 }
4889 if (!TextUtils.isEmpty(mergeNumber)) {
4890 break;
4891 }
4892 }
4893 }
4894 }
4895
4896 // Shortcut when no active merged subscribers
4897 if (TextUtils.isEmpty(mergeNumber)) {
4898 return null;
4899 }
4900
4901 // Second pass, find all subscribers under that line override
4902 final ArraySet<String> result = new ArraySet<>();
4903 for (String key : prefs.keySet()) {
4904 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) {
4905 final String number = (String) prefs.get(key);
4906 if (mergeNumber.equals(number)) {
4907 final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length());
4908 final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
4909 final String subscriberId = (String) prefs.get(subscriberKey);
4910 if (!TextUtils.isEmpty(subscriberId)) {
4911 result.add(subscriberId);
4912 }
4913 }
4914 }
4915 }
4916
4917 final String[] resultArray = result.toArray(new String[result.size()]);
4918 Arrays.sort(resultArray);
4919 if (DBG_MERGE) {
4920 Slog.d(LOG_TAG,
4921 "Found subscribers " + Arrays.toString(resultArray) + " after merge");
4922 }
4923 return resultArray;
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07004924 } finally {
4925 Binder.restoreCallingIdentity(identity);
Jeff Sharkey85190e62014-12-05 09:40:12 -08004926 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08004927 }
4928
4929 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004930 public boolean setOperatorBrandOverride(int subId, String brand) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004931 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
4932 subId, "setOperatorBrandOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004933
4934 final long identity = Binder.clearCallingIdentity();
4935 try {
4936 final Phone phone = getPhone(subId);
4937 return phone == null ? false : phone.setOperatorBrandOverride(brand);
4938 } finally {
4939 Binder.restoreCallingIdentity(identity);
4940 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07004941 }
Steven Liu4bf01bc2014-07-17 11:05:29 -05004942
4943 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004944 public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
Shishir Agrawal621a47c2014-12-01 10:25:09 -08004945 List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
4946 List<String> cdmaNonRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004947 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setRoamingOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004948
4949 final long identity = Binder.clearCallingIdentity();
4950 try {
4951 final Phone phone = getPhone(subId);
4952 if (phone == null) {
4953 return false;
4954 }
4955 return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList,
4956 cdmaNonRoamingList);
4957 } finally {
4958 Binder.restoreCallingIdentity(identity);
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004959 }
Shishir Agrawal621a47c2014-12-01 10:25:09 -08004960 }
4961
4962 @Override
Shuo Qian850e4d6a2018-04-25 21:02:08 +00004963 @Deprecated
4964 public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
4965 enforceModifyPermission();
4966
4967 int returnValue = 0;
4968 try {
vagdeviaf9a5b92018-08-15 16:01:53 -07004969 AsyncResult result = (AsyncResult) sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
Shuo Qian850e4d6a2018-04-25 21:02:08 +00004970 if(result.exception == null) {
4971 if (result.result != null) {
4972 byte[] responseData = (byte[])(result.result);
4973 if(responseData.length > oemResp.length) {
4974 Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +
4975 responseData.length + "bytes. Buffer Size is " +
4976 oemResp.length + "bytes.");
4977 }
4978 System.arraycopy(responseData, 0, oemResp, 0, responseData.length);
4979 returnValue = responseData.length;
4980 }
4981 } else {
4982 CommandException ex = (CommandException) result.exception;
4983 returnValue = ex.getCommandError().ordinal();
4984 if(returnValue > 0) returnValue *= -1;
4985 }
4986 } catch (RuntimeException e) {
4987 Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");
4988 returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());
4989 if(returnValue > 0) returnValue *= -1;
4990 }
4991
4992 return returnValue;
4993 }
4994
4995 @Override
Wink Saville5d475dd2014-10-17 15:00:58 -07004996 public void setRadioCapability(RadioAccessFamily[] rafs) {
4997 try {
4998 ProxyController.getInstance().setRadioCapability(rafs);
4999 } catch (RuntimeException e) {
5000 Log.w(LOG_TAG, "setRadioCapability: Runtime Exception");
5001 }
5002 }
5003
5004 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07005005 public int getRadioAccessFamily(int phoneId, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08005006 Phone phone = PhoneFactory.getPhone(phoneId);
chen xub97461a2018-10-26 14:17:57 -07005007 int raf = RadioAccessFamily.RAF_UNKNOWN;
Jeff Davidson913390f2018-02-23 17:11:49 -08005008 if (phone == null) {
chen xub97461a2018-10-26 14:17:57 -07005009 return raf;
Jeff Davidson913390f2018-02-23 17:11:49 -08005010 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005011 final long identity = Binder.clearCallingIdentity();
5012 try {
chen xub97461a2018-10-26 14:17:57 -07005013 TelephonyPermissions
5014 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5015 mApp, phone.getSubId(), "getRadioAccessFamily");
5016 raf = ProxyController.getInstance().getRadioAccessFamily(phoneId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005017 } finally {
5018 Binder.restoreCallingIdentity(identity);
5019 }
chen xub97461a2018-10-26 14:17:57 -07005020 return raf;
Wink Saville5d475dd2014-10-17 15:00:58 -07005021 }
Andrew Leedf14ead2014-10-17 14:22:52 -07005022
5023 @Override
5024 public void enableVideoCalling(boolean enable) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005025 final Phone defaultPhone = getDefaultPhone();
Andrew Leedf14ead2014-10-17 14:22:52 -07005026 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005027
5028 final long identity = Binder.clearCallingIdentity();
5029 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005030 ImsManager.getInstance(defaultPhone.getContext(),
5031 defaultPhone.getPhoneId()).setVtSetting(enable);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005032 } finally {
5033 Binder.restoreCallingIdentity(identity);
5034 }
Andrew Leedf14ead2014-10-17 14:22:52 -07005035 }
5036
5037 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07005038 public boolean isVideoCallingEnabled(String callingPackage) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005039 final Phone defaultPhone = getDefaultPhone();
Amit Mahajan578e53d2018-03-20 16:18:38 +00005040 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005041 mApp, defaultPhone.getSubId(), callingPackage, "isVideoCallingEnabled")) {
Amit Mahajan578e53d2018-03-20 16:18:38 +00005042 return false;
5043 }
Svet Ganovb320e182015-04-16 12:30:10 -07005044
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005045 final long identity = Binder.clearCallingIdentity();
5046 try {
5047 // Check the user preference and the system-level IMS setting. Even if the user has
5048 // enabled video calling, if IMS is disabled we aren't able to support video calling.
5049 // In the long run, we may instead need to check if there exists a connection service
5050 // which can support video calling.
5051 ImsManager imsManager =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005052 ImsManager.getInstance(defaultPhone.getContext(), defaultPhone.getPhoneId());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005053 return imsManager.isVtEnabledByPlatform()
5054 && imsManager.isEnhanced4gLteModeSettingEnabledByUser()
5055 && imsManager.isVtEnabledByUser();
5056 } finally {
5057 Binder.restoreCallingIdentity(identity);
5058 }
Andrew Leedf14ead2014-10-17 14:22:52 -07005059 }
Libin.Tang@motorola.comafe82642014-12-18 13:27:53 -06005060
Andrew Leea1239f22015-03-02 17:44:07 -08005061 @Override
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005062 public boolean canChangeDtmfToneLength(int subId, String callingPackage) {
5063 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5064 mApp, subId, callingPackage, "isVideoCallingEnabled")) {
5065 return false;
5066 }
5067
5068 final long identity = Binder.clearCallingIdentity();
5069 try {
5070 CarrierConfigManager configManager =
5071 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005072 return configManager.getConfigForSubId(subId)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005073 .getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL);
5074 } finally {
5075 Binder.restoreCallingIdentity(identity);
5076 }
Andrew Leea1239f22015-03-02 17:44:07 -08005077 }
5078
5079 @Override
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005080 public boolean isWorldPhone(int subId, String callingPackage) {
5081 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5082 mApp, subId, callingPackage, "isVideoCallingEnabled")) {
5083 return false;
5084 }
5085
5086 final long identity = Binder.clearCallingIdentity();
5087 try {
5088 CarrierConfigManager configManager =
5089 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005090 return configManager.getConfigForSubId(subId)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005091 .getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL);
5092 } finally {
5093 Binder.restoreCallingIdentity(identity);
5094 }
Andrew Leea1239f22015-03-02 17:44:07 -08005095 }
5096
Andrew Lee9431b832015-03-09 18:46:45 -07005097 @Override
5098 public boolean isTtyModeSupported() {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005099 TelecomManager telecomManager = TelecomManager.from(mApp);
Wooki Wu1f82f7a2016-02-15 15:59:58 +08005100 return telecomManager.isTtySupported();
Andrew Lee9431b832015-03-09 18:46:45 -07005101 }
5102
5103 @Override
5104 public boolean isHearingAidCompatibilitySupported() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005105 final long identity = Binder.clearCallingIdentity();
5106 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005107 return mApp.getResources().getBoolean(R.bool.hac_enabled);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005108 } finally {
5109 Binder.restoreCallingIdentity(identity);
5110 }
Andrew Lee9431b832015-03-09 18:46:45 -07005111 }
5112
Hall Liuf6668912018-10-31 17:05:23 -07005113 /**
5114 * Determines whether the device currently supports RTT (Real-time text). Based both on carrier
5115 * support for the feature and device firmware support.
5116 *
5117 * @return {@code true} if the device and carrier both support RTT, {@code false} otherwise.
5118 */
5119 @Override
5120 public boolean isRttSupported(int subscriptionId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005121 final long identity = Binder.clearCallingIdentity();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005122 final Phone phone = getPhone(subscriptionId);
5123 if (phone == null) {
5124 loge("isRttSupported: no Phone found. Invalid subId:" + subscriptionId);
5125 return false;
5126 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005127 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005128 boolean isCarrierSupported = mApp.getCarrierConfigForSubId(subscriptionId).getBoolean(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005129 CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
5130 boolean isDeviceSupported =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005131 phone.getContext().getResources().getBoolean(R.bool.config_support_rtt);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005132 return isCarrierSupported && isDeviceSupported;
5133 } finally {
5134 Binder.restoreCallingIdentity(identity);
5135 }
Hall Liu98187582018-01-22 19:15:32 -08005136 }
5137
Hall Liuf6668912018-10-31 17:05:23 -07005138 /**
5139 * Determines whether the user has turned on RTT. Only returns true if the device and carrier
5140 * both also support RTT.
5141 */
5142 public boolean isRttEnabled(int subscriptionId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005143 final long identity = Binder.clearCallingIdentity();
5144 try {
Hall Liuf6668912018-10-31 17:05:23 -07005145 return isRttSupported(subscriptionId) && Settings.Secure.getInt(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005146 mApp.getContentResolver(), Settings.Secure.RTT_CALLING_MODE, 0) != 0;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005147 } finally {
5148 Binder.restoreCallingIdentity(identity);
5149 }
Hall Liu3ad5f012018-04-06 16:23:39 -07005150 }
5151
Sanket Padawe7310cc72015-01-14 09:53:20 -08005152 /**
5153 * Returns the unique device ID of phone, for example, the IMEI for
5154 * GSM and the MEID for CDMA phones. Return null if device ID is not available.
5155 *
5156 * <p>Requires Permission:
5157 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
5158 */
5159 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07005160 public String getDeviceId(String callingPackage) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08005161 final Phone phone = PhoneFactory.getPhone(0);
Jeff Davidson913390f2018-02-23 17:11:49 -08005162 if (phone == null) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08005163 return null;
5164 }
Jeff Davidson913390f2018-02-23 17:11:49 -08005165 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07005166 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
5167 callingPackage, "getDeviceId")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08005168 return null;
5169 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005170
5171 final long identity = Binder.clearCallingIdentity();
5172 try {
5173 return phone.getDeviceId();
5174 } finally {
5175 Binder.restoreCallingIdentity(identity);
5176 }
Sanket Padawe7310cc72015-01-14 09:53:20 -08005177 }
5178
Ping Sunc67b7c22016-03-02 19:16:45 +08005179 /**
5180 * {@hide}
5181 * Returns the IMS Registration Status on a particular subid
5182 *
5183 * @param subId
5184 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005185 public boolean isImsRegistered(int subId) {
Ping Sunc67b7c22016-03-02 19:16:45 +08005186 Phone phone = getPhone(subId);
5187 if (phone != null) {
5188 return phone.isImsRegistered();
5189 } else {
5190 return false;
5191 }
5192 }
5193
Santos Cordon7a1885b2015-02-03 11:15:19 -08005194 @Override
5195 public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005196 final long identity = Binder.clearCallingIdentity();
5197 try {
5198 return PhoneUtils.getSubIdForPhoneAccount(phoneAccount);
5199 } finally {
5200 Binder.restoreCallingIdentity(identity);
5201 }
Santos Cordon7a1885b2015-02-03 11:15:19 -08005202 }
Nathan Harolddcfc7932015-03-18 10:01:20 -07005203
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005204 /**
5205 * @return the VoWiFi calling availability.
Nathan Haroldc55097a2015-03-11 18:14:50 -07005206 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005207 public boolean isWifiCallingAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005208 final long identity = Binder.clearCallingIdentity();
5209 try {
5210 Phone phone = getPhone(subId);
5211 if (phone != null) {
5212 return phone.isWifiCallingEnabled();
5213 } else {
5214 return false;
5215 }
5216 } finally {
5217 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005218 }
Nathan Haroldc55097a2015-03-11 18:14:50 -07005219 }
5220
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005221 /**
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005222 * @return the VT calling availability.
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07005223 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005224 public boolean isVideoTelephonyAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005225 final long identity = Binder.clearCallingIdentity();
5226 try {
5227 Phone phone = getPhone(subId);
5228 if (phone != null) {
5229 return phone.isVideoEnabled();
5230 } else {
5231 return false;
5232 }
5233 } finally {
5234 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005235 }
5236 }
5237
5238 /**
5239 * @return the IMS registration technology for the MMTEL feature. Valid return values are
5240 * defined in {@link ImsRegistrationImplBase}.
5241 */
5242 public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005243 final long identity = Binder.clearCallingIdentity();
5244 try {
5245 Phone phone = getPhone(subId);
5246 if (phone != null) {
5247 return phone.getImsRegistrationTech();
5248 } else {
5249 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
5250 }
5251 } finally {
5252 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08005253 }
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07005254 }
5255
Stuart Scott8eef64f2015-04-08 15:13:54 -07005256 @Override
5257 public void factoryReset(int subId) {
5258 enforceConnectivityInternalPermission();
Stuart Scott981d8582015-04-21 14:09:50 -07005259 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
5260 return;
5261 }
5262
Svet Ganovcc087f82015-05-12 20:35:54 -07005263 final long identity = Binder.clearCallingIdentity();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005264
Svet Ganovcc087f82015-05-12 20:35:54 -07005265 try {
Stuart Scott981d8582015-04-21 14:09:50 -07005266 if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
5267 UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
Pengquan Meng85728fb2018-03-12 16:31:21 -07005268 setUserDataEnabled(subId, getDefaultDataEnabled());
Svet Ganovcc087f82015-05-12 20:35:54 -07005269 setNetworkSelectionModeAutomatic(subId);
Pengquan Meng85728fb2018-03-12 16:31:21 -07005270 setPreferredNetworkType(subId, getDefaultNetworkType(subId));
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005271 setDataRoamingEnabled(subId, getDefaultDataRoamingEnabled(subId));
5272 CarrierInfoManager.deleteAllCarrierKeysForImsiEncryption(mApp);
Svet Ganovcc087f82015-05-12 20:35:54 -07005273 }
5274 } finally {
5275 Binder.restoreCallingIdentity(identity);
Stuart Scott8eef64f2015-04-08 15:13:54 -07005276 }
5277 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01005278
5279 @Override
chen xu5d3637b2019-01-21 23:31:38 -08005280 public String getSimLocaleForSubscriber(int subId) {
5281 enforceReadPrivilegedPermission("getSimLocaleForSubscriber, subId: " + subId);
5282 final Phone phone = getPhone(subId);
5283 if (phone == null) {
5284 log("getSimLocaleForSubscriber, invalid subId");
chen xu2bb91e42019-01-24 14:35:54 -08005285 return null;
chen xu5d3637b2019-01-21 23:31:38 -08005286 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005287 final long identity = Binder.clearCallingIdentity();
5288 try {
chen xu5d3637b2019-01-21 23:31:38 -08005289 final SubscriptionInfo info = mSubscriptionController.getActiveSubscriptionInfo(subId,
5290 phone.getContext().getOpPackageName());
chen xu6291c472019-02-04 12:55:53 -08005291 if (info == null) {
5292 log("getSimLocaleForSubscriber, inactive subId: " + subId);
5293 return null;
5294 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005295 // Try and fetch the locale from the carrier properties or from the SIM language
5296 // preferences (EF-PL and EF-LI)...
5297 final int mcc = info.getMcc();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005298 String simLanguage = null;
chen xu5d3637b2019-01-21 23:31:38 -08005299 final Locale localeFromDefaultSim = phone.getLocaleFromSimAndCarrierPrefs();
5300 if (localeFromDefaultSim != null) {
5301 if (!localeFromDefaultSim.getCountry().isEmpty()) {
5302 if (DBG) log("Using locale from subId: " + subId + " locale: "
5303 + localeFromDefaultSim);
5304 return localeFromDefaultSim.toLanguageTag();
5305 } else {
5306 simLanguage = localeFromDefaultSim.getLanguage();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005307 }
5308 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01005309
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005310 // The SIM language preferences only store a language (e.g. fr = French), not an
5311 // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
5312 // the SIM and carrier preferences does not include a country we add the country
5313 // determined from the SIM MCC to provide an exact locale.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005314 final Locale mccLocale = MccTable.getLocaleFromMcc(mApp, mcc, simLanguage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005315 if (mccLocale != null) {
chen xu5d3637b2019-01-21 23:31:38 -08005316 if (DBG) log("No locale from SIM, using mcc locale:" + mccLocale);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005317 return mccLocale.toLanguageTag();
5318 }
5319
5320 if (DBG) log("No locale found - returning null");
5321 return null;
5322 } finally {
5323 Binder.restoreCallingIdentity(identity);
5324 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01005325 }
5326
5327 private List<SubscriptionInfo> getAllSubscriptionInfoList() {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005328 return mSubscriptionController.getAllSubInfoList(mApp.getOpPackageName());
Narayan Kamath1c496c22015-04-16 14:40:19 +01005329 }
5330
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005331 /**
5332 * NOTE: this method assumes permission checks are done and caller identity has been cleared.
5333 */
5334 private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005335 return mSubscriptionController.getActiveSubscriptionInfoList(mApp.getOpPackageName());
Narayan Kamath1c496c22015-04-16 14:40:19 +01005336 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07005337
Chenjie Yu1ba97252018-01-11 18:16:20 -08005338 private final ModemActivityInfo mLastModemActivityInfo =
5339 new ModemActivityInfo(0, 0, 0, new int[0], 0, 0);
5340
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07005341 /**
Adam Lesinski903a54c2016-04-11 14:49:52 -07005342 * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
5343 * representing the state of the modem.
5344 *
Chenjie Yu1ba97252018-01-11 18:16:20 -08005345 * NOTE: The underlying implementation clears the modem state, so there should only ever be one
5346 * caller to it. Everyone should call this class to get cumulative data.
Adam Lesinski903a54c2016-04-11 14:49:52 -07005347 * @hide
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07005348 */
5349 @Override
Adam Lesinski903a54c2016-04-11 14:49:52 -07005350 public void requestModemActivityInfo(ResultReceiver result) {
5351 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07005352 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005353
5354 final long identity = Binder.clearCallingIdentity();
5355 try {
5356 ModemActivityInfo ret = null;
5357 synchronized (mLastModemActivityInfo) {
5358 ModemActivityInfo info = (ModemActivityInfo) sendRequest(
5359 CMD_GET_MODEM_ACTIVITY_INFO,
vagdeviaf9a5b92018-08-15 16:01:53 -07005360 null, workSource);
Siddharth Rayb8114062018-06-17 15:02:38 -07005361 if (isModemActivityInfoValid(info)) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005362 int[] mergedTxTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
5363 for (int i = 0; i < mergedTxTimeMs.length; i++) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005364 mergedTxTimeMs[i] = info.getTxTimeMillis()[i]
5365 + mLastModemActivityInfo.getTxTimeMillis()[i];
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005366 }
5367 mLastModemActivityInfo.setTimestamp(info.getTimestamp());
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005368 mLastModemActivityInfo.setSleepTimeMillis(info.getSleepTimeMillis()
5369 + mLastModemActivityInfo.getSleepTimeMillis());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005370 mLastModemActivityInfo.setIdleTimeMillis(
5371 info.getIdleTimeMillis() + mLastModemActivityInfo.getIdleTimeMillis());
5372 mLastModemActivityInfo.setTxTimeMillis(mergedTxTimeMs);
5373 mLastModemActivityInfo.setRxTimeMillis(
5374 info.getRxTimeMillis() + mLastModemActivityInfo.getRxTimeMillis());
5375 mLastModemActivityInfo.setEnergyUsed(
5376 info.getEnergyUsed() + mLastModemActivityInfo.getEnergyUsed());
Chenjie Yu1ba97252018-01-11 18:16:20 -08005377 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005378 ret = new ModemActivityInfo(mLastModemActivityInfo.getTimestamp(),
5379 mLastModemActivityInfo.getSleepTimeMillis(),
5380 mLastModemActivityInfo.getIdleTimeMillis(),
5381 mLastModemActivityInfo.getTxTimeMillis(),
5382 mLastModemActivityInfo.getRxTimeMillis(),
5383 mLastModemActivityInfo.getEnergyUsed());
Chenjie Yu1ba97252018-01-11 18:16:20 -08005384 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005385 Bundle bundle = new Bundle();
5386 bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, ret);
5387 result.send(0, bundle);
5388 } finally {
5389 Binder.restoreCallingIdentity(identity);
Chenjie Yu1ba97252018-01-11 18:16:20 -08005390 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07005391 }
Jack Yu85bd38a2015-11-09 11:34:32 -08005392
Siddharth Rayb8114062018-06-17 15:02:38 -07005393 // Checks that ModemActivityInfo is valid. Sleep time, Idle time, Rx time and Tx time should be
5394 // less than total activity duration.
5395 private boolean isModemActivityInfoValid(ModemActivityInfo info) {
5396 if (info == null) {
5397 return false;
5398 }
5399 int activityDurationMs =
5400 (int) (info.getTimestamp() - mLastModemActivityInfo.getTimestamp());
5401 int totalTxTimeMs = 0;
5402 for (int i = 0; i < info.getTxTimeMillis().length; i++) {
5403 totalTxTimeMs += info.getTxTimeMillis()[i];
5404 }
5405 return (info.isValid()
5406 && (info.getSleepTimeMillis() <= activityDurationMs)
5407 && (info.getIdleTimeMillis() <= activityDurationMs)
5408 && (info.getRxTimeMillis() <= activityDurationMs)
5409 && (totalTxTimeMs <= activityDurationMs));
5410 }
5411
Jack Yu85bd38a2015-11-09 11:34:32 -08005412 /**
5413 * {@hide}
5414 * Returns the service state information on specified subscription.
5415 */
5416 @Override
5417 public ServiceState getServiceStateForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005418 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08005419 mApp, subId, callingPackage, "getServiceStateForSubscriber")) {
Jack Yu85bd38a2015-11-09 11:34:32 -08005420 return null;
5421 }
5422
Hall Liuf19c44f2018-11-27 14:38:17 -08005423 LocationAccessPolicy.LocationPermissionResult fineLocationResult =
5424 LocationAccessPolicy.checkLocationPermission(mApp,
5425 new LocationAccessPolicy.LocationPermissionQuery.Builder()
5426 .setCallingPackage(callingPackage)
5427 .setCallingPid(Binder.getCallingPid())
5428 .setCallingUid(Binder.getCallingUid())
5429 .setMethod("getServiceStateForSubscriber")
5430 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
5431 .build());
5432
5433 LocationAccessPolicy.LocationPermissionResult coarseLocationResult =
5434 LocationAccessPolicy.checkLocationPermission(mApp,
5435 new LocationAccessPolicy.LocationPermissionQuery.Builder()
5436 .setCallingPackage(callingPackage)
5437 .setCallingPid(Binder.getCallingPid())
5438 .setCallingUid(Binder.getCallingUid())
5439 .setMethod("getServiceStateForSubscriber")
5440 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
5441 .build());
5442 // We don't care about hard or soft here -- all we need to know is how much info to scrub.
5443 boolean hasFinePermission =
5444 fineLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
5445 boolean hasCoarsePermission =
5446 coarseLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
5447
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005448 final long identity = Binder.clearCallingIdentity();
5449 try {
5450 final Phone phone = getPhone(subId);
5451 if (phone == null) {
5452 return null;
5453 }
Jack Yu85bd38a2015-11-09 11:34:32 -08005454
Hall Liuf19c44f2018-11-27 14:38:17 -08005455 ServiceState ss = phone.getServiceState();
5456
5457 // Scrub out the location info in ServiceState depending on what level of access
5458 // the caller has.
5459 if (hasFinePermission) return ss;
5460 if (hasCoarsePermission) return ss.sanitizeLocationInfo(false);
5461 return ss.sanitizeLocationInfo(true);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005462 } finally {
5463 Binder.restoreCallingIdentity(identity);
5464 }
Jack Yu85bd38a2015-11-09 11:34:32 -08005465 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08005466
5467 /**
5468 * Returns the URI for the per-account voicemail ringtone set in Phone settings.
5469 *
5470 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
5471 * voicemail ringtone.
5472 * @return The URI for the ringtone to play when receiving a voicemail from a specific
5473 * PhoneAccount.
5474 */
5475 @Override
5476 public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005477 final long identity = Binder.clearCallingIdentity();
5478 try {
5479 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
5480 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005481 phone = getDefaultPhone();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005482 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08005483
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005484 return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext());
5485 } finally {
5486 Binder.restoreCallingIdentity(identity);
5487 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08005488 }
5489
5490 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005491 * Sets the per-account voicemail ringtone.
5492 *
5493 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
5494 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
5495 *
5496 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
5497 * voicemail ringtone.
5498 * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
5499 * PhoneAccount.
5500 */
5501 @Override
5502 public void setVoicemailRingtoneUri(String callingPackage,
5503 PhoneAccountHandle phoneAccountHandle, Uri uri) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005504 final Phone defaultPhone = getDefaultPhone();
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005505 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
5506 if (!TextUtils.equals(callingPackage,
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005507 TelecomManager.from(defaultPhone.getContext()).getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005508 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5509 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
5510 "setVoicemailRingtoneUri");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005511 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005512
5513 final long identity = Binder.clearCallingIdentity();
5514 try {
5515 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
5516 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005517 phone = defaultPhone;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005518 }
5519 VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri);
5520 } finally {
5521 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005522 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005523 }
5524
5525 /**
Nancy Chen31f9ba12016-01-06 11:42:12 -08005526 * Returns whether vibration is set for voicemail notification in Phone settings.
5527 *
5528 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
5529 * voicemail vibration setting.
5530 * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
5531 */
5532 @Override
5533 public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005534 final long identity = Binder.clearCallingIdentity();
5535 try {
5536 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
5537 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005538 phone = getDefaultPhone();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005539 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08005540
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005541 return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext());
5542 } finally {
5543 Binder.restoreCallingIdentity(identity);
5544 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08005545 }
5546
Youhan Wange64578a2016-05-02 15:32:42 -07005547 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005548 * Sets the per-account voicemail vibration.
5549 *
5550 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
5551 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
5552 *
5553 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
5554 * voicemail vibration setting.
5555 * @param enabled Whether to enable or disable vibration for voicemail notifications from a
5556 * specific PhoneAccount.
5557 */
5558 @Override
5559 public void setVoicemailVibrationEnabled(String callingPackage,
5560 PhoneAccountHandle phoneAccountHandle, boolean enabled) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005561 final Phone defaultPhone = getDefaultPhone();
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005562 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
5563 if (!TextUtils.equals(callingPackage,
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005564 TelecomManager.from(defaultPhone.getContext()).getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005565 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5566 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
5567 "setVoicemailVibrationEnabled");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005568 }
5569
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005570 final long identity = Binder.clearCallingIdentity();
5571 try {
5572 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
5573 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005574 phone = defaultPhone;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005575 }
5576 VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled);
5577 } finally {
5578 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005579 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005580 }
5581
5582 /**
Youhan Wange64578a2016-05-02 15:32:42 -07005583 * Make sure either called from same process as self (phone) or IPC caller has read privilege.
5584 *
5585 * @throws SecurityException if the caller does not have the required permission
5586 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07005587 private void enforceReadPrivilegedPermission(String message) {
Youhan Wange64578a2016-05-02 15:32:42 -07005588 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
Brad Ebinger35c841c2018-10-01 10:40:55 -07005589 message);
Youhan Wange64578a2016-05-02 15:32:42 -07005590 }
5591
5592 /**
Ta-wei Yen30a69c82016-12-27 14:52:32 -08005593 * Make sure either called from same process as self (phone) or IPC caller has send SMS
5594 * permission.
5595 *
5596 * @throws SecurityException if the caller does not have the required permission
5597 */
5598 private void enforceSendSmsPermission() {
5599 mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null);
5600 }
5601
5602 /**
Ta-wei Yen527a9c02017-01-06 15:29:25 -08005603 * Make sure called from the package in charge of visual voicemail.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08005604 *
Ta-wei Yen527a9c02017-01-06 15:29:25 -08005605 * @throws SecurityException if the caller is not the visual voicemail package.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08005606 */
Ta-wei Yen527a9c02017-01-06 15:29:25 -08005607 private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005608 final long identity = Binder.clearCallingIdentity();
5609 try {
5610 ComponentName componentName =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005611 RemoteVvmTaskManager.getRemotePackage(mApp, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005612 if (componentName == null) {
5613 throw new SecurityException(
5614 "Caller not current active visual voicemail package[null]");
5615 }
5616 String vvmPackage = componentName.getPackageName();
5617 if (!callingPackage.equals(vvmPackage)) {
5618 throw new SecurityException("Caller not current active visual voicemail package["
5619 + vvmPackage + "]");
5620 }
5621 } finally {
5622 Binder.restoreCallingIdentity(identity);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08005623 }
5624 }
5625
5626 /**
Youhan Wange64578a2016-05-02 15:32:42 -07005627 * Return the application ID for the app type.
5628 *
5629 * @param subId the subscription ID that this request applies to.
5630 * @param appType the uicc app type.
5631 * @return Application ID for specificied app type, or null if no uicc.
5632 */
5633 @Override
5634 public String getAidForAppType(int subId, int appType) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005635 enforceReadPrivilegedPermission("getAidForAppType");
Youhan Wange64578a2016-05-02 15:32:42 -07005636 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005637
5638 final long identity = Binder.clearCallingIdentity();
Youhan Wange64578a2016-05-02 15:32:42 -07005639 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005640 if (phone == null) {
5641 return null;
5642 }
5643 String aid = null;
5644 try {
5645 aid = UiccController.getInstance().getUiccCard(phone.getPhoneId())
5646 .getApplicationByType(appType).getAid();
5647 } catch (Exception e) {
5648 Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e);
5649 }
5650 return aid;
5651 } finally {
5652 Binder.restoreCallingIdentity(identity);
Youhan Wange64578a2016-05-02 15:32:42 -07005653 }
Youhan Wange64578a2016-05-02 15:32:42 -07005654 }
5655
Youhan Wang4001d252016-05-11 10:29:41 -07005656 /**
5657 * Return the Electronic Serial Number.
5658 *
5659 * @param subId the subscription ID that this request applies to.
5660 * @return ESN or null if error.
5661 */
5662 @Override
5663 public String getEsn(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005664 enforceReadPrivilegedPermission("getEsn");
Youhan Wang4001d252016-05-11 10:29:41 -07005665 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005666
5667 final long identity = Binder.clearCallingIdentity();
Youhan Wang4001d252016-05-11 10:29:41 -07005668 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005669 if (phone == null) {
5670 return null;
5671 }
5672 String esn = null;
5673 try {
5674 esn = phone.getEsn();
5675 } catch (Exception e) {
5676 Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e);
5677 }
5678 return esn;
5679 } finally {
5680 Binder.restoreCallingIdentity(identity);
Youhan Wang4001d252016-05-11 10:29:41 -07005681 }
Youhan Wang4001d252016-05-11 10:29:41 -07005682 }
5683
Sanket Padawe99ef1e32016-05-18 16:12:33 -07005684 /**
Youhan Wang66ad5d72016-07-18 17:56:58 -07005685 * Return the Preferred Roaming List Version.
5686 *
5687 * @param subId the subscription ID that this request applies to.
5688 * @return PRLVersion or null if error.
5689 */
5690 @Override
5691 public String getCdmaPrlVersion(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005692 enforceReadPrivilegedPermission("getCdmaPrlVersion");
Youhan Wang66ad5d72016-07-18 17:56:58 -07005693 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005694
5695 final long identity = Binder.clearCallingIdentity();
Youhan Wang66ad5d72016-07-18 17:56:58 -07005696 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005697 if (phone == null) {
5698 return null;
5699 }
5700 String cdmaPrlVersion = null;
5701 try {
5702 cdmaPrlVersion = phone.getCdmaPrlVersion();
5703 } catch (Exception e) {
5704 Log.e(LOG_TAG, "Not getting PRLVersion", e);
5705 }
5706 return cdmaPrlVersion;
5707 } finally {
5708 Binder.restoreCallingIdentity(identity);
Youhan Wang66ad5d72016-07-18 17:56:58 -07005709 }
Youhan Wang66ad5d72016-07-18 17:56:58 -07005710 }
5711
5712 /**
Sanket Padawe99ef1e32016-05-18 16:12:33 -07005713 * Get snapshot of Telephony histograms
5714 * @return List of Telephony histograms
5715 * @hide
5716 */
5717 @Override
5718 public List<TelephonyHistogram> getTelephonyHistograms() {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005719 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5720 mApp, getDefaultSubscription(), "getTelephonyHistograms");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005721
5722 final long identity = Binder.clearCallingIdentity();
5723 try {
5724 return RIL.getTelephonyRILTimingHistograms();
5725 } finally {
5726 Binder.restoreCallingIdentity(identity);
5727 }
Sanket Padawe99ef1e32016-05-18 16:12:33 -07005728 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07005729
5730 /**
5731 * {@hide}
Michele Berionne482f8202018-11-27 18:57:59 -08005732 * Set the allowed carrier list and the excluded carrier list, indicating the priority between
5733 * the two lists.
Meng Wang1a7c35a2016-05-05 20:56:15 -07005734 * Require system privileges. In the future we may add this to carrier APIs.
5735 *
Michele Berionne482f8202018-11-27 18:57:59 -08005736 * @return Integer with the result of the operation, as defined in {@link TelephonyManager}.
Meng Wang1a7c35a2016-05-05 20:56:15 -07005737 */
5738 @Override
Michele Berionne482f8202018-11-27 18:57:59 -08005739 @TelephonyManager.SetCarrierRestrictionResult
5740 public int setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules) {
Meng Wang1a7c35a2016-05-05 20:56:15 -07005741 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07005742 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005743
Michele Berionne482f8202018-11-27 18:57:59 -08005744 if (carrierRestrictionRules == null) {
5745 throw new NullPointerException("carrier restriction cannot be null");
Meng Wang9b7c4e92017-02-17 11:41:27 -08005746 }
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005747
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005748 final long identity = Binder.clearCallingIdentity();
5749 try {
Michele Berionne482f8202018-11-27 18:57:59 -08005750 return (int) sendRequest(CMD_SET_ALLOWED_CARRIERS, carrierRestrictionRules,
vagdeviaf9a5b92018-08-15 16:01:53 -07005751 workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005752 } finally {
5753 Binder.restoreCallingIdentity(identity);
5754 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07005755 }
5756
5757 /**
5758 * {@hide}
Michele Berionne482f8202018-11-27 18:57:59 -08005759 * Get the allowed carrier list and the excluded carrier list, including the priority between
5760 * the two lists.
Meng Wang1a7c35a2016-05-05 20:56:15 -07005761 * Require system privileges. In the future we may add this to carrier APIs.
5762 *
Michele Berionne482f8202018-11-27 18:57:59 -08005763 * @return {@link android.telephony.CarrierRestrictionRules}
Meng Wang1a7c35a2016-05-05 20:56:15 -07005764 */
5765 @Override
Michele Berionne482f8202018-11-27 18:57:59 -08005766 public CarrierRestrictionRules getAllowedCarriers() {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005767 enforceReadPrivilegedPermission("getAllowedCarriers");
vagdeviaf9a5b92018-08-15 16:01:53 -07005768 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005769
5770 final long identity = Binder.clearCallingIdentity();
5771 try {
Michele Berionne482f8202018-11-27 18:57:59 -08005772 Object response = sendRequest(CMD_GET_ALLOWED_CARRIERS, null, workSource);
5773 if (response instanceof CarrierRestrictionRules) {
5774 return (CarrierRestrictionRules) response;
5775 }
5776 // Response is an Exception of some kind,
5777 // which is signalled to the user as a NULL retval
5778 return null;
5779 } catch (Exception e) {
5780 Log.e(LOG_TAG, "getAllowedCarriers. Exception ex=" + e);
5781 return null;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005782 } finally {
5783 Binder.restoreCallingIdentity(identity);
5784 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07005785 }
5786
fionaxu59545b42016-05-25 15:53:37 -07005787 /**
5788 * Action set from carrier signalling broadcast receivers to enable/disable metered apns
5789 * @param subId the subscription ID that this action applies to.
5790 * @param enabled control enable or disable metered apns.
5791 * {@hide}
5792 */
5793 @Override
5794 public void carrierActionSetMeteredApnsEnabled(int subId, boolean enabled) {
5795 enforceModifyPermission();
5796 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005797
5798 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07005799 if (phone == null) {
5800 loge("carrierAction: SetMeteredApnsEnabled fails with invalid subId: " + subId);
5801 return;
5802 }
5803 try {
5804 phone.carrierActionSetMeteredApnsEnabled(enabled);
5805 } catch (Exception e) {
5806 Log.e(LOG_TAG, "carrierAction: SetMeteredApnsEnabled fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005807 } finally {
5808 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07005809 }
5810 }
5811
5812 /**
5813 * Action set from carrier signalling broadcast receivers to enable/disable radio
5814 * @param subId the subscription ID that this action applies to.
5815 * @param enabled control enable or disable radio.
5816 * {@hide}
5817 */
5818 @Override
5819 public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
5820 enforceModifyPermission();
5821 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005822
5823 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07005824 if (phone == null) {
5825 loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
5826 return;
5827 }
5828 try {
5829 phone.carrierActionSetRadioEnabled(enabled);
5830 } catch (Exception e) {
5831 Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005832 } finally {
5833 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07005834 }
5835 }
5836
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07005837 /**
fionaxu8da9cb12017-05-23 15:02:46 -07005838 * Action set from carrier signalling broadcast receivers to start/stop reporting the default
5839 * network status based on which carrier apps could apply actions accordingly,
5840 * enable/disable default url handler for example.
5841 *
5842 * @param subId the subscription ID that this action applies to.
5843 * @param report control start/stop reporting the default network status.
5844 * {@hide}
5845 */
5846 @Override
5847 public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
5848 enforceModifyPermission();
5849 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005850
5851 final long identity = Binder.clearCallingIdentity();
fionaxu8da9cb12017-05-23 15:02:46 -07005852 if (phone == null) {
5853 loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId);
5854 return;
5855 }
5856 try {
5857 phone.carrierActionReportDefaultNetworkStatus(report);
5858 } catch (Exception e) {
5859 Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005860 } finally {
5861 Binder.restoreCallingIdentity(identity);
fionaxu8da9cb12017-05-23 15:02:46 -07005862 }
5863 }
5864
5865 /**
fionaxud9622282017-07-17 17:51:30 -07005866 * Action set from carrier signalling broadcast receivers to reset all carrier actions
5867 * @param subId the subscription ID that this action applies to.
5868 * {@hide}
5869 */
5870 @Override
5871 public void carrierActionResetAll(int subId) {
5872 enforceModifyPermission();
5873 final Phone phone = getPhone(subId);
5874 if (phone == null) {
5875 loge("carrierAction: ResetAll fails with invalid sibId: " + subId);
5876 return;
5877 }
5878 try {
5879 phone.carrierActionResetAll();
5880 } catch (Exception e) {
5881 Log.e(LOG_TAG, "carrierAction: ResetAll fails. Exception ex=" + e);
5882 }
5883 }
5884
5885 /**
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07005886 * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a
5887 * bug report is being generated.
5888 */
5889 @Override
Ta-wei Yen99282e02016-06-21 18:19:35 -07005890 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005891 if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
5892 != PackageManager.PERMISSION_GRANTED) {
dcashman22b950d2016-06-27 11:39:02 -07005893 writer.println("Permission Denial: can't dump Phone from pid="
5894 + Binder.getCallingPid()
5895 + ", uid=" + Binder.getCallingUid()
5896 + "without permission "
5897 + android.Manifest.permission.DUMP);
5898 return;
5899 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005900 DumpsysHandler.dump(mApp, fd, writer, args);
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07005901 }
Jack Yueb89b242016-06-22 13:27:47 -07005902
Brad Ebingerdac2f002018-04-03 15:17:52 -07005903 @Override
5904 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
5905 String[] args, ShellCallback callback, ResultReceiver resultReceiver)
5906 throws RemoteException {
5907 (new TelephonyShellCommand(this)).exec(this, in, out, err, args, callback, resultReceiver);
5908 }
5909
Jack Yueb89b242016-06-22 13:27:47 -07005910 /**
Jack Yu84291ec2017-05-26 16:07:50 -07005911 * Get aggregated video call data usage since boot.
5912 *
5913 * @param perUidStats True if requesting data usage per uid, otherwise overall usage.
5914 * @return Snapshot of video call data usage
Jack Yueb89b242016-06-22 13:27:47 -07005915 * {@hide}
5916 */
5917 @Override
Jack Yu84291ec2017-05-26 16:07:50 -07005918 public NetworkStats getVtDataUsage(int subId, boolean perUidStats) {
Jack Yueb89b242016-06-22 13:27:47 -07005919 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_NETWORK_USAGE_HISTORY,
5920 null);
5921
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005922 final long identity = Binder.clearCallingIdentity();
5923 try {
5924 // NetworkStatsService keeps tracking the active network interface and identity. It
5925 // records the delta with the corresponding network identity.
5926 // We just return the total video call data usage snapshot since boot.
5927 Phone phone = getPhone(subId);
5928 if (phone != null) {
5929 return phone.getVtDataUsage(perUidStats);
5930 }
5931 return null;
5932 } finally {
5933 Binder.restoreCallingIdentity(identity);
Jack Yueb89b242016-06-22 13:27:47 -07005934 }
Jack Yueb89b242016-06-22 13:27:47 -07005935 }
Jack Yu75ab2952016-07-08 14:29:33 -07005936
5937 /**
5938 * Policy control of data connection. Usually used when data limit is passed.
5939 * @param enabled True if enabling the data, otherwise disabling.
5940 * @param subId Subscription index
5941 * {@hide}
5942 */
5943 @Override
5944 public void setPolicyDataEnabled(boolean enabled, int subId) {
5945 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005946
5947 final long identity = Binder.clearCallingIdentity();
5948 try {
5949 Phone phone = getPhone(subId);
5950 if (phone != null) {
Jack Yud79fba22018-12-13 11:51:28 -08005951 phone.getDataEnabledSettings().setPolicyDataEnabled(enabled);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005952 }
5953 } finally {
5954 Binder.restoreCallingIdentity(identity);
Jack Yu75ab2952016-07-08 14:29:33 -07005955 }
5956 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07005957
5958 /**
5959 * Get Client request stats
5960 * @return List of Client Request Stats
5961 * @hide
5962 */
5963 @Override
5964 public List<ClientRequestStats> getClientRequestStats(String callingPackage, int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005965 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08005966 mApp, subId, callingPackage, "getClientRequestStats")) {
Sooraj Sasindran9a909312016-07-18 11:57:25 -07005967 return null;
5968 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07005969 Phone phone = getPhone(subId);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07005970
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005971 final long identity = Binder.clearCallingIdentity();
5972 try {
5973 if (phone != null) {
5974 return phone.getClientRequestStats();
5975 }
5976
5977 return null;
5978 } finally {
5979 Binder.restoreCallingIdentity(identity);
5980 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07005981 }
5982
Narayan Kamathf04b5a12018-01-09 11:47:15 +00005983 private WorkSource getWorkSource(int uid) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005984 String packageName = mApp.getPackageManager().getNameForUid(uid);
Narayan Kamathf04b5a12018-01-09 11:47:15 +00005985 return new WorkSource(uid, packageName);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07005986 }
Jack Yueb4124c2017-02-16 15:32:43 -08005987
5988 /**
Grace Chen70990072017-03-24 17:21:30 -07005989 * Set SIM card power state.
Jack Yueb4124c2017-02-16 15:32:43 -08005990 *
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005991 * @param slotIndex SIM slot id.
Grace Chen70990072017-03-24 17:21:30 -07005992 * @param state State of SIM (power down, power up, pass through)
5993 * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
5994 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
5995 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
Jack Yueb4124c2017-02-16 15:32:43 -08005996 *
5997 **/
5998 @Override
Grace Chen70990072017-03-24 17:21:30 -07005999 public void setSimPowerStateForSlot(int slotIndex, int state) {
Jack Yueb4124c2017-02-16 15:32:43 -08006000 enforceModifyPermission();
Sanket Padawe13bac7b2017-03-20 15:04:47 -07006001 Phone phone = PhoneFactory.getPhone(slotIndex);
6002
vagdeviaf9a5b92018-08-15 16:01:53 -07006003 WorkSource workSource = getWorkSource(Binder.getCallingUid());
6004
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006005 final long identity = Binder.clearCallingIdentity();
6006 try {
6007 if (phone != null) {
vagdeviaf9a5b92018-08-15 16:01:53 -07006008 phone.setSimPowerState(state, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006009 }
6010 } finally {
6011 Binder.restoreCallingIdentity(identity);
Jack Yueb4124c2017-02-16 15:32:43 -08006012 }
6013 }
Shuo Qiandd210312017-04-12 22:11:33 +00006014
Tyler Gunn65d45c22017-06-05 11:22:26 -07006015 private boolean isUssdApiAllowed(int subId) {
6016 CarrierConfigManager configManager =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006017 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Tyler Gunn65d45c22017-06-05 11:22:26 -07006018 if (configManager == null) {
6019 return false;
6020 }
6021 PersistableBundle pb = configManager.getConfigForSubId(subId);
6022 if (pb == null) {
6023 return false;
6024 }
6025 return pb.getBoolean(
6026 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL);
6027 }
6028
Shuo Qiandd210312017-04-12 22:11:33 +00006029 /**
6030 * Check if phone is in emergency callback mode
6031 * @return true if phone is in emergency callback mode
6032 * @param subId sub id
6033 */
goneil9c5f4872017-12-05 14:07:56 -08006034 @Override
Shuo Qiandd210312017-04-12 22:11:33 +00006035 public boolean getEmergencyCallbackMode(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07006036 enforceReadPrivilegedPermission("getEmergencyCallbackMode");
Shuo Qiandd210312017-04-12 22:11:33 +00006037 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006038
6039 final long identity = Binder.clearCallingIdentity();
6040 try {
6041 if (phone != null) {
6042 return phone.isInEcm();
6043 } else {
6044 return false;
6045 }
6046 } finally {
6047 Binder.restoreCallingIdentity(identity);
Shuo Qiandd210312017-04-12 22:11:33 +00006048 }
6049 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08006050
6051 /**
6052 * Get the current signal strength information for the given subscription.
6053 * Because this information is not updated when the device is in a low power state
6054 * it should not be relied-upon to be current.
6055 * @param subId Subscription index
6056 * @return the most recent cached signal strength info from the modem
6057 */
6058 @Override
6059 public SignalStrength getSignalStrength(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006060 final long identity = Binder.clearCallingIdentity();
6061 try {
6062 Phone p = getPhone(subId);
6063 if (p == null) {
6064 return null;
6065 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08006066
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006067 return p.getSignalStrength();
6068 } finally {
6069 Binder.restoreCallingIdentity(identity);
6070 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08006071 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00006072
Pengquan Meng77b7f132018-08-22 14:49:57 -07006073 /**
Chen Xuf792fd62018-10-17 17:54:36 +00006074 * Get the current modem radio state for the given slot.
6075 * @param slotIndex slot index.
6076 * @param callingPackage the name of the package making the call.
6077 * @return the current radio power state from the modem
6078 */
6079 @Override
6080 public int getRadioPowerState(int slotIndex, String callingPackage) {
6081 Phone phone = PhoneFactory.getPhone(slotIndex);
6082 if (phone != null) {
6083 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
6084 mApp, phone.getSubId(), callingPackage, "getRadioPowerState")) {
6085 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
6086 }
6087
6088 final long identity = Binder.clearCallingIdentity();
6089 try {
6090 return phone.getRadioPowerState();
6091 } finally {
6092 Binder.restoreCallingIdentity(identity);
6093 }
6094 }
6095 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
6096 }
6097
6098 /**
Pengquan Meng77b7f132018-08-22 14:49:57 -07006099 * Checks if data roaming is enabled on the subscription with id {@code subId}.
6100 *
6101 * <p>Requires one of the following permissions:
6102 * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
6103 * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
6104 * privileges.
6105 *
6106 * @param subId subscription id
6107 * @return {@code true} if data roaming is enabled on this subscription, otherwise return
6108 * {@code false}.
6109 */
6110 @Override
6111 public boolean isDataRoamingEnabled(int subId) {
Pengquan Menga1bb6272018-09-06 09:59:22 -07006112 boolean isEnabled = false;
6113 final long identity = Binder.clearCallingIdentity();
Pengquan Meng77b7f132018-08-22 14:49:57 -07006114 try {
6115 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
Pengquan Menga1bb6272018-09-06 09:59:22 -07006116 null /* message */);
6117 Phone phone = getPhone(subId);
6118 isEnabled = phone != null ? phone.getDataRoamingEnabled() : false;
Pengquan Meng77b7f132018-08-22 14:49:57 -07006119 } catch (Exception e) {
6120 TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
6121 mApp, subId, "isDataRoamingEnabled");
Pengquan Menga1bb6272018-09-06 09:59:22 -07006122 } finally {
6123 Binder.restoreCallingIdentity(identity);
Pengquan Meng77b7f132018-08-22 14:49:57 -07006124 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07006125 return isEnabled;
Pengquan Meng77b7f132018-08-22 14:49:57 -07006126 }
6127
6128
6129 /**
6130 * Enables/Disables the data roaming on the subscription with id {@code subId}.
6131 *
6132 * <p> Requires permission:
6133 * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier
6134 * privileges.
6135 *
6136 * @param subId subscription id
6137 * @param isEnabled {@code true} means enable, {@code false} means disable.
6138 */
6139 @Override
6140 public void setDataRoamingEnabled(int subId, boolean isEnabled) {
Pengquan Menga1bb6272018-09-06 09:59:22 -07006141 final long identity = Binder.clearCallingIdentity();
6142 try {
6143 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6144 mApp, subId, "setDataRoamingEnabled");
Pengquan Meng77b7f132018-08-22 14:49:57 -07006145
Pengquan Menga1bb6272018-09-06 09:59:22 -07006146 Phone phone = getPhone(subId);
6147 if (phone != null) {
6148 phone.setDataRoamingEnabled(isEnabled);
6149 }
6150 } finally {
6151 Binder.restoreCallingIdentity(identity);
Pengquan Meng77b7f132018-08-22 14:49:57 -07006152 }
6153 }
6154
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00006155 @Override
Pengquan Meng6884a2c2018-10-03 12:19:13 -07006156 public boolean isManualNetworkSelectionAllowed(int subId) {
6157 boolean isAllowed = true;
6158 final long identity = Binder.clearCallingIdentity();
6159 try {
6160 TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
6161 mApp, subId, "isManualNetworkSelectionAllowed");
6162 Phone phone = getPhone(subId);
6163 if (phone != null) {
6164 isAllowed = phone.isCspPlmnEnabled();
6165 }
6166 } finally {
6167 Binder.restoreCallingIdentity(identity);
6168 }
6169 return isAllowed;
6170 }
6171
6172 @Override
Jordan Liu75f43ea2019-01-17 16:56:37 -08006173 public List<UiccCardInfo> getUiccCardsInfo(String callingPackage) {
Jordan Liuc65bc952019-02-12 17:54:02 -08006174 try {
6175 enforceReadPrivilegedPermission("getUiccCardsInfo");
6176 } catch (SecurityException e) {
6177 // even without READ_PRIVILEGED_PHONE_STATE, we allow the call to continue if the caller
6178 // has carrier privileges on an active UICC
6179 if (checkCarrierPrivilegesForPackageAnyPhone(callingPackage)
6180 != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
6181 throw new SecurityException("Caller does not have carrier privileges on any UICC");
6182 }
Jordan Liu75f43ea2019-01-17 16:56:37 -08006183 }
Jordan Liu5aa07002018-12-18 15:44:48 -08006184
6185 final long identity = Binder.clearCallingIdentity();
6186 try {
Jordan Liu75f43ea2019-01-17 16:56:37 -08006187 UiccController uiccController = UiccController.getInstance();
6188 ArrayList<UiccCardInfo> cardInfos = uiccController.getAllUiccCardInfos();
6189
6190 ApplicationInfo ai = mApp.getPackageManager().getApplicationInfo(callingPackage, 0);
6191 if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6192 // Remove private info if the caller doesn't have access
6193 ArrayList<UiccCardInfo> filteredInfos = new ArrayList<>();
6194 for (UiccCardInfo cardInfo : cardInfos) {
6195 UiccCard card = uiccController.getUiccCard(cardInfo.getSlotIndex());
6196 UiccProfile profile = card.getUiccProfile();
6197 if (profile.getCarrierPrivilegeStatus(mApp.getPackageManager(), callingPackage)
6198 != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
6199 filteredInfos.add(cardInfo.getUnprivileged());
6200 } else {
6201 filteredInfos.add(cardInfo);
6202 }
6203 }
6204 return filteredInfos;
6205 }
6206 return cardInfos;
6207 } catch (PackageManager.NameNotFoundException e) {
6208 // This should not happen since we pass the package info in from TelephonyManager
6209 throw new SecurityException("Invalid calling package.");
Jordan Liu5aa07002018-12-18 15:44:48 -08006210 } finally {
6211 Binder.restoreCallingIdentity(identity);
6212 }
6213 }
6214
6215 @Override
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00006216 public UiccSlotInfo[] getUiccSlotsInfo() {
Brad Ebinger35c841c2018-10-01 10:40:55 -07006217 enforceReadPrivilegedPermission("getUiccSlotsInfo");
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00006218
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006219 final long identity = Binder.clearCallingIdentity();
6220 try {
6221 UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
6222 if (slots == null) {
6223 Rlog.i(LOG_TAG, "slots is null.");
6224 return null;
6225 }
6226
6227 UiccSlotInfo[] infos = new UiccSlotInfo[slots.length];
6228 for (int i = 0; i < slots.length; i++) {
6229 UiccSlot slot = slots[i];
6230 if (slot == null) {
6231 continue;
6232 }
6233
6234 String cardId;
6235 UiccCard card = slot.getUiccCard();
6236 if (card != null) {
6237 cardId = card.getCardId();
6238 } else {
6239 cardId = slot.getIccId();
6240 }
6241
6242 int cardState = 0;
6243 switch (slot.getCardState()) {
6244 case CARDSTATE_ABSENT:
6245 cardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
6246 break;
6247 case CARDSTATE_PRESENT:
6248 cardState = UiccSlotInfo.CARD_STATE_INFO_PRESENT;
6249 break;
6250 case CARDSTATE_ERROR:
6251 cardState = UiccSlotInfo.CARD_STATE_INFO_ERROR;
6252 break;
6253 case CARDSTATE_RESTRICTED:
6254 cardState = UiccSlotInfo.CARD_STATE_INFO_RESTRICTED;
6255 break;
6256 default:
6257 break;
6258
6259 }
6260
6261 infos[i] = new UiccSlotInfo(
6262 slot.isActive(),
6263 slot.isEuicc(),
6264 cardId,
6265 cardState,
6266 slot.getPhoneId(),
Jordan Liua2619582019-02-14 12:56:40 -08006267 slot.isExtendedApduSupported(),
6268 slot.isRemovable());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006269 }
6270 return infos;
6271 } finally {
6272 Binder.restoreCallingIdentity(identity);
Holly Jiuyu Sun1d957c52018-04-04 13:52:42 -07006273 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00006274 }
6275
6276 @Override
6277 public boolean switchSlots(int[] physicalSlots) {
6278 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006279
6280 final long identity = Binder.clearCallingIdentity();
6281 try {
6282 return (Boolean) sendRequest(CMD_SWITCH_SLOTS, physicalSlots);
6283 } finally {
6284 Binder.restoreCallingIdentity(identity);
6285 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00006286 }
Jack Yu4c988042018-02-27 15:30:01 -08006287
6288 @Override
Jordan Liu7de49fa2018-12-06 14:48:49 -08006289 public int getCardIdForDefaultEuicc(int subId, String callingPackage) {
Jordan Liu7de49fa2018-12-06 14:48:49 -08006290 final long identity = Binder.clearCallingIdentity();
6291 try {
6292 return UiccController.getInstance().getCardIdForDefaultEuicc();
6293 } finally {
6294 Binder.restoreCallingIdentity(identity);
6295 }
6296 }
6297
6298 @Override
Jack Yu4c988042018-02-27 15:30:01 -08006299 public void setRadioIndicationUpdateMode(int subId, int filters, int mode) {
6300 enforceModifyPermission();
6301 final Phone phone = getPhone(subId);
6302 if (phone == null) {
6303 loge("setRadioIndicationUpdateMode fails with invalid subId: " + subId);
6304 return;
6305 }
6306
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006307 final long identity = Binder.clearCallingIdentity();
6308 try {
6309 phone.setRadioIndicationUpdateMode(filters, mode);
6310 } finally {
6311 Binder.restoreCallingIdentity(identity);
6312 }
Jack Yu4c988042018-02-27 15:30:01 -08006313 }
Pengquan Meng85728fb2018-03-12 16:31:21 -07006314
6315 /**
goneil47ffb6e2018-04-06 15:40:58 -07006316 * A test API to reload the UICC profile.
6317 *
6318 * <p>Requires that the calling app has permission
6319 * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
6320 * @hide
6321 */
6322 @Override
6323 public void refreshUiccProfile(int subId) {
6324 enforceModifyPermission();
6325
6326 final long identity = Binder.clearCallingIdentity();
6327 try {
6328 Phone phone = getPhone(subId);
6329 if (phone == null) {
6330 return;
6331 }
6332 UiccCard uiccCard = phone.getUiccCard();
6333 if (uiccCard == null) {
6334 return;
6335 }
6336 UiccProfile uiccProfile = uiccCard.getUiccProfile();
6337 if (uiccProfile == null) {
6338 return;
6339 }
6340 uiccProfile.refresh();
6341 } finally {
6342 Binder.restoreCallingIdentity(identity);
6343 }
6344 }
6345
6346 /**
Pengquan Meng85728fb2018-03-12 16:31:21 -07006347 * Returns false if the mobile data is disabled by default, otherwise return true.
6348 */
6349 private boolean getDefaultDataEnabled() {
6350 return "true".equalsIgnoreCase(
6351 SystemProperties.get(DEFAULT_MOBILE_DATA_PROPERTY_NAME, "true"));
6352 }
6353
6354 /**
6355 * Returns true if the data roaming is enabled by default, i.e the system property
6356 * of {@link #DEFAULT_DATA_ROAMING_PROPERTY_NAME} is true or the config of
6357 * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} is true.
6358 */
6359 private boolean getDefaultDataRoamingEnabled(int subId) {
6360 final CarrierConfigManager configMgr = (CarrierConfigManager)
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006361 mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Pengquan Meng85728fb2018-03-12 16:31:21 -07006362 boolean isDataRoamingEnabled = "true".equalsIgnoreCase(
6363 SystemProperties.get(DEFAULT_DATA_ROAMING_PROPERTY_NAME, "false"));
6364 isDataRoamingEnabled |= configMgr.getConfigForSubId(subId).getBoolean(
6365 CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
6366 return isDataRoamingEnabled;
6367 }
6368
6369 /**
6370 * Returns the default network type for the given {@code subId}, if the default network type is
6371 * not set, return {@link Phone#PREFERRED_NT_MODE}.
6372 */
6373 private int getDefaultNetworkType(int subId) {
6374 return Integer.parseInt(
6375 TelephonyManager.getTelephonyProperty(
6376 mSubscriptionController.getPhoneId(subId),
6377 DEFAULT_NETWORK_MODE_PROPERTY_NAME,
6378 String.valueOf(Phone.PREFERRED_NT_MODE)));
6379 }
fionaxua13278b2018-03-21 00:08:13 -07006380
6381 @Override
6382 public void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String
6383 gid1, String gid2, String plmn, String spn) {
6384 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006385
6386 final long identity = Binder.clearCallingIdentity();
6387 try {
6388 final Phone phone = getPhone(subId);
6389 if (phone == null) {
6390 loge("setCarrierTestOverride fails with invalid subId: " + subId);
6391 return;
6392 }
6393 phone.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, plmn, spn);
6394 } finally {
6395 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07006396 }
fionaxua13278b2018-03-21 00:08:13 -07006397 }
6398
6399 @Override
6400 public int getCarrierIdListVersion(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07006401 enforceReadPrivilegedPermission("getCarrierIdListVersion");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006402
6403 final long identity = Binder.clearCallingIdentity();
6404 try {
6405 final Phone phone = getPhone(subId);
6406 if (phone == null) {
6407 loge("getCarrierIdListVersion fails with invalid subId: " + subId);
6408 return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
6409 }
6410 return phone.getCarrierIdListVersion();
6411 } finally {
6412 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07006413 }
fionaxua13278b2018-03-21 00:08:13 -07006414 }
Malcolm Chen2c63d402018-08-14 16:00:53 -07006415
6416 @Override
6417 public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage) {
6418 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
6419 mApp, subId, callingPackage, "getNumberOfModemsWithSimultaneousDataConnections")) {
6420 return -1;
6421 }
6422
6423 final long identity = Binder.clearCallingIdentity();
6424 try {
6425 return mPhoneConfigurationManager.getNumberOfModemsWithSimultaneousDataConnections();
6426 } finally {
6427 Binder.restoreCallingIdentity(identity);
6428 }
6429 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07006430
6431 @Override
6432 public int getCdmaRoamingMode(int subId) {
6433 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6434 mApp, subId, "getCdmaRoamingMode");
6435
6436 final long identity = Binder.clearCallingIdentity();
6437 try {
6438 return (int) sendRequest(CMD_GET_CDMA_ROAMING_MODE, null /* argument */, subId);
6439 } finally {
6440 Binder.restoreCallingIdentity(identity);
6441 }
6442 }
6443
6444 @Override
6445 public boolean setCdmaRoamingMode(int subId, int mode) {
6446 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6447 mApp, subId, "setCdmaRoamingMode");
6448
6449 final long identity = Binder.clearCallingIdentity();
6450 try {
6451 return (boolean) sendRequest(CMD_SET_CDMA_ROAMING_MODE, mode, subId);
6452 } finally {
6453 Binder.restoreCallingIdentity(identity);
6454 }
6455 }
6456
6457 @Override
6458 public boolean setCdmaSubscriptionMode(int subId, int mode) {
6459 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6460 mApp, subId, "setCdmaSubscriptionMode");
6461
6462 final long identity = Binder.clearCallingIdentity();
6463 try {
6464 return (boolean) sendRequest(CMD_SET_CDMA_SUBSCRIPTION_MODE, mode, subId);
6465 } finally {
6466 Binder.restoreCallingIdentity(identity);
6467 }
6468 }
Makoto Onukida3bf792018-09-18 16:06:29 -07006469
6470 private void ensureUserRunning(int userId) {
6471 if (!mUserManager.isUserRunning(userId)) {
6472 throw new IllegalStateException("User " + userId + " does not exist or not running");
6473 }
6474 }
6475
6476 /**
6477 * Returns a list of SMS apps on a given user.
6478 *
6479 * Only the shell user (UID 2000 or 0) can call it.
6480 * Target user must be running.
6481 */
6482 @Override
6483 public String[] getSmsApps(int userId) {
6484 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getSmsApps");
6485 ensureUserRunning(userId);
6486
6487 final Collection<SmsApplicationData> apps =
6488 SmsApplication.getApplicationCollectionAsUser(mApp, userId);
6489
6490 String[] ret = new String[apps.size()];
6491 int i = 0;
6492 for (SmsApplicationData app : apps) {
6493 ret[i++] = app.mPackageName;
6494 }
6495 return ret;
6496 }
6497
6498 /**
6499 * Returns the default SMS app package name on a given user.
6500 *
6501 * Only the shell user (UID 2000 or 0) can call it.
6502 * Target user must be running.
6503 */
6504 @Override
6505 public String getDefaultSmsApp(int userId) {
6506 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getDefaultSmsApp");
6507 ensureUserRunning(userId);
6508
6509 final ComponentName cn = SmsApplication.getDefaultSmsApplicationAsUser(mApp,
6510 /* updateIfNeeded= */ true, userId);
6511 return cn == null ? null : cn.getPackageName();
6512 }
6513
6514 /**
6515 * Set a package as the default SMS app on a given user.
6516 *
6517 * Only the shell user (UID 2000 or 0) can call it.
6518 * Target user must be running.
6519 */
6520 @Override
6521 public void setDefaultSmsApp(int userId, String packageName) {
6522 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setDefaultSmsApp");
6523 ensureUserRunning(userId);
6524
6525 boolean found = false;
6526 for (String pkg : getSmsApps(userId)) {
6527 if (TextUtils.equals(packageName, pkg)) {
6528 found = true;
6529 break;
6530 }
6531 }
6532 if (!found) {
6533 throw new IllegalArgumentException("Package " + packageName + " is not an SMS app");
6534 }
6535
6536 SmsApplication.setDefaultApplicationAsUser(packageName, mApp, userId);
6537 }
sqianc5eccab2018-10-19 18:46:41 -07006538
6539 @Override
sqian8c685422019-02-22 15:55:18 -08006540 public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList(
sqianc5eccab2018-10-19 18:46:41 -07006541 String callingPackage) {
sqian11b7a0e2018-12-05 18:48:28 -08006542 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
sqian8c685422019-02-22 15:55:18 -08006543 mApp, getDefaultSubscription(), callingPackage, "getEmergencyNumberList")) {
sqian11b7a0e2018-12-05 18:48:28 -08006544 throw new SecurityException("Requires READ_PHONE_STATE permission.");
6545 }
6546 final long identity = Binder.clearCallingIdentity();
6547 try {
sqian854d44b2018-12-12 16:48:18 -08006548 Map<Integer, List<EmergencyNumber>> emergencyNumberListInternal = new HashMap<>();
6549 for (Phone phone: PhoneFactory.getPhones()) {
6550 if (phone.getEmergencyNumberTracker() != null
6551 && phone.getEmergencyNumberTracker().getEmergencyNumberList() != null) {
6552 emergencyNumberListInternal.put(
6553 phone.getSubId(),
6554 phone.getEmergencyNumberTracker().getEmergencyNumberList());
6555 }
sqian11b7a0e2018-12-05 18:48:28 -08006556 }
sqian854d44b2018-12-12 16:48:18 -08006557 return emergencyNumberListInternal;
sqian11b7a0e2018-12-05 18:48:28 -08006558 } finally {
6559 Binder.restoreCallingIdentity(identity);
6560 }
sqianc5eccab2018-10-19 18:46:41 -07006561 }
6562
6563 @Override
sqian8c685422019-02-22 15:55:18 -08006564 public boolean isEmergencyNumber(String number, boolean exactMatch) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006565 final Phone defaultPhone = getDefaultPhone();
sqian11b7a0e2018-12-05 18:48:28 -08006566 if (!exactMatch) {
6567 TelephonyPermissions
6568 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
sqian8c685422019-02-22 15:55:18 -08006569 mApp, defaultPhone.getSubId(), "isEmergencyNumber(Potential)");
sqian11b7a0e2018-12-05 18:48:28 -08006570 }
6571 final long identity = Binder.clearCallingIdentity();
6572 try {
sqian854d44b2018-12-12 16:48:18 -08006573 for (Phone phone: PhoneFactory.getPhones()) {
6574 if (phone.getEmergencyNumberTracker() != null
6575 && phone.getEmergencyNumberTracker() != null) {
6576 if (phone.getEmergencyNumberTracker().isEmergencyNumber(
6577 number, exactMatch)) {
6578 return true;
sqian11b7a0e2018-12-05 18:48:28 -08006579 }
6580 }
sqian11b7a0e2018-12-05 18:48:28 -08006581 }
6582 return false;
6583 } finally {
6584 Binder.restoreCallingIdentity(identity);
6585 }
6586 }
6587
sqianf4ca7ed2019-01-15 18:32:07 -08006588 /**
6589 * Update emergency number list for test mode.
6590 */
6591 @Override
6592 public void updateEmergencyNumberListTestMode(int action, EmergencyNumber num) {
6593 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
6594 "updateEmergencyNumberListTestMode");
6595
6596 final long identity = Binder.clearCallingIdentity();
6597 try {
6598 for (Phone phone: PhoneFactory.getPhones()) {
6599 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
6600 if (tracker != null) {
6601 tracker.executeEmergencyNumberTestModeCommand(action, num);
6602 }
6603 }
6604 } finally {
6605 Binder.restoreCallingIdentity(identity);
6606 }
6607 }
6608
6609 /**
6610 * Get the full emergency number list for test mode.
6611 */
6612 @Override
6613 public List<String> getEmergencyNumberListTestMode() {
6614 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
6615 "getEmergencyNumberListTestMode");
6616
6617 final long identity = Binder.clearCallingIdentity();
6618 try {
6619 Set<String> emergencyNumbers = new HashSet<>();
6620 for (Phone phone: PhoneFactory.getPhones()) {
6621 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
6622 if (tracker != null) {
6623 for (EmergencyNumber num : tracker.getEmergencyNumberList()) {
6624 emergencyNumbers.add(num.getNumber());
6625 }
6626 }
6627 }
6628 return new ArrayList<>(emergencyNumbers);
6629 } finally {
6630 Binder.restoreCallingIdentity(identity);
6631 }
6632 }
6633
chen xud6b45bd2018-10-30 22:27:10 -07006634 @Override
6635 public List<String> getCertsFromCarrierPrivilegeAccessRules(int subId) {
6636 enforceReadPrivilegedPermission("getCertsFromCarrierPrivilegeAccessRules");
6637 Phone phone = getPhone(subId);
6638 if (phone == null) {
6639 return null;
6640 }
6641 final long identity = Binder.clearCallingIdentity();
6642 try {
6643 UiccProfile profile = UiccController.getInstance()
6644 .getUiccProfileForPhone(phone.getPhoneId());
6645 if (profile != null) {
6646 return profile.getCertsFromCarrierPrivilegeAccessRules();
6647 }
6648 } finally {
6649 Binder.restoreCallingIdentity(identity);
6650 }
6651 return null;
6652 }
Malcolm Chen8e4ed912019-01-15 20:22:16 -08006653
6654 /**
6655 * Enable or disable a modem stack.
6656 */
6657 @Override
6658 public boolean enableModemForSlot(int slotIndex, boolean enable) {
6659 enforceModifyPermission();
6660
6661 final long identity = Binder.clearCallingIdentity();
6662 try {
6663 Phone phone = PhoneFactory.getPhone(slotIndex);
6664 if (phone == null) {
6665 return false;
6666 } else {
6667 return (Boolean) sendRequest(CMD_REQUEST_ENABLE_MODEM, enable, phone, null);
6668 }
6669 } finally {
6670 Binder.restoreCallingIdentity(identity);
6671 }
6672 }
Michelecea4cf22018-12-21 15:00:11 -08006673
6674 @Override
6675 public void setMultisimCarrierRestriction(boolean isMultisimCarrierRestricted) {
6676 enforceModifyPermission();
6677
6678 final long identity = Binder.clearCallingIdentity();
6679 try {
6680 mTelephonySharedPreferences.edit()
6681 .putBoolean(PREF_MULTI_SIM_RESTRICTED, isMultisimCarrierRestricted)
6682 .commit();
6683 } finally {
6684 Binder.restoreCallingIdentity(identity);
6685 }
6686 }
6687
6688 @Override
Michele4245e952019-02-04 11:36:23 -08006689 public boolean isMultisimSupported(String callingPackage) {
6690 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp,
6691 getDefaultPhone().getSubId(), callingPackage, "isMultisimSupported")) {
6692 return false;
6693 }
Michelecea4cf22018-12-21 15:00:11 -08006694
6695 final long identity = Binder.clearCallingIdentity();
6696 try {
Michele30b57b22019-03-01 12:01:14 -08006697 return isMultisimSupportedInternal();
Michelecea4cf22018-12-21 15:00:11 -08006698 } finally {
6699 Binder.restoreCallingIdentity(identity);
6700 }
6701 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08006702
Michele30b57b22019-03-01 12:01:14 -08006703 private boolean isMultisimSupportedInternal() {
6704 // If the device has less than 2 SIM cards, indicate that multisim is restricted.
6705 int numPhysicalSlots = UiccController.getInstance().getUiccSlots().length;
6706 if (numPhysicalSlots < 2) {
6707 loge("isMultisimSupportedInternal: requires at least 2 cards");
6708 return false;
6709 }
6710 // Check if the hardware supports multisim functionality. If usage of multisim is not
6711 // supported by the modem, indicate that it is restricted.
6712 PhoneCapability staticCapability =
6713 mPhoneConfigurationManager.getStaticPhoneCapability();
6714 if (staticCapability == null) {
6715 loge("isMultisimSupportedInternal: no static configuration available");
6716 return false;
6717 }
6718 if (staticCapability.logicalModemList.size() < 2) {
6719 loge("isMultisimSupportedInternal: maximum number of modem is < 2");
6720 return false;
6721 }
6722 // Check if support of multiple SIMs is restricted by carrier
6723 if (mTelephonySharedPreferences.getBoolean(PREF_MULTI_SIM_RESTRICTED, false)) {
6724 return false;
6725 }
6726
6727 return true;
6728 }
6729
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08006730 /**
6731 * Switch configs to enable multi-sim or switch back to single-sim
Nazanin Bakhshi17318782019-03-01 11:56:08 -08006732 * Note: Switch from multi-sim to single-sim is only possible with MODIFY_PHONE_STATE
6733 * permission, but the other way around is possible with either MODIFY_PHONE_STATE
6734 * or carrier privileges
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08006735 * @param numOfSims number of active sims we want to switch to
6736 */
6737 @Override
6738 public void switchMultiSimConfig(int numOfSims) {
Nazanin Bakhshi17318782019-03-01 11:56:08 -08006739 if (numOfSims == 1) {
6740 enforceModifyPermission();
6741 } else {
6742 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6743 mApp, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, "switchMultiSimConfig");
6744 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08006745 final long identity = Binder.clearCallingIdentity();
Michele30b57b22019-03-01 12:01:14 -08006746
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08006747 try {
Michele30b57b22019-03-01 12:01:14 -08006748 //only proceed if multi-sim is not restricted
6749 if (!isMultisimSupportedInternal()) {
6750 loge("switchMultiSimConfig not possible. It is restricted or not supported.");
6751 return;
6752 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08006753 mPhoneConfigurationManager.switchMultiSimConfig(numOfSims);
6754 } finally {
6755 Binder.restoreCallingIdentity(identity);
6756 }
6757 }
6758
6759 /**
Nazanin Bakhshi5fe5ef22019-01-30 10:52:09 -08006760 * Get whether reboot is required or not after making changes to modem configurations.
Nazanin Bakhshi4a68f5f2019-02-08 14:31:19 -08006761 * Return value defaults to true
Nazanin Bakhshi5fe5ef22019-01-30 10:52:09 -08006762 */
6763 @Override
6764 public boolean isRebootRequiredForModemConfigChange() {
6765 enforceReadPrivilegedPermission("isRebootRequiredForModemConfigChange");
6766 final long identity = Binder.clearCallingIdentity();
6767 try {
6768 return mPhoneConfigurationManager.isRebootRequiredForModemConfigChange();
6769 } finally {
6770 Binder.restoreCallingIdentity(identity);
6771 }
6772 }
6773
Nathan Harold29f5f052019-02-15 13:41:57 -08006774 private void updateModemStateMetrics() {
6775 TelephonyMetrics metrics = TelephonyMetrics.getInstance();
6776 // TODO: check the state for each modem if the api is ready.
6777 metrics.updateEnabledModemBitmap((1 << TelephonyManager.from(mApp).getPhoneCount()) - 1);
6778 }
6779
Pengquan Meng3889a572019-01-23 11:16:29 -08006780 @Override
6781 public int[] getSlotsMapping() {
6782 enforceReadPrivilegedPermission("getSlotsMapping");
6783
6784 final long identity = Binder.clearCallingIdentity();
6785 try {
6786 int phoneCount = TelephonyManager.getDefault().getPhoneCount();
6787 // All logical slots should have a mapping to a physical slot.
6788 int[] logicalSlotsMapping = new int[phoneCount];
6789 UiccSlotInfo[] slotInfos = getUiccSlotsInfo();
6790 for (int i = 0; i < slotInfos.length; i++) {
6791 if (SubscriptionManager.isValidPhoneId(slotInfos[i].getLogicalSlotIdx())) {
6792 logicalSlotsMapping[slotInfos[i].getLogicalSlotIdx()] = i;
6793 }
6794 }
6795 return logicalSlotsMapping;
6796 } finally {
6797 Binder.restoreCallingIdentity(identity);
6798 }
6799 }
Nathan Harold48d6fd52019-02-06 19:01:40 -08006800
6801 /**
6802 * Get the IRadio HAL Version
6803 */
6804 @Override
6805 public int getRadioHalVersion() {
6806 Phone phone = getDefaultPhone();
6807 if (phone == null) return -1;
6808 HalVersion hv = phone.getHalVersion();
6809 if (hv.equals(HalVersion.UNKNOWN)) return -1;
6810 return hv.major * 100 + hv.minor;
6811 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07006812}