blob: a470484648ce09557778d700b5e68be1125b631d [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
Tyler Gunn7bcdc742019-10-04 15:56:59 -070021import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_IMS;
Ta-wei Yen87c49842016-05-13 21:19:52 -070022import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
23
Ta-wei Yen30a69c82016-12-27 14:52:32 -080024import android.Manifest.permission;
Hall Liua1548bd2019-12-24 14:14:12 -080025import android.annotation.NonNull;
Tyler Gunnf70ed162019-04-03 15:28:53 -070026import android.annotation.Nullable;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070027import android.app.AppOpsManager;
Ta-wei Yen30a69c82016-12-27 14:52:32 -080028import android.app.PendingIntent;
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -070029import android.content.ComponentName;
Amit Mahajan7dbbd822019-03-13 17:33:47 -070030import android.content.ContentResolver;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070031import android.content.Context;
32import android.content.Intent;
Derek Tan97ebb422014-09-05 16:55:38 -070033import android.content.SharedPreferences;
Nathan Harold31d7ff32018-10-15 20:20:30 -070034import android.content.pm.ApplicationInfo;
Derek Tan740e1672017-06-27 14:56:27 -070035import android.content.pm.ComponentInfo;
Amith Yamasani6e118872016-02-19 12:53:51 -080036import android.content.pm.PackageInfo;
Shishir Agrawal60f9c952014-06-23 12:00:43 -070037import android.content.pm.PackageManager;
Jack Yu84291ec2017-05-26 16:07:50 -070038import android.net.NetworkStats;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070039import android.net.Uri;
40import android.os.AsyncResult;
41import android.os.Binder;
Hall Liuf19c44f2018-11-27 14:38:17 -080042import android.os.Build;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070043import android.os.Bundle;
44import android.os.Handler;
yinxu504e1392017-04-12 16:03:22 -070045import android.os.IBinder;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070046import android.os.Looper;
47import android.os.Message;
yinxu504e1392017-04-12 16:03:22 -070048import android.os.Messenger;
Hall Liua1548bd2019-12-24 14:14:12 -080049import android.os.ParcelFileDescriptor;
Malcolm Chen6ca97372019-07-01 16:28:21 -070050import android.os.ParcelUuid;
Tyler Gunn65d45c22017-06-05 11:22:26 -070051import android.os.PersistableBundle;
Shuo Qiancd19c462020-01-16 20:51:11 -080052import android.os.Process;
Brad Ebinger5f64b052017-12-14 14:26:15 -080053import android.os.RemoteException;
Adam Lesinski903a54c2016-04-11 14:49:52 -070054import android.os.ResultReceiver;
Brad Ebinger1ce9c432019-07-16 13:19:44 -070055import android.os.ServiceSpecificException;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070056import android.os.UserHandle;
Stuart Scott981d8582015-04-21 14:09:50 -070057import android.os.UserManager;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070058import android.os.WorkSource;
Derek Tan97ebb422014-09-05 16:55:38 -070059import android.preference.PreferenceManager;
Naina Nallurid63128d2019-09-17 14:10:30 -070060import android.provider.DeviceConfig;
Ihab Awadf2177b72013-11-25 13:33:23 -080061import android.provider.Settings;
Amit Mahajan7dbbd822019-03-13 17:33:47 -070062import android.provider.Telephony;
Inseob Kim14bb3d02018-12-13 17:11:34 +090063import android.sysprop.TelephonyProperties;
Santos Cordon7a1885b2015-02-03 11:15:19 -080064import android.telecom.PhoneAccount;
Nancy Chen31f9ba12016-01-06 11:42:12 -080065import android.telecom.PhoneAccountHandle;
Andrew Lee9431b832015-03-09 18:46:45 -070066import android.telecom.TelecomManager;
Chen Xu227e06f2019-09-26 22:48:11 -070067import android.telephony.Annotation.ApnType;
Junda Liu12f7d802015-05-01 12:06:44 -070068import android.telephony.CarrierConfigManager;
Michele Berionne482f8202018-11-27 18:57:59 -080069import android.telephony.CarrierRestrictionRules;
yincheng zhao2737e882019-09-06 17:06:54 -070070import android.telephony.CellIdentity;
Meng Wanga10e89e2019-12-09 13:13:01 -080071import android.telephony.CellIdentityCdma;
72import android.telephony.CellIdentityGsm;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070073import android.telephony.CellInfo;
Nathan Haroldf180aac2018-06-01 18:43:55 -070074import android.telephony.CellInfoGsm;
75import android.telephony.CellInfoWcdma;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070076import android.telephony.ClientRequestStats;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -070077import android.telephony.ICellInfoCallback;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -070078import android.telephony.IccOpenLogicalChannelResponse;
Hall Liu1aa510f2017-11-22 17:40:08 -080079import android.telephony.LocationAccessPolicy;
Ta-wei Yen87c49842016-05-13 21:19:52 -070080import android.telephony.ModemActivityInfo;
Jake Hambye994d462014-02-03 13:10:13 -080081import android.telephony.NeighboringCellInfo;
yinxu504e1392017-04-12 16:03:22 -070082import android.telephony.NetworkScanRequest;
Michele4245e952019-02-04 11:36:23 -080083import android.telephony.PhoneCapability;
Hall Liud892bec2018-11-30 14:51:45 -080084import android.telephony.PhoneNumberRange;
Wink Saville5d475dd2014-10-17 15:00:58 -070085import android.telephony.RadioAccessFamily;
Hall Liub2ac8ef2019-02-28 15:56:23 -080086import android.telephony.RadioAccessSpecifier;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070087import android.telephony.ServiceState;
Nathan Harold46b42aa2017-03-10 19:38:22 -080088import android.telephony.SignalStrength;
Wink Saville0f3b5fc2014-11-11 08:40:49 -080089import android.telephony.SubscriptionInfo;
Jeff Sharkey85190e62014-12-05 09:40:12 -080090import android.telephony.SubscriptionManager;
Peter Wangc035ce42020-01-08 21:00:22 -080091import android.telephony.TelephonyFrameworkInitializer;
Sanket Padawe99ef1e32016-05-18 16:12:33 -070092import android.telephony.TelephonyHistogram;
Ta-wei Yenb6929602016-05-24 15:48:27 -070093import android.telephony.TelephonyManager;
Hall Liub2ac8ef2019-02-28 15:56:23 -080094import android.telephony.TelephonyScanManager;
Jordan Liu5aa07002018-12-18 15:44:48 -080095import android.telephony.UiccCardInfo;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +000096import android.telephony.UiccSlotInfo;
Tyler Gunn65d45c22017-06-05 11:22:26 -070097import android.telephony.UssdResponse;
Ta-wei Yenb6929602016-05-24 15:48:27 -070098import android.telephony.VisualVoicemailSmsFilterSettings;
Jack Yub5d8f642018-11-26 11:20:48 -080099import android.telephony.data.ApnSetting;
100import android.telephony.emergency.EmergencyNumber;
Brad Ebinger1ce9c432019-07-16 13:19:44 -0700101import android.telephony.ims.ImsException;
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800102import android.telephony.ims.ProvisioningManager;
Brad Ebingera34a6c22019-10-22 17:36:18 -0700103import android.telephony.ims.RegistrationManager;
Brad Ebinger35c841c2018-10-01 10:40:55 -0700104import android.telephony.ims.aidl.IImsCapabilityCallback;
Brad Ebinger22bc3e42018-01-16 09:39:35 -0800105import android.telephony.ims.aidl.IImsConfig;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -0700106import android.telephony.ims.aidl.IImsConfigCallback;
Brad Ebinger22bc3e42018-01-16 09:39:35 -0800107import android.telephony.ims.aidl.IImsMmTelFeature;
108import android.telephony.ims.aidl.IImsRcsFeature;
109import android.telephony.ims.aidl.IImsRegistration;
Brad Ebinger35c841c2018-10-01 10:40:55 -0700110import android.telephony.ims.aidl.IImsRegistrationCallback;
Brad Ebingerbc7dd582019-10-17 17:03:22 -0700111import android.telephony.ims.feature.ImsFeature;
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800112import android.telephony.ims.feature.MmTelFeature;
allenwtsu99c623b2020-01-03 18:24:23 +0800113import android.telephony.ims.feature.RcsFeature;
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800114import android.telephony.ims.stub.ImsConfigImplBase;
Brad Ebinger1f2b5082018-02-08 16:11:32 -0800115import android.telephony.ims.stub.ImsRegistrationImplBase;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700116import android.text.TextUtils;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800117import android.util.ArraySet;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700118import android.util.Log;
Jake Hambye994d462014-02-03 13:10:13 -0800119import android.util.Pair;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800120import android.util.Slog;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800121
Andrew Lee312e8172014-10-23 17:01:36 -0700122import com.android.ims.ImsManager;
Brad Ebinger34bef922017-11-09 10:27:08 -0800123import com.android.ims.internal.IImsServiceFeatureCallback;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700124import com.android.internal.telephony.CallManager;
Tyler Gunn52dcf772017-04-26 11:30:31 -0700125import com.android.internal.telephony.CallStateException;
pkanwar79ec0542017-07-31 14:10:01 -0700126import com.android.internal.telephony.CarrierInfoManager;
chen xu651eec72018-11-11 19:03:44 -0800127import com.android.internal.telephony.CarrierResolver;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700128import com.android.internal.telephony.CellNetworkScanResult;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700129import com.android.internal.telephony.CommandException;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700130import com.android.internal.telephony.DefaultPhoneNotifier;
Nathan Harold48d6fd52019-02-06 19:01:40 -0800131import com.android.internal.telephony.HalVersion;
Brad Ebingera63db5f2019-04-23 16:31:13 -0700132import com.android.internal.telephony.IIntegerConsumer;
Hall Liud892bec2018-11-30 14:51:45 -0800133import com.android.internal.telephony.INumberVerificationCallback;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700134import com.android.internal.telephony.ITelephony;
Jake Hambye994d462014-02-03 13:10:13 -0800135import com.android.internal.telephony.IccCard;
Jack Yu5f7092c2018-04-13 14:05:37 -0700136import com.android.internal.telephony.LocaleTracker;
yinxub1bed742017-04-17 11:45:04 -0700137import com.android.internal.telephony.NetworkScanRequestTracker;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700138import com.android.internal.telephony.OperatorInfo;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700139import com.android.internal.telephony.Phone;
Malcolm Chen2c63d402018-08-14 16:00:53 -0700140import com.android.internal.telephony.PhoneConfigurationManager;
Nathan Harolda667c152016-12-14 11:27:20 -0800141import com.android.internal.telephony.PhoneConstantConversions;
Ta-wei Yen87c49842016-05-13 21:19:52 -0700142import com.android.internal.telephony.PhoneConstants;
Wink Saville36469e72014-06-11 15:17:00 -0700143import com.android.internal.telephony.PhoneFactory;
Wink Saville5d475dd2014-10-17 15:00:58 -0700144import com.android.internal.telephony.ProxyController;
Sanket Padawe99ef1e32016-05-18 16:12:33 -0700145import com.android.internal.telephony.RIL;
Svet Ganovb320e182015-04-16 12:30:10 -0700146import com.android.internal.telephony.RILConstants;
Jack Yu5f7092c2018-04-13 14:05:37 -0700147import com.android.internal.telephony.ServiceStateTracker;
Amit Mahajandccb3f12019-05-13 13:48:32 -0700148import com.android.internal.telephony.SmsController;
Brad Ebingera63db5f2019-04-23 16:31:13 -0700149import com.android.internal.telephony.SmsPermissions;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800150import com.android.internal.telephony.SubscriptionController;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800151import com.android.internal.telephony.TelephonyPermissions;
Malcolm Chendc8c10e2019-04-10 18:25:07 -0700152import com.android.internal.telephony.dataconnection.ApnSettingUtils;
sqianf4ca7ed2019-01-15 18:32:07 -0800153import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Derek Tan740e1672017-06-27 14:56:27 -0700154import com.android.internal.telephony.euicc.EuiccConnector;
Brad Ebinger9c0eb502019-01-23 15:06:19 -0800155import com.android.internal.telephony.ims.ImsResolver;
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700156import com.android.internal.telephony.imsphone.ImsPhone;
157import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
Pengquan Meng6c2dc9f2019-02-06 11:12:53 -0800158import com.android.internal.telephony.metrics.TelephonyMetrics;
Meng Wangafbc5852019-09-19 17:37:13 -0700159import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700160import com.android.internal.telephony.uicc.IccIoResult;
changbetty7157e9e2019-12-06 18:16:37 +0800161import com.android.internal.telephony.uicc.IccRecords;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700162import com.android.internal.telephony.uicc.IccUtils;
Nathan Haroldb3014052017-01-25 15:57:32 -0800163import com.android.internal.telephony.uicc.SIMRecords;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700164import com.android.internal.telephony.uicc.UiccCard;
Nathan Haroldb3014052017-01-25 15:57:32 -0800165import com.android.internal.telephony.uicc.UiccCardApplication;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700166import com.android.internal.telephony.uicc.UiccController;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800167import com.android.internal.telephony.uicc.UiccProfile;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000168import com.android.internal.telephony.uicc.UiccSlot;
zoey chenc730df82019-12-18 17:07:20 +0800169import com.android.internal.telephony.util.LocaleUtils;
fionaxu7ed723d2017-05-30 18:58:54 -0700170import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
Jake Hambye994d462014-02-03 13:10:13 -0800171import com.android.internal.util.HexDump;
Brad Ebingera63db5f2019-04-23 16:31:13 -0700172import com.android.phone.settings.PickSmsSubscriptionActivity;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700173import com.android.phone.vvm.PhoneAccountHandleConverter;
Ta-wei Yen527a9c02017-01-06 15:29:25 -0800174import com.android.phone.vvm.RemoteVvmTaskManager;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700175import com.android.phone.vvm.VisualVoicemailSettingsUtil;
Ta-wei Yenc8905312017-03-28 11:14:45 -0700176import com.android.phone.vvm.VisualVoicemailSmsFilterConfig;
Peter Wang44b186e2020-01-13 23:33:09 -0800177import com.android.telephony.Rlog;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800178
Ta-wei Yenc236d6b2016-06-21 13:33:12 -0700179import java.io.FileDescriptor;
180import java.io.PrintWriter;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700181import java.util.ArrayList;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800182import java.util.Arrays;
sqian11b7a0e2018-12-05 18:48:28 -0800183import java.util.HashMap;
sqianf4ca7ed2019-01-15 18:32:07 -0800184import java.util.HashSet;
Jake Hambye994d462014-02-03 13:10:13 -0800185import java.util.List;
Narayan Kamath1c496c22015-04-16 14:40:19 +0100186import java.util.Locale;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800187import java.util.Map;
Nazanin Bakhshif71371d2019-04-29 17:29:44 -0700188import java.util.NoSuchElementException;
sqianf4ca7ed2019-01-15 18:32:07 -0800189import java.util.Set;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700190
191/**
192 * Implementation of the ITelephony interface.
193 */
Santos Cordon117fee72014-05-16 17:56:12 -0700194public class PhoneInterfaceManager extends ITelephony.Stub {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700195 private static final String LOG_TAG = "PhoneInterfaceManager";
196 private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
197 private static final boolean DBG_LOC = false;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800198 private static final boolean DBG_MERGE = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700199
200 // Message codes used with mMainThreadHandler
201 private static final int CMD_HANDLE_PIN_MMI = 1;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700202 private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7;
203 private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700204 private static final int CMD_OPEN_CHANNEL = 9;
205 private static final int EVENT_OPEN_CHANNEL_DONE = 10;
206 private static final int CMD_CLOSE_CHANNEL = 11;
207 private static final int EVENT_CLOSE_CHANNEL_DONE = 12;
Jake Hambye994d462014-02-03 13:10:13 -0800208 private static final int CMD_NV_READ_ITEM = 13;
209 private static final int EVENT_NV_READ_ITEM_DONE = 14;
210 private static final int CMD_NV_WRITE_ITEM = 15;
211 private static final int EVENT_NV_WRITE_ITEM_DONE = 16;
212 private static final int CMD_NV_WRITE_CDMA_PRL = 17;
213 private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18;
chen xu6dac5ab2018-10-26 17:39:23 -0700214 private static final int CMD_RESET_MODEM_CONFIG = 19;
215 private static final int EVENT_RESET_MODEM_CONFIG_DONE = 20;
Jake Hamby7c27be32014-03-03 13:25:59 -0800216 private static final int CMD_GET_PREFERRED_NETWORK_TYPE = 21;
217 private static final int EVENT_GET_PREFERRED_NETWORK_TYPE_DONE = 22;
218 private static final int CMD_SET_PREFERRED_NETWORK_TYPE = 23;
219 private static final int EVENT_SET_PREFERRED_NETWORK_TYPE_DONE = 24;
Sailesh Nepal35b59452014-03-06 09:26:56 -0800220 private static final int CMD_SEND_ENVELOPE = 25;
221 private static final int EVENT_SEND_ENVELOPE_DONE = 26;
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000222 private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27;
223 private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28;
Derek Tan6b088ee2014-09-05 14:15:18 -0700224 private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29;
225 private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30;
226 private static final int CMD_EXCHANGE_SIM_IO = 31;
227 private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800228 private static final int CMD_SET_VOICEMAIL_NUMBER = 33;
229 private static final int EVENT_SET_VOICEMAIL_NUMBER_DONE = 34;
Stuart Scott54788802015-03-30 13:18:01 -0700230 private static final int CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC = 35;
231 private static final int EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE = 36;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700232 private static final int CMD_GET_MODEM_ACTIVITY_INFO = 37;
233 private static final int EVENT_GET_MODEM_ACTIVITY_INFO_DONE = 38;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700234 private static final int CMD_PERFORM_NETWORK_SCAN = 39;
235 private static final int EVENT_PERFORM_NETWORK_SCAN_DONE = 40;
236 private static final int CMD_SET_NETWORK_SELECTION_MODE_MANUAL = 41;
237 private static final int EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE = 42;
Meng Wang1a7c35a2016-05-05 20:56:15 -0700238 private static final int CMD_SET_ALLOWED_CARRIERS = 43;
239 private static final int EVENT_SET_ALLOWED_CARRIERS_DONE = 44;
240 private static final int CMD_GET_ALLOWED_CARRIERS = 45;
241 private static final int EVENT_GET_ALLOWED_CARRIERS_DONE = 46;
pkanwar32d516d2016-10-14 19:37:38 -0700242 private static final int CMD_HANDLE_USSD_REQUEST = 47;
Nathan Haroldb3014052017-01-25 15:57:32 -0800243 private static final int CMD_GET_FORBIDDEN_PLMNS = 48;
244 private static final int EVENT_GET_FORBIDDEN_PLMNS_DONE = 49;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000245 private static final int CMD_SWITCH_SLOTS = 50;
246 private static final int EVENT_SWITCH_SLOTS_DONE = 51;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700247 private static final int CMD_GET_NETWORK_SELECTION_MODE = 52;
248 private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 53;
249 private static final int CMD_GET_CDMA_ROAMING_MODE = 54;
250 private static final int EVENT_GET_CDMA_ROAMING_MODE_DONE = 55;
251 private static final int CMD_SET_CDMA_ROAMING_MODE = 56;
252 private static final int EVENT_SET_CDMA_ROAMING_MODE_DONE = 57;
253 private static final int CMD_SET_CDMA_SUBSCRIPTION_MODE = 58;
254 private static final int EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE = 59;
Nathan Harold3ff88932018-08-14 10:19:49 -0700255 private static final int CMD_GET_ALL_CELL_INFO = 60;
256 private static final int EVENT_GET_ALL_CELL_INFO_DONE = 61;
257 private static final int CMD_GET_CELL_LOCATION = 62;
258 private static final int EVENT_GET_CELL_LOCATION_DONE = 63;
chen xu6dac5ab2018-10-26 17:39:23 -0700259 private static final int CMD_MODEM_REBOOT = 64;
260 private static final int EVENT_CMD_MODEM_REBOOT_DONE = 65;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -0700261 private static final int CMD_REQUEST_CELL_INFO_UPDATE = 66;
262 private static final int EVENT_REQUEST_CELL_INFO_UPDATE_DONE = 67;
Malcolm Chen8e4ed912019-01-15 20:22:16 -0800263 private static final int CMD_REQUEST_ENABLE_MODEM = 68;
264 private static final int EVENT_ENABLE_MODEM_DONE = 69;
Nazanin Bakhshif71371d2019-04-29 17:29:44 -0700265 private static final int CMD_GET_MODEM_STATUS = 70;
266 private static final int EVENT_GET_MODEM_STATUS_DONE = 71;
yincheng zhao2737e882019-09-06 17:06:54 -0700267 private static final int CMD_SET_FORBIDDEN_PLMNS = 72;
268 private static final int EVENT_SET_FORBIDDEN_PLMNS_DONE = 73;
Naina Nallurid63128d2019-09-17 14:10:30 -0700269 private static final int CMD_ERASE_MODEM_CONFIG = 74;
270 private static final int EVENT_ERASE_MODEM_CONFIG_DONE = 75;
zoey chene02881a2019-12-30 16:11:23 +0800271 private static final int CMD_CHANGE_ICC_LOCK_PASSWORD = 76;
272 private static final int EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE = 77;
273 private static final int CMD_SET_ICC_LOCK_ENABLED = 78;
274 private static final int EVENT_SET_ICC_LOCK_ENABLED_DONE = 79;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700275
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -0800276 // Parameters of select command.
277 private static final int SELECT_COMMAND = 0xA4;
278 private static final int SELECT_P1 = 0x04;
279 private static final int SELECT_P2 = 0;
280 private static final int SELECT_P3 = 0x10;
281
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700282 /** The singleton instance. */
283 private static PhoneInterfaceManager sInstance;
284
Wink Saville3ab207e2014-11-20 13:07:20 -0800285 private PhoneGlobals mApp;
Wink Saville3ab207e2014-11-20 13:07:20 -0800286 private CallManager mCM;
Brad Ebinger24c29992019-12-05 13:03:21 -0800287 private ImsResolver mImsResolver;
Stuart Scott981d8582015-04-21 14:09:50 -0700288 private UserManager mUserManager;
Wink Saville3ab207e2014-11-20 13:07:20 -0800289 private AppOpsManager mAppOps;
290 private MainThreadHandler mMainThreadHandler;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800291 private SubscriptionController mSubscriptionController;
Wink Saville3ab207e2014-11-20 13:07:20 -0800292 private SharedPreferences mTelephonySharedPreferences;
Malcolm Chen2c63d402018-08-14 16:00:53 -0700293 private PhoneConfigurationManager mPhoneConfigurationManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700294
Derek Tan97ebb422014-09-05 16:55:38 -0700295 private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
296 private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
Jeff Sharkey85190e62014-12-05 09:40:12 -0800297 private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800298 private static final String PREF_PROVISION_IMS_MMTEL_PREFIX = "provision_ims_mmtel_";
Derek Tan89e89d42014-07-08 17:00:10 -0700299
Michelecea4cf22018-12-21 15:00:11 -0800300 // String to store multi SIM allowed
301 private static final String PREF_MULTI_SIM_RESTRICTED = "multisim_restricted";
302
Derek Tan740e1672017-06-27 14:56:27 -0700303 // The AID of ISD-R.
304 private static final String ISDR_AID = "A0000005591010FFFFFFFF8900000100";
305
yinxub1bed742017-04-17 11:45:04 -0700306 private NetworkScanRequestTracker mNetworkScanRequestTracker;
307
David Kelly5e06a7f2018-03-12 14:10:59 +0000308 private static final int TYPE_ALLOCATION_CODE_LENGTH = 8;
309 private static final int MANUFACTURER_CODE_LENGTH = 8;
310
Derek Tan89e89d42014-07-08 17:00:10 -0700311 /**
Naina Nallurid63128d2019-09-17 14:10:30 -0700312 * Experiment flag to enable erase modem config on reset network, default value is false
313 */
314 public static final String RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED =
315 "reset_network_erase_modem_config_enabled";
316
317 /**
Shishir Agrawal566b7612013-10-28 14:41:00 -0700318 * A request object to use for transmitting data to an ICC.
319 */
320 private static final class IccAPDUArgument {
321 public int channel, cla, command, p1, p2, p3;
322 public String data;
323
324 public IccAPDUArgument(int channel, int cla, int command,
325 int p1, int p2, int p3, String data) {
326 this.channel = channel;
327 this.cla = cla;
328 this.command = command;
329 this.p1 = p1;
330 this.p2 = p2;
331 this.p3 = p3;
332 this.data = data;
333 }
334 }
335
336 /**
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700337 * A request object to use for transmitting data to an ICC.
338 */
339 private static final class ManualNetworkSelectionArgument {
340 public OperatorInfo operatorInfo;
341 public boolean persistSelection;
342
343 public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) {
344 this.operatorInfo = operatorInfo;
345 this.persistSelection = persistSelection;
346 }
347 }
348
349 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700350 * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
351 * request after sending. The main thread will notify the request when it is complete.
352 */
353 private static final class MainThreadRequest {
354 /** The argument to use for the request */
355 public Object argument;
356 /** The result of the request that is run on the main thread */
357 public Object result;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800358 // The subscriber id that this request applies to. Defaults to
359 // SubscriptionManager.INVALID_SUBSCRIPTION_ID
360 public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700361
Nathan Harold92bed182018-10-12 18:16:49 -0700362 // In cases where subId is unavailable, the caller needs to specify the phone.
363 public Phone phone;
364
vagdeviaf9a5b92018-08-15 16:01:53 -0700365 public WorkSource workSource;
366
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700367 public MainThreadRequest(Object argument) {
368 this.argument = argument;
369 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800370
Nathan Harold92bed182018-10-12 18:16:49 -0700371 MainThreadRequest(Object argument, Phone phone, WorkSource workSource) {
372 this.argument = argument;
373 if (phone != null) {
374 this.phone = phone;
375 }
376 this.workSource = workSource;
377 }
378
vagdeviaf9a5b92018-08-15 16:01:53 -0700379 MainThreadRequest(Object argument, Integer subId, WorkSource workSource) {
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800380 this.argument = argument;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800381 if (subId != null) {
382 this.subId = subId;
383 }
vagdeviaf9a5b92018-08-15 16:01:53 -0700384 this.workSource = workSource;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800385 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700386 }
387
Sailesh Nepalcc0375f2013-11-13 09:15:18 -0800388 private static final class IncomingThirdPartyCallArgs {
389 public final ComponentName component;
390 public final String callId;
391 public final String callerDisplayName;
392
393 public IncomingThirdPartyCallArgs(ComponentName component, String callId,
394 String callerDisplayName) {
395 this.component = component;
396 this.callId = callId;
397 this.callerDisplayName = callerDisplayName;
398 }
399 }
400
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700401 /**
402 * A handler that processes messages on the main thread in the phone process. Since many
403 * of the Phone calls are not thread safe this is needed to shuttle the requests from the
404 * inbound binder threads to the main thread in the phone process. The Binder thread
405 * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
406 * on, which will be notified when the operation completes and will contain the result of the
407 * request.
408 *
409 * <p>If a MainThreadRequest object is provided in the msg.obj field,
410 * note that request.result must be set to something non-null for the calling thread to
411 * unblock.
412 */
413 private final class MainThreadHandler extends Handler {
414 @Override
415 public void handleMessage(Message msg) {
416 MainThreadRequest request;
417 Message onCompleted;
418 AsyncResult ar;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800419 UiccCard uiccCard;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700420 IccAPDUArgument iccArgument;
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800421 final Phone defaultPhone = getDefaultPhone();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700422
423 switch (msg.what) {
Pengquan Menga1bb6272018-09-06 09:59:22 -0700424 case CMD_HANDLE_USSD_REQUEST: {
425 request = (MainThreadRequest) msg.obj;
426 final Phone phone = getPhoneFromRequest(request);
427 Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
428 String ussdRequest = ussdObject.first;
429 ResultReceiver wrappedCallback = ussdObject.second;
Tyler Gunn65d45c22017-06-05 11:22:26 -0700430
Pengquan Menga1bb6272018-09-06 09:59:22 -0700431 if (!isUssdApiAllowed(request.subId)) {
432 // Carrier does not support use of this API, return failure.
433 Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
434 UssdResponse response = new UssdResponse(ussdRequest, null);
435 Bundle returnData = new Bundle();
436 returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
437 wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
Tyler Gunn65d45c22017-06-05 11:22:26 -0700438
Pengquan Menga1bb6272018-09-06 09:59:22 -0700439 request.result = true;
440 notifyRequester(request);
441 return;
442 }
Tyler Gunn65d45c22017-06-05 11:22:26 -0700443
Pengquan Menga1bb6272018-09-06 09:59:22 -0700444 try {
445 request.result = phone != null
446 ? phone.handleUssdRequest(ussdRequest, wrappedCallback) : false;
447 } catch (CallStateException cse) {
448 request.result = false;
449 }
450 // Wake up the requesting thread
451 notifyRequester(request);
452 break;
pkanwar32d516d2016-10-14 19:37:38 -0700453 }
454
Yorke Lee716f67e2015-06-17 15:39:16 -0700455 case CMD_HANDLE_PIN_MMI: {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700456 request = (MainThreadRequest) msg.obj;
Yorke Lee716f67e2015-06-17 15:39:16 -0700457 final Phone phone = getPhoneFromRequest(request);
458 request.result = phone != null ?
459 getPhoneFromRequest(request).handlePinMmi((String) request.argument)
460 : false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700461 // Wake up the requesting thread
Pengquan Menga1bb6272018-09-06 09:59:22 -0700462 notifyRequester(request);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700463 break;
Yorke Lee716f67e2015-06-17 15:39:16 -0700464 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700465
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700466 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700467 request = (MainThreadRequest) msg.obj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700468 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800469 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700470 if (uiccCard == null) {
471 loge("iccTransmitApduLogicalChannel: No UICC");
472 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700473 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700474 } else {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700475 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
476 request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700477 uiccCard.iccTransmitApduLogicalChannel(
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700478 iccArgument.channel, iccArgument.cla, iccArgument.command,
479 iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data,
Shishir Agrawal566b7612013-10-28 14:41:00 -0700480 onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700481 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700482 break;
483
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700484 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700485 ar = (AsyncResult) msg.obj;
486 request = (MainThreadRequest) ar.userObj;
487 if (ar.exception == null && ar.result != null) {
488 request.result = ar.result;
489 } else {
490 request.result = new IccIoResult(0x6F, 0, (byte[])null);
491 if (ar.result == null) {
492 loge("iccTransmitApduLogicalChannel: Empty response");
Jake Hambye994d462014-02-03 13:10:13 -0800493 } else if (ar.exception instanceof CommandException) {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700494 loge("iccTransmitApduLogicalChannel: CommandException: " +
Jake Hambye994d462014-02-03 13:10:13 -0800495 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700496 } else {
497 loge("iccTransmitApduLogicalChannel: Unknown exception");
498 }
499 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700500 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700501 break;
502
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700503 case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
504 request = (MainThreadRequest) msg.obj;
505 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800506 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700507 if (uiccCard == null) {
508 loge("iccTransmitApduBasicChannel: No UICC");
509 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700510 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700511 } else {
512 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
513 request);
514 uiccCard.iccTransmitApduBasicChannel(
515 iccArgument.cla, iccArgument.command, iccArgument.p1, iccArgument.p2,
516 iccArgument.p3, iccArgument.data, onCompleted);
517 }
518 break;
519
520 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
521 ar = (AsyncResult) msg.obj;
522 request = (MainThreadRequest) ar.userObj;
523 if (ar.exception == null && ar.result != null) {
524 request.result = ar.result;
525 } else {
526 request.result = new IccIoResult(0x6F, 0, (byte[])null);
527 if (ar.result == null) {
528 loge("iccTransmitApduBasicChannel: Empty response");
529 } else if (ar.exception instanceof CommandException) {
530 loge("iccTransmitApduBasicChannel: CommandException: " +
531 ar.exception);
532 } else {
533 loge("iccTransmitApduBasicChannel: Unknown exception");
534 }
535 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700536 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700537 break;
538
539 case CMD_EXCHANGE_SIM_IO:
540 request = (MainThreadRequest) msg.obj;
541 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800542 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700543 if (uiccCard == null) {
544 loge("iccExchangeSimIO: No UICC");
545 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700546 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700547 } else {
548 onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
549 request);
550 uiccCard.iccExchangeSimIO(iccArgument.cla, /* fileID */
551 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3,
552 iccArgument.data, onCompleted);
553 }
554 break;
555
556 case EVENT_EXCHANGE_SIM_IO_DONE:
557 ar = (AsyncResult) msg.obj;
558 request = (MainThreadRequest) ar.userObj;
559 if (ar.exception == null && ar.result != null) {
560 request.result = ar.result;
561 } else {
562 request.result = new IccIoResult(0x6f, 0, (byte[])null);
563 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700564 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700565 break;
566
Derek Tan4d5e5c12014-02-04 11:54:58 -0800567 case CMD_SEND_ENVELOPE:
568 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800569 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700570 if (uiccCard == null) {
571 loge("sendEnvelopeWithStatus: No UICC");
572 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700573 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700574 } else {
575 onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
576 uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted);
577 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800578 break;
579
580 case EVENT_SEND_ENVELOPE_DONE:
581 ar = (AsyncResult) msg.obj;
582 request = (MainThreadRequest) ar.userObj;
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700583 if (ar.exception == null && ar.result != null) {
584 request.result = ar.result;
Derek Tan4d5e5c12014-02-04 11:54:58 -0800585 } else {
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700586 request.result = new IccIoResult(0x6F, 0, (byte[])null);
587 if (ar.result == null) {
588 loge("sendEnvelopeWithStatus: Empty response");
589 } else if (ar.exception instanceof CommandException) {
590 loge("sendEnvelopeWithStatus: CommandException: " +
591 ar.exception);
592 } else {
593 loge("sendEnvelopeWithStatus: exception:" + ar.exception);
594 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800595 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700596 notifyRequester(request);
Derek Tan4d5e5c12014-02-04 11:54:58 -0800597 break;
598
Shishir Agrawal566b7612013-10-28 14:41:00 -0700599 case CMD_OPEN_CHANNEL:
600 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800601 uiccCard = getUiccCardFromRequest(request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800602 Pair<String, Integer> openChannelArgs = (Pair<String, Integer>) request.argument;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700603 if (uiccCard == null) {
604 loge("iccOpenLogicalChannel: No UICC");
Shishir Agrawalfc0492a2016-02-17 11:15:33 -0800605 request.result = new IccOpenLogicalChannelResponse(-1,
606 IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700607 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700608 } else {
609 onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800610 uiccCard.iccOpenLogicalChannel(openChannelArgs.first,
611 openChannelArgs.second, onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700612 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700613 break;
614
615 case EVENT_OPEN_CHANNEL_DONE:
616 ar = (AsyncResult) msg.obj;
617 request = (MainThreadRequest) ar.userObj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700618 IccOpenLogicalChannelResponse openChannelResp;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700619 if (ar.exception == null && ar.result != null) {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700620 int[] result = (int[]) ar.result;
621 int channelId = result[0];
622 byte[] selectResponse = null;
623 if (result.length > 1) {
624 selectResponse = new byte[result.length - 1];
625 for (int i = 1; i < result.length; ++i) {
626 selectResponse[i - 1] = (byte) result[i];
627 }
628 }
629 openChannelResp = new IccOpenLogicalChannelResponse(channelId,
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700630 IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700631 } else {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700632 if (ar.result == null) {
633 loge("iccOpenLogicalChannel: Empty response");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700634 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700635 if (ar.exception != null) {
636 loge("iccOpenLogicalChannel: Exception: " + ar.exception);
637 }
638
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700639 int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR;
Junda Liua754ba12015-05-20 01:17:52 -0700640 if (ar.exception instanceof CommandException) {
641 CommandException.Error error =
642 ((CommandException) (ar.exception)).getCommandError();
643 if (error == CommandException.Error.MISSING_RESOURCE) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700644 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE;
Junda Liua754ba12015-05-20 01:17:52 -0700645 } else if (error == CommandException.Error.NO_SUCH_ELEMENT) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700646 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700647 }
648 }
649 openChannelResp = new IccOpenLogicalChannelResponse(
650 IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700651 }
Shishir Agrawal82c8a462014-07-31 18:13:17 -0700652 request.result = openChannelResp;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700653 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700654 break;
655
656 case CMD_CLOSE_CHANNEL:
657 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800658 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700659 if (uiccCard == null) {
660 loge("iccCloseLogicalChannel: No UICC");
Yoshiaki Naka2e29d822016-09-02 19:27:39 +0900661 request.result = false;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700662 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700663 } else {
664 onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
665 uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
666 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700667 break;
668
669 case EVENT_CLOSE_CHANNEL_DONE:
Jake Hambye994d462014-02-03 13:10:13 -0800670 handleNullReturnEvent(msg, "iccCloseLogicalChannel");
671 break;
672
673 case CMD_NV_READ_ITEM:
674 request = (MainThreadRequest) msg.obj;
675 onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800676 defaultPhone.nvReadItem((Integer) request.argument, onCompleted,
677 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800678 break;
679
680 case EVENT_NV_READ_ITEM_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700681 ar = (AsyncResult) msg.obj;
682 request = (MainThreadRequest) ar.userObj;
Jake Hambye994d462014-02-03 13:10:13 -0800683 if (ar.exception == null && ar.result != null) {
684 request.result = ar.result; // String
Shishir Agrawal566b7612013-10-28 14:41:00 -0700685 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800686 request.result = "";
687 if (ar.result == null) {
688 loge("nvReadItem: Empty response");
689 } else if (ar.exception instanceof CommandException) {
690 loge("nvReadItem: CommandException: " +
691 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700692 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800693 loge("nvReadItem: Unknown exception");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700694 }
695 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700696 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700697 break;
698
Jake Hambye994d462014-02-03 13:10:13 -0800699 case CMD_NV_WRITE_ITEM:
700 request = (MainThreadRequest) msg.obj;
701 onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
702 Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800703 defaultPhone.nvWriteItem(idValue.first, idValue.second, onCompleted,
vagdeviaf9a5b92018-08-15 16:01:53 -0700704 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800705 break;
706
707 case EVENT_NV_WRITE_ITEM_DONE:
708 handleNullReturnEvent(msg, "nvWriteItem");
709 break;
710
711 case CMD_NV_WRITE_CDMA_PRL:
712 request = (MainThreadRequest) msg.obj;
713 onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800714 defaultPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
Jake Hambye994d462014-02-03 13:10:13 -0800715 break;
716
717 case EVENT_NV_WRITE_CDMA_PRL_DONE:
718 handleNullReturnEvent(msg, "nvWriteCdmaPrl");
719 break;
720
chen xu6dac5ab2018-10-26 17:39:23 -0700721 case CMD_RESET_MODEM_CONFIG:
Jake Hambye994d462014-02-03 13:10:13 -0800722 request = (MainThreadRequest) msg.obj;
chen xu6dac5ab2018-10-26 17:39:23 -0700723 onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800724 defaultPhone.resetModemConfig(onCompleted);
Jake Hambye994d462014-02-03 13:10:13 -0800725 break;
726
chen xu6dac5ab2018-10-26 17:39:23 -0700727 case EVENT_RESET_MODEM_CONFIG_DONE:
728 handleNullReturnEvent(msg, "resetModemConfig");
Jake Hambye994d462014-02-03 13:10:13 -0800729 break;
730
Jake Hamby7c27be32014-03-03 13:25:59 -0800731 case CMD_GET_PREFERRED_NETWORK_TYPE:
732 request = (MainThreadRequest) msg.obj;
733 onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request);
Stuart Scott54788802015-03-30 13:18:01 -0700734 getPhoneFromRequest(request).getPreferredNetworkType(onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800735 break;
736
737 case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE:
738 ar = (AsyncResult) msg.obj;
739 request = (MainThreadRequest) ar.userObj;
740 if (ar.exception == null && ar.result != null) {
741 request.result = ar.result; // Integer
742 } else {
Sanket Padawecfc2d352016-01-05 19:52:14 -0800743 request.result = null;
Jake Hamby7c27be32014-03-03 13:25:59 -0800744 if (ar.result == null) {
745 loge("getPreferredNetworkType: Empty response");
746 } else if (ar.exception instanceof CommandException) {
747 loge("getPreferredNetworkType: CommandException: " +
748 ar.exception);
749 } else {
750 loge("getPreferredNetworkType: Unknown exception");
751 }
752 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700753 notifyRequester(request);
Jake Hamby7c27be32014-03-03 13:25:59 -0800754 break;
755
756 case CMD_SET_PREFERRED_NETWORK_TYPE:
757 request = (MainThreadRequest) msg.obj;
758 onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request);
759 int networkType = (Integer) request.argument;
Stuart Scott54788802015-03-30 13:18:01 -0700760 getPhoneFromRequest(request).setPreferredNetworkType(networkType, onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800761 break;
762
763 case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE:
764 handleNullReturnEvent(msg, "setPreferredNetworkType");
765 break;
766
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000767 case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
768 request = (MainThreadRequest)msg.obj;
769 onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800770 defaultPhone.invokeOemRilRequestRaw((byte[]) request.argument, onCompleted);
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000771 break;
772
773 case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
774 ar = (AsyncResult)msg.obj;
775 request = (MainThreadRequest)ar.userObj;
776 request.result = ar;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700777 notifyRequester(request);
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000778 break;
779
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800780 case CMD_SET_VOICEMAIL_NUMBER:
781 request = (MainThreadRequest) msg.obj;
782 onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
783 Pair<String, String> tagNum = (Pair<String, String>) request.argument;
Stuart Scott584921c2015-01-15 17:10:34 -0800784 getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
785 onCompleted);
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800786 break;
787
788 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
789 handleNullReturnEvent(msg, "setVoicemailNumber");
790 break;
791
Stuart Scott54788802015-03-30 13:18:01 -0700792 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC:
793 request = (MainThreadRequest) msg.obj;
794 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE,
795 request);
796 getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted);
797 break;
798
799 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE:
800 handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic");
801 break;
802
Shishir Agrawal302c8692015-06-19 13:49:39 -0700803 case CMD_PERFORM_NETWORK_SCAN:
804 request = (MainThreadRequest) msg.obj;
805 onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request);
806 getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
807 break;
808
809 case EVENT_PERFORM_NETWORK_SCAN_DONE:
810 ar = (AsyncResult) msg.obj;
811 request = (MainThreadRequest) ar.userObj;
812 CellNetworkScanResult cellScanResult;
813 if (ar.exception == null && ar.result != null) {
814 cellScanResult = new CellNetworkScanResult(
815 CellNetworkScanResult.STATUS_SUCCESS,
816 (List<OperatorInfo>) ar.result);
817 } else {
818 if (ar.result == null) {
819 loge("getCellNetworkScanResults: Empty response");
820 }
821 if (ar.exception != null) {
822 loge("getCellNetworkScanResults: Exception: " + ar.exception);
823 }
824 int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR;
825 if (ar.exception instanceof CommandException) {
826 CommandException.Error error =
827 ((CommandException) (ar.exception)).getCommandError();
828 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
829 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE;
830 } else if (error == CommandException.Error.GENERIC_FAILURE) {
831 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE;
832 }
833 }
834 cellScanResult = new CellNetworkScanResult(errorCode, null);
835 }
836 request.result = cellScanResult;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700837 notifyRequester(request);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700838 break;
839
840 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
841 request = (MainThreadRequest) msg.obj;
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700842 ManualNetworkSelectionArgument selArg =
843 (ManualNetworkSelectionArgument) request.argument;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700844 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE,
845 request);
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700846 getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo,
847 selArg.persistSelection, onCompleted);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700848 break;
849
850 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
Pengquan Menge3d01e22018-09-20 15:25:35 -0700851 ar = (AsyncResult) msg.obj;
852 request = (MainThreadRequest) ar.userObj;
853 if (ar.exception == null) {
854 request.result = true;
855 } else {
856 request.result = false;
857 loge("setNetworkSelectionModeManual " + ar.exception);
858 }
859 notifyRequester(request);
860 mApp.onNetworkSelectionChanged(request.subId);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700861 break;
862
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700863 case CMD_GET_MODEM_ACTIVITY_INFO:
864 request = (MainThreadRequest) msg.obj;
865 onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
James Mattisab947702019-04-03 14:18:34 -0700866 if (defaultPhone != null) {
867 defaultPhone.getModemActivityInfo(onCompleted, request.workSource);
868 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700869 break;
870
871 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE:
872 ar = (AsyncResult) msg.obj;
873 request = (MainThreadRequest) ar.userObj;
874 if (ar.exception == null && ar.result != null) {
875 request.result = ar.result;
876 } else {
877 if (ar.result == null) {
878 loge("queryModemActivityInfo: Empty response");
879 } else if (ar.exception instanceof CommandException) {
880 loge("queryModemActivityInfo: CommandException: " +
881 ar.exception);
882 } else {
883 loge("queryModemActivityInfo: Unknown exception");
884 }
885 }
Amit Mahajand4766222016-01-28 15:28:28 -0800886 // Result cannot be null. Return ModemActivityInfo with all fields set to 0.
887 if (request.result == null) {
Peter Collingbournec00e9022019-11-26 09:56:26 -0800888 request.result = new ModemActivityInfo(0, 0, 0, new int[0], 0);
Amit Mahajand4766222016-01-28 15:28:28 -0800889 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700890 notifyRequester(request);
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700891 break;
892
Meng Wang1a7c35a2016-05-05 20:56:15 -0700893 case CMD_SET_ALLOWED_CARRIERS:
894 request = (MainThreadRequest) msg.obj;
Michele Berionne482f8202018-11-27 18:57:59 -0800895 CarrierRestrictionRules argument =
896 (CarrierRestrictionRules) request.argument;
Meng Wang1a7c35a2016-05-05 20:56:15 -0700897 onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
Michele Berionne482f8202018-11-27 18:57:59 -0800898 defaultPhone.setAllowedCarriers(argument, onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700899 break;
900
901 case EVENT_SET_ALLOWED_CARRIERS_DONE:
902 ar = (AsyncResult) msg.obj;
903 request = (MainThreadRequest) ar.userObj;
904 if (ar.exception == null && ar.result != null) {
905 request.result = ar.result;
906 } else {
Michele Berionne482f8202018-11-27 18:57:59 -0800907 request.result = TelephonyManager.SET_CARRIER_RESTRICTION_ERROR;
908 if (ar.exception instanceof CommandException) {
909 loge("setAllowedCarriers: CommandException: " + ar.exception);
910 CommandException.Error error =
911 ((CommandException) (ar.exception)).getCommandError();
912 if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
913 request.result =
914 TelephonyManager.SET_CARRIER_RESTRICTION_NOT_SUPPORTED;
915 }
Meng Wang1a7c35a2016-05-05 20:56:15 -0700916 } else {
917 loge("setAllowedCarriers: Unknown exception");
918 }
919 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700920 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700921 break;
922
923 case CMD_GET_ALLOWED_CARRIERS:
924 request = (MainThreadRequest) msg.obj;
925 onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800926 defaultPhone.getAllowedCarriers(onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700927 break;
928
929 case EVENT_GET_ALLOWED_CARRIERS_DONE:
930 ar = (AsyncResult) msg.obj;
931 request = (MainThreadRequest) ar.userObj;
932 if (ar.exception == null && ar.result != null) {
933 request.result = ar.result;
934 } else {
Michele Berionne482f8202018-11-27 18:57:59 -0800935 request.result = new IllegalStateException(
936 "Failed to get carrier restrictions");
Meng Wang1a7c35a2016-05-05 20:56:15 -0700937 if (ar.result == null) {
938 loge("getAllowedCarriers: Empty response");
939 } else if (ar.exception instanceof CommandException) {
940 loge("getAllowedCarriers: CommandException: " +
941 ar.exception);
942 } else {
943 loge("getAllowedCarriers: Unknown exception");
944 }
945 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700946 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700947 break;
948
Nathan Haroldb3014052017-01-25 15:57:32 -0800949 case EVENT_GET_FORBIDDEN_PLMNS_DONE:
950 ar = (AsyncResult) msg.obj;
951 request = (MainThreadRequest) ar.userObj;
952 if (ar.exception == null && ar.result != null) {
953 request.result = ar.result;
954 } else {
955 request.result = new IllegalArgumentException(
956 "Failed to retrieve Forbidden Plmns");
957 if (ar.result == null) {
958 loge("getForbiddenPlmns: Empty response");
959 } else {
960 loge("getForbiddenPlmns: Unknown exception");
961 }
962 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700963 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -0800964 break;
965
966 case CMD_GET_FORBIDDEN_PLMNS:
967 request = (MainThreadRequest) msg.obj;
968 uiccCard = getUiccCardFromRequest(request);
969 if (uiccCard == null) {
970 loge("getForbiddenPlmns() UiccCard is null");
971 request.result = new IllegalArgumentException(
972 "getForbiddenPlmns() UiccCard is null");
Pengquan Menga1bb6272018-09-06 09:59:22 -0700973 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -0800974 break;
975 }
976 Integer appType = (Integer) request.argument;
977 UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType);
978 if (uiccApp == null) {
979 loge("getForbiddenPlmns() no app with specified type -- "
980 + appType);
981 request.result = new IllegalArgumentException("Failed to get UICC App");
Pengquan Menga1bb6272018-09-06 09:59:22 -0700982 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -0800983 break;
984 } else {
985 if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
986 + " specified type -- " + appType);
987 }
988 onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
989 ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
990 onCompleted);
991 break;
992
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000993 case CMD_SWITCH_SLOTS:
994 request = (MainThreadRequest) msg.obj;
995 int[] physicalSlots = (int[]) request.argument;
996 onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
997 UiccController.getInstance().switchSlots(physicalSlots, onCompleted);
998 break;
999
1000 case EVENT_SWITCH_SLOTS_DONE:
1001 ar = (AsyncResult) msg.obj;
1002 request = (MainThreadRequest) ar.userObj;
1003 request.result = (ar.exception == null);
Pengquan Menga1bb6272018-09-06 09:59:22 -07001004 notifyRequester(request);
1005 break;
1006 case CMD_GET_NETWORK_SELECTION_MODE:
1007 request = (MainThreadRequest) msg.obj;
1008 onCompleted = obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE, request);
1009 getPhoneFromRequest(request).getNetworkSelectionMode(onCompleted);
1010 break;
1011
1012 case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
1013 ar = (AsyncResult) msg.obj;
1014 request = (MainThreadRequest) ar.userObj;
1015 if (ar.exception != null) {
1016 request.result = TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
1017 } else {
1018 int mode = ((int[]) ar.result)[0];
1019 if (mode == 0) {
1020 request.result = TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
1021 } else {
1022 request.result = TelephonyManager.NETWORK_SELECTION_MODE_MANUAL;
1023 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001024 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001025 notifyRequester(request);
1026 break;
1027 case CMD_GET_CDMA_ROAMING_MODE:
1028 request = (MainThreadRequest) msg.obj;
1029 onCompleted = obtainMessage(EVENT_GET_CDMA_ROAMING_MODE_DONE, request);
1030 getPhoneFromRequest(request).queryCdmaRoamingPreference(onCompleted);
1031 break;
1032 case EVENT_GET_CDMA_ROAMING_MODE_DONE:
1033 ar = (AsyncResult) msg.obj;
1034 request = (MainThreadRequest) ar.userObj;
1035 if (ar.exception != null) {
1036 request.result = TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT;
1037 } else {
1038 request.result = ((int[]) ar.result)[0];
1039 }
1040 notifyRequester(request);
1041 break;
1042 case CMD_SET_CDMA_ROAMING_MODE:
1043 request = (MainThreadRequest) msg.obj;
1044 onCompleted = obtainMessage(EVENT_SET_CDMA_ROAMING_MODE_DONE, request);
1045 int mode = (int) request.argument;
1046 getPhoneFromRequest(request).setCdmaRoamingPreference(mode, onCompleted);
1047 break;
1048 case EVENT_SET_CDMA_ROAMING_MODE_DONE:
1049 ar = (AsyncResult) msg.obj;
1050 request = (MainThreadRequest) ar.userObj;
1051 request.result = ar.exception == null;
1052 notifyRequester(request);
1053 break;
1054 case CMD_SET_CDMA_SUBSCRIPTION_MODE:
1055 request = (MainThreadRequest) msg.obj;
1056 onCompleted = obtainMessage(EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1057 int subscriptionMode = (int) request.argument;
1058 getPhoneFromRequest(request).setCdmaSubscription(subscriptionMode, onCompleted);
1059 break;
1060 case EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE:
1061 ar = (AsyncResult) msg.obj;
1062 request = (MainThreadRequest) ar.userObj;
1063 request.result = ar.exception == null;
1064 notifyRequester(request);
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001065 break;
Nathan Harold3ff88932018-08-14 10:19:49 -07001066 case CMD_GET_ALL_CELL_INFO:
1067 request = (MainThreadRequest) msg.obj;
Nathan Harold3ff88932018-08-14 10:19:49 -07001068 onCompleted = obtainMessage(EVENT_GET_ALL_CELL_INFO_DONE, request);
Nathan Harold92bed182018-10-12 18:16:49 -07001069 request.phone.requestCellInfoUpdate(request.workSource, onCompleted);
Nathan Harold3ff88932018-08-14 10:19:49 -07001070 break;
Nathan Harold3ff88932018-08-14 10:19:49 -07001071 case EVENT_GET_ALL_CELL_INFO_DONE:
1072 ar = (AsyncResult) msg.obj;
1073 request = (MainThreadRequest) ar.userObj;
Nathan Harold8d0f1742018-10-02 12:14:47 -07001074 // If a timeout occurs, the response will be null
1075 request.result = (ar.exception == null && ar.result != null)
1076 ? ar.result : new ArrayList<CellInfo>();
Nathan Harold3ff88932018-08-14 10:19:49 -07001077 synchronized (request) {
1078 request.notifyAll();
1079 }
1080 break;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001081 case CMD_REQUEST_CELL_INFO_UPDATE:
1082 request = (MainThreadRequest) msg.obj;
1083 request.phone.requestCellInfoUpdate(request.workSource,
1084 obtainMessage(EVENT_REQUEST_CELL_INFO_UPDATE_DONE, request));
1085 break;
1086 case EVENT_REQUEST_CELL_INFO_UPDATE_DONE:
1087 ar = (AsyncResult) msg.obj;
1088 request = (MainThreadRequest) ar.userObj;
1089 ICellInfoCallback cb = (ICellInfoCallback) request.argument;
1090 try {
1091 if (ar.exception != null) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001092 Log.e(LOG_TAG, "Exception retrieving CellInfo=" + ar.exception);
Meng Wangd8921f42019-09-30 17:13:54 -07001093 cb.onError(
1094 TelephonyManager.CellInfoCallback.ERROR_MODEM_ERROR,
1095 ar.exception.getClass().getName(),
1096 ar.exception.toString());
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001097 } else if (ar.result == null) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001098 Log.w(LOG_TAG, "Timeout Waiting for CellInfo!");
Meng Wangd8921f42019-09-30 17:13:54 -07001099 cb.onError(TelephonyManager.CellInfoCallback.ERROR_TIMEOUT, null, null);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001100 } else {
1101 // use the result as returned
1102 cb.onCellInfo((List<CellInfo>) ar.result);
1103 }
1104 } catch (RemoteException re) {
1105 Log.w(LOG_TAG, "Discarded CellInfo due to Callback RemoteException");
1106 }
1107 break;
1108 case CMD_GET_CELL_LOCATION:
Nathan Harold3ff88932018-08-14 10:19:49 -07001109 request = (MainThreadRequest) msg.obj;
1110 WorkSource ws = (WorkSource) request.argument;
1111 Phone phone = getPhoneFromRequest(request);
Meng Wanga10e89e2019-12-09 13:13:01 -08001112 phone.getCellIdentity(ws, obtainMessage(EVENT_GET_CELL_LOCATION_DONE, request));
Nathan Harold3ff88932018-08-14 10:19:49 -07001113 break;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001114 case EVENT_GET_CELL_LOCATION_DONE:
Nathan Harold3ff88932018-08-14 10:19:49 -07001115 ar = (AsyncResult) msg.obj;
1116 request = (MainThreadRequest) ar.userObj;
1117 if (ar.exception == null) {
1118 request.result = ar.result;
1119 } else {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001120 phone = getPhoneFromRequest(request);
Nathan Harold3ff88932018-08-14 10:19:49 -07001121 request.result = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
Meng Wanga10e89e2019-12-09 13:13:01 -08001122 ? new CellIdentityCdma() : new CellIdentityGsm();
Nathan Harold3ff88932018-08-14 10:19:49 -07001123 }
1124
1125 synchronized (request) {
1126 request.notifyAll();
1127 }
1128 break;
chen xu6dac5ab2018-10-26 17:39:23 -07001129 case CMD_MODEM_REBOOT:
1130 request = (MainThreadRequest) msg.obj;
1131 onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001132 defaultPhone.rebootModem(onCompleted);
chen xu6dac5ab2018-10-26 17:39:23 -07001133 break;
chen xu6dac5ab2018-10-26 17:39:23 -07001134 case EVENT_CMD_MODEM_REBOOT_DONE:
1135 handleNullReturnEvent(msg, "rebootModem");
1136 break;
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001137 case CMD_REQUEST_ENABLE_MODEM:
1138 request = (MainThreadRequest) msg.obj;
1139 boolean enable = (boolean) request.argument;
1140 onCompleted = obtainMessage(EVENT_ENABLE_MODEM_DONE, request);
Nazanin Bakhshi33d584b2019-02-27 10:44:32 -08001141 onCompleted.arg1 = enable ? 1 : 0;
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001142 PhoneConfigurationManager.getInstance()
1143 .enablePhone(request.phone, enable, onCompleted);
1144 break;
1145 case EVENT_ENABLE_MODEM_DONE:
1146 ar = (AsyncResult) msg.obj;
1147 request = (MainThreadRequest) ar.userObj;
1148 request.result = (ar.exception == null);
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07001149 int phoneId = request.phone.getPhoneId();
Nazanin Bakhshi33d584b2019-02-27 10:44:32 -08001150 //update the cache as modem status has changed
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07001151 if ((boolean) request.result) {
1152 mPhoneConfigurationManager.addToPhoneStatusCache(phoneId, msg.arg1 == 1);
1153 updateModemStateMetrics();
1154 } else {
1155 Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1156 + ar.exception);
1157 }
1158 notifyRequester(request);
1159 break;
1160 case CMD_GET_MODEM_STATUS:
1161 request = (MainThreadRequest) msg.obj;
1162 onCompleted = obtainMessage(EVENT_GET_MODEM_STATUS_DONE, request);
1163 PhoneConfigurationManager.getInstance()
1164 .getPhoneStatusFromModem(request.phone, onCompleted);
1165 break;
1166 case EVENT_GET_MODEM_STATUS_DONE:
1167 ar = (AsyncResult) msg.obj;
1168 request = (MainThreadRequest) ar.userObj;
1169 int id = request.phone.getPhoneId();
1170 if (ar.exception == null && ar.result != null) {
1171 request.result = ar.result;
1172 //update the cache as modem status has changed
1173 mPhoneConfigurationManager.addToPhoneStatusCache(id,
1174 (boolean) request.result);
1175 } else {
1176 // Return true if modem status cannot be retrieved. For most cases,
1177 // modem status is on. And for older version modems, GET_MODEM_STATUS
1178 // and disable modem are not supported. Modem is always on.
1179 // TODO: this should be fixed in R to support a third
1180 // status UNKNOWN b/131631629
1181 request.result = true;
1182 Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1183 + ar.exception);
1184 }
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001185 notifyRequester(request);
1186 break;
yincheng zhao2737e882019-09-06 17:06:54 -07001187 case EVENT_SET_FORBIDDEN_PLMNS_DONE:
1188 ar = (AsyncResult) msg.obj;
1189 request = (MainThreadRequest) ar.userObj;
1190 if (ar.exception == null && ar.result != null) {
1191 request.result = ar.result;
1192 } else {
1193 request.result = -1;
1194 loge("Failed to set Forbidden Plmns");
1195 if (ar.result == null) {
1196 loge("setForbidenPlmns: Empty response");
1197 } else if (ar.exception != null) {
1198 loge("setForbiddenPlmns: Exception: " + ar.exception);
1199 request.result = -1;
1200 } else {
1201 loge("setForbiddenPlmns: Unknown exception");
1202 }
1203 }
1204 notifyRequester(request);
1205 break;
1206 case CMD_SET_FORBIDDEN_PLMNS:
1207 request = (MainThreadRequest) msg.obj;
1208 uiccCard = getUiccCardFromRequest(request);
1209 if (uiccCard == null) {
1210 loge("setForbiddenPlmns: UiccCard is null");
1211 request.result = -1;
1212 notifyRequester(request);
1213 break;
1214 }
1215 Pair<Integer, List<String>> setFplmnsArgs =
1216 (Pair<Integer, List<String>>) request.argument;
1217 appType = setFplmnsArgs.first;
1218 List<String> fplmns = setFplmnsArgs.second;
1219 uiccApp = uiccCard.getApplicationByType(appType);
1220 if (uiccApp == null) {
1221 loge("setForbiddenPlmns: no app with specified type -- " + appType);
1222 request.result = -1;
1223 loge("Failed to get UICC App");
1224 notifyRequester(request);
1225 } else {
1226 onCompleted = obtainMessage(EVENT_SET_FORBIDDEN_PLMNS_DONE, request);
1227 ((SIMRecords) uiccApp.getIccRecords())
1228 .setForbiddenPlmns(onCompleted, fplmns);
1229 }
yinchengzhao4d163c02019-12-12 15:21:47 -08001230 break;
Naina Nallurid63128d2019-09-17 14:10:30 -07001231 case CMD_ERASE_MODEM_CONFIG:
1232 request = (MainThreadRequest) msg.obj;
1233 onCompleted = obtainMessage(EVENT_ERASE_MODEM_CONFIG_DONE, request);
1234 defaultPhone.eraseModemConfig(onCompleted);
1235 break;
1236 case EVENT_ERASE_MODEM_CONFIG_DONE:
1237 handleNullReturnEvent(msg, "eraseModemConfig");
yincheng zhao2737e882019-09-06 17:06:54 -07001238 break;
zoey chene02881a2019-12-30 16:11:23 +08001239
1240 case CMD_CHANGE_ICC_LOCK_PASSWORD:
1241 request = (MainThreadRequest) msg.obj;
1242 onCompleted = obtainMessage(EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE, request);
1243 Pair<String, String> changed = (Pair<String, String>) request.argument;
1244 getPhoneFromRequest(request).getIccCard().changeIccLockPassword(
1245 changed.first, changed.second, onCompleted);
1246 break;
1247 case EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE:
1248 ar = (AsyncResult) msg.obj;
1249 request = (MainThreadRequest) ar.userObj;
1250 if (ar.exception == null) {
1251 request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
1252 } else {
1253 request.result = msg.arg1;
1254 }
1255 notifyRequester(request);
1256 break;
1257
1258 case CMD_SET_ICC_LOCK_ENABLED:
1259 request = (MainThreadRequest) msg.obj;
1260 onCompleted = obtainMessage(EVENT_SET_ICC_LOCK_ENABLED_DONE, request);
1261 Pair<Boolean, String> enabled = (Pair<Boolean, String>) request.argument;
1262 getPhoneFromRequest(request).getIccCard().setIccLockEnabled(
1263 enabled.first, enabled.second, onCompleted);
1264 break;
1265 case EVENT_SET_ICC_LOCK_ENABLED_DONE:
1266 ar = (AsyncResult) msg.obj;
1267 request = (MainThreadRequest) ar.userObj;
1268 if (ar.exception == null) {
1269 request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
1270 } else {
1271 request.result = msg.arg1;
1272 }
1273 notifyRequester(request);
1274 break;
1275
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001276 default:
1277 Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
1278 break;
1279 }
1280 }
Jake Hambye994d462014-02-03 13:10:13 -08001281
Pengquan Menga1bb6272018-09-06 09:59:22 -07001282 private void notifyRequester(MainThreadRequest request) {
1283 synchronized (request) {
1284 request.notifyAll();
1285 }
1286 }
1287
Jake Hambye994d462014-02-03 13:10:13 -08001288 private void handleNullReturnEvent(Message msg, String command) {
1289 AsyncResult ar = (AsyncResult) msg.obj;
1290 MainThreadRequest request = (MainThreadRequest) ar.userObj;
1291 if (ar.exception == null) {
1292 request.result = true;
1293 } else {
1294 request.result = false;
1295 if (ar.exception instanceof CommandException) {
1296 loge(command + ": CommandException: " + ar.exception);
1297 } else {
1298 loge(command + ": Unknown exception");
1299 }
1300 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001301 notifyRequester(request);
Jake Hambye994d462014-02-03 13:10:13 -08001302 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001303 }
1304
1305 /**
1306 * Posts the specified command to be executed on the main thread,
1307 * waits for the request to complete, and returns the result.
1308 * @see #sendRequestAsync
1309 */
1310 private Object sendRequest(int command, Object argument) {
Nathan Harold92bed182018-10-12 18:16:49 -07001311 return sendRequest(
1312 command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, null, null);
vagdeviaf9a5b92018-08-15 16:01:53 -07001313 }
1314
1315 /**
1316 * Posts the specified command to be executed on the main thread,
1317 * waits for the request to complete, and returns the result.
1318 * @see #sendRequestAsync
1319 */
1320 private Object sendRequest(int command, Object argument, WorkSource workSource) {
1321 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
Nathan Harold92bed182018-10-12 18:16:49 -07001322 null, workSource);
Wink Saville36469e72014-06-11 15:17:00 -07001323 }
1324
1325 /**
1326 * Posts the specified command to be executed on the main thread,
1327 * waits for the request to complete, and returns the result.
1328 * @see #sendRequestAsync
1329 */
Shishir Agrawal76d5da92014-11-09 16:17:25 -08001330 private Object sendRequest(int command, Object argument, Integer subId) {
Nathan Harold92bed182018-10-12 18:16:49 -07001331 return sendRequest(command, argument, subId, null, null);
vagdeviaf9a5b92018-08-15 16:01:53 -07001332 }
1333
1334 /**
1335 * Posts the specified command to be executed on the main thread,
1336 * waits for the request to complete, and returns the result.
1337 * @see #sendRequestAsync
1338 */
Nathan Harold92bed182018-10-12 18:16:49 -07001339 private Object sendRequest(int command, Object argument, int subId, WorkSource workSource) {
1340 return sendRequest(command, argument, subId, null, workSource);
1341 }
1342
1343 /**
1344 * Posts the specified command to be executed on the main thread,
1345 * waits for the request to complete, and returns the result.
1346 * @see #sendRequestAsync
1347 */
1348 private Object sendRequest(int command, Object argument, Phone phone, WorkSource workSource) {
1349 return sendRequest(
1350 command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phone, workSource);
1351 }
1352
1353 /**
1354 * Posts the specified command to be executed on the main thread,
1355 * waits for the request to complete, and returns the result.
1356 * @see #sendRequestAsync
1357 */
1358 private Object sendRequest(
1359 int command, Object argument, Integer subId, Phone phone, WorkSource workSource) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001360 if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
1361 throw new RuntimeException("This method will deadlock if called from the main thread.");
1362 }
1363
Nathan Harold92bed182018-10-12 18:16:49 -07001364 MainThreadRequest request = null;
1365 if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && phone != null) {
1366 throw new IllegalArgumentException("subId and phone cannot both be specified!");
1367 } else if (phone != null) {
1368 request = new MainThreadRequest(argument, phone, workSource);
1369 } else {
1370 request = new MainThreadRequest(argument, subId, workSource);
1371 }
1372
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001373 Message msg = mMainThreadHandler.obtainMessage(command, request);
1374 msg.sendToTarget();
1375
1376 // Wait for the request to complete
1377 synchronized (request) {
1378 while (request.result == null) {
1379 try {
1380 request.wait();
1381 } catch (InterruptedException e) {
1382 // Do nothing, go back and wait until the request is complete
1383 }
1384 }
1385 }
1386 return request.result;
1387 }
1388
1389 /**
1390 * Asynchronous ("fire and forget") version of sendRequest():
1391 * Posts the specified command to be executed on the main thread, and
1392 * returns immediately.
1393 * @see #sendRequest
1394 */
1395 private void sendRequestAsync(int command) {
1396 mMainThreadHandler.sendEmptyMessage(command);
1397 }
1398
1399 /**
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001400 * Same as {@link #sendRequestAsync(int)} except it takes an argument.
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001401 * @see {@link #sendRequest(int)}
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001402 */
1403 private void sendRequestAsync(int command, Object argument) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001404 sendRequestAsync(command, argument, null, null);
1405 }
1406
1407 /**
1408 * Same as {@link #sendRequestAsync(int,Object)} except it takes a Phone and WorkSource.
1409 * @see {@link #sendRequest(int,Object)}
1410 */
1411 private void sendRequestAsync(
1412 int command, Object argument, Phone phone, WorkSource workSource) {
1413 MainThreadRequest request = new MainThreadRequest(argument, phone, workSource);
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001414 Message msg = mMainThreadHandler.obtainMessage(command, request);
1415 msg.sendToTarget();
1416 }
1417
1418 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001419 * Initialize the singleton PhoneInterfaceManager instance.
1420 * This is only done once, at startup, from PhoneApp.onCreate().
1421 */
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001422 /* package */ static PhoneInterfaceManager init(PhoneGlobals app) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001423 synchronized (PhoneInterfaceManager.class) {
1424 if (sInstance == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001425 sInstance = new PhoneInterfaceManager(app);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001426 } else {
1427 Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
1428 }
1429 return sInstance;
1430 }
1431 }
1432
1433 /** Private constructor; @see init() */
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001434 private PhoneInterfaceManager(PhoneGlobals app) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001435 mApp = app;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001436 mCM = PhoneGlobals.getInstance().mCM;
Brad Ebinger24c29992019-12-05 13:03:21 -08001437 mImsResolver = PhoneGlobals.getInstance().getImsResolver();
Stuart Scott981d8582015-04-21 14:09:50 -07001438 mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001439 mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
1440 mMainThreadHandler = new MainThreadHandler();
Tobias Thiererb19e1f12018-12-11 17:54:03 +00001441 mSubscriptionController = SubscriptionController.getInstance();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001442 mTelephonySharedPreferences =
1443 PreferenceManager.getDefaultSharedPreferences(mApp);
yinxub1bed742017-04-17 11:45:04 -07001444 mNetworkScanRequestTracker = new NetworkScanRequestTracker();
Malcolm Chen2c63d402018-08-14 16:00:53 -07001445 mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
Wink Saville3ab207e2014-11-20 13:07:20 -08001446
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001447 publish();
1448 }
1449
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001450 private Phone getDefaultPhone() {
1451 Phone thePhone = getPhone(getDefaultSubscription());
1452 return (thePhone != null) ? thePhone : PhoneFactory.getDefaultPhone();
1453 }
1454
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001455 private void publish() {
1456 if (DBG) log("publish: " + this);
1457
Peter Wangc035ce42020-01-08 21:00:22 -08001458 TelephonyFrameworkInitializer
1459 .getTelephonyServiceManager()
1460 .getTelephonyServiceRegisterer()
1461 .register(this);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001462 }
1463
Stuart Scott584921c2015-01-15 17:10:34 -08001464 private Phone getPhoneFromRequest(MainThreadRequest request) {
Jordan Liu4c733742019-02-28 12:03:40 -08001465 if (request.phone != null) {
1466 return request.phone;
1467 } else {
1468 return getPhoneFromSubId(request.subId);
1469 }
1470 }
1471
1472 private Phone getPhoneFromSubId(int subId) {
1473 return (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
1474 ? getDefaultPhone() : getPhone(subId);
Stuart Scott584921c2015-01-15 17:10:34 -08001475 }
1476
Shishir Agrawalc04d9752016-02-19 10:41:00 -08001477 private UiccCard getUiccCardFromRequest(MainThreadRequest request) {
1478 Phone phone = getPhoneFromRequest(request);
1479 return phone == null ? null :
1480 UiccController.getInstance().getUiccCard(phone.getPhoneId());
1481 }
1482
Wink Saville36469e72014-06-11 15:17:00 -07001483 // returns phone associated with the subId.
Wink Savilleb564aae2014-10-23 10:18:09 -07001484 private Phone getPhone(int subId) {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08001485 return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId));
Wink Saville36469e72014-06-11 15:17:00 -07001486 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001487
Naina Nallurid63128d2019-09-17 14:10:30 -07001488 private void sendEraseModemConfig(Phone phone) {
1489 if (phone != null) {
1490 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
1491 mApp, phone.getSubId(), "eraseModemConfig");
1492 final long identity = Binder.clearCallingIdentity();
1493 try {
1494 Boolean success = (Boolean) sendRequest(CMD_ERASE_MODEM_CONFIG, null);
1495 if (DBG) log("eraseModemConfig:" + ' ' + (success ? "ok" : "fail"));
1496 } finally {
1497 Binder.restoreCallingIdentity(identity);
1498 }
1499 }
1500 }
1501
Peter Wang44b186e2020-01-13 23:33:09 -08001502 private boolean isImsAvailableOnDevice() {
1503 PackageManager pm = getDefaultPhone().getContext().getPackageManager();
1504 if (pm == null) {
1505 // For some reason package manger is not available.. This will fail internally anyway,
1506 // so do not throw error and allow.
1507 return true;
1508 }
1509 return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS, 0);
1510 }
1511
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001512 public void dial(String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001513 dialForSubscriber(getPreferredVoiceSubscription(), number);
Wink Saville36469e72014-06-11 15:17:00 -07001514 }
1515
Wink Savilleb564aae2014-10-23 10:18:09 -07001516 public void dialForSubscriber(int subId, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001517 if (DBG) log("dial: " + number);
1518 // No permission check needed here: This is just a wrapper around the
1519 // ACTION_DIAL intent, which is available to any app since it puts up
1520 // the UI before it does anything.
1521
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001522 final long identity = Binder.clearCallingIdentity();
1523 try {
1524 String url = createTelUrl(number);
1525 if (url == null) {
1526 return;
1527 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001528
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001529 // PENDING: should we just silently fail if phone is offhook or ringing?
1530 PhoneConstants.State state = mCM.getState(subId);
1531 if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
1532 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
1533 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1534 mApp.startActivity(intent);
1535 }
1536 } finally {
1537 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001538 }
1539 }
1540
1541 public void call(String callingPackage, String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001542 callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number);
Wink Saville36469e72014-06-11 15:17:00 -07001543 }
1544
Wink Savilleb564aae2014-10-23 10:18:09 -07001545 public void callForSubscriber(int subId, String callingPackage, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001546 if (DBG) log("call: " + number);
1547
1548 // This is just a wrapper around the ACTION_CALL intent, but we still
1549 // need to do a permission check since we're calling startActivity()
1550 // from the context of the phone app.
1551 enforceCallPermission();
1552
Jordan Liu1617b712019-07-10 15:06:26 -07001553 if (mAppOps.noteOp(AppOpsManager.OPSTR_CALL_PHONE, Binder.getCallingUid(), callingPackage)
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001554 != AppOpsManager.MODE_ALLOWED) {
1555 return;
1556 }
1557
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001558 final long identity = Binder.clearCallingIdentity();
1559 try {
1560 String url = createTelUrl(number);
1561 if (url == null) {
1562 return;
1563 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001564
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001565 boolean isValid = false;
1566 final List<SubscriptionInfo> slist = getActiveSubscriptionInfoListPrivileged();
1567 if (slist != null) {
1568 for (SubscriptionInfo subInfoRecord : slist) {
1569 if (subInfoRecord.getSubscriptionId() == subId) {
1570 isValid = true;
1571 break;
1572 }
Wink Saville3ab207e2014-11-20 13:07:20 -08001573 }
Wink Saville08874612014-08-31 19:19:58 -07001574 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001575 if (!isValid) {
1576 return;
1577 }
Wink Saville08874612014-08-31 19:19:58 -07001578
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001579 Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
1580 intent.putExtra(SUBSCRIPTION_KEY, subId);
1581 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1582 mApp.startActivity(intent);
1583 } finally {
1584 Binder.restoreCallingIdentity(identity);
1585 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001586 }
1587
Wink Savilleb564aae2014-10-23 10:18:09 -07001588 public boolean supplyPinForSubscriber(int subId, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001589 int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07001590 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1591 }
1592
Wink Savilleb564aae2014-10-23 10:18:09 -07001593 public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001594 int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07001595 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1596 }
1597
Wink Savilleb564aae2014-10-23 10:18:09 -07001598 public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001599 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001600
1601 final long identity = Binder.clearCallingIdentity();
1602 try {
1603 final UnlockSim checkSimPin = new UnlockSim(getPhone(subId).getIccCard());
1604 checkSimPin.start();
1605 return checkSimPin.unlockSim(null, pin);
1606 } finally {
1607 Binder.restoreCallingIdentity(identity);
1608 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001609 }
1610
Wink Savilleb564aae2014-10-23 10:18:09 -07001611 public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001612 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001613
1614 final long identity = Binder.clearCallingIdentity();
1615 try {
1616 final UnlockSim checkSimPuk = new UnlockSim(getPhone(subId).getIccCard());
1617 checkSimPuk.start();
1618 return checkSimPuk.unlockSim(puk, pin);
1619 } finally {
1620 Binder.restoreCallingIdentity(identity);
1621 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001622 }
1623
1624 /**
Wink Saville9de0f752013-10-22 19:04:03 -07001625 * Helper thread to turn async call to SimCard#supplyPin into
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001626 * a synchronous one.
1627 */
1628 private static class UnlockSim extends Thread {
1629
1630 private final IccCard mSimCard;
1631
1632 private boolean mDone = false;
Wink Saville9de0f752013-10-22 19:04:03 -07001633 private int mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1634 private int mRetryCount = -1;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001635
1636 // For replies from SimCard interface
1637 private Handler mHandler;
1638
1639 // For async handler to identify request type
1640 private static final int SUPPLY_PIN_COMPLETE = 100;
1641
1642 public UnlockSim(IccCard simCard) {
1643 mSimCard = simCard;
1644 }
1645
1646 @Override
1647 public void run() {
1648 Looper.prepare();
1649 synchronized (UnlockSim.this) {
1650 mHandler = new Handler() {
1651 @Override
1652 public void handleMessage(Message msg) {
1653 AsyncResult ar = (AsyncResult) msg.obj;
1654 switch (msg.what) {
1655 case SUPPLY_PIN_COMPLETE:
1656 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
1657 synchronized (UnlockSim.this) {
Wink Saville9de0f752013-10-22 19:04:03 -07001658 mRetryCount = msg.arg1;
1659 if (ar.exception != null) {
1660 if (ar.exception instanceof CommandException &&
1661 ((CommandException)(ar.exception)).getCommandError()
1662 == CommandException.Error.PASSWORD_INCORRECT) {
1663 mResult = PhoneConstants.PIN_PASSWORD_INCORRECT;
1664 } else {
1665 mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1666 }
1667 } else {
1668 mResult = PhoneConstants.PIN_RESULT_SUCCESS;
1669 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001670 mDone = true;
1671 UnlockSim.this.notifyAll();
1672 }
1673 break;
1674 }
1675 }
1676 };
1677 UnlockSim.this.notifyAll();
1678 }
1679 Looper.loop();
1680 }
1681
1682 /*
1683 * Use PIN or PUK to unlock SIM card
1684 *
1685 * If PUK is null, unlock SIM card with PIN
1686 *
1687 * If PUK is not null, unlock SIM card with PUK and set PIN code
1688 */
Wink Saville9de0f752013-10-22 19:04:03 -07001689 synchronized int[] unlockSim(String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001690
1691 while (mHandler == null) {
1692 try {
1693 wait();
1694 } catch (InterruptedException e) {
1695 Thread.currentThread().interrupt();
1696 }
1697 }
1698 Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
1699
1700 if (puk == null) {
1701 mSimCard.supplyPin(pin, callback);
1702 } else {
1703 mSimCard.supplyPuk(puk, pin, callback);
1704 }
1705
1706 while (!mDone) {
1707 try {
1708 Log.d(LOG_TAG, "wait for done");
1709 wait();
1710 } catch (InterruptedException e) {
1711 // Restore the interrupted status
1712 Thread.currentThread().interrupt();
1713 }
1714 }
1715 Log.d(LOG_TAG, "done");
Wink Saville9de0f752013-10-22 19:04:03 -07001716 int[] resultArray = new int[2];
1717 resultArray[0] = mResult;
1718 resultArray[1] = mRetryCount;
1719 return resultArray;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001720 }
1721 }
1722
1723 public void updateServiceLocation() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001724 updateServiceLocationForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001725
1726 }
1727
Wink Savilleb564aae2014-10-23 10:18:09 -07001728 public void updateServiceLocationForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001729 // No permission check needed here: this call is harmless, and it's
1730 // needed for the ServiceState.requestStateUpdate() call (which is
1731 // already intentionally exposed to 3rd parties.)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001732 final long identity = Binder.clearCallingIdentity();
1733 try {
1734 final Phone phone = getPhone(subId);
1735 if (phone != null) {
1736 phone.updateServiceLocation();
1737 }
1738 } finally {
1739 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001740 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001741 }
1742
Philip P. Moltmann700a9592019-10-03 11:53:50 -07001743 @Deprecated
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001744 @Override
1745 public boolean isRadioOn(String callingPackage) {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07001746 return isRadioOnWithFeature(callingPackage, null);
1747 }
1748
1749
1750 @Override
1751 public boolean isRadioOnWithFeature(String callingPackage, String callingFeatureId) {
1752 return isRadioOnForSubscriberWithFeature(getDefaultSubscription(), callingPackage,
1753 callingFeatureId);
1754 }
1755
1756 @Deprecated
1757 @Override
1758 public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
1759 return isRadioOnForSubscriberWithFeature(subId, callingPackage, null);
Wink Saville36469e72014-06-11 15:17:00 -07001760 }
1761
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001762 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07001763 public boolean isRadioOnForSubscriberWithFeature(int subId, String callingPackage,
1764 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08001765 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07001766 mApp, subId, callingPackage, callingFeatureId, "isRadioOnForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001767 return false;
1768 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001769
1770 final long identity = Binder.clearCallingIdentity();
1771 try {
1772 return isRadioOnForSubscriber(subId);
1773 } finally {
1774 Binder.restoreCallingIdentity(identity);
1775 }
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001776 }
1777
1778 private boolean isRadioOnForSubscriber(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001779 final long identity = Binder.clearCallingIdentity();
1780 try {
1781 final Phone phone = getPhone(subId);
1782 if (phone != null) {
1783 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
1784 } else {
1785 return false;
1786 }
1787 } finally {
1788 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001789 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001790 }
1791
1792 public void toggleRadioOnOff() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001793 toggleRadioOnOffForSubscriber(getDefaultSubscription());
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001794 }
Wink Saville36469e72014-06-11 15:17:00 -07001795
Wink Savilleb564aae2014-10-23 10:18:09 -07001796 public void toggleRadioOnOffForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001797 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001798
1799 final long identity = Binder.clearCallingIdentity();
1800 try {
1801 final Phone phone = getPhone(subId);
1802 if (phone != null) {
1803 phone.setRadioPower(!isRadioOnForSubscriber(subId));
1804 }
1805 } finally {
1806 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001807 }
Wink Saville36469e72014-06-11 15:17:00 -07001808 }
1809
1810 public boolean setRadio(boolean turnOn) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001811 return setRadioForSubscriber(getDefaultSubscription(), turnOn);
Wink Saville36469e72014-06-11 15:17:00 -07001812 }
1813
Wink Savilleb564aae2014-10-23 10:18:09 -07001814 public boolean setRadioForSubscriber(int subId, boolean turnOn) {
Wink Saville36469e72014-06-11 15:17:00 -07001815 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001816
1817 final long identity = Binder.clearCallingIdentity();
1818 try {
1819 final Phone phone = getPhone(subId);
1820 if (phone == null) {
1821 return false;
1822 }
1823 if ((phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF) != turnOn) {
1824 toggleRadioOnOffForSubscriber(subId);
1825 }
1826 return true;
1827 } finally {
1828 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001829 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001830 }
Wink Saville36469e72014-06-11 15:17:00 -07001831
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001832 public boolean needMobileRadioShutdown() {
Shuo Qianfa7b6b32019-12-10 10:40:38 -08001833 enforceReadPrivilegedPermission("needMobileRadioShutdown");
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001834 /*
1835 * If any of the Radios are available, it will need to be
1836 * shutdown. So return true if any Radio is available.
1837 */
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001838 final long identity = Binder.clearCallingIdentity();
1839 try {
1840 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1841 Phone phone = PhoneFactory.getPhone(i);
1842 if (phone != null && phone.isRadioAvailable()) return true;
1843 }
1844 logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown.");
1845 return false;
1846 } finally {
1847 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001848 }
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001849 }
1850
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001851 @Override
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001852 public void shutdownMobileRadios() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001853 enforceModifyPermission();
1854
1855 final long identity = Binder.clearCallingIdentity();
1856 try {
1857 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1858 logv("Shutting down Phone " + i);
1859 shutdownRadioUsingPhoneId(i);
1860 }
1861 } finally {
1862 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001863 }
1864 }
1865
1866 private void shutdownRadioUsingPhoneId(int phoneId) {
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001867 Phone phone = PhoneFactory.getPhone(phoneId);
1868 if (phone != null && phone.isRadioAvailable()) {
1869 phone.shutdownRadio();
1870 }
1871 }
1872
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001873 public boolean setRadioPower(boolean turnOn) {
Jack Yub4e16162017-05-15 12:48:40 -07001874 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001875
1876 final long identity = Binder.clearCallingIdentity();
1877 try {
1878 final Phone defaultPhone = PhoneFactory.getDefaultPhone();
1879 if (defaultPhone != null) {
1880 defaultPhone.setRadioPower(turnOn);
1881 return true;
1882 } else {
1883 loge("There's no default phone.");
1884 return false;
1885 }
1886 } finally {
1887 Binder.restoreCallingIdentity(identity);
Wei Liu9ae2a062016-08-08 11:09:34 -07001888 }
Wink Saville36469e72014-06-11 15:17:00 -07001889 }
1890
Wink Savilleb564aae2014-10-23 10:18:09 -07001891 public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001892 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001893
1894 final long identity = Binder.clearCallingIdentity();
1895 try {
1896 final Phone phone = getPhone(subId);
1897 if (phone != null) {
1898 phone.setRadioPower(turnOn);
1899 return true;
1900 } else {
1901 return false;
1902 }
1903 } finally {
1904 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001905 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001906 }
1907
Wink Saville36469e72014-06-11 15:17:00 -07001908 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07001909 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001910 public boolean enableDataConnectivity() {
1911 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001912
1913 final long identity = Binder.clearCallingIdentity();
1914 try {
1915 int subId = mSubscriptionController.getDefaultDataSubId();
1916 final Phone phone = getPhone(subId);
1917 if (phone != null) {
Jack Yud79fba22018-12-13 11:51:28 -08001918 phone.getDataEnabledSettings().setUserDataEnabled(true);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001919 return true;
1920 } else {
1921 return false;
1922 }
1923 } finally {
1924 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001925 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001926 }
1927
Wink Saville36469e72014-06-11 15:17:00 -07001928 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07001929 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001930 public boolean disableDataConnectivity() {
1931 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001932
1933 final long identity = Binder.clearCallingIdentity();
1934 try {
1935 int subId = mSubscriptionController.getDefaultDataSubId();
1936 final Phone phone = getPhone(subId);
1937 if (phone != null) {
Jack Yud79fba22018-12-13 11:51:28 -08001938 phone.getDataEnabledSettings().setUserDataEnabled(false);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001939 return true;
1940 } else {
1941 return false;
1942 }
1943 } finally {
1944 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001945 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001946 }
1947
Sanket Padawe356d7632015-06-22 14:03:32 -07001948 @Override
Jack Yuacf8a132017-05-01 17:00:48 -07001949 public boolean isDataConnectivityPossible(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001950 final long identity = Binder.clearCallingIdentity();
1951 try {
1952 final Phone phone = getPhone(subId);
1953 if (phone != null) {
Jack Yub5d8f642018-11-26 11:20:48 -08001954 return phone.isDataAllowed(ApnSetting.TYPE_DEFAULT);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001955 } else {
1956 return false;
1957 }
1958 } finally {
1959 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001960 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001961 }
1962
1963 public boolean handlePinMmi(String dialString) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001964 return handlePinMmiForSubscriber(getDefaultSubscription(), dialString);
Wink Saville36469e72014-06-11 15:17:00 -07001965 }
1966
pkanwarae03a6b2016-11-06 20:37:09 -08001967 public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001968 enforceCallPermission();
1969
1970 final long identity = Binder.clearCallingIdentity();
1971 try {
1972 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1973 return;
1974 }
1975 Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback);
1976 sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId);
1977 } finally {
1978 Binder.restoreCallingIdentity(identity);
1979 }
pkanwar32d516d2016-10-14 19:37:38 -07001980 };
1981
Wink Savilleb564aae2014-10-23 10:18:09 -07001982 public boolean handlePinMmiForSubscriber(int subId, String dialString) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001983 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001984
1985 final long identity = Binder.clearCallingIdentity();
1986 try {
1987 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1988 return false;
1989 }
1990 return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
1991 } finally {
1992 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001993 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001994 }
1995
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001996 public int getCallState() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07001997 return getCallStateForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001998 }
1999
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002000 public int getCallStateForSlot(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002001 final long identity = Binder.clearCallingIdentity();
2002 try {
2003 Phone phone = PhoneFactory.getPhone(slotIndex);
2004 return phone == null ? TelephonyManager.CALL_STATE_IDLE :
2005 PhoneConstantConversions.convertCallState(phone.getState());
2006 } finally {
2007 Binder.restoreCallingIdentity(identity);
2008 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002009 }
2010
Sanket Padawe356d7632015-06-22 14:03:32 -07002011 @Override
Nathan Harolde037c472019-06-26 00:41:07 +00002012 public int getDataState() {
Nathan Haroldc4689b12019-06-14 16:58:30 -07002013 return getDataStateForSubId(mSubscriptionController.getDefaultDataSubId());
2014 }
2015
2016 @Override
2017 public int getDataStateForSubId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002018 final long identity = Binder.clearCallingIdentity();
2019 try {
Nathan Haroldc4689b12019-06-14 16:58:30 -07002020 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002021 if (phone != null) {
2022 return PhoneConstantConversions.convertDataState(phone.getDataConnectionState());
2023 } else {
2024 return PhoneConstantConversions.convertDataState(
2025 PhoneConstants.DataState.DISCONNECTED);
2026 }
2027 } finally {
2028 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002029 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002030 }
2031
Sanket Padawe356d7632015-06-22 14:03:32 -07002032 @Override
Nathan Harolde037c472019-06-26 00:41:07 +00002033 public int getDataActivity() {
Nathan Haroldc4689b12019-06-14 16:58:30 -07002034 return getDataActivityForSubId(mSubscriptionController.getDefaultDataSubId());
2035 }
2036
2037 @Override
2038 public int getDataActivityForSubId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002039 final long identity = Binder.clearCallingIdentity();
2040 try {
Nathan Haroldc4689b12019-06-14 16:58:30 -07002041 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002042 if (phone != null) {
2043 return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState());
2044 } else {
2045 return TelephonyManager.DATA_ACTIVITY_NONE;
2046 }
2047 } finally {
2048 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002049 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002050 }
2051
2052 @Override
Meng Wanga10e89e2019-12-09 13:13:01 -08002053 public CellIdentity getCellLocation(String callingPackage, String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002054 mApp.getSystemService(AppOpsManager.class)
Hall Liu1aa510f2017-11-22 17:40:08 -08002055 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08002056
2057 LocationAccessPolicy.LocationPermissionResult locationResult =
2058 LocationAccessPolicy.checkLocationPermission(mApp,
2059 new LocationAccessPolicy.LocationPermissionQuery.Builder()
2060 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002061 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08002062 .setCallingPid(Binder.getCallingPid())
2063 .setCallingUid(Binder.getCallingUid())
2064 .setMethod("getCellLocation")
2065 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2066 .build());
2067 switch (locationResult) {
2068 case DENIED_HARD:
2069 throw new SecurityException("Not allowed to access cell location");
2070 case DENIED_SOFT:
Meng Wanga10e89e2019-12-09 13:13:01 -08002071 return (getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
2072 ? new CellIdentityCdma() : new CellIdentityGsm();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002073 }
2074
Narayan Kamathf04b5a12018-01-09 11:47:15 +00002075 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002076 final long identity = Binder.clearCallingIdentity();
2077 try {
2078 if (DBG_LOC) log("getCellLocation: is active user");
Nathan Harold3ff88932018-08-14 10:19:49 -07002079 int subId = mSubscriptionController.getDefaultDataSubId();
Meng Wanga10e89e2019-12-09 13:13:01 -08002080 return (CellIdentity) sendRequest(CMD_GET_CELL_LOCATION, workSource, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002081 } finally {
2082 Binder.restoreCallingIdentity(identity);
2083 }
Svetoslav64fad262015-04-14 14:35:21 -07002084 }
2085
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002086 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002087 public String getNetworkCountryIsoForPhone(int phoneId, String callingPackage,
2088 String callingFeatureId) {
Jack Yu1e81ccd2019-09-26 11:48:33 -07002089 if (!TextUtils.isEmpty(callingPackage)) {
2090 final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002091 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
2092 callingFeatureId, "getNetworkCountryIsoForPhone")) {
Jack Yu1e81ccd2019-09-26 11:48:33 -07002093 return "";
2094 }
2095 }
2096
Jonathan Basseribf5362b2017-07-19 12:22:35 -07002097 // Reporting the correct network country is ambiguous when IWLAN could conflict with
2098 // registered cell info, so return a NULL country instead.
2099 final long identity = Binder.clearCallingIdentity();
2100 try {
Malcolm Chen3732c2b2018-07-18 20:15:24 -07002101 if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
2102 // Get default phone in this case.
2103 phoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
2104 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07002105 final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
Jack Yu5f7092c2018-04-13 14:05:37 -07002106 // Todo: fix this when we can get the actual cellular network info when the device
2107 // is on IWLAN.
Jonathan Basseribf5362b2017-07-19 12:22:35 -07002108 if (TelephonyManager.NETWORK_TYPE_IWLAN
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002109 == getVoiceNetworkTypeForSubscriber(subId, mApp.getPackageName(),
2110 mApp.getFeatureId())) {
Jonathan Basseribf5362b2017-07-19 12:22:35 -07002111 return "";
2112 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002113 Phone phone = PhoneFactory.getPhone(phoneId);
2114 if (phone != null) {
2115 ServiceStateTracker sst = phone.getServiceStateTracker();
sqianb9d961a2019-07-31 20:23:45 -07002116 EmergencyNumberTracker emergencyNumberTracker = phone.getEmergencyNumberTracker();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002117 if (sst != null) {
2118 LocaleTracker lt = sst.getLocaleTracker();
2119 if (lt != null) {
sqianb9d961a2019-07-31 20:23:45 -07002120 if (!TextUtils.isEmpty(lt.getCurrentCountry())) {
2121 return lt.getCurrentCountry();
2122 } else if (emergencyNumberTracker != null) {
2123 return emergencyNumberTracker.getEmergencyCountryIso();
2124 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002125 }
2126 }
2127 }
2128 return "";
Jonathan Basseribf5362b2017-07-19 12:22:35 -07002129 } finally {
2130 Binder.restoreCallingIdentity(identity);
2131 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07002132 }
2133
2134 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002135 public void enableLocationUpdates() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002136 enableLocationUpdatesForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002137 }
2138
Sanket Padawe356d7632015-06-22 14:03:32 -07002139 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002140 public void enableLocationUpdatesForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002141 mApp.enforceCallingOrSelfPermission(
2142 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002143
2144 final long identity = Binder.clearCallingIdentity();
2145 try {
2146 final Phone phone = getPhone(subId);
2147 if (phone != null) {
2148 phone.enableLocationUpdates();
2149 }
2150 } finally {
2151 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002152 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002153 }
2154
2155 @Override
2156 public void disableLocationUpdates() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002157 disableLocationUpdatesForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002158 }
2159
Sanket Padawe356d7632015-06-22 14:03:32 -07002160 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002161 public void disableLocationUpdatesForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002162 mApp.enforceCallingOrSelfPermission(
2163 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002164
2165 final long identity = Binder.clearCallingIdentity();
2166 try {
2167 final Phone phone = getPhone(subId);
2168 if (phone != null) {
2169 phone.disableLocationUpdates();
2170 }
2171 } finally {
2172 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002173 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002174 }
2175
Nathan Harold31d7ff32018-10-15 20:20:30 -07002176 /**
2177 * Returns the target SDK version number for a given package name.
2178 *
Nathan Haroldec184742019-07-10 17:04:16 -07002179 * This call MUST be invoked before clearing the calling UID.
2180 *
Nathan Harold31d7ff32018-10-15 20:20:30 -07002181 * @return target SDK if the package is found or INT_MAX.
2182 */
2183 private int getTargetSdk(String packageName) {
2184 try {
Nathan Haroldec184742019-07-10 17:04:16 -07002185 final ApplicationInfo ai = mApp.getPackageManager().getApplicationInfoAsUser(
Chen Xu0150f0e2019-07-30 15:12:06 -07002186 packageName, 0, UserHandle.getUserHandleForUid(Binder.getCallingUid()));
Nathan Harold31d7ff32018-10-15 20:20:30 -07002187 if (ai != null) return ai.targetSdkVersion;
2188 } catch (PackageManager.NameNotFoundException unexpected) {
Nathan Haroldec184742019-07-10 17:04:16 -07002189 loge("Failed to get package info for pkg="
2190 + packageName + ", uid=" + Binder.getCallingUid());
Nathan Harold31d7ff32018-10-15 20:20:30 -07002191 }
2192 return Integer.MAX_VALUE;
2193 }
2194
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002195 @Override
2196 @SuppressWarnings("unchecked")
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002197 public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage,
2198 String callingFeatureId) {
Nathan Harold31d7ff32018-10-15 20:20:30 -07002199 final int targetSdk = getTargetSdk(callingPackage);
Nathan Harolddbea45a2018-08-30 14:35:07 -07002200 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
2201 throw new SecurityException(
2202 "getNeighboringCellInfo() is unavailable to callers targeting Q+ SDK levels.");
2203 }
Nathan Haroldb4d55612018-07-20 13:13:08 -07002204
Jordan Liu1617b712019-07-10 15:06:26 -07002205 if (mAppOps.noteOp(AppOpsManager.OPSTR_NEIGHBORING_CELLS, Binder.getCallingUid(),
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002206 callingPackage) != AppOpsManager.MODE_ALLOWED) {
2207 return null;
2208 }
Svetoslav64fad262015-04-14 14:35:21 -07002209
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07002210 if (DBG_LOC) log("getNeighboringCellInfo: is active user");
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002211
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002212 List<CellInfo> info = getAllCellInfo(callingPackage, callingFeatureId);
Nathan Haroldf180aac2018-06-01 18:43:55 -07002213 if (info == null) return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002214
Nathan Haroldf180aac2018-06-01 18:43:55 -07002215 List<NeighboringCellInfo> neighbors = new ArrayList<NeighboringCellInfo>();
2216 for (CellInfo ci : info) {
2217 if (ci instanceof CellInfoGsm) {
2218 neighbors.add(new NeighboringCellInfo((CellInfoGsm) ci));
2219 } else if (ci instanceof CellInfoWcdma) {
2220 neighbors.add(new NeighboringCellInfo((CellInfoWcdma) ci));
2221 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002222 }
Nathan Haroldf180aac2018-06-01 18:43:55 -07002223 return (neighbors.size()) > 0 ? neighbors : null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002224 }
2225
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002226 private List<CellInfo> getCachedCellInfo() {
2227 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
2228 for (Phone phone : PhoneFactory.getPhones()) {
2229 List<CellInfo> info = phone.getAllCellInfo();
2230 if (info != null) cellInfos.addAll(info);
2231 }
2232 return cellInfos;
2233 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002234
2235 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002236 public List<CellInfo> getAllCellInfo(String callingPackage, String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002237 mApp.getSystemService(AppOpsManager.class)
Hall Liu1aa510f2017-11-22 17:40:08 -08002238 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08002239
2240 LocationAccessPolicy.LocationPermissionResult locationResult =
2241 LocationAccessPolicy.checkLocationPermission(mApp,
2242 new LocationAccessPolicy.LocationPermissionQuery.Builder()
2243 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002244 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08002245 .setCallingPid(Binder.getCallingPid())
2246 .setCallingUid(Binder.getCallingUid())
2247 .setMethod("getAllCellInfo")
Nathan Harold5ae50b52019-02-20 15:46:36 -08002248 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
Hall Liuf19c44f2018-11-27 14:38:17 -08002249 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2250 .build());
2251 switch (locationResult) {
2252 case DENIED_HARD:
2253 throw new SecurityException("Not allowed to access cell info");
2254 case DENIED_SOFT:
2255 return new ArrayList<>();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002256 }
2257
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002258 final int targetSdk = getTargetSdk(callingPackage);
2259 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
2260 return getCachedCellInfo();
2261 }
2262
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07002263 if (DBG_LOC) log("getAllCellInfo: is active user");
Narayan Kamathf04b5a12018-01-09 11:47:15 +00002264 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002265 final long identity = Binder.clearCallingIdentity();
2266 try {
2267 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
2268 for (Phone phone : PhoneFactory.getPhones()) {
Nathan Harold3ff88932018-08-14 10:19:49 -07002269 final List<CellInfo> info = (List<CellInfo>) sendRequest(
Nathan Harold92bed182018-10-12 18:16:49 -07002270 CMD_GET_ALL_CELL_INFO, null, phone, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002271 if (info != null) cellInfos.addAll(info);
2272 }
2273 return cellInfos;
2274 } finally {
2275 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002276 }
2277 }
2278
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07002279 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002280 public void requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage,
2281 String callingFeatureId) {
2282 requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId,
2283 getWorkSource(Binder.getCallingUid()));
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002284 }
2285
2286 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002287 public void requestCellInfoUpdateWithWorkSource(int subId, ICellInfoCallback cb,
2288 String callingPackage, String callingFeatureId, WorkSource workSource) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002289 enforceModifyPermission();
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002290 requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId, workSource);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002291 }
2292
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002293 private void requestCellInfoUpdateInternal(int subId, ICellInfoCallback cb,
2294 String callingPackage, String callingFeatureId, WorkSource workSource) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002295 mApp.getSystemService(AppOpsManager.class)
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002296 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08002297
2298 LocationAccessPolicy.LocationPermissionResult locationResult =
2299 LocationAccessPolicy.checkLocationPermission(mApp,
2300 new LocationAccessPolicy.LocationPermissionQuery.Builder()
2301 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002302 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08002303 .setCallingPid(Binder.getCallingPid())
2304 .setCallingUid(Binder.getCallingUid())
2305 .setMethod("requestCellInfoUpdate")
2306 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2307 .build());
2308 switch (locationResult) {
2309 case DENIED_HARD:
2310 throw new SecurityException("Not allowed to access cell info");
2311 case DENIED_SOFT:
Nathan Harold5320c422019-05-09 10:26:08 -07002312 try {
2313 cb.onCellInfo(new ArrayList<CellInfo>());
2314 } catch (RemoteException re) {
2315 // Drop without consequences
2316 }
Hall Liuf19c44f2018-11-27 14:38:17 -08002317 return;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002318 }
2319
Nathan Harolda939a962019-05-09 10:13:47 -07002320
2321 final Phone phone = getPhoneFromSubId(subId);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002322 if (phone == null) throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
2323
2324 sendRequestAsync(CMD_REQUEST_CELL_INFO_UPDATE, cb, phone, workSource);
2325 }
2326
2327 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002328 public void setCellInfoListRate(int rateInMillis) {
Jack Yua8d8cb82017-01-16 10:15:34 -08002329 enforceModifyPermission();
Narayan Kamathf04b5a12018-01-09 11:47:15 +00002330 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002331
2332 final long identity = Binder.clearCallingIdentity();
2333 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002334 getDefaultPhone().setCellInfoListRate(rateInMillis, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002335 } finally {
2336 Binder.restoreCallingIdentity(identity);
2337 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002338 }
2339
Shishir Agrawala9f32182016-04-12 12:00:16 -07002340 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002341 public String getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002342 Phone phone = PhoneFactory.getPhone(slotIndex);
2343 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002344 return null;
2345 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002346 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07002347 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002348 callingPackage, callingFeatureId, "getImeiForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002349 return null;
2350 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002351
2352 final long identity = Binder.clearCallingIdentity();
2353 try {
2354 return phone.getImei();
2355 } finally {
2356 Binder.restoreCallingIdentity(identity);
2357 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002358 }
2359
2360 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002361 public String getTypeAllocationCodeForSlot(int slotIndex) {
2362 Phone phone = PhoneFactory.getPhone(slotIndex);
2363 String tac = null;
2364 if (phone != null) {
2365 String imei = phone.getImei();
2366 tac = imei == null ? null : imei.substring(0, TYPE_ALLOCATION_CODE_LENGTH);
2367 }
2368 return tac;
2369 }
2370
2371 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002372 public String getMeidForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002373 Phone phone = PhoneFactory.getPhone(slotIndex);
2374 if (phone == null) {
Jack Yu2af8d712017-03-15 17:14:14 -07002375 return null;
2376 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002377
Jeff Davidson913390f2018-02-23 17:11:49 -08002378 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07002379 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002380 callingPackage, callingFeatureId, "getMeidForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002381 return null;
2382 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002383
2384 final long identity = Binder.clearCallingIdentity();
2385 try {
2386 return phone.getMeid();
2387 } finally {
2388 Binder.restoreCallingIdentity(identity);
2389 }
Jack Yu2af8d712017-03-15 17:14:14 -07002390 }
2391
2392 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002393 public String getManufacturerCodeForSlot(int slotIndex) {
2394 Phone phone = PhoneFactory.getPhone(slotIndex);
2395 String manufacturerCode = null;
2396 if (phone != null) {
2397 String meid = phone.getMeid();
2398 manufacturerCode = meid == null ? null : meid.substring(0, MANUFACTURER_CODE_LENGTH);
2399 }
2400 return manufacturerCode;
2401 }
2402
2403 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002404 public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage,
2405 String callingFeatureId) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002406 Phone phone = PhoneFactory.getPhone(slotIndex);
2407 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002408 return null;
2409 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002410 int subId = phone.getSubId();
2411 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002412 mApp, subId, callingPackage, callingFeatureId,
2413 "getDeviceSoftwareVersionForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002414 return null;
2415 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002416
2417 final long identity = Binder.clearCallingIdentity();
2418 try {
2419 return phone.getDeviceSvn();
2420 } finally {
2421 Binder.restoreCallingIdentity(identity);
2422 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002423 }
2424
fionaxu43304da2017-11-27 22:51:16 -08002425 @Override
2426 public int getSubscriptionCarrierId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002427 final long identity = Binder.clearCallingIdentity();
2428 try {
2429 final Phone phone = getPhone(subId);
2430 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getCarrierId();
2431 } finally {
2432 Binder.restoreCallingIdentity(identity);
2433 }
fionaxu43304da2017-11-27 22:51:16 -08002434 }
2435
2436 @Override
2437 public String getSubscriptionCarrierName(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002438 final long identity = Binder.clearCallingIdentity();
2439 try {
2440 final Phone phone = getPhone(subId);
2441 return phone == null ? null : phone.getCarrierName();
2442 } finally {
2443 Binder.restoreCallingIdentity(identity);
2444 }
fionaxu43304da2017-11-27 22:51:16 -08002445 }
2446
calvinpanffe225e2018-11-01 19:43:06 +08002447 @Override
chen xu0026ca62019-03-06 15:28:50 -08002448 public int getSubscriptionSpecificCarrierId(int subId) {
chen xu25637222018-11-04 17:17:00 -08002449 final long identity = Binder.clearCallingIdentity();
2450 try {
2451 final Phone phone = getPhone(subId);
2452 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID
chen xu0026ca62019-03-06 15:28:50 -08002453 : phone.getSpecificCarrierId();
chen xu25637222018-11-04 17:17:00 -08002454 } finally {
2455 Binder.restoreCallingIdentity(identity);
2456 }
2457 }
2458
2459 @Override
chen xu0026ca62019-03-06 15:28:50 -08002460 public String getSubscriptionSpecificCarrierName(int subId) {
chen xu25637222018-11-04 17:17:00 -08002461 final long identity = Binder.clearCallingIdentity();
2462 try {
2463 final Phone phone = getPhone(subId);
chen xu0026ca62019-03-06 15:28:50 -08002464 return phone == null ? null : phone.getSpecificCarrierName();
chen xu25637222018-11-04 17:17:00 -08002465 } finally {
2466 Binder.restoreCallingIdentity(identity);
2467 }
2468 }
2469
chen xu651eec72018-11-11 19:03:44 -08002470 @Override
chen xu864e11c2018-12-06 22:10:03 -08002471 public int getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc) {
2472 if (!isSubscriptionMccMnc) {
2473 enforceReadPrivilegedPermission("getCarrierIdFromMccMnc");
2474 }
chen xu651eec72018-11-11 19:03:44 -08002475 final Phone phone = PhoneFactory.getPhone(slotIndex);
2476 if (phone == null) {
2477 return TelephonyManager.UNKNOWN_CARRIER_ID;
2478 }
2479 final long identity = Binder.clearCallingIdentity();
2480 try {
2481 return CarrierResolver.getCarrierIdFromMccMnc(phone.getContext(), mccmnc);
2482 } finally {
2483 Binder.restoreCallingIdentity(identity);
2484 }
2485 }
2486
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002487 //
2488 // Internal helper methods.
2489 //
2490
Sanket Padaweee13a9b2016-03-08 17:30:28 -08002491 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002492 * Make sure the caller has the MODIFY_PHONE_STATE permission.
2493 *
2494 * @throws SecurityException if the caller does not have the required permission
2495 */
2496 private void enforceModifyPermission() {
2497 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
2498 }
2499
Shuo Qiancd19c462020-01-16 20:51:11 -08002500 /**
2501 * Make sure the caller is system.
2502 *
2503 * @throws SecurityException if the caller is not system.
2504 */
2505 private void enforceSystemCaller() {
2506 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
2507 throw new SecurityException("Caller must be system");
2508 }
2509 }
2510
Shuo Qian3b6ee772019-11-13 17:43:31 -08002511 private void enforceActiveEmergencySessionPermission() {
2512 mApp.enforceCallingOrSelfPermission(
2513 android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION, null);
2514 }
2515
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002516 /**
2517 * Make sure the caller has the CALL_PHONE permission.
2518 *
2519 * @throws SecurityException if the caller does not have the required permission
2520 */
2521 private void enforceCallPermission() {
2522 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
2523 }
2524
paulhu5a773602019-08-23 19:17:33 +08002525 private void enforceSettingsPermission() {
2526 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.NETWORK_SETTINGS, null);
Stuart Scott8eef64f2015-04-08 15:13:54 -07002527 }
2528
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002529 private String createTelUrl(String number) {
2530 if (TextUtils.isEmpty(number)) {
2531 return null;
2532 }
2533
Jake Hambye994d462014-02-03 13:10:13 -08002534 return "tel:" + number;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002535 }
2536
Ihab Awadf9e92732013-12-05 18:02:52 -08002537 private static void log(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002538 Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg);
2539 }
2540
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002541 private static void logv(String msg) {
2542 Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg);
2543 }
2544
Ihab Awadf9e92732013-12-05 18:02:52 -08002545 private static void loge(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002546 Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg);
2547 }
2548
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002549 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002550 public int getActivePhoneType() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07002551 return getActivePhoneTypeForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002552 }
2553
Sanket Padawe356d7632015-06-22 14:03:32 -07002554 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002555 public int getActivePhoneTypeForSlot(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002556 final long identity = Binder.clearCallingIdentity();
2557 try {
2558 final Phone phone = PhoneFactory.getPhone(slotIndex);
2559 if (phone == null) {
2560 return PhoneConstants.PHONE_TYPE_NONE;
2561 } else {
2562 return phone.getPhoneType();
2563 }
2564 } finally {
2565 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002566 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002567 }
2568
2569 /**
2570 * Returns the CDMA ERI icon index to display
2571 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002572 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002573 public int getCdmaEriIconIndex(String callingPackage, String callingFeatureId) {
2574 return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage,
2575 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07002576 }
2577
Sanket Padawe356d7632015-06-22 14:03:32 -07002578 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002579 public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage,
2580 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002581 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002582 mApp, subId, callingPackage, callingFeatureId,
2583 "getCdmaEriIconIndexForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002584 return -1;
2585 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002586
2587 final long identity = Binder.clearCallingIdentity();
2588 try {
2589 final Phone phone = getPhone(subId);
2590 if (phone != null) {
2591 return phone.getCdmaEriIconIndex();
2592 } else {
2593 return -1;
2594 }
2595 } finally {
2596 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002597 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002598 }
2599
2600 /**
2601 * Returns the CDMA ERI icon mode,
2602 * 0 - ON
2603 * 1 - FLASHING
2604 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002605 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002606 public int getCdmaEriIconMode(String callingPackage, String callingFeatureId) {
2607 return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage,
2608 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07002609 }
2610
Sanket Padawe356d7632015-06-22 14:03:32 -07002611 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002612 public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage,
2613 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002614 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002615 mApp, subId, callingPackage, callingFeatureId,
2616 "getCdmaEriIconModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002617 return -1;
2618 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002619
2620 final long identity = Binder.clearCallingIdentity();
2621 try {
2622 final Phone phone = getPhone(subId);
2623 if (phone != null) {
2624 return phone.getCdmaEriIconMode();
2625 } else {
2626 return -1;
2627 }
2628 } finally {
2629 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002630 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002631 }
2632
2633 /**
2634 * Returns the CDMA ERI text,
2635 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002636 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002637 public String getCdmaEriText(String callingPackage, String callingFeatureId) {
2638 return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage,
2639 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07002640 }
2641
Sanket Padawe356d7632015-06-22 14:03:32 -07002642 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002643 public String getCdmaEriTextForSubscriber(int subId, String callingPackage,
2644 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002645 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002646 mApp, subId, callingPackage, callingFeatureId,
2647 "getCdmaEriIconTextForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002648 return null;
2649 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002650
2651 final long identity = Binder.clearCallingIdentity();
2652 try {
2653 final Phone phone = getPhone(subId);
2654 if (phone != null) {
2655 return phone.getCdmaEriText();
2656 } else {
2657 return null;
2658 }
2659 } finally {
2660 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002661 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002662 }
2663
2664 /**
Junda Liuca05d5d2014-08-14 22:36:34 -07002665 * Returns the CDMA MDN.
2666 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002667 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002668 public String getCdmaMdn(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002669 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2670 mApp, subId, "getCdmaMdn");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002671
2672 final long identity = Binder.clearCallingIdentity();
2673 try {
2674 final Phone phone = getPhone(subId);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002675 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002676 return phone.getLine1Number();
2677 } else {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002678 loge("getCdmaMdn: no phone found. Invalid subId: " + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002679 return null;
2680 }
2681 } finally {
2682 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07002683 }
2684 }
2685
2686 /**
2687 * Returns the CDMA MIN.
2688 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002689 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002690 public String getCdmaMin(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002691 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2692 mApp, subId, "getCdmaMin");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002693
2694 final long identity = Binder.clearCallingIdentity();
2695 try {
2696 final Phone phone = getPhone(subId);
2697 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
2698 return phone.getCdmaMin();
2699 } else {
2700 return null;
2701 }
2702 } finally {
2703 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07002704 }
2705 }
2706
Hall Liud892bec2018-11-30 14:51:45 -08002707 @Override
2708 public void requestNumberVerification(PhoneNumberRange range, long timeoutMillis,
2709 INumberVerificationCallback callback, String callingPackage) {
2710 if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
2711 != PERMISSION_GRANTED) {
2712 throw new SecurityException("Caller must hold the MODIFY_PHONE_STATE permission");
2713 }
2714 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2715
2716 String authorizedPackage = NumberVerificationManager.getAuthorizedPackage(mApp);
2717 if (!TextUtils.equals(callingPackage, authorizedPackage)) {
2718 throw new SecurityException("Calling package must be configured in the device config");
2719 }
2720
2721 if (range == null) {
2722 throw new NullPointerException("Range must be non-null");
2723 }
2724
2725 timeoutMillis = Math.min(timeoutMillis,
Hall Liubd069e32019-02-28 18:56:30 -08002726 TelephonyManager.getMaxNumberVerificationTimeoutMillis());
Hall Liud892bec2018-11-30 14:51:45 -08002727
2728 NumberVerificationManager.getInstance().requestVerification(range, callback, timeoutMillis);
2729 }
2730
Junda Liuca05d5d2014-08-14 22:36:34 -07002731 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002732 * Returns true if CDMA provisioning needs to run.
2733 */
2734 public boolean needsOtaServiceProvisioning() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002735 final long identity = Binder.clearCallingIdentity();
2736 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002737 return getDefaultPhone().needsOtaServiceProvisioning();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002738 } finally {
2739 Binder.restoreCallingIdentity(identity);
2740 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002741 }
2742
2743 /**
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002744 * Sets the voice mail number of a given subId.
2745 */
2746 @Override
2747 public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08002748 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
2749 mApp, subId, "setVoiceMailNumber");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002750
2751 final long identity = Binder.clearCallingIdentity();
2752 try {
2753 Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
2754 new Pair<String, String>(alphaTag, number), new Integer(subId));
2755 return success;
2756 } finally {
2757 Binder.restoreCallingIdentity(identity);
2758 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002759 }
2760
Ta-wei Yen87c49842016-05-13 21:19:52 -07002761 @Override
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002762 public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
2763 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07002764 TelecomManager tm = mApp.getSystemService(TelecomManager.class);
2765 String systemDialer = tm.getSystemDialerPackage();
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002766 if (!TextUtils.equals(callingPackage, systemDialer)) {
2767 throw new SecurityException("caller must be system dialer");
2768 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002769
2770 final long identity = Binder.clearCallingIdentity();
2771 try {
2772 PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
2773 if (phoneAccountHandle == null) {
2774 return null;
2775 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002776 return VisualVoicemailSettingsUtil.dump(mApp, phoneAccountHandle);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002777 } finally {
2778 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002779 }
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002780 }
2781
2782 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002783 public String getVisualVoicemailPackageName(String callingPackage, String callingFeatureId,
2784 int subId) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08002785 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jeff Davidson7e17e312018-02-13 18:17:36 -08002786 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002787 mApp, subId, callingPackage, callingFeatureId,
2788 "getVisualVoicemailPackageName")) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08002789 return null;
2790 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002791
Jeff Davidsona8e4e242018-03-15 17:16:18 -07002792 final long identity = Binder.clearCallingIdentity();
2793 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002794 return RemoteVvmTaskManager.getRemotePackage(mApp, subId).getPackageName();
Jeff Davidsona8e4e242018-03-15 17:16:18 -07002795 } finally {
2796 Binder.restoreCallingIdentity(identity);
2797 }
Ta-wei Yendca928f2017-01-10 16:17:08 -08002798 }
2799
2800 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002801 public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
2802 VisualVoicemailSmsFilterSettings settings) {
2803 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002804
2805 final long identity = Binder.clearCallingIdentity();
2806 try {
2807 VisualVoicemailSmsFilterConfig.enableVisualVoicemailSmsFilter(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002808 mApp, callingPackage, subId, settings);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002809 } finally {
2810 Binder.restoreCallingIdentity(identity);
2811 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002812 }
2813
2814 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002815 public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
2816 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002817
2818 final long identity = Binder.clearCallingIdentity();
2819 try {
2820 VisualVoicemailSmsFilterConfig.disableVisualVoicemailSmsFilter(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002821 mApp, callingPackage, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002822 } finally {
2823 Binder.restoreCallingIdentity(identity);
2824 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002825 }
2826
2827 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002828 public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
2829 String callingPackage, int subId) {
2830 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002831
2832 final long identity = Binder.clearCallingIdentity();
2833 try {
2834 return VisualVoicemailSmsFilterConfig.getVisualVoicemailSmsFilterSettings(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002835 mApp, callingPackage, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002836 } finally {
2837 Binder.restoreCallingIdentity(identity);
2838 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002839 }
2840
2841 @Override
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002842 public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002843 enforceReadPrivilegedPermission("getActiveVisualVoicemailSmsFilterSettings");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002844
2845 final long identity = Binder.clearCallingIdentity();
2846 try {
2847 return VisualVoicemailSmsFilterConfig.getActiveVisualVoicemailSmsFilterSettings(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002848 mApp, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002849 } finally {
2850 Binder.restoreCallingIdentity(identity);
2851 }
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002852 }
2853
2854 @Override
2855 public void sendVisualVoicemailSmsForSubscriber(String callingPackage, int subId,
2856 String number, int port, String text, PendingIntent sentIntent) {
2857 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Ta-wei Yen527a9c02017-01-06 15:29:25 -08002858 enforceVisualVoicemailPackage(callingPackage, subId);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002859 enforceSendSmsPermission();
Amit Mahajandccb3f12019-05-13 13:48:32 -07002860 SmsController smsController = PhoneFactory.getSmsController();
2861 smsController.sendVisualVoicemailSmsForSubscriber(callingPackage, subId, number, port, text,
2862 sentIntent);
Ta-wei Yen87c49842016-05-13 21:19:52 -07002863 }
Amit Mahajandccb3f12019-05-13 13:48:32 -07002864
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002865 /**
fionaxu0152e512016-11-14 13:36:14 -08002866 * Sets the voice activation state of a given subId.
2867 */
2868 @Override
2869 public void setVoiceActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002870 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2871 mApp, subId, "setVoiceActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002872
2873 final long identity = Binder.clearCallingIdentity();
2874 try {
2875 final Phone phone = getPhone(subId);
2876 if (phone != null) {
2877 phone.setVoiceActivationState(activationState);
2878 } else {
2879 loge("setVoiceActivationState fails with invalid subId: " + subId);
2880 }
2881 } finally {
2882 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002883 }
2884 }
2885
2886 /**
2887 * Sets the data activation state of a given subId.
2888 */
2889 @Override
2890 public void setDataActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002891 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2892 mApp, subId, "setDataActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002893
2894 final long identity = Binder.clearCallingIdentity();
2895 try {
2896 final Phone phone = getPhone(subId);
2897 if (phone != null) {
2898 phone.setDataActivationState(activationState);
2899 } else {
Taesu Leef8fbed92019-10-07 18:47:02 +09002900 loge("setDataActivationState fails with invalid subId: " + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002901 }
2902 } finally {
2903 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002904 }
2905 }
2906
2907 /**
2908 * Returns the voice activation state of a given subId.
2909 */
2910 @Override
2911 public int getVoiceActivationState(int subId, String callingPackage) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002912 enforceReadPrivilegedPermission("getVoiceActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002913
fionaxu0152e512016-11-14 13:36:14 -08002914 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002915 final long identity = Binder.clearCallingIdentity();
2916 try {
2917 if (phone != null) {
2918 return phone.getVoiceActivationState();
2919 } else {
2920 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2921 }
2922 } finally {
2923 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002924 }
2925 }
2926
2927 /**
2928 * Returns the data activation state of a given subId.
2929 */
2930 @Override
2931 public int getDataActivationState(int subId, String callingPackage) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002932 enforceReadPrivilegedPermission("getDataActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002933
fionaxu0152e512016-11-14 13:36:14 -08002934 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002935 final long identity = Binder.clearCallingIdentity();
2936 try {
2937 if (phone != null) {
2938 return phone.getDataActivationState();
2939 } else {
2940 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2941 }
2942 } finally {
2943 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002944 }
2945 }
2946
2947 /**
Wink Saville36469e72014-06-11 15:17:00 -07002948 * Returns the unread count of voicemails for a subId
2949 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002950 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002951 public int getVoiceMessageCountForSubscriber(int subId, String callingPackage,
2952 String callingFeatureId) {
Brad Ebingerf7664ba2018-11-29 12:43:38 -08002953 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002954 mApp, subId, callingPackage, callingFeatureId,
2955 "getVoiceMessageCountForSubscriber")) {
Brad Ebingerf7664ba2018-11-29 12:43:38 -08002956 return 0;
2957 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002958 final long identity = Binder.clearCallingIdentity();
2959 try {
2960 final Phone phone = getPhone(subId);
2961 if (phone != null) {
2962 return phone.getVoiceMessageCount();
2963 } else {
2964 return 0;
2965 }
2966 } finally {
2967 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002968 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002969 }
2970
2971 /**
pkanwar8a4dcfb2017-01-19 13:43:16 -08002972 * returns true, if the device is in a state where both voice and data
2973 * are supported simultaneously. This can change based on location or network condition.
2974 */
2975 @Override
2976 public boolean isConcurrentVoiceAndDataAllowed(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002977 final long identity = Binder.clearCallingIdentity();
2978 try {
2979 final Phone phone = getPhone(subId);
2980 return (phone == null ? false : phone.isConcurrentVoiceAndDataAllowed());
2981 } finally {
2982 Binder.restoreCallingIdentity(identity);
2983 }
pkanwar8a4dcfb2017-01-19 13:43:16 -08002984 }
2985
2986 /**
fionaxu235cc5e2017-03-06 22:25:57 -08002987 * Send the dialer code if called from the current default dialer or the caller has
2988 * carrier privilege.
2989 * @param inputCode The dialer code to send
2990 */
2991 @Override
2992 public void sendDialerSpecialCode(String callingPackage, String inputCode) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002993 final Phone defaultPhone = getDefaultPhone();
fionaxu235cc5e2017-03-06 22:25:57 -08002994 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07002995 TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
2996 String defaultDialer = tm.getDefaultDialerPackage();
fionaxu235cc5e2017-03-06 22:25:57 -08002997 if (!TextUtils.equals(callingPackage, defaultDialer)) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08002998 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
Jeff Davidson7e17e312018-02-13 18:17:36 -08002999 getDefaultSubscription(), "sendDialerSpecialCode");
fionaxu235cc5e2017-03-06 22:25:57 -08003000 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003001
3002 final long identity = Binder.clearCallingIdentity();
3003 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003004 defaultPhone.sendDialerSpecialCode(inputCode);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003005 } finally {
3006 Binder.restoreCallingIdentity(identity);
3007 }
fionaxu235cc5e2017-03-06 22:25:57 -08003008 }
3009
Pengquan Menga1bb6272018-09-06 09:59:22 -07003010 @Override
3011 public int getNetworkSelectionMode(int subId) {
Pengquan Menge92a50d2018-09-21 15:54:48 -07003012 if (!isActiveSubscription(subId)) {
3013 return TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
3014 }
3015
Pengquan Menga1bb6272018-09-06 09:59:22 -07003016 return (int) sendRequest(CMD_GET_NETWORK_SELECTION_MODE, null /* argument */, subId);
3017 }
3018
Brad Ebinger35c841c2018-10-01 10:40:55 -07003019 @Override
Brad Ebingerb2b65522019-03-15 13:48:47 -07003020 public boolean isInEmergencySmsMode() {
3021 enforceReadPrivilegedPermission("isInEmergencySmsMode");
3022 final long identity = Binder.clearCallingIdentity();
3023 try {
3024 for (Phone phone : PhoneFactory.getPhones()) {
3025 if (phone.isInEmergencySmsMode()) {
3026 return true;
3027 }
3028 }
3029 } finally {
3030 Binder.restoreCallingIdentity(identity);
3031 }
3032 return false;
3033 }
3034
shilu366312e2019-12-17 09:28:10 -08003035 /**
3036 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3037 * @param subId The subscription to use to check the configuration.
3038 * @param c The callback that will be used to send the result.
3039 */
Brad Ebingerb2b65522019-03-15 13:48:47 -07003040 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003041 public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback c)
3042 throws RemoteException {
shilu366312e2019-12-17 09:28:10 -08003043 //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003044 enforceReadPrivilegedPermission("registerImsRegistrationCallback");
shilu366312e2019-12-17 09:28:10 -08003045
Brad Ebingerbc7dd582019-10-17 17:03:22 -07003046 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3047 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3048 "IMS not available on device.");
3049 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07003050 final long token = Binder.clearCallingIdentity();
3051 try {
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003052 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003053 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger35c841c2018-10-01 10:40:55 -07003054 .addRegistrationCallbackForSubscription(c, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003055 } catch (ImsException e) {
3056 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003057 } finally {
3058 Binder.restoreCallingIdentity(token);
3059 }
3060 }
3061
shilu366312e2019-12-17 09:28:10 -08003062 /**
3063 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3064 * @param subId The subscription to use to check the configuration.
3065 * @param c The callback that will be used to send the result.
3066 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003067 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003068 public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c) {
shilu366312e2019-12-17 09:28:10 -08003069 //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003070 enforceReadPrivilegedPermission("unregisterImsRegistrationCallback");
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003071 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3072 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
3073 }
Meng Wangafbc5852019-09-19 17:37:13 -07003074 final long token = Binder.clearCallingIdentity();
3075 try {
3076 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone.
3077 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
3078 .removeRegistrationCallbackForSubscription(c, subId);
3079 } catch (ImsException e) {
3080 Log.i(LOG_TAG, "unregisterImsRegistrationCallback: " + subId
3081 + "is inactive, ignoring unregister.");
3082 // If the subscription is no longer active, just return, since the callback
3083 // will already have been removed internally.
3084 } finally {
3085 Binder.restoreCallingIdentity(token);
3086 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07003087 }
3088
Brad Ebingera34a6c22019-10-22 17:36:18 -07003089 /**
3090 * Get the IMS service registration state for the MmTelFeature associated with this sub id.
3091 */
3092 @Override
3093 public void getImsMmTelRegistrationState(int subId, IIntegerConsumer consumer) {
3094 enforceReadPrivilegedPermission("getImsMmTelRegistrationState");
3095 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3096 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3097 "IMS not available on device.");
3098 }
3099 final long token = Binder.clearCallingIdentity();
3100 try {
3101 Phone phone = getPhone(subId);
3102 if (phone == null) {
3103 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
3104 + subId + "'");
3105 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
3106 }
3107 phone.getImsRegistrationState(regState -> {
3108 try {
3109 consumer.accept((regState == null)
3110 ? RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED : regState);
3111 } catch (RemoteException e) {
3112 // Ignore if the remote process is no longer available to call back.
3113 Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
3114 }
3115 });
3116 } finally {
3117 Binder.restoreCallingIdentity(token);
3118 }
3119 }
3120
3121 /**
3122 * Get the transport type for the IMS service registration state.
3123 */
3124 @Override
3125 public void getImsMmTelRegistrationTransportType(int subId, IIntegerConsumer consumer) {
shilu366312e2019-12-17 09:28:10 -08003126 //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
Brad Ebingera34a6c22019-10-22 17:36:18 -07003127 enforceReadPrivilegedPermission("getImsMmTelRegistrationTransportType");
3128 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3129 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3130 "IMS not available on device.");
3131 }
3132 final long token = Binder.clearCallingIdentity();
3133 try {
3134 Phone phone = getPhone(subId);
3135 if (phone == null) {
3136 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
3137 + subId + "'");
3138 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
3139 }
3140 phone.getImsRegistrationTech(regTech -> {
3141 // Convert registration tech from ImsRegistrationImplBase -> RegistrationManager
3142 int regTechConverted = (regTech == null)
3143 ? ImsRegistrationImplBase.REGISTRATION_TECH_NONE : regTech;
3144 regTechConverted = RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(
3145 regTechConverted);
3146 try {
3147 consumer.accept(regTechConverted);
3148 } catch (RemoteException e) {
3149 // Ignore if the remote process is no longer available to call back.
3150 Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
3151 }
3152 });
3153 } finally {
3154 Binder.restoreCallingIdentity(token);
3155 }
3156 }
3157
shilu366312e2019-12-17 09:28:10 -08003158 /**
3159 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3160 * @param subId The subscription to use to check the configuration.
3161 * @param c The callback that will be used to send the result.
3162 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003163 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003164 public void registerMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)
3165 throws RemoteException {
shilu366312e2019-12-17 09:28:10 -08003166 //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003167 enforceReadPrivilegedPermission("registerMmTelCapabilityCallback");
Brad Ebingerbc7dd582019-10-17 17:03:22 -07003168 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3169 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3170 "IMS not available on device.");
3171 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07003172 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3173 final long token = Binder.clearCallingIdentity();
3174 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003175 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger35c841c2018-10-01 10:40:55 -07003176 .addCapabilitiesCallbackForSubscription(c, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003177 } catch (ImsException e) {
3178 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003179 } finally {
3180 Binder.restoreCallingIdentity(token);
3181 }
3182 }
3183
shilu366312e2019-12-17 09:28:10 -08003184 /**
3185 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3186 * @param subId The subscription to use to check the configuration.
3187 * @param c The callback that will be used to send the result.
3188 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003189 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003190 public void unregisterMmTelCapabilityCallback(int subId, IImsCapabilityCallback c) {
shilu366312e2019-12-17 09:28:10 -08003191 //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003192 enforceReadPrivilegedPermission("unregisterMmTelCapabilityCallback");
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003193 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3194 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
3195 }
Meng Wangafbc5852019-09-19 17:37:13 -07003196
3197 final long token = Binder.clearCallingIdentity();
3198 try {
3199 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone.
3200 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003201 .removeCapabilitiesCallbackForSubscription(c, subId);
Meng Wangafbc5852019-09-19 17:37:13 -07003202 } catch (ImsException e) {
3203 Log.i(LOG_TAG, "unregisterMmTelCapabilityCallback: " + subId
3204 + "is inactive, ignoring unregister.");
3205 // If the subscription is no longer active, just return, since the callback
3206 // will already have been removed internally.
3207 } finally {
3208 Binder.restoreCallingIdentity(token);
3209 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07003210 }
3211
3212 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003213 public boolean isCapable(int subId, int capability, int regTech) {
3214 enforceReadPrivilegedPermission("isCapable");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003215 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3216 final long token = Binder.clearCallingIdentity();
3217 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003218 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003219 getSlotIndexOrException(subId)).queryMmTelCapability(capability, regTech);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003220 } catch (com.android.ims.ImsException e) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003221 Log.w(LOG_TAG, "IMS isCapable - service unavailable: " + e.getMessage());
3222 return false;
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003223 } catch (ImsException e) {
Brad Ebinger6b5ac222019-02-04 14:36:52 -08003224 Log.i(LOG_TAG, "isCapable: " + subId + " is inactive, returning false.");
3225 return false;
Brad Ebinger35c841c2018-10-01 10:40:55 -07003226 } finally {
3227 Binder.restoreCallingIdentity(token);
3228 }
3229 }
3230
3231 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003232 public boolean isAvailable(int subId, int capability, int regTech) {
3233 enforceReadPrivilegedPermission("isAvailable");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003234 final long token = Binder.clearCallingIdentity();
3235 try {
3236 Phone phone = getPhone(subId);
3237 if (phone == null) return false;
3238 return phone.isImsCapabilityAvailable(capability, regTech);
3239 } finally {
3240 Binder.restoreCallingIdentity(token);
3241 }
3242 }
3243
Brad Ebingerbc7dd582019-10-17 17:03:22 -07003244 /**
3245 * Determines if the MmTel feature capability is supported by the carrier configuration for this
3246 * subscription.
3247 * @param subId The subscription to use to check the configuration.
3248 * @param callback The callback that will be used to send the result.
3249 * @param capability The MmTelFeature capability that will be used to send the result.
3250 * @param transportType The transport type of the MmTelFeature capability.
3251 */
3252 @Override
3253 public void isMmTelCapabilitySupported(int subId, IIntegerConsumer callback, int capability,
3254 int transportType) {
3255 enforceReadPrivilegedPermission("isMmTelCapabilitySupported");
3256 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3257 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3258 "IMS not available on device.");
3259 }
3260 final long token = Binder.clearCallingIdentity();
3261 try {
3262 int slotId = getSlotIndex(subId);
3263 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
3264 Log.w(LOG_TAG, "isMmTelCapabilitySupported: called with an inactive subscription '"
3265 + subId + "'");
3266 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
3267 }
3268 ImsManager.getInstance(mApp, slotId).isSupported(capability,
3269 transportType, aBoolean -> {
3270 try {
3271 callback.accept((aBoolean == null) ? 0 : (aBoolean ? 1 : 0));
3272 } catch (RemoteException e) {
3273 Log.w(LOG_TAG, "isMmTelCapabilitySupported: remote caller is not "
3274 + "running. Ignore");
3275 }
3276 });
3277 } finally {
3278 Binder.restoreCallingIdentity(token);
3279 }
3280 }
3281
shilu366312e2019-12-17 09:28:10 -08003282 /**
3283 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3284 * @param subId The subscription to use to check the configuration.
3285 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003286 @Override
3287 public boolean isAdvancedCallingSettingEnabled(int subId) {
shilu366312e2019-12-17 09:28:10 -08003288 //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
3289 enforceReadPrivilegedPermission("isAdvancedCallingSettingEnabled");
3290
Brad Ebinger35c841c2018-10-01 10:40:55 -07003291 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3292 final long token = Binder.clearCallingIdentity();
3293 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003294 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003295 getSlotIndexOrException(subId)).isEnhanced4gLteModeSettingEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003296 } catch (ImsException e) {
3297 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003298 } finally {
3299 Binder.restoreCallingIdentity(token);
3300 }
3301 }
3302
3303 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08003304 public void setAdvancedCallingSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003305 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08003306 "setAdvancedCallingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003307 final long identity = Binder.clearCallingIdentity();
3308 try {
3309 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003310 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003311 getSlotIndexOrException(subId)).setEnhanced4gLteModeSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003312 } catch (ImsException e) {
3313 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003314 } finally {
3315 Binder.restoreCallingIdentity(identity);
3316 }
3317 }
3318
shilu366312e2019-12-17 09:28:10 -08003319 /**
3320 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3321 * @param subId The subscription to use to check the configuration.
3322 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003323 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003324 public boolean isVtSettingEnabled(int subId) {
shilu366312e2019-12-17 09:28:10 -08003325 //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003326 enforceReadPrivilegedPermission("isVtSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003327 final long identity = Binder.clearCallingIdentity();
3328 try {
3329 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003330 return ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).isVtEnabledByUser();
3331 } catch (ImsException e) {
3332 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003333 } finally {
3334 Binder.restoreCallingIdentity(identity);
3335 }
3336 }
3337
3338 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08003339 public void setVtSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003340 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08003341 "setVtSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003342 final long identity = Binder.clearCallingIdentity();
3343 try {
3344 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003345 ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setVtSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003346 } catch (ImsException e) {
3347 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003348 } finally {
3349 Binder.restoreCallingIdentity(identity);
3350 }
3351 }
3352
shilu366312e2019-12-17 09:28:10 -08003353 /**
3354 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3355 * @param subId The subscription to use to check the configuration.
3356 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003357 @Override
3358 public boolean isVoWiFiSettingEnabled(int subId) {
shilu366312e2019-12-17 09:28:10 -08003359 //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
Brad Ebinger35c841c2018-10-01 10:40:55 -07003360 enforceReadPrivilegedPermission("isVoWiFiSettingEnabled");
3361 final long identity = Binder.clearCallingIdentity();
3362 try {
3363 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003364 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003365 getSlotIndexOrException(subId)).isWfcEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003366 } catch (ImsException e) {
3367 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003368 } finally {
3369 Binder.restoreCallingIdentity(identity);
3370 }
3371 }
3372
3373 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08003374 public void setVoWiFiSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003375 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08003376 "setVoWiFiSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003377 final long identity = Binder.clearCallingIdentity();
3378 try {
3379 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003380 ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setWfcSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003381 } catch (ImsException e) {
3382 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003383 } finally {
3384 Binder.restoreCallingIdentity(identity);
3385 }
3386 }
3387
shilu366312e2019-12-17 09:28:10 -08003388 /**
3389 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3390 * @param subId The subscription to use to check the configuration.
3391 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003392 @Override
3393 public boolean isVoWiFiRoamingSettingEnabled(int subId) {
shilu366312e2019-12-17 09:28:10 -08003394 //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
Brad Ebinger35c841c2018-10-01 10:40:55 -07003395 enforceReadPrivilegedPermission("isVoWiFiRoamingSettingEnabled");
3396 final long identity = Binder.clearCallingIdentity();
3397 try {
3398 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003399 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003400 getSlotIndexOrException(subId)).isWfcRoamingEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003401 } catch (ImsException e) {
3402 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003403 } finally {
3404 Binder.restoreCallingIdentity(identity);
3405 }
3406 }
3407
3408 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08003409 public void setVoWiFiRoamingSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003410 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08003411 "setVoWiFiRoamingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003412 final long identity = Binder.clearCallingIdentity();
3413 try {
3414 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003415 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003416 getSlotIndexOrException(subId)).setWfcRoamingSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003417 } catch (ImsException e) {
3418 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003419 } finally {
3420 Binder.restoreCallingIdentity(identity);
3421 }
3422 }
3423
3424 @Override
3425 public void setVoWiFiNonPersistent(int subId, boolean isCapable, int mode) {
3426 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3427 "setVoWiFiNonPersistent");
3428 final long identity = Binder.clearCallingIdentity();
3429 try {
3430 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003431 ImsManager.getInstance(mApp,
Brad Ebinger2d29c012019-05-07 18:33:46 -07003432 getSlotIndexOrException(subId)).setWfcNonPersistent(isCapable, mode);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003433 } catch (ImsException e) {
3434 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003435 } finally {
3436 Binder.restoreCallingIdentity(identity);
3437 }
3438 }
3439
shilu366312e2019-12-17 09:28:10 -08003440 /**
3441 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3442 * @param subId The subscription to use to check the configuration.
3443 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003444 @Override
3445 public int getVoWiFiModeSetting(int subId) {
shilu366312e2019-12-17 09:28:10 -08003446 //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
Brad Ebinger35c841c2018-10-01 10:40:55 -07003447 enforceReadPrivilegedPermission("getVoWiFiModeSetting");
3448 final long identity = Binder.clearCallingIdentity();
3449 try {
3450 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003451 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003452 getSlotIndexOrException(subId)).getWfcMode(false /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003453 } catch (ImsException e) {
3454 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003455 } finally {
3456 Binder.restoreCallingIdentity(identity);
3457 }
3458 }
3459
3460 @Override
3461 public void setVoWiFiModeSetting(int subId, int mode) {
3462 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3463 "setVoWiFiModeSetting");
3464 final long identity = Binder.clearCallingIdentity();
3465 try {
3466 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003467 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003468 getSlotIndexOrException(subId)).setWfcMode(mode, false /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003469 } catch (ImsException e) {
3470 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003471 } finally {
3472 Binder.restoreCallingIdentity(identity);
3473 }
3474 }
3475
3476 @Override
3477 public int getVoWiFiRoamingModeSetting(int subId) {
3478 enforceReadPrivilegedPermission("getVoWiFiRoamingModeSetting");
3479 final long identity = Binder.clearCallingIdentity();
3480 try {
3481 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003482 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003483 getSlotIndexOrException(subId)).getWfcMode(true /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003484 } catch (ImsException e) {
3485 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003486 } finally {
3487 Binder.restoreCallingIdentity(identity);
3488 }
3489 }
3490
3491 @Override
3492 public void setVoWiFiRoamingModeSetting(int subId, int mode) {
3493 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3494 "setVoWiFiRoamingModeSetting");
3495 final long identity = Binder.clearCallingIdentity();
3496 try {
3497 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003498 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003499 getSlotIndexOrException(subId)).setWfcMode(mode, true /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003500 } catch (ImsException e) {
3501 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003502 } finally {
3503 Binder.restoreCallingIdentity(identity);
3504 }
3505 }
3506
3507 @Override
3508 public void setRttCapabilitySetting(int subId, boolean isEnabled) {
3509 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3510 "setRttCapabilityEnabled");
3511 final long identity = Binder.clearCallingIdentity();
3512 try {
3513 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003514 ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setRttEnabled(isEnabled);
3515 } catch (ImsException e) {
3516 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003517 } finally {
3518 Binder.restoreCallingIdentity(identity);
3519 }
3520 }
3521
shilu366312e2019-12-17 09:28:10 -08003522 /**
3523 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3524 * @param subId The subscription to use to check the configuration.
3525 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003526 @Override
3527 public boolean isTtyOverVolteEnabled(int subId) {
shilu366312e2019-12-17 09:28:10 -08003528 //TODO: b/147498511 will add TelephonyPermissions#checkCallingOrSelfReadPrecisePhoneState
Brad Ebinger35c841c2018-10-01 10:40:55 -07003529 enforceReadPrivilegedPermission("isTtyOverVolteEnabled");
3530 final long identity = Binder.clearCallingIdentity();
3531 try {
3532 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003533 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003534 getSlotIndexOrException(subId)).isTtyOnVoLteCapable();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003535 } catch (ImsException e) {
3536 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003537 } finally {
3538 Binder.restoreCallingIdentity(identity);
3539 }
3540 }
3541
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003542 @Override
3543 public void registerImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
3544 enforceReadPrivilegedPermission("registerImsProvisioningChangedCallback");
3545 final long identity = Binder.clearCallingIdentity();
3546 try {
Brad Ebingerd0331732020-01-16 11:21:18 -08003547 if (!isImsAvailableOnDevice()) {
3548 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3549 "IMS not available on device.");
Peter Wang44b186e2020-01-13 23:33:09 -08003550 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003551 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003552 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003553 .addProvisioningCallbackForSubscription(callback, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003554 } catch (ImsException e) {
3555 throw new ServiceSpecificException(e.getCode());
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003556 } finally {
3557 Binder.restoreCallingIdentity(identity);
3558 }
3559 }
3560
3561 @Override
3562 public void unregisterImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
3563 enforceReadPrivilegedPermission("unregisterImsProvisioningChangedCallback");
3564 final long identity = Binder.clearCallingIdentity();
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003565 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3566 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
3567 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003568 try {
3569 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003570 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003571 .removeProvisioningCallbackForSubscription(callback, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003572 } catch (ImsException e) {
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003573 Log.i(LOG_TAG, "unregisterImsProvisioningChangedCallback: " + subId
3574 + "is inactive, ignoring unregister.");
3575 // If the subscription is no longer active, just return, since the callback will already
3576 // have been removed internally.
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003577 } finally {
3578 Binder.restoreCallingIdentity(identity);
3579 }
3580 }
3581
allenwtsu99c623b2020-01-03 18:24:23 +08003582
3583 private void checkModifyPhoneStatePermission(int subId, String message) {
3584 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3585 message);
3586 }
3587
3588 private boolean isImsProvisioningRequired(int subId, int capability,
3589 boolean isMmtelCapability) {
3590 Phone phone = getPhone(subId);
3591 if (phone == null) {
3592 loge("phone instance null for subid " + subId);
3593 return false;
3594 }
3595 if (isMmtelCapability) {
3596 if (!doesImsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
3597 return false;
3598 }
3599 } else {
3600 if (!doesRcsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
3601 return false;
3602 }
3603 }
3604 return true;
3605 }
3606
3607 @Override
3608 public void setRcsProvisioningStatusForCapability(int subId, int capability,
3609 boolean isProvisioned) {
3610 checkModifyPhoneStatePermission(subId, "setRcsProvisioningStatusForCapability");
3611
3612 final long identity = Binder.clearCallingIdentity();
3613 try {
3614 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3615 if (!isImsProvisioningRequired(subId, capability, false)) {
3616 return;
3617 }
3618
3619 // this capability requires provisioning, route to the correct API.
3620 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
3621 switch (capability) {
3622 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE:
3623 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
3624 ims.setEabProvisioned(isProvisioned);
3625 break;
3626 default: {
3627 throw new IllegalArgumentException("Tried to set provisioning for "
3628 + "rcs capability '" + capability + "', which does not require "
3629 + "provisioning.");
3630 }
3631 }
3632 } finally {
3633 Binder.restoreCallingIdentity(identity);
3634 }
3635
3636 }
3637
3638
3639 @Override
3640 public boolean getRcsProvisioningStatusForCapability(int subId, int capability) {
3641 enforceReadPrivilegedPermission("getRcsProvisioningStatusForCapability");
3642 final long identity = Binder.clearCallingIdentity();
3643 try {
3644 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3645 if (!isImsProvisioningRequired(subId, capability, false)) {
3646 return true;
3647 }
3648
3649 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
3650 switch (capability) {
3651 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE:
3652 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
3653 return ims.isEabProvisionedOnDevice();
3654
3655 default: {
3656 throw new IllegalArgumentException("Tried to get rcs provisioning for "
3657 + "capability '" + capability + "', which does not require "
3658 + "provisioning.");
3659 }
3660 }
3661
3662 } finally {
3663 Binder.restoreCallingIdentity(identity);
3664 }
3665 }
3666
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003667 @Override
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003668 public void setImsProvisioningStatusForCapability(int subId, int capability, int tech,
3669 boolean isProvisioned) {
3670 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3671 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3672 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
3673 }
allenwtsu99c623b2020-01-03 18:24:23 +08003674 checkModifyPhoneStatePermission(subId, "setImsProvisioningStatusForCapability");
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003675 final long identity = Binder.clearCallingIdentity();
3676 try {
3677 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
allenwtsu99c623b2020-01-03 18:24:23 +08003678 if (!isImsProvisioningRequired(subId, capability, true)) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003679 return;
3680 }
3681
3682 // this capability requires provisioning, route to the correct API.
3683 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
3684 switch (capability) {
3685 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
3686 if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3687 ims.setVolteProvisioned(isProvisioned);
3688 } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
3689 ims.setWfcProvisioned(isProvisioned);
3690 }
3691 break;
3692 }
3693 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
3694 // There is currently no difference in VT provisioning type.
3695 ims.setVtProvisioned(isProvisioned);
3696 break;
3697 }
3698 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
3699 // There is no "deprecated" UT provisioning mechanism through ImsConfig, so
3700 // change the capability of the feature instead if needed.
3701 if (isMmTelCapabilityProvisionedInCache(subId, capability, tech)
3702 == isProvisioned) {
3703 // No change in provisioning.
3704 return;
3705 }
3706 cacheMmTelCapabilityProvisioning(subId, capability, tech, isProvisioned);
3707 try {
3708 ims.changeMmTelCapability(capability, tech, isProvisioned);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003709 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003710 loge("setImsProvisioningStatusForCapability: couldn't change UT capability"
3711 + ", Exception" + e.getMessage());
3712 }
3713 break;
3714 }
3715 default: {
allenwtsu99c623b2020-01-03 18:24:23 +08003716 throw new IllegalArgumentException("Tried to set provisioning for "
3717 + "MmTel capability '" + capability + "', which does not require "
3718 + "provisioning. ");
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003719 }
3720 }
3721
3722 } finally {
3723 Binder.restoreCallingIdentity(identity);
3724 }
3725 }
3726
3727 @Override
3728 public boolean getImsProvisioningStatusForCapability(int subId, int capability, int tech) {
3729 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3730 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3731 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
3732 }
3733 enforceReadPrivilegedPermission("getProvisioningStatusForCapability");
3734 final long identity = Binder.clearCallingIdentity();
3735 try {
3736 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
allenwtsu99c623b2020-01-03 18:24:23 +08003737 if (!isImsProvisioningRequired(subId, capability, true)) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003738 return true;
3739 }
3740
3741 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
3742 switch (capability) {
3743 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
3744 if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3745 return ims.isVolteProvisionedOnDevice();
3746 } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
3747 return ims.isWfcProvisionedOnDevice();
3748 }
3749 // This should never happen, since we are checking tech above to make sure it
3750 // is either LTE or IWLAN.
3751 throw new IllegalArgumentException("Invalid radio technology for voice "
3752 + "capability.");
3753 }
3754 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
3755 // There is currently no difference in VT provisioning type.
3756 return ims.isVtProvisionedOnDevice();
3757 }
3758 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
3759 // There is no "deprecated" UT provisioning mechanism, so get from shared prefs.
3760 return isMmTelCapabilityProvisionedInCache(subId, capability, tech);
3761 }
3762 default: {
allenwtsu99c623b2020-01-03 18:24:23 +08003763 throw new IllegalArgumentException(
3764 "Tried to get provisioning for MmTel capability '" + capability
3765 + "', which does not require provisioning.");
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003766 }
3767 }
3768
3769 } finally {
3770 Binder.restoreCallingIdentity(identity);
3771 }
3772 }
3773
3774 @Override
3775 public boolean isMmTelCapabilityProvisionedInCache(int subId, int capability, int tech) {
3776 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3777 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3778 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
3779 }
3780 enforceReadPrivilegedPermission("isMmTelCapabilityProvisionedInCache");
3781 int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
3782 return (provisionedBits & capability) > 0;
3783 }
3784
3785 @Override
3786 public void cacheMmTelCapabilityProvisioning(int subId, int capability, int tech,
3787 boolean isProvisioned) {
3788 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3789 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3790 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
3791 }
3792 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3793 "setProvisioningStatusForCapability");
3794 int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
3795 // If the current provisioning status for capability already matches isProvisioned,
3796 // do nothing.
3797 if (((provisionedBits & capability) > 0) == isProvisioned) {
3798 return;
3799 }
3800 if (isProvisioned) {
3801 setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits | capability));
3802 } else {
3803 setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits & ~capability));
3804 }
3805 }
3806
3807 /**
3808 * @return the bitfield containing the MmTel provisioning for the provided subscription and
3809 * technology. The bitfield should mirror the bitfield defined by
3810 * {@link MmTelFeature.MmTelCapabilities.MmTelCapability}.
3811 */
3812 private int getMmTelCapabilityProvisioningBitfield(int subId, int tech) {
3813 String key = getMmTelProvisioningKey(subId, tech);
3814 // Default is no capabilities are provisioned.
3815 return mTelephonySharedPreferences.getInt(key, 0 /*default*/);
3816 }
3817
3818 /**
3819 * Sets the MmTel capability provisioning bitfield (defined by
3820 * {@link MmTelFeature.MmTelCapabilities.MmTelCapability}) for the subscription and
3821 * technology specified.
3822 *
3823 * Note: This is a synchronous command and should not be called on UI thread.
3824 */
3825 private void setMmTelCapabilityProvisioningBitfield(int subId, int tech, int newField) {
3826 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
3827 String key = getMmTelProvisioningKey(subId, tech);
3828 editor.putInt(key, newField);
3829 editor.commit();
3830 }
3831
3832 private static String getMmTelProvisioningKey(int subId, int tech) {
3833 // resulting key is provision_ims_mmtel_{subId}_{tech}
3834 return PREF_PROVISION_IMS_MMTEL_PREFIX + subId + "_" + tech;
3835 }
3836
3837 /**
3838 * Query CarrierConfig to see if the specified capability requires provisioning for the
3839 * carrier associated with the subscription id.
3840 */
3841 private boolean doesImsCapabilityRequireProvisioning(Context context, int subId,
3842 int capability) {
3843 CarrierConfigManager configManager = new CarrierConfigManager(context);
3844 PersistableBundle c = configManager.getConfigForSubId(subId);
3845 boolean requireUtProvisioning = c.getBoolean(
Brad Ebinger076903f2019-05-13 10:00:22 -07003846 CarrierConfigManager.KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL, false)
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003847 && c.getBoolean(CarrierConfigManager.KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL,
3848 false);
3849 boolean requireVoiceVtProvisioning = c.getBoolean(
3850 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, false);
3851
3852 // First check to make sure that the capability requires provisioning.
3853 switch (capability) {
3854 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE:
3855 // intentional fallthrough
3856 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
3857 if (requireVoiceVtProvisioning) {
3858 // Voice and Video requires provisioning
3859 return true;
3860 }
3861 break;
3862 }
3863 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
3864 if (requireUtProvisioning) {
3865 // UT requires provisioning
3866 return true;
3867 }
3868 break;
3869 }
3870 }
3871 return false;
3872 }
3873
allenwtsu99c623b2020-01-03 18:24:23 +08003874 private boolean doesRcsCapabilityRequireProvisioning(Context context, int subId,
3875 int capability) {
3876 CarrierConfigManager configManager = new CarrierConfigManager(context);
3877 PersistableBundle c = configManager.getConfigForSubId(subId);
3878
3879 boolean requireRcsProvisioning = c.getBoolean(
3880 CarrierConfigManager.KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL, false);
3881
3882 // First check to make sure that the capability requires provisioning.
3883 switch (capability) {
3884 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
3885 // intentional fallthrough
3886 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE: {
3887 if (requireRcsProvisioning) {
3888 // OPTION or PRESENCE requires provisioning
3889 return true;
3890 }
3891 break;
3892 }
3893 }
3894 return false;
3895 }
3896
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003897 @Override
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003898 public int getImsProvisioningInt(int subId, int key) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003899 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3900 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
3901 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003902 enforceReadPrivilegedPermission("getImsProvisioningInt");
3903 final long identity = Binder.clearCallingIdentity();
3904 try {
3905 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003906 int slotId = getSlotIndex(subId);
3907 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
3908 Log.w(LOG_TAG, "getImsProvisioningInt: called with an inactive subscription '"
3909 + subId + "' for key:" + key);
3910 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
3911 }
3912 return ImsManager.getInstance(mApp, slotId).getConfigInterface().getConfigInt(key);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003913 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003914 Log.w(LOG_TAG, "getImsProvisioningInt: ImsService is not available for subscription '"
3915 + subId + "' for key:" + key);
3916 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003917 } finally {
3918 Binder.restoreCallingIdentity(identity);
3919 }
3920 }
3921
3922 @Override
3923 public String getImsProvisioningString(int subId, int key) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003924 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3925 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
3926 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003927 enforceReadPrivilegedPermission("getImsProvisioningString");
3928 final long identity = Binder.clearCallingIdentity();
3929 try {
3930 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003931 int slotId = getSlotIndex(subId);
3932 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
3933 Log.w(LOG_TAG, "getImsProvisioningString: called for an inactive subscription id '"
3934 + subId + "' for key:" + key);
3935 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_GENERIC;
3936 }
3937 return ImsManager.getInstance(mApp, slotId).getConfigInterface().getConfigString(key);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003938 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003939 Log.w(LOG_TAG, "getImsProvisioningString: ImsService is not available for sub '"
3940 + subId + "' for key:" + key);
3941 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_NOT_READY;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003942 } finally {
3943 Binder.restoreCallingIdentity(identity);
3944 }
3945 }
3946
3947 @Override
3948 public int setImsProvisioningInt(int subId, int key, int value) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003949 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3950 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
3951 }
Brad Ebinger3d0b34e2018-11-15 14:13:12 -08003952 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3953 "setImsProvisioningInt");
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003954 final long identity = Binder.clearCallingIdentity();
3955 try {
3956 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003957 int slotId = getSlotIndex(subId);
3958 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
3959 Log.w(LOG_TAG, "setImsProvisioningInt: called with an inactive subscription id '"
3960 + subId + "' for key:" + key);
3961 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
3962 }
3963 return ImsManager.getInstance(mApp, slotId).getConfigInterface().setConfig(key, value);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003964 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003965 Log.w(LOG_TAG, "setImsProvisioningInt: ImsService unavailable for sub '" + subId
3966 + "' for key:" + key);
3967 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003968 } finally {
3969 Binder.restoreCallingIdentity(identity);
3970 }
3971 }
3972
3973 @Override
3974 public int setImsProvisioningString(int subId, int key, String value) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003975 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3976 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
3977 }
Brad Ebinger3d0b34e2018-11-15 14:13:12 -08003978 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3979 "setImsProvisioningString");
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003980 final long identity = Binder.clearCallingIdentity();
3981 try {
3982 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003983 int slotId = getSlotIndex(subId);
3984 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
3985 Log.w(LOG_TAG, "setImsProvisioningString: called with an inactive subscription id '"
3986 + subId + "' for key:" + key);
3987 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
3988 }
3989 return ImsManager.getInstance(mApp, slotId).getConfigInterface().setConfig(key, value);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003990 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08003991 Log.w(LOG_TAG, "setImsProvisioningString: ImsService unavailable for sub '" + subId
3992 + "' for key:" + key);
3993 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003994 } finally {
3995 Binder.restoreCallingIdentity(identity);
3996 }
3997 }
3998
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003999 private int getSlotIndexOrException(int subId) throws ImsException {
Brad Ebinger35c841c2018-10-01 10:40:55 -07004000 int slotId = SubscriptionManager.getSlotIndex(subId);
4001 if (!SubscriptionManager.isValidSlotIndex(slotId)) {
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004002 throw new ImsException("Invalid Subscription Id, subId=" + subId,
4003 ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
Brad Ebinger35c841c2018-10-01 10:40:55 -07004004 }
4005 return slotId;
4006 }
4007
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004008 private int getSlotIndex(int subId) {
4009 int slotId = SubscriptionManager.getSlotIndex(subId);
4010 if (!SubscriptionManager.isValidSlotIndex(slotId)) {
4011 return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
4012 }
4013 return slotId;
4014 }
4015
Wink Saville36469e72014-06-11 15:17:00 -07004016 /**
Nathan Harold9042f0b2019-05-21 15:51:27 -07004017 * Returns the data network type for a subId; does not throw SecurityException.
Wink Saville36469e72014-06-11 15:17:00 -07004018 */
4019 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004020 public int getNetworkTypeForSubscriber(int subId, String callingPackage,
4021 String callingFeatureId) {
Nathan Haroldef60dba2019-05-22 13:55:14 -07004022 final int targetSdk = getTargetSdk(callingPackage);
4023 if (targetSdk > android.os.Build.VERSION_CODES.Q) {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004024 return getDataNetworkTypeForSubscriber(subId, callingPackage, callingFeatureId);
Nathan Haroldef60dba2019-05-22 13:55:14 -07004025 } else if (targetSdk == android.os.Build.VERSION_CODES.Q
Nathan Harold9042f0b2019-05-21 15:51:27 -07004026 && !TelephonyPermissions.checkCallingOrSelfReadPhoneStateNoThrow(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004027 mApp, subId, callingPackage, callingFeatureId,
4028 "getNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004029 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4030 }
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07004031
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004032 final long identity = Binder.clearCallingIdentity();
4033 try {
4034 final Phone phone = getPhone(subId);
4035 if (phone != null) {
4036 return phone.getServiceState().getDataNetworkType();
4037 } else {
4038 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4039 }
4040 } finally {
4041 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004042 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004043 }
4044
4045 /**
4046 * Returns the data network type
4047 */
4048 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004049 public int getDataNetworkType(String callingPackage, String callingFeatureId) {
4050 return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage,
4051 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07004052 }
4053
4054 /**
4055 * Returns the data network type for a subId
4056 */
4057 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004058 public int getDataNetworkTypeForSubscriber(int subId, String callingPackage,
4059 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004060 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004061 mApp, subId, callingPackage, callingFeatureId,
4062 "getDataNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004063 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4064 }
4065
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004066 final long identity = Binder.clearCallingIdentity();
4067 try {
4068 final Phone phone = getPhone(subId);
4069 if (phone != null) {
4070 return phone.getServiceState().getDataNetworkType();
4071 } else {
4072 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4073 }
4074 } finally {
4075 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004076 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004077 }
4078
4079 /**
Wink Saville36469e72014-06-11 15:17:00 -07004080 * Returns the Voice network type for a subId
4081 */
4082 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004083 public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage,
4084 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004085 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004086 mApp, subId, callingPackage, callingFeatureId,
4087 "getDataNetworkTypeForSubscriber")) {
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07004088 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4089 }
4090
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004091 final long identity = Binder.clearCallingIdentity();
4092 try {
4093 final Phone phone = getPhone(subId);
4094 if (phone != null) {
4095 return phone.getServiceState().getVoiceNetworkType();
4096 } else {
4097 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4098 }
4099 } finally {
4100 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004101 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004102 }
4103
4104 /**
4105 * @return true if a ICC card is present
4106 */
4107 public boolean hasIccCard() {
Wink Saville36469e72014-06-11 15:17:00 -07004108 // FIXME Make changes to pass defaultSimId of type int
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004109 return hasIccCardUsingSlotIndex(mSubscriptionController.getSlotIndex(
4110 getDefaultSubscription()));
Wink Saville36469e72014-06-11 15:17:00 -07004111 }
4112
4113 /**
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004114 * @return true if a ICC card is present for a slotIndex
Wink Saville36469e72014-06-11 15:17:00 -07004115 */
Sanket Padawe356d7632015-06-22 14:03:32 -07004116 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004117 public boolean hasIccCardUsingSlotIndex(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004118 final long identity = Binder.clearCallingIdentity();
4119 try {
4120 final Phone phone = PhoneFactory.getPhone(slotIndex);
4121 if (phone != null) {
4122 return phone.getIccCard().hasIccCard();
4123 } else {
4124 return false;
4125 }
4126 } finally {
4127 Binder.restoreCallingIdentity(identity);
Amit Mahajana6fc2a82015-01-06 11:53:51 -08004128 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004129 }
4130
4131 /**
4132 * Return if the current radio is LTE on CDMA. This
4133 * is a tri-state return value as for a period of time
4134 * the mode may be unknown.
4135 *
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004136 * @param callingPackage the name of the package making the call.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004137 * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
Jake Hambye994d462014-02-03 13:10:13 -08004138 * or {@link Phone#LTE_ON_CDMA_TRUE}
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004139 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004140 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004141 public int getLteOnCdmaMode(String callingPackage, String callingFeatureId) {
4142 return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage,
4143 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07004144 }
4145
Sanket Padawe356d7632015-06-22 14:03:32 -07004146 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004147 public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage,
4148 String callingFeatureId) {
Sarah Chin790d2922020-01-16 12:17:23 -08004149 try {
4150 enforceReadPrivilegedPermission("getLteOnCdmaModeForSubscriber");
4151 } catch (SecurityException e) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004152 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
4153 }
4154
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004155 final long identity = Binder.clearCallingIdentity();
4156 try {
4157 final Phone phone = getPhone(subId);
4158 if (phone == null) {
4159 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
4160 } else {
4161 return phone.getLteOnCdmaMode();
4162 }
4163 } finally {
4164 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004165 }
Wink Saville36469e72014-06-11 15:17:00 -07004166 }
4167
Wink Saville36469e72014-06-11 15:17:00 -07004168 /**
4169 * {@hide}
4170 * Returns Default subId, 0 in the case of single standby.
4171 */
Wink Savilleb564aae2014-10-23 10:18:09 -07004172 private int getDefaultSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08004173 return mSubscriptionController.getDefaultSubId();
Wink Saville36469e72014-06-11 15:17:00 -07004174 }
4175
Shishir Agrawala9f32182016-04-12 12:00:16 -07004176 private int getSlotForDefaultSubscription() {
4177 return mSubscriptionController.getPhoneId(getDefaultSubscription());
4178 }
4179
Wink Savilleb564aae2014-10-23 10:18:09 -07004180 private int getPreferredVoiceSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08004181 return mSubscriptionController.getDefaultVoiceSubId();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004182 }
Ihab Awadf2177b72013-11-25 13:33:23 -08004183
Pengquan Menge92a50d2018-09-21 15:54:48 -07004184 private boolean isActiveSubscription(int subId) {
4185 return mSubscriptionController.isActiveSubId(subId);
4186 }
4187
Ihab Awadf2177b72013-11-25 13:33:23 -08004188 /**
4189 * @see android.telephony.TelephonyManager.WifiCallingChoices
4190 */
4191 public int getWhenToMakeWifiCalls() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004192 final long identity = Binder.clearCallingIdentity();
4193 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004194 return Settings.System.getInt(mApp.getContentResolver(),
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004195 Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
4196 getWhenToMakeWifiCallsDefaultPreference());
4197 } finally {
4198 Binder.restoreCallingIdentity(identity);
4199 }
Ihab Awadf2177b72013-11-25 13:33:23 -08004200 }
4201
4202 /**
4203 * @see android.telephony.TelephonyManager.WifiCallingChoices
4204 */
4205 public void setWhenToMakeWifiCalls(int preference) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004206 final long identity = Binder.clearCallingIdentity();
4207 try {
4208 if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004209 Settings.System.putInt(mApp.getContentResolver(),
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004210 Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference);
4211 } finally {
4212 Binder.restoreCallingIdentity(identity);
4213 }
Ihab Awadf9e92732013-12-05 18:02:52 -08004214 }
4215
Sailesh Nepald1e68152013-12-12 19:08:02 -08004216 private static int getWhenToMakeWifiCallsDefaultPreference() {
Santos Cordonda120f42014-08-06 04:44:34 -07004217 // TODO: Use a build property to choose this value.
Evan Charlton9829e882013-12-19 15:30:38 -08004218 return TelephonyManager.WifiCallingChoices.ALWAYS_USE;
Ihab Awadf2177b72013-11-25 13:33:23 -08004219 }
Shishir Agrawal69f68122013-12-16 17:25:49 -08004220
Jordan Liu4c733742019-02-28 12:03:40 -08004221 private Phone getPhoneFromSlotIdOrThrowException(int slotIndex) {
4222 int phoneId = UiccController.getInstance().getPhoneIdFromSlotId(slotIndex);
4223 if (phoneId == -1) {
4224 throw new IllegalArgumentException("Given slot index: " + slotIndex
4225 + " does not correspond to an active phone");
4226 }
4227 return PhoneFactory.getPhone(phoneId);
4228 }
4229
Shishir Agrawal566b7612013-10-28 14:41:00 -07004230 @Override
Derek Tan740e1672017-06-27 14:56:27 -07004231 public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
4232 int subId, String callingPackage, String aid, int p2) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004233 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4234 mApp, subId, "iccOpenLogicalChannel");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004235 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jordan Liu4c733742019-02-28 12:03:40 -08004236 if (DBG) {
4237 log("iccOpenLogicalChannel: subId=" + subId + " aid=" + aid + " p2=" + p2);
4238 }
4239 return iccOpenLogicalChannelWithPermission(getPhoneFromSubId(subId), callingPackage, aid,
4240 p2);
4241 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07004242
Jordan Liu4c733742019-02-28 12:03:40 -08004243
4244 @Override
4245 public IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(
4246 int slotIndex, String callingPackage, String aid, int p2) {
4247 enforceModifyPermission();
4248 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4249 if (DBG) {
4250 log("iccOpenLogicalChannelBySlot: slot=" + slotIndex + " aid=" + aid + " p2=" + p2);
4251 }
4252 return iccOpenLogicalChannelWithPermission(getPhoneFromSlotIdOrThrowException(slotIndex),
4253 callingPackage, aid, p2);
4254 }
4255
4256 private IccOpenLogicalChannelResponse iccOpenLogicalChannelWithPermission(Phone phone,
4257 String callingPackage, String aid, int p2) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004258 final long identity = Binder.clearCallingIdentity();
4259 try {
4260 if (TextUtils.equals(ISDR_AID, aid)) {
4261 // Only allows LPA to open logical channel to ISD-R.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004262 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
4263 .getContext().getPackageManager());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004264 if (bestComponent == null
4265 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
4266 loge("The calling package is not allowed to access ISD-R.");
4267 throw new SecurityException(
4268 "The calling package is not allowed to access ISD-R.");
4269 }
Derek Tan740e1672017-06-27 14:56:27 -07004270 }
Derek Tan740e1672017-06-27 14:56:27 -07004271
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004272 IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse) sendRequest(
Jordan Liu4c733742019-02-28 12:03:40 -08004273 CMD_OPEN_CHANNEL, new Pair<String, Integer>(aid, p2), phone,
4274 null /* workSource */);
4275 if (DBG) log("iccOpenLogicalChannelWithPermission: " + response);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004276 return response;
4277 } finally {
4278 Binder.restoreCallingIdentity(identity);
4279 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07004280 }
4281
4282 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004283 public boolean iccCloseLogicalChannel(int subId, int channel) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004284 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4285 mApp, subId, "iccCloseLogicalChannel");
Jordan Liu4c733742019-02-28 12:03:40 -08004286 if (DBG) log("iccCloseLogicalChannel: subId=" + subId + " chnl=" + channel);
4287 return iccCloseLogicalChannelWithPermission(getPhoneFromSubId(subId), channel);
4288 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07004289
Jordan Liu4c733742019-02-28 12:03:40 -08004290 @Override
4291 public boolean iccCloseLogicalChannelBySlot(int slotIndex, int channel) {
4292 enforceModifyPermission();
4293 if (DBG) log("iccCloseLogicalChannelBySlot: slotIndex=" + slotIndex + " chnl=" + channel);
4294 return iccCloseLogicalChannelWithPermission(getPhoneFromSlotIdOrThrowException(slotIndex),
4295 channel);
4296 }
4297
4298 private boolean iccCloseLogicalChannelWithPermission(Phone phone, int channel) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004299 final long identity = Binder.clearCallingIdentity();
4300 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004301 if (channel < 0) {
4302 return false;
4303 }
Jordan Liu4c733742019-02-28 12:03:40 -08004304 Boolean success = (Boolean) sendRequest(CMD_CLOSE_CHANNEL, channel, phone,
4305 null /* workSource */);
4306 if (DBG) log("iccCloseLogicalChannelWithPermission: " + success);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004307 return success;
4308 } finally {
4309 Binder.restoreCallingIdentity(identity);
Shishir Agrawal566b7612013-10-28 14:41:00 -07004310 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07004311 }
4312
4313 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004314 public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
Shishir Agrawal566b7612013-10-28 14:41:00 -07004315 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004316 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4317 mApp, subId, "iccTransmitApduLogicalChannel");
Jordan Liu4c733742019-02-28 12:03:40 -08004318 if (DBG) {
4319 log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel
4320 + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
4321 + p3 + " data=" + data);
4322 }
4323 return iccTransmitApduLogicalChannelWithPermission(getPhoneFromSubId(subId), channel, cla,
4324 command, p1, p2, p3, data);
4325 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07004326
Jordan Liu4c733742019-02-28 12:03:40 -08004327 @Override
4328 public String iccTransmitApduLogicalChannelBySlot(int slotIndex, int channel, int cla,
4329 int command, int p1, int p2, int p3, String data) {
4330 enforceModifyPermission();
4331 if (DBG) {
4332 log("iccTransmitApduLogicalChannelBySlot: slotIndex=" + slotIndex + " chnl=" + channel
4333 + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
4334 + p3 + " data=" + data);
4335 }
4336 return iccTransmitApduLogicalChannelWithPermission(
4337 getPhoneFromSlotIdOrThrowException(slotIndex), channel, cla, command, p1, p2, p3,
4338 data);
4339 }
4340
4341 private String iccTransmitApduLogicalChannelWithPermission(Phone phone, int channel, int cla,
4342 int command, int p1, int p2, int p3, String data) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004343 final long identity = Binder.clearCallingIdentity();
4344 try {
Hall Liu4fd771b2019-05-02 09:16:29 -07004345 if (channel <= 0) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004346 return "";
4347 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07004348
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004349 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL,
Jordan Liu4c733742019-02-28 12:03:40 -08004350 new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), phone,
4351 null /* workSource */);
4352 if (DBG) log("iccTransmitApduLogicalChannelWithPermission: " + response);
Shishir Agrawal566b7612013-10-28 14:41:00 -07004353
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004354 // Append the returned status code to the end of the response payload.
4355 String s = Integer.toHexString(
4356 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
4357 if (response.payload != null) {
4358 s = IccUtils.bytesToHexString(response.payload) + s;
4359 }
4360 return s;
4361 } finally {
4362 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07004363 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07004364 }
Jake Hambye994d462014-02-03 13:10:13 -08004365
Evan Charltonc66da362014-05-16 14:06:40 -07004366 @Override
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08004367 public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
4368 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004369 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4370 mApp, subId, "iccTransmitApduBasicChannel");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004371 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jordan Liu4c733742019-02-28 12:03:40 -08004372 if (DBG) {
4373 log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd="
4374 + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
4375 }
4376 return iccTransmitApduBasicChannelWithPermission(getPhoneFromSubId(subId), callingPackage,
4377 cla, command, p1, p2, p3, data);
4378 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004379
Jordan Liu4c733742019-02-28 12:03:40 -08004380 @Override
4381 public String iccTransmitApduBasicChannelBySlot(int slotIndex, String callingPackage, int cla,
4382 int command, int p1, int p2, int p3, String data) {
4383 enforceModifyPermission();
4384 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4385 if (DBG) {
4386 log("iccTransmitApduBasicChannelBySlot: slotIndex=" + slotIndex + " cla=" + cla
4387 + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3
4388 + " data=" + data);
4389 }
4390
4391 return iccTransmitApduBasicChannelWithPermission(
4392 getPhoneFromSlotIdOrThrowException(slotIndex), callingPackage, cla, command, p1,
4393 p2, p3, data);
4394 }
4395
4396 // open APDU basic channel assuming the caller has sufficient permissions
4397 private String iccTransmitApduBasicChannelWithPermission(Phone phone, String callingPackage,
4398 int cla, int command, int p1, int p2, int p3, String data) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004399 final long identity = Binder.clearCallingIdentity();
4400 try {
4401 if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
4402 && TextUtils.equals(ISDR_AID, data)) {
4403 // Only allows LPA to select ISD-R.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004404 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
4405 .getContext().getPackageManager());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004406 if (bestComponent == null
4407 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
4408 loge("The calling package is not allowed to select ISD-R.");
4409 throw new SecurityException(
4410 "The calling package is not allowed to select ISD-R.");
4411 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08004412 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08004413
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004414 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL,
Jordan Liu4c733742019-02-28 12:03:40 -08004415 new IccAPDUArgument(0, cla, command, p1, p2, p3, data), phone,
4416 null /* workSource */);
4417 if (DBG) log("iccTransmitApduBasicChannelWithPermission: " + response);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004418
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004419 // Append the returned status code to the end of the response payload.
4420 String s = Integer.toHexString(
4421 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
4422 if (response.payload != null) {
4423 s = IccUtils.bytesToHexString(response.payload) + s;
4424 }
4425 return s;
4426 } finally {
4427 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07004428 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004429 }
4430
4431 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004432 public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004433 String filePath) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004434 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4435 mApp, subId, "iccExchangeSimIO");
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004436
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004437 final long identity = Binder.clearCallingIdentity();
4438 try {
4439 if (DBG) {
4440 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " "
4441 + p1 + " " + p2 + " " + p3 + ":" + filePath);
4442 }
4443
4444 IccIoResult response =
4445 (IccIoResult) sendRequest(CMD_EXCHANGE_SIM_IO,
4446 new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath),
4447 subId);
4448
4449 if (DBG) {
4450 log("Exchange SIM_IO [R]" + response);
4451 }
4452
4453 byte[] result = null;
4454 int length = 2;
4455 if (response.payload != null) {
4456 length = 2 + response.payload.length;
4457 result = new byte[length];
4458 System.arraycopy(response.payload, 0, result, 0, response.payload.length);
4459 } else {
4460 result = new byte[length];
4461 }
4462
4463 result[length - 1] = (byte) response.sw2;
4464 result[length - 2] = (byte) response.sw1;
4465 return result;
4466 } finally {
4467 Binder.restoreCallingIdentity(identity);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004468 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004469 }
4470
Nathan Haroldb3014052017-01-25 15:57:32 -08004471 /**
4472 * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
4473 * on a particular subscription
4474 */
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004475 public String[] getForbiddenPlmns(int subId, int appType, String callingPackage,
4476 String callingFeatureId) {
sqianb6e41952018-03-12 14:54:01 -07004477 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004478 mApp, subId, callingPackage, callingFeatureId, "getForbiddenPlmns")) {
sqianb6e41952018-03-12 14:54:01 -07004479 return null;
4480 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004481
4482 final long identity = Binder.clearCallingIdentity();
4483 try {
4484 if (appType != TelephonyManager.APPTYPE_USIM
4485 && appType != TelephonyManager.APPTYPE_SIM) {
4486 loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
4487 return null;
4488 }
4489 Object response = sendRequest(
4490 CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
4491 if (response instanceof String[]) {
4492 return (String[]) response;
4493 }
yincheng zhao2737e882019-09-06 17:06:54 -07004494 // Response is an Exception of some kind
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004495 // which is signalled to the user as a NULL retval
Nathan Haroldb3014052017-01-25 15:57:32 -08004496 return null;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004497 } finally {
4498 Binder.restoreCallingIdentity(identity);
Nathan Haroldb3014052017-01-25 15:57:32 -08004499 }
Nathan Haroldb3014052017-01-25 15:57:32 -08004500 }
4501
yincheng zhao2737e882019-09-06 17:06:54 -07004502 /**
4503 * Set the forbidden PLMN list from the given app type (ex APPTYPE_USIM) on a particular
4504 * subscription.
4505 *
4506 * @param subId the id of the subscription.
4507 * @param appType the uicc app type, must be USIM or SIM.
4508 * @param fplmns the Forbiden plmns list that needed to be written to the SIM.
4509 * @param callingPackage the op Package name.
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004510 * @param callingFeatureId the feature in the package.
yincheng zhao2737e882019-09-06 17:06:54 -07004511 * @return number of fplmns that is successfully written to the SIM.
4512 */
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004513 public int setForbiddenPlmns(int subId, int appType, List<String> fplmns, String callingPackage,
4514 String callingFeatureId) {
4515 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
4516 callingFeatureId, "setForbiddenPlmns")) {
yincheng zhao2737e882019-09-06 17:06:54 -07004517 if (DBG) logv("no permissions for setForbiddenplmns");
4518 throw new IllegalStateException("No Permissions for setForbiddenPlmns");
4519 }
4520 if (appType != TelephonyManager.APPTYPE_USIM && appType != TelephonyManager.APPTYPE_SIM) {
4521 loge("setForbiddenPlmnList(): App Type must be USIM or SIM");
4522 throw new IllegalArgumentException("Invalid appType: App Type must be USIM or SIM");
4523 }
4524 if (fplmns == null) {
4525 throw new IllegalArgumentException("Fplmn List provided is null");
4526 }
4527 for (String fplmn : fplmns) {
4528 if (!CellIdentity.isValidPlmn(fplmn)) {
4529 throw new IllegalArgumentException("Invalid fplmn provided: " + fplmn);
4530 }
4531 }
4532 final long identity = Binder.clearCallingIdentity();
4533 try {
4534 Object response = sendRequest(
4535 CMD_SET_FORBIDDEN_PLMNS,
4536 new Pair<Integer, List<String>>(new Integer(appType), fplmns),
4537 subId);
4538 return (int) response;
4539 } finally {
4540 Binder.restoreCallingIdentity(identity);
4541 }
4542 }
4543
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004544 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004545 public String sendEnvelopeWithStatus(int subId, String content) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004546 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4547 mApp, subId, "sendEnvelopeWithStatus");
Evan Charltonc66da362014-05-16 14:06:40 -07004548
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004549 final long identity = Binder.clearCallingIdentity();
4550 try {
4551 IccIoResult response = (IccIoResult) sendRequest(CMD_SEND_ENVELOPE, content, subId);
4552 if (response.payload == null) {
4553 return "";
4554 }
Evan Charltonc66da362014-05-16 14:06:40 -07004555
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004556 // Append the returned status code to the end of the response payload.
4557 String s = Integer.toHexString(
4558 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
4559 s = IccUtils.bytesToHexString(response.payload) + s;
4560 return s;
4561 } finally {
4562 Binder.restoreCallingIdentity(identity);
4563 }
Evan Charltonc66da362014-05-16 14:06:40 -07004564 }
4565
Jake Hambye994d462014-02-03 13:10:13 -08004566 /**
4567 * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
4568 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
4569 *
4570 * @param itemID the ID of the item to read
4571 * @return the NV item as a String, or null on error.
4572 */
4573 @Override
4574 public String nvReadItem(int itemID) {
vagdeviaf9a5b92018-08-15 16:01:53 -07004575 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08004576 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4577 mApp, getDefaultSubscription(), "nvReadItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004578
4579 final long identity = Binder.clearCallingIdentity();
4580 try {
4581 if (DBG) log("nvReadItem: item " + itemID);
vagdeviaf9a5b92018-08-15 16:01:53 -07004582 String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004583 if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
4584 return value;
4585 } finally {
4586 Binder.restoreCallingIdentity(identity);
4587 }
Jake Hambye994d462014-02-03 13:10:13 -08004588 }
4589
4590 /**
4591 * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
4592 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
4593 *
4594 * @param itemID the ID of the item to read
4595 * @param itemValue the value to write, as a String
4596 * @return true on success; false on any failure
4597 */
4598 @Override
4599 public boolean nvWriteItem(int itemID, String itemValue) {
vagdeviaf9a5b92018-08-15 16:01:53 -07004600 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08004601 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4602 mApp, getDefaultSubscription(), "nvWriteItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004603
4604 final long identity = Binder.clearCallingIdentity();
4605 try {
4606 if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
4607 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
vagdeviaf9a5b92018-08-15 16:01:53 -07004608 new Pair<Integer, String>(itemID, itemValue), workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004609 if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
4610 return success;
4611 } finally {
4612 Binder.restoreCallingIdentity(identity);
4613 }
Jake Hambye994d462014-02-03 13:10:13 -08004614 }
4615
4616 /**
4617 * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
4618 * Used for device configuration by some CDMA operators.
4619 *
4620 * @param preferredRoamingList byte array containing the new PRL
4621 * @return true on success; false on any failure
4622 */
4623 @Override
4624 public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004625 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4626 mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004627
4628 final long identity = Binder.clearCallingIdentity();
4629 try {
4630 if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
4631 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
4632 if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
4633 return success;
4634 } finally {
4635 Binder.restoreCallingIdentity(identity);
4636 }
Jake Hambye994d462014-02-03 13:10:13 -08004637 }
4638
4639 /**
chen xu6dac5ab2018-10-26 17:39:23 -07004640 * Rollback modem configurations to factory default except some config which are in whitelist.
Jake Hambye994d462014-02-03 13:10:13 -08004641 * Used for device configuration by some CDMA operators.
4642 *
chen xu6dac5ab2018-10-26 17:39:23 -07004643 * @param slotIndex - device slot.
4644 *
Jake Hambye994d462014-02-03 13:10:13 -08004645 * @return true on success; false on any failure
4646 */
4647 @Override
chen xu6dac5ab2018-10-26 17:39:23 -07004648 public boolean resetModemConfig(int slotIndex) {
4649 Phone phone = PhoneFactory.getPhone(slotIndex);
4650 if (phone != null) {
4651 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4652 mApp, phone.getSubId(), "resetModemConfig");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004653
chen xu6dac5ab2018-10-26 17:39:23 -07004654 final long identity = Binder.clearCallingIdentity();
4655 try {
4656 Boolean success = (Boolean) sendRequest(CMD_RESET_MODEM_CONFIG, null);
4657 if (DBG) log("resetModemConfig:" + ' ' + (success ? "ok" : "fail"));
4658 return success;
4659 } finally {
4660 Binder.restoreCallingIdentity(identity);
4661 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004662 }
chen xu6dac5ab2018-10-26 17:39:23 -07004663 return false;
4664 }
4665
4666 /**
4667 * Generate a radio modem reset. Used for device configuration by some CDMA operators.
4668 *
4669 * @param slotIndex - device slot.
4670 *
4671 * @return true on success; false on any failure
4672 */
4673 @Override
4674 public boolean rebootModem(int slotIndex) {
4675 Phone phone = PhoneFactory.getPhone(slotIndex);
4676 if (phone != null) {
4677 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4678 mApp, phone.getSubId(), "rebootModem");
4679
4680 final long identity = Binder.clearCallingIdentity();
4681 try {
4682 Boolean success = (Boolean) sendRequest(CMD_MODEM_REBOOT, null);
4683 if (DBG) log("rebootModem:" + ' ' + (success ? "ok" : "fail"));
4684 return success;
4685 } finally {
4686 Binder.restoreCallingIdentity(identity);
4687 }
4688 }
4689 return false;
Jake Hambye994d462014-02-03 13:10:13 -08004690 }
Jake Hamby7c27be32014-03-03 13:25:59 -08004691
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004692 public String[] getPcscfAddress(String apnType, String callingPackage,
4693 String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004694 final Phone defaultPhone = getDefaultPhone();
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004695 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
4696 callingPackage, callingFeatureId, "getPcscfAddress")) {
Svet Ganovb320e182015-04-16 12:30:10 -07004697 return new String[0];
4698 }
4699
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004700 final long identity = Binder.clearCallingIdentity();
4701 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004702 return defaultPhone.getPcscfAddress(apnType);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004703 } finally {
4704 Binder.restoreCallingIdentity(identity);
4705 }
Wink Saville36469e72014-06-11 15:17:00 -07004706 }
4707
Brad Ebinger51f743a2017-01-23 13:50:20 -08004708 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004709 * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
4710 * status updates, if not already enabled.
Brad Ebinger51f743a2017-01-23 13:50:20 -08004711 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004712 public void enableIms(int slotId) {
Brad Ebinger51f743a2017-01-23 13:50:20 -08004713 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004714
4715 final long identity = Binder.clearCallingIdentity();
4716 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08004717 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004718 // may happen if the device does not support IMS.
4719 return;
4720 }
Brad Ebinger24c29992019-12-05 13:03:21 -08004721 mImsResolver.enableIms(slotId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004722 } finally {
4723 Binder.restoreCallingIdentity(identity);
4724 }
Brad Ebinger34bef922017-11-09 10:27:08 -08004725 }
4726
4727 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004728 * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
4729 * status updates to disabled.
Brad Ebinger34bef922017-11-09 10:27:08 -08004730 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004731 public void disableIms(int slotId) {
4732 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004733
4734 final long identity = Binder.clearCallingIdentity();
4735 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08004736 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004737 // may happen if the device does not support IMS.
4738 return;
4739 }
Brad Ebinger24c29992019-12-05 13:03:21 -08004740 mImsResolver.disableIms(slotId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004741 } finally {
4742 Binder.restoreCallingIdentity(identity);
4743 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004744 }
4745
4746 /**
4747 * Returns the {@link IImsMmTelFeature} that corresponds to the given slot Id for the MMTel
4748 * feature or {@link null} if the service is not available. If the feature is available, the
4749 * {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates.
4750 */
4751 public IImsMmTelFeature getMmTelFeatureAndListen(int slotId,
Brad Ebinger34bef922017-11-09 10:27:08 -08004752 IImsServiceFeatureCallback callback) {
4753 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004754
4755 final long identity = Binder.clearCallingIdentity();
4756 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08004757 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004758 // may happen if the device does not support IMS.
4759 return null;
4760 }
Brad Ebinger24c29992019-12-05 13:03:21 -08004761 return mImsResolver.getMmTelFeatureAndListen(slotId, callback);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004762 } finally {
4763 Binder.restoreCallingIdentity(identity);
4764 }
Brad Ebinger34bef922017-11-09 10:27:08 -08004765 }
4766
4767 /**
4768 * Returns the {@link IImsRcsFeature} that corresponds to the given slot Id for the RCS
4769 * feature during emergency calling or {@link null} if the service is not available. If the
4770 * feature is available, the {@link IImsServiceFeatureCallback} callback is registered as a
4771 * listener for feature updates.
4772 */
4773 public IImsRcsFeature getRcsFeatureAndListen(int slotId, IImsServiceFeatureCallback callback) {
4774 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004775
4776 final long identity = Binder.clearCallingIdentity();
4777 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08004778 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004779 // may happen if the device does not support IMS.
4780 return null;
4781 }
Brad Ebinger24c29992019-12-05 13:03:21 -08004782 return mImsResolver.getRcsFeatureAndListen(slotId, callback);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004783 } finally {
4784 Binder.restoreCallingIdentity(identity);
4785 }
Brad Ebinger51f743a2017-01-23 13:50:20 -08004786 }
4787
Brad Ebinger5f64b052017-12-14 14:26:15 -08004788 /**
4789 * Returns the {@link IImsRegistration} structure associated with the slotId and feature
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004790 * specified or null if IMS is not supported on the slot specified.
Brad Ebinger5f64b052017-12-14 14:26:15 -08004791 */
4792 public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
4793 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004794
4795 final long identity = Binder.clearCallingIdentity();
4796 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08004797 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004798 // may happen if the device does not support IMS.
4799 return null;
4800 }
Brad Ebinger24c29992019-12-05 13:03:21 -08004801 return mImsResolver.getImsRegistration(slotId, feature);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004802 } finally {
4803 Binder.restoreCallingIdentity(identity);
4804 }
Brad Ebinger5f64b052017-12-14 14:26:15 -08004805 }
4806
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004807 /**
4808 * Returns the {@link IImsConfig} structure associated with the slotId and feature
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004809 * specified or null if IMS is not supported on the slot specified.
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004810 */
4811 public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
4812 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004813
4814 final long identity = Binder.clearCallingIdentity();
4815 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08004816 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004817 // may happen if the device does not support IMS.
4818 return null;
4819 }
Brad Ebinger24c29992019-12-05 13:03:21 -08004820 return mImsResolver.getImsConfig(slotId, feature);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004821 } finally {
4822 Binder.restoreCallingIdentity(identity);
4823 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08004824 }
4825
Brad Ebinger884c07b2018-02-15 16:17:40 -08004826 /**
Brad Ebingerdac2f002018-04-03 15:17:52 -07004827 * Sets the ImsService Package Name that Telephony will bind to.
4828 *
Brad Ebinger24c29992019-12-05 13:03:21 -08004829 * @param slotIndex the slot ID that the ImsService should bind for.
4830 * @param isCarrierService true if the ImsService is the carrier override, false if the
Brad Ebingerdac2f002018-04-03 15:17:52 -07004831 * ImsService is the device default ImsService.
Brad Ebinger24c29992019-12-05 13:03:21 -08004832 * @param featureTypes An integer array of feature types associated with a packageName.
4833 * @param packageName The name of the package that the current configuration will be replaced
4834 * with.
Brad Ebingerdac2f002018-04-03 15:17:52 -07004835 * @return true if setting the ImsService to bind to succeeded, false if it did not.
Brad Ebingerdac2f002018-04-03 15:17:52 -07004836 */
Brad Ebinger24c29992019-12-05 13:03:21 -08004837 public boolean setBoundImsServiceOverride(int slotIndex, boolean isCarrierService,
4838 int[] featureTypes, String packageName) {
4839 int[] subIds = SubscriptionManager.getSubId(slotIndex);
4840 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setBoundImsServiceOverride");
Brad Ebingerde696de2018-04-06 09:56:40 -07004841 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
4842 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
Brad Ebinger24c29992019-12-05 13:03:21 -08004843 "setBoundImsServiceOverride");
Brad Ebingerde696de2018-04-06 09:56:40 -07004844
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004845 final long identity = Binder.clearCallingIdentity();
4846 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08004847 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004848 // may happen if the device does not support IMS.
4849 return false;
4850 }
Brad Ebinger24c29992019-12-05 13:03:21 -08004851 Map<Integer, String> featureConfig = new HashMap<>();
4852 for (int featureType : featureTypes) {
4853 featureConfig.put(featureType, packageName);
4854 }
4855 return mImsResolver.overrideImsServiceConfiguration(slotIndex, isCarrierService,
4856 featureConfig);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004857 } finally {
4858 Binder.restoreCallingIdentity(identity);
4859 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07004860 }
4861
4862 /**
Brad Ebinger24c29992019-12-05 13:03:21 -08004863 * Return the package name of the currently bound ImsService.
Brad Ebingerdac2f002018-04-03 15:17:52 -07004864 *
4865 * @param slotId The slot that the ImsService is associated with.
4866 * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
4867 * the device default.
Brad Ebinger24c29992019-12-05 13:03:21 -08004868 * @param featureType The feature associated with the queried configuration.
Brad Ebingerdac2f002018-04-03 15:17:52 -07004869 * @return the package name of the ImsService configuration.
4870 */
Brad Ebinger24c29992019-12-05 13:03:21 -08004871 public String getBoundImsServicePackage(int slotId, boolean isCarrierImsService,
4872 @ImsFeature.FeatureType int featureType) {
Brad Ebingerde696de2018-04-06 09:56:40 -07004873 int[] subIds = SubscriptionManager.getSubId(slotId);
Brad Ebinger24c29992019-12-05 13:03:21 -08004874 TelephonyPermissions
4875 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
4876 mApp, (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
4877 "getBoundImsServicePackage");
Brad Ebingerde696de2018-04-06 09:56:40 -07004878
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004879 final long identity = Binder.clearCallingIdentity();
4880 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08004881 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08004882 // may happen if the device does not support IMS.
4883 return "";
4884 }
Brad Ebingera80c3312019-12-02 10:59:39 -08004885 // TODO: change API to query RCS separately.
Brad Ebinger24c29992019-12-05 13:03:21 -08004886 return mImsResolver.getImsServiceConfiguration(slotId, isCarrierImsService,
4887 featureType);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004888 } finally {
4889 Binder.restoreCallingIdentity(identity);
4890 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07004891 }
4892
Brad Ebingerbc7dd582019-10-17 17:03:22 -07004893 /**
4894 * Get the MmTelFeature state associated with the requested subscription id.
4895 * @param subId The subscription that the MmTelFeature is associated with.
4896 * @param callback A callback with an integer containing the
4897 * {@link android.telephony.ims.feature.ImsFeature.ImsState} associated with the MmTelFeature.
4898 */
4899 @Override
4900 public void getImsMmTelFeatureState(int subId, IIntegerConsumer callback) {
4901 enforceReadPrivilegedPermission("getImsMmTelFeatureState");
4902 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4903 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4904 "IMS not available on device.");
4905 }
4906 final long token = Binder.clearCallingIdentity();
4907 try {
4908 int slotId = getSlotIndex(subId);
4909 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4910 Log.w(LOG_TAG, "getImsMmTelFeatureState: called with an inactive subscription '"
4911 + subId + "'");
4912 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
4913 }
4914 ImsManager.getInstance(mApp, slotId).getImsServiceState(anInteger -> {
4915 try {
4916 callback.accept(anInteger == null ? ImsFeature.STATE_UNAVAILABLE : anInteger);
4917 } catch (RemoteException e) {
4918 Log.w(LOG_TAG, "getImsMmTelFeatureState: remote caller is no longer running. "
4919 + "Ignore");
4920 }
4921 });
4922 } finally {
4923 Binder.restoreCallingIdentity(token);
4924 }
4925 }
4926
Wink Saville36469e72014-06-11 15:17:00 -07004927 public void setImsRegistrationState(boolean registered) {
4928 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004929
4930 final long identity = Binder.clearCallingIdentity();
4931 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004932 getDefaultPhone().setImsRegistrationState(registered);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004933 } finally {
4934 Binder.restoreCallingIdentity(identity);
4935 }
Wink Saville36469e72014-06-11 15:17:00 -07004936 }
4937
4938 /**
Stuart Scott54788802015-03-30 13:18:01 -07004939 * Set the network selection mode to automatic.
4940 *
4941 */
4942 @Override
4943 public void setNetworkSelectionModeAutomatic(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004944 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4945 mApp, subId, "setNetworkSelectionModeAutomatic");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004946
Pengquan Menge92a50d2018-09-21 15:54:48 -07004947 if (!isActiveSubscription(subId)) {
4948 return;
4949 }
4950
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004951 final long identity = Binder.clearCallingIdentity();
4952 try {
4953 if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
4954 sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId);
4955 } finally {
4956 Binder.restoreCallingIdentity(identity);
4957 }
Stuart Scott54788802015-03-30 13:18:01 -07004958 }
4959
Pengquan Mengea84e042018-09-20 14:57:26 -07004960 /**
4961 * Ask the radio to connect to the input network and change selection mode to manual.
4962 *
4963 * @param subId the id of the subscription.
4964 * @param operatorInfo the operator information, included the PLMN, long name and short name of
4965 * the operator to attach to.
4966 * @param persistSelection whether the selection will persist until reboot. If true, only allows
4967 * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
4968 * normal network selection next time.
4969 * @return {@code true} on success; {@code true} on any failure.
Shishir Agrawal302c8692015-06-19 13:49:39 -07004970 */
4971 @Override
Pengquan Mengea84e042018-09-20 14:57:26 -07004972 public boolean setNetworkSelectionModeManual(
4973 int subId, OperatorInfo operatorInfo, boolean persistSelection) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004974 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4975 mApp, subId, "setNetworkSelectionModeManual");
Pengquan Menge92a50d2018-09-21 15:54:48 -07004976
4977 if (!isActiveSubscription(subId)) {
4978 return false;
4979 }
4980
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004981 final long identity = Binder.clearCallingIdentity();
4982 try {
Pengquan Mengea84e042018-09-20 14:57:26 -07004983 ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operatorInfo,
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004984 persistSelection);
Pengquan Mengea84e042018-09-20 14:57:26 -07004985 if (DBG) {
4986 log("setNetworkSelectionModeManual: subId: " + subId
4987 + " operator: " + operatorInfo);
4988 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004989 return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
4990 } finally {
4991 Binder.restoreCallingIdentity(identity);
4992 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07004993 }
4994
4995 /**
4996 * Scans for available networks.
4997 */
4998 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07004999 public CellNetworkScanResult getCellNetworkScanResults(int subId, String callingPackage,
5000 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005001 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5002 mApp, subId, "getCellNetworkScanResults");
Hall Liuf19c44f2018-11-27 14:38:17 -08005003 LocationAccessPolicy.LocationPermissionResult locationResult =
5004 LocationAccessPolicy.checkLocationPermission(mApp,
5005 new LocationAccessPolicy.LocationPermissionQuery.Builder()
5006 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07005007 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08005008 .setCallingPid(Binder.getCallingPid())
5009 .setCallingUid(Binder.getCallingUid())
5010 .setMethod("getCellNetworkScanResults")
5011 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
5012 .build());
5013 switch (locationResult) {
5014 case DENIED_HARD:
5015 throw new SecurityException("Not allowed to access scan results -- location");
5016 case DENIED_SOFT:
5017 return null;
5018 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005019
Pengquan Menga1bb6272018-09-06 09:59:22 -07005020 long identity = Binder.clearCallingIdentity();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005021 try {
5022 if (DBG) log("getCellNetworkScanResults: subId " + subId);
Pengquan Menga1bb6272018-09-06 09:59:22 -07005023 return (CellNetworkScanResult) sendRequest(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005024 CMD_PERFORM_NETWORK_SCAN, null, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005025 } finally {
5026 Binder.restoreCallingIdentity(identity);
5027 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07005028 }
5029
5030 /**
yinxub1bed742017-04-17 11:45:04 -07005031 * Starts a new network scan and returns the id of this scan.
yinxu504e1392017-04-12 16:03:22 -07005032 *
yinxub1bed742017-04-17 11:45:04 -07005033 * @param subId id of the subscription
5034 * @param request contains the radio access networks with bands/channels to scan
5035 * @param messenger callback messenger for scan results or errors
5036 * @param binder for the purpose of auto clean when the user thread crashes
yinxu504e1392017-04-12 16:03:22 -07005037 * @return the id of the requested scan which can be used to stop the scan.
5038 */
5039 @Override
5040 public int requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger,
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07005041 IBinder binder, String callingPackage, String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005042 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5043 mApp, subId, "requestNetworkScan");
Hall Liuf19c44f2018-11-27 14:38:17 -08005044 LocationAccessPolicy.LocationPermissionResult locationResult =
5045 LocationAccessPolicy.checkLocationPermission(mApp,
5046 new LocationAccessPolicy.LocationPermissionQuery.Builder()
5047 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07005048 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08005049 .setCallingPid(Binder.getCallingPid())
5050 .setCallingUid(Binder.getCallingUid())
5051 .setMethod("requestNetworkScan")
5052 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
5053 .build());
Hall Liub2ac8ef2019-02-28 15:56:23 -08005054 if (locationResult != LocationAccessPolicy.LocationPermissionResult.ALLOWED) {
Hall Liu558027f2019-05-15 19:14:05 -07005055 SecurityException e = checkNetworkRequestForSanitizedLocationAccess(request, subId);
Hall Liub2ac8ef2019-02-28 15:56:23 -08005056 if (e != null) {
5057 if (locationResult == LocationAccessPolicy.LocationPermissionResult.DENIED_HARD) {
5058 throw e;
5059 } else {
Hall Liu0e5abaf2019-04-04 01:25:30 -07005060 loge(e.getMessage());
Hall Liub2ac8ef2019-02-28 15:56:23 -08005061 return TelephonyScanManager.INVALID_SCAN_ID;
5062 }
5063 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005064 }
Hall Liu912dfd32019-04-25 14:02:26 -07005065 int callingUid = Binder.getCallingUid();
5066 int callingPid = Binder.getCallingPid();
Ying Xu94a46582019-04-18 17:14:56 -07005067 final long identity = Binder.clearCallingIdentity();
5068 try {
5069 return mNetworkScanRequestTracker.startNetworkScan(
5070 request, messenger, binder, getPhone(subId),
Hall Liu912dfd32019-04-25 14:02:26 -07005071 callingUid, callingPid, callingPackage);
Ying Xu94a46582019-04-18 17:14:56 -07005072 } finally {
5073 Binder.restoreCallingIdentity(identity);
5074 }
yinxu504e1392017-04-12 16:03:22 -07005075 }
5076
Hall Liub2ac8ef2019-02-28 15:56:23 -08005077 private SecurityException checkNetworkRequestForSanitizedLocationAccess(
Hall Liu558027f2019-05-15 19:14:05 -07005078 NetworkScanRequest request, int subId) {
5079 boolean hasCarrierPriv = getCarrierPrivilegeStatusForUid(subId, Binder.getCallingUid())
5080 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
5081 boolean hasNetworkScanPermission =
5082 mApp.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_SCAN)
5083 == PERMISSION_GRANTED;
5084
5085 if (!hasCarrierPriv && !hasNetworkScanPermission) {
5086 return new SecurityException("permission.NETWORK_SCAN or carrier privileges is needed"
5087 + " for network scans without location access.");
Hall Liub2ac8ef2019-02-28 15:56:23 -08005088 }
5089
5090 if (request.getSpecifiers() != null && request.getSpecifiers().length > 0) {
5091 for (RadioAccessSpecifier ras : request.getSpecifiers()) {
Hall Liub2ac8ef2019-02-28 15:56:23 -08005092 if (ras.getChannels() != null && ras.getChannels().length > 0) {
5093 return new SecurityException("Specific channels must not be"
5094 + " scanned without location access.");
5095 }
5096 }
5097 }
5098
Hall Liub2ac8ef2019-02-28 15:56:23 -08005099 return null;
5100 }
5101
yinxu504e1392017-04-12 16:03:22 -07005102 /**
5103 * Stops an existing network scan with the given scanId.
yinxub1bed742017-04-17 11:45:04 -07005104 *
5105 * @param subId id of the subscription
5106 * @param scanId id of the scan that needs to be stopped
yinxu504e1392017-04-12 16:03:22 -07005107 */
5108 @Override
5109 public void stopNetworkScan(int subId, int scanId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005110 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5111 mApp, subId, "stopNetworkScan");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005112
Hall Liu912dfd32019-04-25 14:02:26 -07005113 int callingUid = Binder.getCallingUid();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005114 final long identity = Binder.clearCallingIdentity();
5115 try {
Hall Liu912dfd32019-04-25 14:02:26 -07005116 mNetworkScanRequestTracker.stopNetworkScan(scanId, callingUid);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005117 } finally {
5118 Binder.restoreCallingIdentity(identity);
5119 }
yinxu504e1392017-04-12 16:03:22 -07005120 }
5121
5122 /**
Junda Liu84d15a22014-07-02 11:21:04 -07005123 * Get the calculated preferred network type.
5124 * Used for debugging incorrect network type.
5125 *
5126 * @return the preferred network type, defined in RILConstants.java.
5127 */
5128 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005129 public int getCalculatedPreferredNetworkType(String callingPackage, String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005130 final Phone defaultPhone = getDefaultPhone();
5131 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005132 callingPackage, callingFeatureId, "getCalculatedPreferredNetworkType")) {
Svet Ganovb320e182015-04-16 12:30:10 -07005133 return RILConstants.PREFERRED_NETWORK_MODE;
5134 }
5135
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005136 final long identity = Binder.clearCallingIdentity();
5137 try {
5138 // FIXME: need to get SubId from somewhere.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005139 return PhoneFactory.calculatePreferredNetworkType(defaultPhone.getContext(), 0);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005140 } finally {
5141 Binder.restoreCallingIdentity(identity);
5142 }
Junda Liu84d15a22014-07-02 11:21:04 -07005143 }
5144
5145 /**
Jake Hamby7c27be32014-03-03 13:25:59 -08005146 * Get the preferred network type.
5147 * Used for device configuration by some CDMA operators.
5148 *
5149 * @return the preferred network type, defined in RILConstants.java.
5150 */
5151 @Override
Stuart Scott54788802015-03-30 13:18:01 -07005152 public int getPreferredNetworkType(int subId) {
Pengquan Menga4009cb2018-12-20 11:00:24 -08005153 TelephonyPermissions
5154 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5155 mApp, subId, "getPreferredNetworkType");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005156
5157 final long identity = Binder.clearCallingIdentity();
5158 try {
5159 if (DBG) log("getPreferredNetworkType");
5160 int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null, subId);
5161 int networkType = (result != null ? result[0] : -1);
5162 if (DBG) log("getPreferredNetworkType: " + networkType);
5163 return networkType;
5164 } finally {
5165 Binder.restoreCallingIdentity(identity);
5166 }
Jake Hamby7c27be32014-03-03 13:25:59 -08005167 }
5168
5169 /**
5170 * Set the preferred network type.
5171 * Used for device configuration by some CDMA operators.
5172 *
5173 * @param networkType the preferred network type, defined in RILConstants.java.
5174 * @return true on success; false on any failure.
5175 */
5176 @Override
Stuart Scott54788802015-03-30 13:18:01 -07005177 public boolean setPreferredNetworkType(int subId, int networkType) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005178 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5179 mApp, subId, "setPreferredNetworkType");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005180
5181 final long identity = Binder.clearCallingIdentity();
5182 try {
calvinpan0ac9c1a2020-01-14 20:42:55 +08005183 Settings.Global.putInt(mApp.getContentResolver(),
5184 Settings.Global.PREFERRED_NETWORK_MODE + subId, networkType);
5185 return setPreferredNetworkTypesInternal(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005186 } finally {
5187 Binder.restoreCallingIdentity(identity);
Junda Liu80bc0d12014-07-14 16:36:44 -07005188 }
Jake Hamby7c27be32014-03-03 13:25:59 -08005189 }
Robert Greenwalted86e582014-05-21 20:03:20 -07005190
5191 /**
calvinpan0ac9c1a2020-01-14 20:42:55 +08005192 * Get the allowed network types that store in the telephony provider.
5193 *
5194 * @param subId the id of the subscription.
5195 * @return allowedNetworkTypes the allowed network types.
5196 */
5197 @Override
5198 public long getAllowedNetworkTypes(int subId) {
5199 TelephonyPermissions
5200 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5201 mApp, subId, "getAllowedNetworkTypes");
5202
5203 final long identity = Binder.clearCallingIdentity();
5204 try {
5205 return SubscriptionManager.getLongSubscriptionProperty(
5206 subId, SubscriptionManager.ALLOWED_NETWORK_TYPES, -1, mApp);
5207 } finally {
5208 Binder.restoreCallingIdentity(identity);
5209 }
5210 }
5211
5212 /**
5213 * Set the allowed network types.
5214 *
5215 * @param subId the id of the subscription.
5216 * @param allowedNetworkTypes the allowed network types.
5217 * @return true on success; false on any failure.
5218 */
5219 @Override
5220 public boolean setAllowedNetworkTypes(int subId, long allowedNetworkTypes) {
5221 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5222 mApp, subId, "setAllowedNetworkTypes");
5223 final long identity = Binder.clearCallingIdentity();
5224 try {
5225 SubscriptionManager.setSubscriptionProperty(subId,
5226 SubscriptionManager.ALLOWED_NETWORK_TYPES,
5227 String.valueOf(allowedNetworkTypes));
5228 return setPreferredNetworkTypesInternal(subId);
5229 } finally {
5230 Binder.restoreCallingIdentity(identity);
5231 }
5232 }
5233
5234 private boolean setPreferredNetworkTypesInternal(int subId) {
5235 long networkTypeBitMask = RadioAccessFamily.getRafFromNetworkType(
5236 Settings.Global.getInt(mApp.getContentResolver(),
5237 Settings.Global.PREFERRED_NETWORK_MODE + subId,
5238 RILConstants.PREFERRED_NETWORK_MODE));
5239 long allowedNetworkTypes = SubscriptionManager.getLongSubscriptionProperty(
5240 subId, SubscriptionManager.ALLOWED_NETWORK_TYPES, -1, mApp);
5241 int networkMode = RadioAccessFamily.getNetworkTypeFromRaf(
5242 (int) (networkTypeBitMask & allowedNetworkTypes));
5243
5244 if (DBG) {
5245 log("setPreferredNetworkTypesInternal: subId " + subId
5246 + " networkTypes " + networkTypeBitMask
5247 + " allowedNetworkTypes " + allowedNetworkTypes
5248 + " networkMode " + networkMode);
5249 }
5250
5251 Boolean success = (Boolean) sendRequest(
5252 CMD_SET_PREFERRED_NETWORK_TYPE, networkMode, subId);
5253 if (DBG) log("setPreferredNetworkTypesInternal: " + (success ? "ok" : "fail"));
5254 return success;
5255 }
5256
5257 /**
Miaoa84611c2019-03-15 09:21:10 +08005258 * Check whether DUN APN is required for tethering with subId.
Junda Liu475951f2014-11-07 16:45:03 -08005259 *
Miaoa84611c2019-03-15 09:21:10 +08005260 * @param subId the id of the subscription to require tethering.
Amit Mahajanfe58cdf2017-07-11 12:01:53 -07005261 * @return {@code true} if DUN APN is required for tethering.
Junda Liu475951f2014-11-07 16:45:03 -08005262 * @hide
5263 */
5264 @Override
SongFerngWangf08d8122019-11-15 14:58:44 +08005265 public boolean isTetheringApnRequiredForSubscriber(int subId) {
Shishir Agrawalc04d9752016-02-19 10:41:00 -08005266 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005267 final long identity = Binder.clearCallingIdentity();
Miaoa84611c2019-03-15 09:21:10 +08005268 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005269 try {
Miaoa84611c2019-03-15 09:21:10 +08005270 if (phone != null) {
5271 return phone.hasMatchedTetherApnSetting();
5272 } else {
5273 return false;
5274 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005275 } finally {
5276 Binder.restoreCallingIdentity(identity);
Junda Liu475951f2014-11-07 16:45:03 -08005277 }
Junda Liu475951f2014-11-07 16:45:03 -08005278 }
5279
5280 /**
Robert Greenwalted86e582014-05-21 20:03:20 -07005281 * Set mobile data enabled
5282 * Used by the user through settings etc to turn on/off mobile data
5283 *
5284 * @param enable {@code true} turn turn data on, else {@code false}
5285 */
5286 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08005287 public void setUserDataEnabled(int subId, boolean enable) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005288 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5289 mApp, subId, "setUserDataEnabled");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005290
5291 final long identity = Binder.clearCallingIdentity();
5292 try {
5293 int phoneId = mSubscriptionController.getPhoneId(subId);
5294 if (DBG) log("setUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
5295 Phone phone = PhoneFactory.getPhone(phoneId);
5296 if (phone != null) {
5297 if (DBG) log("setUserDataEnabled: subId=" + subId + " enable=" + enable);
Jack Yud79fba22018-12-13 11:51:28 -08005298 phone.getDataEnabledSettings().setUserDataEnabled(enable);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005299 } else {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005300 loge("setUserDataEnabled: no phone found. Invalid subId=" + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005301 }
5302 } finally {
5303 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08005304 }
Robert Greenwalted86e582014-05-21 20:03:20 -07005305 }
5306
5307 /**
Shuo Qiancd19c462020-01-16 20:51:11 -08005308 * Enable or disable always reporting signal strength changes from radio.
5309 *
5310 * @param isEnable {@code true} for enabling; {@code false} for disabling.
5311 */
5312 @Override
5313 public void setAlwaysReportSignalStrength(int subId, boolean isEnable) {
5314 enforceModifyPermission();
5315 enforceSystemCaller();
5316
5317 final long identity = Binder.clearCallingIdentity();
5318 final Phone phone = getPhone(subId);
5319 try {
5320 if (phone != null) {
5321 if (DBG) {
5322 log("setAlwaysReportSignalStrength: subId=" + subId
5323 + " isEnable=" + isEnable);
5324 }
5325 phone.setAlwaysReportSignalStrength(isEnable);
5326 } else {
5327 loge("setAlwaysReportSignalStrength: no phone found for subId="
5328 + subId);
5329 }
5330 } finally {
5331 Binder.restoreCallingIdentity(identity);
5332 }
5333 }
5334
5335 /**
Malcolm Chen964682d2017-11-28 16:20:07 -08005336 * Get the user enabled state of Mobile Data.
5337 *
5338 * TODO: remove and use isUserDataEnabled.
5339 * This can't be removed now because some vendor codes
5340 * calls through ITelephony directly while they should
5341 * use TelephonyManager.
5342 *
5343 * @return true on enabled
5344 */
5345 @Override
5346 public boolean getDataEnabled(int subId) {
5347 return isUserDataEnabled(subId);
5348 }
5349
5350 /**
5351 * Get whether mobile data is enabled per user setting.
5352 *
5353 * There are other factors deciding whether mobile data is actually enabled, but they are
5354 * not considered here. See {@link #isDataEnabled(int)} for more details.
Robert Greenwalt646120a2014-05-23 11:54:03 -07005355 *
Jeff Davidsona1920712016-11-18 17:05:56 -08005356 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
Robert Greenwalted86e582014-05-21 20:03:20 -07005357 *
5358 * @return {@code true} if data is enabled else {@code false}
5359 */
5360 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08005361 public boolean isUserDataEnabled(int subId) {
Robert Greenwalt646120a2014-05-23 11:54:03 -07005362 try {
5363 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
5364 null);
5365 } catch (Exception e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005366 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5367 mApp, subId, "isUserDataEnabled");
Robert Greenwalt646120a2014-05-23 11:54:03 -07005368 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005369
5370 final long identity = Binder.clearCallingIdentity();
5371 try {
5372 int phoneId = mSubscriptionController.getPhoneId(subId);
5373 if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
5374 Phone phone = PhoneFactory.getPhone(phoneId);
5375 if (phone != null) {
5376 boolean retVal = phone.isUserDataEnabled();
5377 if (DBG) log("isUserDataEnabled: subId=" + subId + " retVal=" + retVal);
5378 return retVal;
5379 } else {
5380 if (DBG) loge("isUserDataEnabled: no phone subId=" + subId + " retVal=false");
5381 return false;
5382 }
5383 } finally {
5384 Binder.restoreCallingIdentity(identity);
Malcolm Chen964682d2017-11-28 16:20:07 -08005385 }
5386 }
5387
5388 /**
Shuo Qian8ee4e882020-01-08 14:30:06 -08005389 * Checks if the device is capable of mobile data by considering whether whether the
5390 * user has enabled mobile data, whether the carrier has enabled mobile data, and
5391 * whether the network policy allows data connections.
Malcolm Chen964682d2017-11-28 16:20:07 -08005392 *
Shuo Qian8ee4e882020-01-08 14:30:06 -08005393 * @return {@code true} if the overall data connection is capable; {@code false} if not.
Malcolm Chen964682d2017-11-28 16:20:07 -08005394 */
5395 @Override
5396 public boolean isDataEnabled(int subId) {
Shuo Qian8ee4e882020-01-08 14:30:06 -08005397 enforceReadPrivilegedPermission("isDataEnabled");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005398
5399 final long identity = Binder.clearCallingIdentity();
5400 try {
5401 int phoneId = mSubscriptionController.getPhoneId(subId);
5402 if (DBG) log("isDataEnabled: subId=" + subId + " phoneId=" + phoneId);
5403 Phone phone = PhoneFactory.getPhone(phoneId);
5404 if (phone != null) {
Jack Yud79fba22018-12-13 11:51:28 -08005405 boolean retVal = phone.getDataEnabledSettings().isDataEnabled();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005406 if (DBG) log("isDataEnabled: subId=" + subId + " retVal=" + retVal);
5407 return retVal;
5408 } else {
5409 if (DBG) loge("isDataEnabled: no phone subId=" + subId + " retVal=false");
5410 return false;
5411 }
5412 } finally {
5413 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08005414 }
Robert Greenwalted86e582014-05-21 20:03:20 -07005415 }
Shishir Agrawal60f9c952014-06-23 12:00:43 -07005416
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07005417 private int getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim,
5418 Phone phone) {
5419 //load access rules from carrier configs, and check those as well: b/139133814
5420 SubscriptionController subController = SubscriptionController.getInstance();
5421 if (privilegeFromSim == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
5422 || subController == null) return privilegeFromSim;
5423
5424 int uid = Binder.getCallingUid();
5425 PackageManager pkgMgr = phone.getContext().getPackageManager();
5426 String[] packages = pkgMgr.getPackagesForUid(uid);
5427
5428 final long identity = Binder.clearCallingIdentity();
5429 try {
5430 SubscriptionInfo subInfo = subController.getSubscriptionInfo(phone.getSubId());
5431 SubscriptionManager subManager = (SubscriptionManager)
5432 phone.getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
5433 for (String pkg : packages) {
5434 if (subManager.canManageSubscription(subInfo, pkg)) {
5435 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
5436 }
5437 }
5438 return privilegeFromSim;
5439 } finally {
5440 Binder.restoreCallingIdentity(identity);
5441 }
5442 }
5443
5444 private int getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, Phone phone,
5445 String pkgName) {
5446 //load access rules from carrier configs, and check those as well: b/139133814
5447 SubscriptionController subController = SubscriptionController.getInstance();
5448 if (privilegeFromSim == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
5449 || subController == null) return privilegeFromSim;
5450
5451 final long identity = Binder.clearCallingIdentity();
5452 try {
5453 SubscriptionInfo subInfo = subController.getSubscriptionInfo(phone.getSubId());
5454 SubscriptionManager subManager = (SubscriptionManager)
5455 phone.getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
5456 return subManager.canManageSubscription(subInfo, pkgName)
5457 ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS : privilegeFromSim;
5458 } finally {
5459 Binder.restoreCallingIdentity(identity);
5460 }
5461 }
5462
Shishir Agrawal60f9c952014-06-23 12:00:43 -07005463 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08005464 public int getCarrierPrivilegeStatus(int subId) {
5465 final Phone phone = getPhone(subId);
5466 if (phone == null) {
5467 loge("getCarrierPrivilegeStatus: Invalid subId");
5468 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
5469 }
5470 UiccCard card = UiccController.getInstance().getUiccCard(phone.getPhoneId());
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07005471 if (card == null) {
Shishir Agrawal5e5becd2014-11-18 11:38:23 -08005472 loge("getCarrierPrivilegeStatus: No UICC");
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07005473 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
5474 }
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07005475
5476 return getCarrierPrivilegeStatusFromCarrierConfigRules(
5477 card.getCarrierPrivilegeStatusForCurrentTransaction(
5478 phone.getContext().getPackageManager()), phone);
Shishir Agrawal60f9c952014-06-23 12:00:43 -07005479 }
Junda Liu29340342014-07-10 15:23:27 -07005480
5481 @Override
Jeff Davidson7e17e312018-02-13 18:17:36 -08005482 public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08005483 enforceReadPrivilegedPermission("getCarrierPrivilegeStatusForUid");
Jeff Davidson7e17e312018-02-13 18:17:36 -08005484 final Phone phone = getPhone(subId);
5485 if (phone == null) {
Taesu Leef8fbed92019-10-07 18:47:02 +09005486 loge("getCarrierPrivilegeStatusForUid: Invalid subId");
Jeff Davidson7e17e312018-02-13 18:17:36 -08005487 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
5488 }
5489 UiccProfile profile =
5490 UiccController.getInstance().getUiccProfileForPhone(phone.getPhoneId());
5491 if (profile == null) {
Taesu Leef8fbed92019-10-07 18:47:02 +09005492 loge("getCarrierPrivilegeStatusForUid: No UICC");
Jeff Davidson7e17e312018-02-13 18:17:36 -08005493 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
5494 }
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07005495 return getCarrierPrivilegeStatusFromCarrierConfigRules(
Shuo Qian2c0ae432019-12-05 11:40:37 -08005496 profile.getCarrierPrivilegeStatusForUid(
5497 phone.getContext().getPackageManager(), uid), phone);
Jeff Davidson7e17e312018-02-13 18:17:36 -08005498 }
5499
5500 @Override
chen xuf7e9fe82019-05-09 19:31:02 -07005501 public int checkCarrierPrivilegesForPackage(int subId, String pkgName) {
5502 if (TextUtils.isEmpty(pkgName)) {
Junda Liu317d70b2016-03-08 09:33:53 -08005503 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
chen xuf7e9fe82019-05-09 19:31:02 -07005504 }
5505
5506 int phoneId = SubscriptionManager.getPhoneId(subId);
5507 UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07005508 if (card == null) {
chen xuf7e9fe82019-05-09 19:31:02 -07005509 loge("checkCarrierPrivilegesForPackage: No UICC on subId " + subId);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07005510 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
5511 }
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07005512 return getCarrierPrivilegeStatusFromCarrierConfigRules(
5513 card.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName),
5514 getPhone(phoneId), pkgName);
Zach Johnson50ecba32015-05-19 00:24:21 -07005515 }
5516
5517 @Override
5518 public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
Junda Liu317d70b2016-03-08 09:33:53 -08005519 if (TextUtils.isEmpty(pkgName))
5520 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Zach Johnson50ecba32015-05-19 00:24:21 -07005521 int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
5522 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
5523 UiccCard card = UiccController.getInstance().getUiccCard(i);
5524 if (card == null) {
Jonathan Basseri7d320df2015-06-16 12:17:08 -07005525 // No UICC in that slot.
Zach Johnson50ecba32015-05-19 00:24:21 -07005526 continue;
5527 }
5528
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07005529 result = getCarrierPrivilegeStatusFromCarrierConfigRules(
5530 card.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName),
5531 getPhone(i), pkgName);
Zach Johnson50ecba32015-05-19 00:24:21 -07005532 if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
5533 break;
5534 }
5535 }
5536
5537 return result;
Junda Liu29340342014-07-10 15:23:27 -07005538 }
Derek Tan89e89d42014-07-08 17:00:10 -07005539
5540 @Override
Junda Liue64de782015-04-16 17:19:16 -07005541 public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
5542 if (!SubscriptionManager.isValidPhoneId(phoneId)) {
5543 loge("phoneId " + phoneId + " is not valid.");
5544 return null;
5545 }
5546 UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07005547 if (card == null) {
Taesu Leef8fbed92019-10-07 18:47:02 +09005548 loge("getCarrierPackageNamesForIntentAndPhone: No UICC");
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07005549 return null ;
5550 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005551 return card.getCarrierPackageNamesForIntent(mApp.getPackageManager(), intent);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07005552 }
5553
Amith Yamasani6e118872016-02-19 12:53:51 -08005554 @Override
chen xuf7e9fe82019-05-09 19:31:02 -07005555 public List<String> getPackagesWithCarrierPrivileges(int phoneId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005556 PackageManager pm = mApp.getPackageManager();
Amith Yamasani6e118872016-02-19 12:53:51 -08005557 List<String> privilegedPackages = new ArrayList<>();
5558 List<PackageInfo> packages = null;
chen xuf7e9fe82019-05-09 19:31:02 -07005559 UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
5560 // has UICC in that slot.
5561 if (card != null) {
Amith Yamasani6e118872016-02-19 12:53:51 -08005562 if (card.hasCarrierPrivilegeRules()) {
5563 if (packages == null) {
5564 // Only check packages in user 0 for now
5565 packages = pm.getInstalledPackagesAsUser(
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07005566 PackageManager.MATCH_DISABLED_COMPONENTS
5567 | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
Cheonho Park17089c62019-08-01 15:23:12 +09005568 | PackageManager.GET_SIGNING_CERTIFICATES,
5569 UserHandle.USER_SYSTEM);
Amith Yamasani6e118872016-02-19 12:53:51 -08005570 }
5571 for (int p = packages.size() - 1; p >= 0; p--) {
5572 PackageInfo pkgInfo = packages.get(p);
5573 if (pkgInfo != null && pkgInfo.packageName != null
5574 && card.getCarrierPrivilegeStatus(pkgInfo)
chen xuf7e9fe82019-05-09 19:31:02 -07005575 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
Amith Yamasani6e118872016-02-19 12:53:51 -08005576 privilegedPackages.add(pkgInfo.packageName);
5577 }
5578 }
5579 }
5580 }
5581 return privilegedPackages;
5582 }
5583
chen xuf7e9fe82019-05-09 19:31:02 -07005584 @Override
5585 public List<String> getPackagesWithCarrierPrivilegesForAllPhones() {
Shuo Qian067a06d2019-12-03 23:40:18 +00005586 enforceReadPrivilegedPermission("getPackagesWithCarrierPrivilegesForAllPhones");
5587
5588 final long identity = Binder.clearCallingIdentity();
5589
chen xuf7e9fe82019-05-09 19:31:02 -07005590 List<String> privilegedPackages = new ArrayList<>();
Shuo Qian067a06d2019-12-03 23:40:18 +00005591 try {
5592 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
5593 privilegedPackages.addAll(getPackagesWithCarrierPrivileges(i));
5594 }
5595 } finally {
5596 Binder.restoreCallingIdentity(identity);
chen xuf7e9fe82019-05-09 19:31:02 -07005597 }
5598 return privilegedPackages;
5599 }
5600
Wink Savilleb564aae2014-10-23 10:18:09 -07005601 private String getIccId(int subId) {
Sanket Padawe356d7632015-06-22 14:03:32 -07005602 final Phone phone = getPhone(subId);
5603 UiccCard card = phone == null ? null : phone.getUiccCard();
Derek Tan97ebb422014-09-05 16:55:38 -07005604 if (card == null) {
5605 loge("getIccId: No UICC");
5606 return null;
5607 }
5608 String iccId = card.getIccId();
5609 if (TextUtils.isEmpty(iccId)) {
5610 loge("getIccId: ICC ID is null or empty.");
5611 return null;
5612 }
5613 return iccId;
5614 }
5615
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07005616 @Override
Jeff Sharkey85190e62014-12-05 09:40:12 -08005617 public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
5618 String number) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08005619 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
Jeff Davidson7e17e312018-02-13 18:17:36 -08005620 subId, "setLine1NumberForDisplayForSubscriber");
Derek Tan97ebb422014-09-05 16:55:38 -07005621
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005622 final long identity = Binder.clearCallingIdentity();
5623 try {
5624 final String iccId = getIccId(subId);
5625 final Phone phone = getPhone(subId);
5626 if (phone == null) {
5627 return false;
5628 }
5629 final String subscriberId = phone.getSubscriberId();
5630
5631 if (DBG_MERGE) {
5632 Slog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId="
5633 + subscriberId + " to " + number);
5634 }
5635
5636 if (TextUtils.isEmpty(iccId)) {
5637 return false;
5638 }
5639
5640 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
5641
5642 final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
5643 if (alphaTag == null) {
5644 editor.remove(alphaTagPrefKey);
5645 } else {
5646 editor.putString(alphaTagPrefKey, alphaTag);
5647 }
5648
5649 // Record both the line number and IMSI for this ICCID, since we need to
5650 // track all merged IMSIs based on line number
5651 final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
5652 final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
5653 if (number == null) {
5654 editor.remove(numberPrefKey);
5655 editor.remove(subscriberPrefKey);
5656 } else {
5657 editor.putString(numberPrefKey, number);
5658 editor.putString(subscriberPrefKey, subscriberId);
5659 }
5660
5661 editor.commit();
5662 return true;
5663 } finally {
5664 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07005665 }
Derek Tan7226c842014-07-02 17:42:23 -07005666 }
5667
5668 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005669 public String getLine1NumberForDisplay(int subId, String callingPackage,
5670 String callingFeatureId) {
Makoto Onukifee69342015-06-29 14:44:50 -07005671 // This is open to apps with WRITE_SMS.
Jeff Davidson7e17e312018-02-13 18:17:36 -08005672 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005673 mApp, subId, callingPackage, callingFeatureId, "getLine1NumberForDisplay")) {
Amit Mahajan9cf11512015-11-09 11:40:48 -08005674 if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
Svet Ganovb320e182015-04-16 12:30:10 -07005675 return null;
5676 }
Derek Tan97ebb422014-09-05 16:55:38 -07005677
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005678 final long identity = Binder.clearCallingIdentity();
5679 try {
5680 String iccId = getIccId(subId);
5681 if (iccId != null) {
5682 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
5683 if (DBG_MERGE) {
5684 log("getLine1NumberForDisplay returning "
5685 + mTelephonySharedPreferences.getString(numberPrefKey, null));
5686 }
5687 return mTelephonySharedPreferences.getString(numberPrefKey, null);
Amit Mahajan9cf11512015-11-09 11:40:48 -08005688 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005689 if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null");
5690 return null;
5691 } finally {
5692 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07005693 }
Derek Tan7226c842014-07-02 17:42:23 -07005694 }
5695
5696 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005697 public String getLine1AlphaTagForDisplay(int subId, String callingPackage,
5698 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005699 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005700 mApp, subId, callingPackage, callingFeatureId, "getLine1AlphaTagForDisplay")) {
Svet Ganovb320e182015-04-16 12:30:10 -07005701 return null;
5702 }
Derek Tan97ebb422014-09-05 16:55:38 -07005703
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005704 final long identity = Binder.clearCallingIdentity();
5705 try {
5706 String iccId = getIccId(subId);
5707 if (iccId != null) {
5708 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
5709 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null);
5710 }
5711 return null;
5712 } finally {
5713 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07005714 }
Derek Tan7226c842014-07-02 17:42:23 -07005715 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07005716
5717 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005718 public String[] getMergedSubscriberIds(int subId, String callingPackage,
5719 String callingFeatureId) {
Jeff Davidson913390f2018-02-23 17:11:49 -08005720 // This API isn't public, so no need to provide a valid subscription ID - we're not worried
5721 // about carrier-privileged callers not having access.
Jeff Davidson7e17e312018-02-13 18:17:36 -08005722 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08005723 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005724 callingFeatureId, "getMergedSubscriberIds")) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07005725 return null;
5726 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08005727
Jordan Liub49b04b2019-05-06 14:45:15 -07005728 // Clear calling identity, when calling TelephonyManager, because callerUid must be
5729 // the process, where TelephonyManager was instantiated.
5730 // Otherwise AppOps check will fail.
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07005731 final long identity = Binder.clearCallingIdentity();
5732 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005733 final Context context = mApp;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005734 final TelephonyManager tele = TelephonyManager.from(context);
5735 final SubscriptionManager sub = SubscriptionManager.from(context);
5736
5737 // Figure out what subscribers are currently active
5738 final ArraySet<String> activeSubscriberIds = new ArraySet<>();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005739
Jordan Liub49b04b2019-05-06 14:45:15 -07005740 // Only consider subs which match the current subId
5741 // This logic can be simplified. See b/131189269 for progress.
5742 if (isActiveSubscription(subId)) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07005743 activeSubscriberIds.add(tele.getSubscriberId(subId));
5744 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005745
5746 // First pass, find a number override for an active subscriber
5747 String mergeNumber = null;
5748 final Map<String, ?> prefs = mTelephonySharedPreferences.getAll();
5749 for (String key : prefs.keySet()) {
5750 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) {
5751 final String subscriberId = (String) prefs.get(key);
5752 if (activeSubscriberIds.contains(subscriberId)) {
5753 final String iccId = key.substring(
5754 PREF_CARRIERS_SUBSCRIBER_PREFIX.length());
5755 final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
5756 mergeNumber = (String) prefs.get(numberKey);
5757 if (DBG_MERGE) {
5758 Slog.d(LOG_TAG, "Found line number " + mergeNumber
5759 + " for active subscriber " + subscriberId);
5760 }
5761 if (!TextUtils.isEmpty(mergeNumber)) {
5762 break;
5763 }
5764 }
5765 }
5766 }
5767
5768 // Shortcut when no active merged subscribers
5769 if (TextUtils.isEmpty(mergeNumber)) {
5770 return null;
5771 }
5772
5773 // Second pass, find all subscribers under that line override
5774 final ArraySet<String> result = new ArraySet<>();
5775 for (String key : prefs.keySet()) {
5776 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) {
5777 final String number = (String) prefs.get(key);
5778 if (mergeNumber.equals(number)) {
5779 final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length());
5780 final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
5781 final String subscriberId = (String) prefs.get(subscriberKey);
5782 if (!TextUtils.isEmpty(subscriberId)) {
5783 result.add(subscriberId);
5784 }
5785 }
5786 }
5787 }
5788
5789 final String[] resultArray = result.toArray(new String[result.size()]);
5790 Arrays.sort(resultArray);
5791 if (DBG_MERGE) {
5792 Slog.d(LOG_TAG,
5793 "Found subscribers " + Arrays.toString(resultArray) + " after merge");
5794 }
5795 return resultArray;
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07005796 } finally {
5797 Binder.restoreCallingIdentity(identity);
Jeff Sharkey85190e62014-12-05 09:40:12 -08005798 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08005799 }
5800
5801 @Override
zoey chen38003472019-12-13 17:16:31 +08005802 public String[] getMergedImsisFromGroup(int subId, String callingPackage) {
5803 enforceReadPrivilegedPermission("getMergedImsisFromGroup");
Malcolm Chen6ca97372019-07-01 16:28:21 -07005804
5805 final long identity = Binder.clearCallingIdentity();
5806 try {
5807 final TelephonyManager telephonyManager = mApp.getSystemService(
5808 TelephonyManager.class);
5809 String subscriberId = telephonyManager.getSubscriberId(subId);
5810 if (subscriberId == null) {
5811 if (DBG) {
zoey chen38003472019-12-13 17:16:31 +08005812 log("getMergedImsisFromGroup can't find subscriberId for subId "
Malcolm Chen6ca97372019-07-01 16:28:21 -07005813 + subId);
5814 }
5815 return null;
5816 }
5817
5818 final SubscriptionInfo info = SubscriptionController.getInstance()
5819 .getSubscriptionInfo(subId);
5820 final ParcelUuid groupUuid = info.getGroupUuid();
5821 // If it doesn't belong to any group, return just subscriberId of itself.
5822 if (groupUuid == null) {
5823 return new String[]{subscriberId};
5824 }
5825
5826 // Get all subscriberIds from the group.
5827 final List<String> mergedSubscriberIds = new ArrayList<>();
5828 final List<SubscriptionInfo> groupInfos = SubscriptionController.getInstance()
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005829 .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName(),
5830 mApp.getFeatureId());
Malcolm Chen6ca97372019-07-01 16:28:21 -07005831 for (SubscriptionInfo subInfo : groupInfos) {
5832 subscriberId = telephonyManager.getSubscriberId(subInfo.getSubscriptionId());
5833 if (subscriberId != null) {
5834 mergedSubscriberIds.add(subscriberId);
5835 }
5836 }
5837
5838 return mergedSubscriberIds.toArray(new String[mergedSubscriberIds.size()]);
5839 } finally {
5840 Binder.restoreCallingIdentity(identity);
5841
5842 }
5843 }
5844
5845 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08005846 public boolean setOperatorBrandOverride(int subId, String brand) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08005847 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
Jeff Davidson7e17e312018-02-13 18:17:36 -08005848 subId, "setOperatorBrandOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005849
5850 final long identity = Binder.clearCallingIdentity();
5851 try {
5852 final Phone phone = getPhone(subId);
5853 return phone == null ? false : phone.setOperatorBrandOverride(brand);
5854 } finally {
5855 Binder.restoreCallingIdentity(identity);
5856 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07005857 }
Steven Liu4bf01bc2014-07-17 11:05:29 -05005858
5859 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08005860 public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
Shishir Agrawal621a47c2014-12-01 10:25:09 -08005861 List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
5862 List<String> cdmaNonRoamingList) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08005863 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
5864 mApp, subId, "setRoamingOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005865
5866 final long identity = Binder.clearCallingIdentity();
5867 try {
5868 final Phone phone = getPhone(subId);
5869 if (phone == null) {
5870 return false;
5871 }
5872 return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList,
5873 cdmaNonRoamingList);
5874 } finally {
5875 Binder.restoreCallingIdentity(identity);
Shishir Agrawalc04d9752016-02-19 10:41:00 -08005876 }
Shishir Agrawal621a47c2014-12-01 10:25:09 -08005877 }
5878
5879 @Override
Shuo Qian850e4d6a2018-04-25 21:02:08 +00005880 @Deprecated
5881 public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
5882 enforceModifyPermission();
5883
5884 int returnValue = 0;
5885 try {
vagdeviaf9a5b92018-08-15 16:01:53 -07005886 AsyncResult result = (AsyncResult) sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
Shuo Qian850e4d6a2018-04-25 21:02:08 +00005887 if(result.exception == null) {
5888 if (result.result != null) {
5889 byte[] responseData = (byte[])(result.result);
5890 if(responseData.length > oemResp.length) {
5891 Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +
5892 responseData.length + "bytes. Buffer Size is " +
5893 oemResp.length + "bytes.");
5894 }
5895 System.arraycopy(responseData, 0, oemResp, 0, responseData.length);
5896 returnValue = responseData.length;
5897 }
5898 } else {
5899 CommandException ex = (CommandException) result.exception;
5900 returnValue = ex.getCommandError().ordinal();
5901 if(returnValue > 0) returnValue *= -1;
5902 }
5903 } catch (RuntimeException e) {
5904 Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");
5905 returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());
5906 if(returnValue > 0) returnValue *= -1;
5907 }
5908
5909 return returnValue;
5910 }
5911
5912 @Override
Wink Saville5d475dd2014-10-17 15:00:58 -07005913 public void setRadioCapability(RadioAccessFamily[] rafs) {
5914 try {
5915 ProxyController.getInstance().setRadioCapability(rafs);
5916 } catch (RuntimeException e) {
5917 Log.w(LOG_TAG, "setRadioCapability: Runtime Exception");
5918 }
5919 }
5920
5921 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07005922 public int getRadioAccessFamily(int phoneId, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08005923 Phone phone = PhoneFactory.getPhone(phoneId);
chen xub97461a2018-10-26 14:17:57 -07005924 int raf = RadioAccessFamily.RAF_UNKNOWN;
Jeff Davidson913390f2018-02-23 17:11:49 -08005925 if (phone == null) {
chen xub97461a2018-10-26 14:17:57 -07005926 return raf;
Jeff Davidson913390f2018-02-23 17:11:49 -08005927 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005928 final long identity = Binder.clearCallingIdentity();
5929 try {
chen xub97461a2018-10-26 14:17:57 -07005930 TelephonyPermissions
5931 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5932 mApp, phone.getSubId(), "getRadioAccessFamily");
5933 raf = ProxyController.getInstance().getRadioAccessFamily(phoneId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005934 } finally {
5935 Binder.restoreCallingIdentity(identity);
5936 }
chen xub97461a2018-10-26 14:17:57 -07005937 return raf;
Wink Saville5d475dd2014-10-17 15:00:58 -07005938 }
Andrew Leedf14ead2014-10-17 14:22:52 -07005939
5940 @Override
5941 public void enableVideoCalling(boolean enable) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005942 final Phone defaultPhone = getDefaultPhone();
Andrew Leedf14ead2014-10-17 14:22:52 -07005943 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005944
5945 final long identity = Binder.clearCallingIdentity();
5946 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005947 ImsManager.getInstance(defaultPhone.getContext(),
5948 defaultPhone.getPhoneId()).setVtSetting(enable);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005949 } finally {
5950 Binder.restoreCallingIdentity(identity);
5951 }
Andrew Leedf14ead2014-10-17 14:22:52 -07005952 }
5953
5954 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005955 public boolean isVideoCallingEnabled(String callingPackage, String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005956 final Phone defaultPhone = getDefaultPhone();
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005957 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
5958 callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
Amit Mahajan578e53d2018-03-20 16:18:38 +00005959 return false;
5960 }
Svet Ganovb320e182015-04-16 12:30:10 -07005961
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005962 final long identity = Binder.clearCallingIdentity();
5963 try {
5964 // Check the user preference and the system-level IMS setting. Even if the user has
5965 // enabled video calling, if IMS is disabled we aren't able to support video calling.
5966 // In the long run, we may instead need to check if there exists a connection service
5967 // which can support video calling.
5968 ImsManager imsManager =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005969 ImsManager.getInstance(defaultPhone.getContext(), defaultPhone.getPhoneId());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005970 return imsManager.isVtEnabledByPlatform()
5971 && imsManager.isEnhanced4gLteModeSettingEnabledByUser()
5972 && imsManager.isVtEnabledByUser();
5973 } finally {
5974 Binder.restoreCallingIdentity(identity);
5975 }
Andrew Leedf14ead2014-10-17 14:22:52 -07005976 }
Libin.Tang@motorola.comafe82642014-12-18 13:27:53 -06005977
Andrew Leea1239f22015-03-02 17:44:07 -08005978 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005979 public boolean canChangeDtmfToneLength(int subId, String callingPackage,
5980 String callingFeatureId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005981 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005982 mApp, subId, callingPackage, callingFeatureId,
5983 "isVideoCallingEnabled")) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005984 return false;
5985 }
5986
5987 final long identity = Binder.clearCallingIdentity();
5988 try {
5989 CarrierConfigManager configManager =
5990 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005991 return configManager.getConfigForSubId(subId)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005992 .getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL);
5993 } finally {
5994 Binder.restoreCallingIdentity(identity);
5995 }
Andrew Leea1239f22015-03-02 17:44:07 -08005996 }
5997
5998 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005999 public boolean isWorldPhone(int subId, String callingPackage, String callingFeatureId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006000 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006001 mApp, subId, callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006002 return false;
6003 }
6004
6005 final long identity = Binder.clearCallingIdentity();
6006 try {
6007 CarrierConfigManager configManager =
6008 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006009 return configManager.getConfigForSubId(subId)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006010 .getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL);
6011 } finally {
6012 Binder.restoreCallingIdentity(identity);
6013 }
Andrew Leea1239f22015-03-02 17:44:07 -08006014 }
6015
Andrew Lee9431b832015-03-09 18:46:45 -07006016 @Override
6017 public boolean isTtyModeSupported() {
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07006018 TelecomManager telecomManager = mApp.getSystemService(TelecomManager.class);
Wooki Wu1f82f7a2016-02-15 15:59:58 +08006019 return telecomManager.isTtySupported();
Andrew Lee9431b832015-03-09 18:46:45 -07006020 }
6021
6022 @Override
6023 public boolean isHearingAidCompatibilitySupported() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006024 final long identity = Binder.clearCallingIdentity();
6025 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006026 return mApp.getResources().getBoolean(R.bool.hac_enabled);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006027 } finally {
6028 Binder.restoreCallingIdentity(identity);
6029 }
Andrew Lee9431b832015-03-09 18:46:45 -07006030 }
6031
Hall Liuf6668912018-10-31 17:05:23 -07006032 /**
6033 * Determines whether the device currently supports RTT (Real-time text). Based both on carrier
6034 * support for the feature and device firmware support.
6035 *
6036 * @return {@code true} if the device and carrier both support RTT, {@code false} otherwise.
6037 */
6038 @Override
6039 public boolean isRttSupported(int subscriptionId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006040 final long identity = Binder.clearCallingIdentity();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006041 final Phone phone = getPhone(subscriptionId);
6042 if (phone == null) {
6043 loge("isRttSupported: no Phone found. Invalid subId:" + subscriptionId);
6044 return false;
6045 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006046 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006047 boolean isCarrierSupported = mApp.getCarrierConfigForSubId(subscriptionId).getBoolean(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006048 CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
6049 boolean isDeviceSupported =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006050 phone.getContext().getResources().getBoolean(R.bool.config_support_rtt);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006051 return isCarrierSupported && isDeviceSupported;
6052 } finally {
6053 Binder.restoreCallingIdentity(identity);
6054 }
Hall Liu98187582018-01-22 19:15:32 -08006055 }
6056
Hall Liuf6668912018-10-31 17:05:23 -07006057 /**
Hall Liuf2daa022019-07-23 18:39:00 -07006058 * Determines whether the user has turned on RTT. If the carrier wants to ignore the user-set
6059 * RTT setting, will return true if the device and carrier both support RTT.
6060 * Otherwise. only returns true if the device and carrier both also support RTT.
Hall Liuf6668912018-10-31 17:05:23 -07006061 */
6062 public boolean isRttEnabled(int subscriptionId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006063 final long identity = Binder.clearCallingIdentity();
6064 try {
Hall Liu5bab75c2019-12-11 23:58:20 +00006065 boolean isRttSupported = isRttSupported(subscriptionId);
6066 boolean isUserRttSettingOn = Settings.Secure.getInt(
6067 mApp.getContentResolver(), Settings.Secure.RTT_CALLING_MODE, 0) != 0;
6068 boolean shouldIgnoreUserRttSetting = mApp.getCarrierConfigForSubId(subscriptionId)
6069 .getBoolean(CarrierConfigManager.KEY_IGNORE_RTT_MODE_SETTING_BOOL);
6070 return isRttSupported && (isUserRttSettingOn || shouldIgnoreUserRttSetting);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006071 } finally {
6072 Binder.restoreCallingIdentity(identity);
6073 }
Hall Liu3ad5f012018-04-06 16:23:39 -07006074 }
6075
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006076 @Deprecated
6077 @Override
6078 public String getDeviceId(String callingPackage) {
6079 return getDeviceIdWithFeature(callingPackage, null);
6080 }
6081
Sanket Padawe7310cc72015-01-14 09:53:20 -08006082 /**
6083 * Returns the unique device ID of phone, for example, the IMEI for
6084 * GSM and the MEID for CDMA phones. Return null if device ID is not available.
6085 *
6086 * <p>Requires Permission:
6087 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
6088 */
6089 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006090 public String getDeviceIdWithFeature(String callingPackage, String callingFeatureId) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08006091 final Phone phone = PhoneFactory.getPhone(0);
Jeff Davidson913390f2018-02-23 17:11:49 -08006092 if (phone == null) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08006093 return null;
6094 }
Jeff Davidson913390f2018-02-23 17:11:49 -08006095 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07006096 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006097 callingPackage, callingFeatureId, "getDeviceId")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08006098 return null;
6099 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006100
6101 final long identity = Binder.clearCallingIdentity();
6102 try {
6103 return phone.getDeviceId();
6104 } finally {
6105 Binder.restoreCallingIdentity(identity);
6106 }
Sanket Padawe7310cc72015-01-14 09:53:20 -08006107 }
6108
Ping Sunc67b7c22016-03-02 19:16:45 +08006109 /**
6110 * {@hide}
6111 * Returns the IMS Registration Status on a particular subid
6112 *
6113 * @param subId
6114 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08006115 public boolean isImsRegistered(int subId) {
Ping Sunc67b7c22016-03-02 19:16:45 +08006116 Phone phone = getPhone(subId);
6117 if (phone != null) {
6118 return phone.isImsRegistered();
6119 } else {
6120 return false;
6121 }
6122 }
6123
Santos Cordon7a1885b2015-02-03 11:15:19 -08006124 @Override
6125 public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006126 final long identity = Binder.clearCallingIdentity();
6127 try {
6128 return PhoneUtils.getSubIdForPhoneAccount(phoneAccount);
6129 } finally {
6130 Binder.restoreCallingIdentity(identity);
6131 }
Santos Cordon7a1885b2015-02-03 11:15:19 -08006132 }
Nathan Harolddcfc7932015-03-18 10:01:20 -07006133
Tyler Gunnf70ed162019-04-03 15:28:53 -07006134 @Override
Shuo Qian6e6137d2019-10-30 16:33:31 -07006135 public int getSubIdForPhoneAccountHandle(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006136 PhoneAccountHandle phoneAccountHandle, String callingPackage, String callingFeatureId) {
Shuo Qian6e6137d2019-10-30 16:33:31 -07006137 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, getDefaultSubscription(),
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006138 callingPackage, callingFeatureId, "getSubIdForPhoneAccountHandle")) {
Shuo Qian6e6137d2019-10-30 16:33:31 -07006139 throw new SecurityException("Requires READ_PHONE_STATE permission.");
6140 }
6141 final long identity = Binder.clearCallingIdentity();
6142 try {
6143 return PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle);
6144 } finally {
6145 Binder.restoreCallingIdentity(identity);
6146 }
6147 }
6148
6149 @Override
Tyler Gunnf70ed162019-04-03 15:28:53 -07006150 public @Nullable PhoneAccountHandle getPhoneAccountHandleForSubscriptionId(int subscriptionId) {
6151 final long identity = Binder.clearCallingIdentity();
6152 try {
6153 Phone phone = getPhone(subscriptionId);
6154 if (phone == null) {
6155 return null;
6156 }
6157 return PhoneUtils.makePstnPhoneAccountHandle(phone);
6158 } finally {
6159 Binder.restoreCallingIdentity(identity);
6160 }
6161 }
6162
Brad Ebinger1f2b5082018-02-08 16:11:32 -08006163 /**
6164 * @return the VoWiFi calling availability.
Nathan Haroldc55097a2015-03-11 18:14:50 -07006165 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08006166 public boolean isWifiCallingAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006167 final long identity = Binder.clearCallingIdentity();
6168 try {
6169 Phone phone = getPhone(subId);
6170 if (phone != null) {
6171 return phone.isWifiCallingEnabled();
6172 } else {
6173 return false;
6174 }
6175 } finally {
6176 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08006177 }
Nathan Haroldc55097a2015-03-11 18:14:50 -07006178 }
6179
Brad Ebinger1f2b5082018-02-08 16:11:32 -08006180 /**
Brad Ebinger1f2b5082018-02-08 16:11:32 -08006181 * @return the VT calling availability.
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07006182 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08006183 public boolean isVideoTelephonyAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006184 final long identity = Binder.clearCallingIdentity();
6185 try {
6186 Phone phone = getPhone(subId);
6187 if (phone != null) {
6188 return phone.isVideoEnabled();
6189 } else {
6190 return false;
6191 }
6192 } finally {
6193 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08006194 }
6195 }
6196
6197 /**
6198 * @return the IMS registration technology for the MMTEL feature. Valid return values are
6199 * defined in {@link ImsRegistrationImplBase}.
6200 */
6201 public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006202 final long identity = Binder.clearCallingIdentity();
6203 try {
6204 Phone phone = getPhone(subId);
6205 if (phone != null) {
6206 return phone.getImsRegistrationTech();
6207 } else {
6208 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
6209 }
6210 } finally {
6211 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08006212 }
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07006213 }
6214
Stuart Scott8eef64f2015-04-08 15:13:54 -07006215 @Override
6216 public void factoryReset(int subId) {
paulhu5a773602019-08-23 19:17:33 +08006217 enforceSettingsPermission();
Stuart Scott981d8582015-04-21 14:09:50 -07006218 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
6219 return;
6220 }
6221
Svet Ganovcc087f82015-05-12 20:35:54 -07006222 final long identity = Binder.clearCallingIdentity();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006223
Svet Ganovcc087f82015-05-12 20:35:54 -07006224 try {
Stuart Scott981d8582015-04-21 14:09:50 -07006225 if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
6226 UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
Pengquan Meng85728fb2018-03-12 16:31:21 -07006227 setUserDataEnabled(subId, getDefaultDataEnabled());
Svet Ganovcc087f82015-05-12 20:35:54 -07006228 setNetworkSelectionModeAutomatic(subId);
Pengquan Meng85728fb2018-03-12 16:31:21 -07006229 setPreferredNetworkType(subId, getDefaultNetworkType(subId));
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006230 setDataRoamingEnabled(subId, getDefaultDataRoamingEnabled(subId));
6231 CarrierInfoManager.deleteAllCarrierKeysForImsiEncryption(mApp);
Svet Ganovcc087f82015-05-12 20:35:54 -07006232 }
Amit Mahajan7dbbd822019-03-13 17:33:47 -07006233 // There has been issues when Sms raw table somehow stores orphan
6234 // fragments. They lead to garbled message when new fragments come
6235 // in and combined with those stale ones. In case this happens again,
6236 // user can reset all network settings which will clean up this table.
6237 cleanUpSmsRawTable(getDefaultPhone().getContext());
Brad Ebingerbc7dd582019-10-17 17:03:22 -07006238 // Clean up IMS settings as well here.
6239 int slotId = getSlotIndex(subId);
6240 if (slotId > SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
6241 ImsManager.getInstance(mApp, slotId).factoryReset();
6242 }
Naina Nallurid63128d2019-09-17 14:10:30 -07006243
6244 // Erase modem config if erase modem on network setting is enabled.
6245 String configValue = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_TELEPHONY,
6246 RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED);
6247 if (configValue != null && Boolean.parseBoolean(configValue)) {
6248 sendEraseModemConfig(getDefaultPhone());
6249 }
Svet Ganovcc087f82015-05-12 20:35:54 -07006250 } finally {
6251 Binder.restoreCallingIdentity(identity);
Stuart Scott8eef64f2015-04-08 15:13:54 -07006252 }
6253 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01006254
Amit Mahajan7dbbd822019-03-13 17:33:47 -07006255 private void cleanUpSmsRawTable(Context context) {
6256 ContentResolver resolver = context.getContentResolver();
6257 Uri uri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete");
6258 resolver.delete(uri, null, null);
6259 }
6260
Narayan Kamath1c496c22015-04-16 14:40:19 +01006261 @Override
chen xu5d3637b2019-01-21 23:31:38 -08006262 public String getSimLocaleForSubscriber(int subId) {
6263 enforceReadPrivilegedPermission("getSimLocaleForSubscriber, subId: " + subId);
6264 final Phone phone = getPhone(subId);
6265 if (phone == null) {
6266 log("getSimLocaleForSubscriber, invalid subId");
chen xu2bb91e42019-01-24 14:35:54 -08006267 return null;
chen xu5d3637b2019-01-21 23:31:38 -08006268 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006269 final long identity = Binder.clearCallingIdentity();
6270 try {
chen xu5d3637b2019-01-21 23:31:38 -08006271 final SubscriptionInfo info = mSubscriptionController.getActiveSubscriptionInfo(subId,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006272 phone.getContext().getOpPackageName(), phone.getContext().getFeatureId());
chen xu6291c472019-02-04 12:55:53 -08006273 if (info == null) {
6274 log("getSimLocaleForSubscriber, inactive subId: " + subId);
6275 return null;
6276 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006277 // Try and fetch the locale from the carrier properties or from the SIM language
6278 // preferences (EF-PL and EF-LI)...
6279 final int mcc = info.getMcc();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006280 String simLanguage = null;
chen xu5d3637b2019-01-21 23:31:38 -08006281 final Locale localeFromDefaultSim = phone.getLocaleFromSimAndCarrierPrefs();
6282 if (localeFromDefaultSim != null) {
6283 if (!localeFromDefaultSim.getCountry().isEmpty()) {
6284 if (DBG) log("Using locale from subId: " + subId + " locale: "
6285 + localeFromDefaultSim);
6286 return localeFromDefaultSim.toLanguageTag();
6287 } else {
6288 simLanguage = localeFromDefaultSim.getLanguage();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006289 }
6290 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01006291
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006292 // The SIM language preferences only store a language (e.g. fr = French), not an
6293 // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
6294 // the SIM and carrier preferences does not include a country we add the country
6295 // determined from the SIM MCC to provide an exact locale.
zoey chenc730df82019-12-18 17:07:20 +08006296 final Locale mccLocale = LocaleUtils.getLocaleFromMcc(mApp, mcc, simLanguage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006297 if (mccLocale != null) {
chen xu5d3637b2019-01-21 23:31:38 -08006298 if (DBG) log("No locale from SIM, using mcc locale:" + mccLocale);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006299 return mccLocale.toLanguageTag();
6300 }
6301
6302 if (DBG) log("No locale found - returning null");
6303 return null;
6304 } finally {
6305 Binder.restoreCallingIdentity(identity);
6306 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01006307 }
6308
6309 private List<SubscriptionInfo> getAllSubscriptionInfoList() {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006310 return mSubscriptionController.getAllSubInfoList(mApp.getOpPackageName(),
6311 mApp.getFeatureId());
Narayan Kamath1c496c22015-04-16 14:40:19 +01006312 }
6313
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006314 /**
6315 * NOTE: this method assumes permission checks are done and caller identity has been cleared.
6316 */
6317 private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006318 return mSubscriptionController.getActiveSubscriptionInfoList(mApp.getOpPackageName(),
6319 mApp.getFeatureId());
Narayan Kamath1c496c22015-04-16 14:40:19 +01006320 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07006321
Chenjie Yu1ba97252018-01-11 18:16:20 -08006322 private final ModemActivityInfo mLastModemActivityInfo =
Chen Xud78231e2019-09-10 18:49:52 -07006323 new ModemActivityInfo(0, 0, 0, new int[0], 0);
Chenjie Yu1ba97252018-01-11 18:16:20 -08006324
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07006325 /**
Adam Lesinski903a54c2016-04-11 14:49:52 -07006326 * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
6327 * representing the state of the modem.
6328 *
Chenjie Yu1ba97252018-01-11 18:16:20 -08006329 * NOTE: The underlying implementation clears the modem state, so there should only ever be one
6330 * caller to it. Everyone should call this class to get cumulative data.
Adam Lesinski903a54c2016-04-11 14:49:52 -07006331 * @hide
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07006332 */
6333 @Override
Adam Lesinski903a54c2016-04-11 14:49:52 -07006334 public void requestModemActivityInfo(ResultReceiver result) {
6335 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07006336 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006337
6338 final long identity = Binder.clearCallingIdentity();
6339 try {
6340 ModemActivityInfo ret = null;
6341 synchronized (mLastModemActivityInfo) {
6342 ModemActivityInfo info = (ModemActivityInfo) sendRequest(
6343 CMD_GET_MODEM_ACTIVITY_INFO,
vagdeviaf9a5b92018-08-15 16:01:53 -07006344 null, workSource);
Siddharth Rayb8114062018-06-17 15:02:38 -07006345 if (isModemActivityInfoValid(info)) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006346 int[] mergedTxTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
Chen Xud78231e2019-09-10 18:49:52 -07006347 int[] txTimeMs = info.getTransmitTimeMillis();
6348 int[] lastModemTxTimeMs = mLastModemActivityInfo.getTransmitTimeMillis();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006349 for (int i = 0; i < mergedTxTimeMs.length; i++) {
Chen Xud78231e2019-09-10 18:49:52 -07006350 mergedTxTimeMs[i] = txTimeMs[i] + lastModemTxTimeMs[i];
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006351 }
6352 mLastModemActivityInfo.setTimestamp(info.getTimestamp());
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006353 mLastModemActivityInfo.setSleepTimeMillis(info.getSleepTimeMillis()
6354 + mLastModemActivityInfo.getSleepTimeMillis());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006355 mLastModemActivityInfo.setIdleTimeMillis(
6356 info.getIdleTimeMillis() + mLastModemActivityInfo.getIdleTimeMillis());
Chen Xud78231e2019-09-10 18:49:52 -07006357 mLastModemActivityInfo.setTransmitTimeMillis(mergedTxTimeMs);
6358 mLastModemActivityInfo.setReceiveTimeMillis(
6359 info.getReceiveTimeMillis() + mLastModemActivityInfo
6360 .getReceiveTimeMillis());
Chenjie Yu1ba97252018-01-11 18:16:20 -08006361 }
Chen Xud78231e2019-09-10 18:49:52 -07006362
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006363 ret = new ModemActivityInfo(mLastModemActivityInfo.getTimestamp(),
6364 mLastModemActivityInfo.getSleepTimeMillis(),
6365 mLastModemActivityInfo.getIdleTimeMillis(),
Chen Xud78231e2019-09-10 18:49:52 -07006366 mLastModemActivityInfo.getTransmitTimeMillis(),
6367 mLastModemActivityInfo.getReceiveTimeMillis());
Chenjie Yu1ba97252018-01-11 18:16:20 -08006368 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006369 Bundle bundle = new Bundle();
6370 bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, ret);
6371 result.send(0, bundle);
6372 } finally {
6373 Binder.restoreCallingIdentity(identity);
Chenjie Yu1ba97252018-01-11 18:16:20 -08006374 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07006375 }
Jack Yu85bd38a2015-11-09 11:34:32 -08006376
Siddharth Rayb8114062018-06-17 15:02:38 -07006377 // Checks that ModemActivityInfo is valid. Sleep time, Idle time, Rx time and Tx time should be
6378 // less than total activity duration.
6379 private boolean isModemActivityInfoValid(ModemActivityInfo info) {
6380 if (info == null) {
6381 return false;
6382 }
6383 int activityDurationMs =
6384 (int) (info.getTimestamp() - mLastModemActivityInfo.getTimestamp());
6385 int totalTxTimeMs = 0;
Chen Xud78231e2019-09-10 18:49:52 -07006386 int[] txTimeMs = info.getTransmitTimeMillis();
6387 for (int i = 0; i < info.getTransmitPowerInfo().size(); i++) {
6388 totalTxTimeMs += txTimeMs[i];
Siddharth Rayb8114062018-06-17 15:02:38 -07006389 }
6390 return (info.isValid()
6391 && (info.getSleepTimeMillis() <= activityDurationMs)
6392 && (info.getIdleTimeMillis() <= activityDurationMs)
Chen Xud78231e2019-09-10 18:49:52 -07006393 && (info.getReceiveTimeMillis() <= activityDurationMs)
Siddharth Rayb8114062018-06-17 15:02:38 -07006394 && (totalTxTimeMs <= activityDurationMs));
6395 }
6396
Jack Yu85bd38a2015-11-09 11:34:32 -08006397 /**
6398 * {@hide}
6399 * Returns the service state information on specified subscription.
6400 */
6401 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07006402 public ServiceState getServiceStateForSubscriber(int subId, String callingPackage,
6403 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006404 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006405 mApp, subId, callingPackage, callingFeatureId, "getServiceStateForSubscriber")) {
Jack Yu85bd38a2015-11-09 11:34:32 -08006406 return null;
6407 }
6408
Hall Liuf19c44f2018-11-27 14:38:17 -08006409 LocationAccessPolicy.LocationPermissionResult fineLocationResult =
6410 LocationAccessPolicy.checkLocationPermission(mApp,
6411 new LocationAccessPolicy.LocationPermissionQuery.Builder()
6412 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07006413 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08006414 .setCallingPid(Binder.getCallingPid())
6415 .setCallingUid(Binder.getCallingUid())
6416 .setMethod("getServiceStateForSubscriber")
Hall Liuf18a0cf2019-04-17 13:37:11 -07006417 .setLogAsInfo(true)
Hall Liuf19c44f2018-11-27 14:38:17 -08006418 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
6419 .build());
6420
6421 LocationAccessPolicy.LocationPermissionResult coarseLocationResult =
6422 LocationAccessPolicy.checkLocationPermission(mApp,
6423 new LocationAccessPolicy.LocationPermissionQuery.Builder()
6424 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07006425 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08006426 .setCallingPid(Binder.getCallingPid())
6427 .setCallingUid(Binder.getCallingUid())
6428 .setMethod("getServiceStateForSubscriber")
Hall Liuf18a0cf2019-04-17 13:37:11 -07006429 .setLogAsInfo(true)
Hall Liuf19c44f2018-11-27 14:38:17 -08006430 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
6431 .build());
6432 // We don't care about hard or soft here -- all we need to know is how much info to scrub.
6433 boolean hasFinePermission =
6434 fineLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
6435 boolean hasCoarsePermission =
6436 coarseLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
6437
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006438 final long identity = Binder.clearCallingIdentity();
6439 try {
6440 final Phone phone = getPhone(subId);
6441 if (phone == null) {
6442 return null;
6443 }
Jack Yu85bd38a2015-11-09 11:34:32 -08006444
Hall Liuf19c44f2018-11-27 14:38:17 -08006445 ServiceState ss = phone.getServiceState();
6446
6447 // Scrub out the location info in ServiceState depending on what level of access
6448 // the caller has.
6449 if (hasFinePermission) return ss;
Malcolm Chen5052de62019-12-30 13:56:38 -08006450 if (hasCoarsePermission) return ss.createLocationInfoSanitizedCopy(false);
6451 return ss.createLocationInfoSanitizedCopy(true);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006452 } finally {
6453 Binder.restoreCallingIdentity(identity);
6454 }
Jack Yu85bd38a2015-11-09 11:34:32 -08006455 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08006456
6457 /**
6458 * Returns the URI for the per-account voicemail ringtone set in Phone settings.
6459 *
6460 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
6461 * voicemail ringtone.
6462 * @return The URI for the ringtone to play when receiving a voicemail from a specific
6463 * PhoneAccount.
6464 */
6465 @Override
6466 public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006467 final long identity = Binder.clearCallingIdentity();
6468 try {
6469 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
6470 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006471 phone = getDefaultPhone();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006472 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08006473
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006474 return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext());
6475 } finally {
6476 Binder.restoreCallingIdentity(identity);
6477 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08006478 }
6479
6480 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08006481 * Sets the per-account voicemail ringtone.
6482 *
6483 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
6484 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
6485 *
6486 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
6487 * voicemail ringtone.
6488 * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
6489 * PhoneAccount.
6490 */
6491 @Override
6492 public void setVoicemailRingtoneUri(String callingPackage,
6493 PhoneAccountHandle phoneAccountHandle, Uri uri) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006494 final Phone defaultPhone = getDefaultPhone();
Ta-wei Yenc33877d2017-01-23 18:11:21 -08006495 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07006496 TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
6497 if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006498 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6499 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
6500 "setVoicemailRingtoneUri");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08006501 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006502
6503 final long identity = Binder.clearCallingIdentity();
6504 try {
6505 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
6506 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006507 phone = defaultPhone;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006508 }
6509 VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri);
6510 } finally {
6511 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08006512 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08006513 }
6514
6515 /**
Nancy Chen31f9ba12016-01-06 11:42:12 -08006516 * Returns whether vibration is set for voicemail notification in Phone settings.
6517 *
6518 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
6519 * voicemail vibration setting.
6520 * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
6521 */
6522 @Override
6523 public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006524 final long identity = Binder.clearCallingIdentity();
6525 try {
6526 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
6527 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006528 phone = getDefaultPhone();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006529 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08006530
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006531 return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext());
6532 } finally {
6533 Binder.restoreCallingIdentity(identity);
6534 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08006535 }
6536
Youhan Wange64578a2016-05-02 15:32:42 -07006537 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08006538 * Sets the per-account voicemail vibration.
6539 *
6540 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
6541 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
6542 *
6543 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
6544 * voicemail vibration setting.
6545 * @param enabled Whether to enable or disable vibration for voicemail notifications from a
6546 * specific PhoneAccount.
6547 */
6548 @Override
6549 public void setVoicemailVibrationEnabled(String callingPackage,
6550 PhoneAccountHandle phoneAccountHandle, boolean enabled) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006551 final Phone defaultPhone = getDefaultPhone();
Ta-wei Yenc33877d2017-01-23 18:11:21 -08006552 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07006553 TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
6554 if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006555 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6556 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
6557 "setVoicemailVibrationEnabled");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08006558 }
6559
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006560 final long identity = Binder.clearCallingIdentity();
6561 try {
6562 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
6563 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006564 phone = defaultPhone;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006565 }
6566 VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled);
6567 } finally {
6568 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08006569 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08006570 }
6571
6572 /**
Youhan Wange64578a2016-05-02 15:32:42 -07006573 * Make sure either called from same process as self (phone) or IPC caller has read privilege.
6574 *
6575 * @throws SecurityException if the caller does not have the required permission
6576 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07006577 private void enforceReadPrivilegedPermission(String message) {
Youhan Wange64578a2016-05-02 15:32:42 -07006578 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
Brad Ebinger35c841c2018-10-01 10:40:55 -07006579 message);
Youhan Wange64578a2016-05-02 15:32:42 -07006580 }
6581
6582 /**
Ta-wei Yen30a69c82016-12-27 14:52:32 -08006583 * Make sure either called from same process as self (phone) or IPC caller has send SMS
6584 * permission.
6585 *
6586 * @throws SecurityException if the caller does not have the required permission
6587 */
6588 private void enforceSendSmsPermission() {
6589 mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null);
6590 }
6591
6592 /**
Ta-wei Yen527a9c02017-01-06 15:29:25 -08006593 * Make sure called from the package in charge of visual voicemail.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08006594 *
Ta-wei Yen527a9c02017-01-06 15:29:25 -08006595 * @throws SecurityException if the caller is not the visual voicemail package.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08006596 */
Ta-wei Yen527a9c02017-01-06 15:29:25 -08006597 private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006598 final long identity = Binder.clearCallingIdentity();
6599 try {
6600 ComponentName componentName =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006601 RemoteVvmTaskManager.getRemotePackage(mApp, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006602 if (componentName == null) {
6603 throw new SecurityException(
6604 "Caller not current active visual voicemail package[null]");
6605 }
6606 String vvmPackage = componentName.getPackageName();
6607 if (!callingPackage.equals(vvmPackage)) {
6608 throw new SecurityException("Caller not current active visual voicemail package["
6609 + vvmPackage + "]");
6610 }
6611 } finally {
6612 Binder.restoreCallingIdentity(identity);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08006613 }
6614 }
6615
6616 /**
Youhan Wange64578a2016-05-02 15:32:42 -07006617 * Return the application ID for the app type.
6618 *
6619 * @param subId the subscription ID that this request applies to.
6620 * @param appType the uicc app type.
6621 * @return Application ID for specificied app type, or null if no uicc.
6622 */
6623 @Override
6624 public String getAidForAppType(int subId, int appType) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07006625 enforceReadPrivilegedPermission("getAidForAppType");
Youhan Wange64578a2016-05-02 15:32:42 -07006626 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006627
6628 final long identity = Binder.clearCallingIdentity();
Youhan Wange64578a2016-05-02 15:32:42 -07006629 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006630 if (phone == null) {
6631 return null;
6632 }
6633 String aid = null;
6634 try {
6635 aid = UiccController.getInstance().getUiccCard(phone.getPhoneId())
6636 .getApplicationByType(appType).getAid();
6637 } catch (Exception e) {
6638 Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e);
6639 }
6640 return aid;
6641 } finally {
6642 Binder.restoreCallingIdentity(identity);
Youhan Wange64578a2016-05-02 15:32:42 -07006643 }
Youhan Wange64578a2016-05-02 15:32:42 -07006644 }
6645
Youhan Wang4001d252016-05-11 10:29:41 -07006646 /**
6647 * Return the Electronic Serial Number.
6648 *
6649 * @param subId the subscription ID that this request applies to.
6650 * @return ESN or null if error.
6651 */
6652 @Override
6653 public String getEsn(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07006654 enforceReadPrivilegedPermission("getEsn");
Youhan Wang4001d252016-05-11 10:29:41 -07006655 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006656
6657 final long identity = Binder.clearCallingIdentity();
Youhan Wang4001d252016-05-11 10:29:41 -07006658 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006659 if (phone == null) {
6660 return null;
6661 }
6662 String esn = null;
6663 try {
6664 esn = phone.getEsn();
6665 } catch (Exception e) {
6666 Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e);
6667 }
6668 return esn;
6669 } finally {
6670 Binder.restoreCallingIdentity(identity);
Youhan Wang4001d252016-05-11 10:29:41 -07006671 }
Youhan Wang4001d252016-05-11 10:29:41 -07006672 }
6673
Sanket Padawe99ef1e32016-05-18 16:12:33 -07006674 /**
Youhan Wang66ad5d72016-07-18 17:56:58 -07006675 * Return the Preferred Roaming List Version.
6676 *
6677 * @param subId the subscription ID that this request applies to.
6678 * @return PRLVersion or null if error.
6679 */
6680 @Override
6681 public String getCdmaPrlVersion(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07006682 enforceReadPrivilegedPermission("getCdmaPrlVersion");
Youhan Wang66ad5d72016-07-18 17:56:58 -07006683 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006684
6685 final long identity = Binder.clearCallingIdentity();
Youhan Wang66ad5d72016-07-18 17:56:58 -07006686 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006687 if (phone == null) {
6688 return null;
6689 }
6690 String cdmaPrlVersion = null;
6691 try {
6692 cdmaPrlVersion = phone.getCdmaPrlVersion();
6693 } catch (Exception e) {
6694 Log.e(LOG_TAG, "Not getting PRLVersion", e);
6695 }
6696 return cdmaPrlVersion;
6697 } finally {
6698 Binder.restoreCallingIdentity(identity);
Youhan Wang66ad5d72016-07-18 17:56:58 -07006699 }
Youhan Wang66ad5d72016-07-18 17:56:58 -07006700 }
6701
6702 /**
Sanket Padawe99ef1e32016-05-18 16:12:33 -07006703 * Get snapshot of Telephony histograms
6704 * @return List of Telephony histograms
6705 * @hide
6706 */
6707 @Override
6708 public List<TelephonyHistogram> getTelephonyHistograms() {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006709 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6710 mApp, getDefaultSubscription(), "getTelephonyHistograms");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006711
6712 final long identity = Binder.clearCallingIdentity();
6713 try {
6714 return RIL.getTelephonyRILTimingHistograms();
6715 } finally {
6716 Binder.restoreCallingIdentity(identity);
6717 }
Sanket Padawe99ef1e32016-05-18 16:12:33 -07006718 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07006719
6720 /**
6721 * {@hide}
Michele Berionne482f8202018-11-27 18:57:59 -08006722 * Set the allowed carrier list and the excluded carrier list, indicating the priority between
6723 * the two lists.
Meng Wang1a7c35a2016-05-05 20:56:15 -07006724 * Require system privileges. In the future we may add this to carrier APIs.
6725 *
Michele Berionne482f8202018-11-27 18:57:59 -08006726 * @return Integer with the result of the operation, as defined in {@link TelephonyManager}.
Meng Wang1a7c35a2016-05-05 20:56:15 -07006727 */
6728 @Override
Michele Berionne482f8202018-11-27 18:57:59 -08006729 @TelephonyManager.SetCarrierRestrictionResult
6730 public int setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules) {
Meng Wang1a7c35a2016-05-05 20:56:15 -07006731 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07006732 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Sanket Padawe13bac7b2017-03-20 15:04:47 -07006733
Michele Berionne482f8202018-11-27 18:57:59 -08006734 if (carrierRestrictionRules == null) {
6735 throw new NullPointerException("carrier restriction cannot be null");
Meng Wang9b7c4e92017-02-17 11:41:27 -08006736 }
Sanket Padawe13bac7b2017-03-20 15:04:47 -07006737
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006738 final long identity = Binder.clearCallingIdentity();
6739 try {
Michele Berionne482f8202018-11-27 18:57:59 -08006740 return (int) sendRequest(CMD_SET_ALLOWED_CARRIERS, carrierRestrictionRules,
vagdeviaf9a5b92018-08-15 16:01:53 -07006741 workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006742 } finally {
6743 Binder.restoreCallingIdentity(identity);
6744 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07006745 }
6746
6747 /**
6748 * {@hide}
Michele Berionne482f8202018-11-27 18:57:59 -08006749 * Get the allowed carrier list and the excluded carrier list, including the priority between
6750 * the two lists.
Meng Wang1a7c35a2016-05-05 20:56:15 -07006751 * Require system privileges. In the future we may add this to carrier APIs.
6752 *
Michele Berionne482f8202018-11-27 18:57:59 -08006753 * @return {@link android.telephony.CarrierRestrictionRules}
Meng Wang1a7c35a2016-05-05 20:56:15 -07006754 */
6755 @Override
Michele Berionne482f8202018-11-27 18:57:59 -08006756 public CarrierRestrictionRules getAllowedCarriers() {
Brad Ebinger35c841c2018-10-01 10:40:55 -07006757 enforceReadPrivilegedPermission("getAllowedCarriers");
vagdeviaf9a5b92018-08-15 16:01:53 -07006758 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006759
6760 final long identity = Binder.clearCallingIdentity();
6761 try {
Michele Berionne482f8202018-11-27 18:57:59 -08006762 Object response = sendRequest(CMD_GET_ALLOWED_CARRIERS, null, workSource);
6763 if (response instanceof CarrierRestrictionRules) {
6764 return (CarrierRestrictionRules) response;
6765 }
6766 // Response is an Exception of some kind,
6767 // which is signalled to the user as a NULL retval
6768 return null;
6769 } catch (Exception e) {
6770 Log.e(LOG_TAG, "getAllowedCarriers. Exception ex=" + e);
6771 return null;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006772 } finally {
6773 Binder.restoreCallingIdentity(identity);
6774 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07006775 }
6776
fionaxu59545b42016-05-25 15:53:37 -07006777 /**
6778 * Action set from carrier signalling broadcast receivers to enable/disable metered apns
6779 * @param subId the subscription ID that this action applies to.
6780 * @param enabled control enable or disable metered apns.
6781 * {@hide}
6782 */
6783 @Override
6784 public void carrierActionSetMeteredApnsEnabled(int subId, boolean enabled) {
6785 enforceModifyPermission();
6786 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006787
6788 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07006789 if (phone == null) {
6790 loge("carrierAction: SetMeteredApnsEnabled fails with invalid subId: " + subId);
6791 return;
6792 }
6793 try {
6794 phone.carrierActionSetMeteredApnsEnabled(enabled);
6795 } catch (Exception e) {
6796 Log.e(LOG_TAG, "carrierAction: SetMeteredApnsEnabled fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006797 } finally {
6798 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07006799 }
6800 }
6801
6802 /**
6803 * Action set from carrier signalling broadcast receivers to enable/disable radio
6804 * @param subId the subscription ID that this action applies to.
6805 * @param enabled control enable or disable radio.
6806 * {@hide}
6807 */
6808 @Override
6809 public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
6810 enforceModifyPermission();
6811 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006812
6813 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07006814 if (phone == null) {
6815 loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
6816 return;
6817 }
6818 try {
6819 phone.carrierActionSetRadioEnabled(enabled);
6820 } catch (Exception e) {
6821 Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006822 } finally {
6823 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07006824 }
6825 }
6826
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07006827 /**
fionaxu8da9cb12017-05-23 15:02:46 -07006828 * Action set from carrier signalling broadcast receivers to start/stop reporting the default
6829 * network status based on which carrier apps could apply actions accordingly,
6830 * enable/disable default url handler for example.
6831 *
6832 * @param subId the subscription ID that this action applies to.
6833 * @param report control start/stop reporting the default network status.
6834 * {@hide}
6835 */
6836 @Override
6837 public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
6838 enforceModifyPermission();
6839 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006840
6841 final long identity = Binder.clearCallingIdentity();
fionaxu8da9cb12017-05-23 15:02:46 -07006842 if (phone == null) {
6843 loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId);
6844 return;
6845 }
6846 try {
6847 phone.carrierActionReportDefaultNetworkStatus(report);
6848 } catch (Exception e) {
6849 Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006850 } finally {
6851 Binder.restoreCallingIdentity(identity);
fionaxu8da9cb12017-05-23 15:02:46 -07006852 }
6853 }
6854
6855 /**
fionaxud9622282017-07-17 17:51:30 -07006856 * Action set from carrier signalling broadcast receivers to reset all carrier actions
6857 * @param subId the subscription ID that this action applies to.
6858 * {@hide}
6859 */
6860 @Override
6861 public void carrierActionResetAll(int subId) {
6862 enforceModifyPermission();
6863 final Phone phone = getPhone(subId);
6864 if (phone == null) {
6865 loge("carrierAction: ResetAll fails with invalid sibId: " + subId);
6866 return;
6867 }
6868 try {
6869 phone.carrierActionResetAll();
6870 } catch (Exception e) {
6871 Log.e(LOG_TAG, "carrierAction: ResetAll fails. Exception ex=" + e);
6872 }
6873 }
6874
6875 /**
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07006876 * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a
6877 * bug report is being generated.
6878 */
6879 @Override
Ta-wei Yen99282e02016-06-21 18:19:35 -07006880 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006881 if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
6882 != PackageManager.PERMISSION_GRANTED) {
dcashman22b950d2016-06-27 11:39:02 -07006883 writer.println("Permission Denial: can't dump Phone from pid="
6884 + Binder.getCallingPid()
6885 + ", uid=" + Binder.getCallingUid()
6886 + "without permission "
6887 + android.Manifest.permission.DUMP);
6888 return;
6889 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006890 DumpsysHandler.dump(mApp, fd, writer, args);
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07006891 }
Jack Yueb89b242016-06-22 13:27:47 -07006892
Brad Ebingerdac2f002018-04-03 15:17:52 -07006893 @Override
Hall Liua1548bd2019-12-24 14:14:12 -08006894 public int handleShellCommand(@NonNull ParcelFileDescriptor in,
6895 @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
6896 @NonNull String[] args) {
6897 return new TelephonyShellCommand(this, getDefaultPhone().getContext()).exec(
6898 this, in.getFileDescriptor(), out.getFileDescriptor(),
6899 err.getFileDescriptor(), args);
Brad Ebingerdac2f002018-04-03 15:17:52 -07006900 }
6901
Jack Yueb89b242016-06-22 13:27:47 -07006902 /**
Jack Yu84291ec2017-05-26 16:07:50 -07006903 * Get aggregated video call data usage since boot.
6904 *
6905 * @param perUidStats True if requesting data usage per uid, otherwise overall usage.
6906 * @return Snapshot of video call data usage
Jack Yueb89b242016-06-22 13:27:47 -07006907 * {@hide}
6908 */
6909 @Override
Jack Yu84291ec2017-05-26 16:07:50 -07006910 public NetworkStats getVtDataUsage(int subId, boolean perUidStats) {
Jack Yueb89b242016-06-22 13:27:47 -07006911 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_NETWORK_USAGE_HISTORY,
6912 null);
6913
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006914 final long identity = Binder.clearCallingIdentity();
6915 try {
6916 // NetworkStatsService keeps tracking the active network interface and identity. It
6917 // records the delta with the corresponding network identity.
6918 // We just return the total video call data usage snapshot since boot.
6919 Phone phone = getPhone(subId);
6920 if (phone != null) {
6921 return phone.getVtDataUsage(perUidStats);
6922 }
6923 return null;
6924 } finally {
6925 Binder.restoreCallingIdentity(identity);
Jack Yueb89b242016-06-22 13:27:47 -07006926 }
Jack Yueb89b242016-06-22 13:27:47 -07006927 }
Jack Yu75ab2952016-07-08 14:29:33 -07006928
6929 /**
6930 * Policy control of data connection. Usually used when data limit is passed.
6931 * @param enabled True if enabling the data, otherwise disabling.
6932 * @param subId Subscription index
6933 * {@hide}
6934 */
6935 @Override
6936 public void setPolicyDataEnabled(boolean enabled, int subId) {
6937 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006938
6939 final long identity = Binder.clearCallingIdentity();
6940 try {
6941 Phone phone = getPhone(subId);
6942 if (phone != null) {
Jack Yud79fba22018-12-13 11:51:28 -08006943 phone.getDataEnabledSettings().setPolicyDataEnabled(enabled);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006944 }
6945 } finally {
6946 Binder.restoreCallingIdentity(identity);
Jack Yu75ab2952016-07-08 14:29:33 -07006947 }
6948 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07006949
6950 /**
6951 * Get Client request stats
6952 * @return List of Client Request Stats
6953 * @hide
6954 */
6955 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006956 public List<ClientRequestStats> getClientRequestStats(String callingPackage,
6957 String callingFeatureId, int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006958 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006959 mApp, subId, callingPackage, callingFeatureId, "getClientRequestStats")) {
Sooraj Sasindran9a909312016-07-18 11:57:25 -07006960 return null;
6961 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07006962 Phone phone = getPhone(subId);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07006963
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006964 final long identity = Binder.clearCallingIdentity();
6965 try {
6966 if (phone != null) {
6967 return phone.getClientRequestStats();
6968 }
6969
6970 return null;
6971 } finally {
6972 Binder.restoreCallingIdentity(identity);
6973 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07006974 }
6975
Narayan Kamathf04b5a12018-01-09 11:47:15 +00006976 private WorkSource getWorkSource(int uid) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006977 String packageName = mApp.getPackageManager().getNameForUid(uid);
Narayan Kamathf04b5a12018-01-09 11:47:15 +00006978 return new WorkSource(uid, packageName);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07006979 }
Jack Yueb4124c2017-02-16 15:32:43 -08006980
6981 /**
Grace Chen70990072017-03-24 17:21:30 -07006982 * Set SIM card power state.
Jack Yueb4124c2017-02-16 15:32:43 -08006983 *
Sanket Padawe13bac7b2017-03-20 15:04:47 -07006984 * @param slotIndex SIM slot id.
Grace Chen70990072017-03-24 17:21:30 -07006985 * @param state State of SIM (power down, power up, pass through)
6986 * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
6987 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
6988 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
Jack Yueb4124c2017-02-16 15:32:43 -08006989 *
6990 **/
6991 @Override
Grace Chen70990072017-03-24 17:21:30 -07006992 public void setSimPowerStateForSlot(int slotIndex, int state) {
Jack Yueb4124c2017-02-16 15:32:43 -08006993 enforceModifyPermission();
Sanket Padawe13bac7b2017-03-20 15:04:47 -07006994 Phone phone = PhoneFactory.getPhone(slotIndex);
6995
vagdeviaf9a5b92018-08-15 16:01:53 -07006996 WorkSource workSource = getWorkSource(Binder.getCallingUid());
6997
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006998 final long identity = Binder.clearCallingIdentity();
6999 try {
7000 if (phone != null) {
vagdeviaf9a5b92018-08-15 16:01:53 -07007001 phone.setSimPowerState(state, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007002 }
7003 } finally {
7004 Binder.restoreCallingIdentity(identity);
Jack Yueb4124c2017-02-16 15:32:43 -08007005 }
7006 }
Shuo Qiandd210312017-04-12 22:11:33 +00007007
Tyler Gunn65d45c22017-06-05 11:22:26 -07007008 private boolean isUssdApiAllowed(int subId) {
7009 CarrierConfigManager configManager =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007010 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Tyler Gunn65d45c22017-06-05 11:22:26 -07007011 if (configManager == null) {
7012 return false;
7013 }
7014 PersistableBundle pb = configManager.getConfigForSubId(subId);
7015 if (pb == null) {
7016 return false;
7017 }
7018 return pb.getBoolean(
7019 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL);
7020 }
7021
Shuo Qiandd210312017-04-12 22:11:33 +00007022 /**
7023 * Check if phone is in emergency callback mode
7024 * @return true if phone is in emergency callback mode
7025 * @param subId sub id
7026 */
goneil9c5f4872017-12-05 14:07:56 -08007027 @Override
Shuo Qiandd210312017-04-12 22:11:33 +00007028 public boolean getEmergencyCallbackMode(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07007029 enforceReadPrivilegedPermission("getEmergencyCallbackMode");
Shuo Qiandd210312017-04-12 22:11:33 +00007030 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007031
7032 final long identity = Binder.clearCallingIdentity();
7033 try {
7034 if (phone != null) {
7035 return phone.isInEcm();
7036 } else {
7037 return false;
7038 }
7039 } finally {
7040 Binder.restoreCallingIdentity(identity);
Shuo Qiandd210312017-04-12 22:11:33 +00007041 }
7042 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08007043
7044 /**
7045 * Get the current signal strength information for the given subscription.
7046 * Because this information is not updated when the device is in a low power state
7047 * it should not be relied-upon to be current.
7048 * @param subId Subscription index
7049 * @return the most recent cached signal strength info from the modem
7050 */
7051 @Override
7052 public SignalStrength getSignalStrength(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007053 final long identity = Binder.clearCallingIdentity();
7054 try {
7055 Phone p = getPhone(subId);
7056 if (p == null) {
7057 return null;
7058 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08007059
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007060 return p.getSignalStrength();
7061 } finally {
7062 Binder.restoreCallingIdentity(identity);
7063 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08007064 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00007065
Pengquan Meng77b7f132018-08-22 14:49:57 -07007066 /**
Chen Xuf792fd62018-10-17 17:54:36 +00007067 * Get the current modem radio state for the given slot.
7068 * @param slotIndex slot index.
7069 * @param callingPackage the name of the package making the call.
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007070 * @param callingFeatureId The feature in the package.
Chen Xuf792fd62018-10-17 17:54:36 +00007071 * @return the current radio power state from the modem
7072 */
7073 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007074 public int getRadioPowerState(int slotIndex, String callingPackage, String callingFeatureId) {
Chen Xuf792fd62018-10-17 17:54:36 +00007075 Phone phone = PhoneFactory.getPhone(slotIndex);
7076 if (phone != null) {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007077 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, phone.getSubId(),
7078 callingPackage, callingFeatureId, "getRadioPowerState")) {
Chen Xuf792fd62018-10-17 17:54:36 +00007079 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
7080 }
7081
7082 final long identity = Binder.clearCallingIdentity();
7083 try {
7084 return phone.getRadioPowerState();
7085 } finally {
7086 Binder.restoreCallingIdentity(identity);
7087 }
7088 }
7089 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
7090 }
7091
7092 /**
Pengquan Meng77b7f132018-08-22 14:49:57 -07007093 * Checks if data roaming is enabled on the subscription with id {@code subId}.
7094 *
7095 * <p>Requires one of the following permissions:
7096 * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
7097 * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
7098 * privileges.
7099 *
7100 * @param subId subscription id
7101 * @return {@code true} if data roaming is enabled on this subscription, otherwise return
7102 * {@code false}.
7103 */
7104 @Override
7105 public boolean isDataRoamingEnabled(int subId) {
Pengquan Meng44e66f12019-04-01 10:48:20 -07007106 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
7107 null /* message */);
7108
Pengquan Menga1bb6272018-09-06 09:59:22 -07007109 boolean isEnabled = false;
7110 final long identity = Binder.clearCallingIdentity();
Pengquan Meng77b7f132018-08-22 14:49:57 -07007111 try {
Pengquan Menga1bb6272018-09-06 09:59:22 -07007112 Phone phone = getPhone(subId);
7113 isEnabled = phone != null ? phone.getDataRoamingEnabled() : false;
Pengquan Meng77b7f132018-08-22 14:49:57 -07007114 } catch (Exception e) {
7115 TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
7116 mApp, subId, "isDataRoamingEnabled");
Pengquan Menga1bb6272018-09-06 09:59:22 -07007117 } finally {
7118 Binder.restoreCallingIdentity(identity);
Pengquan Meng77b7f132018-08-22 14:49:57 -07007119 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07007120 return isEnabled;
Pengquan Meng77b7f132018-08-22 14:49:57 -07007121 }
7122
7123
7124 /**
7125 * Enables/Disables the data roaming on the subscription with id {@code subId}.
7126 *
7127 * <p> Requires permission:
7128 * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier
7129 * privileges.
7130 *
7131 * @param subId subscription id
7132 * @param isEnabled {@code true} means enable, {@code false} means disable.
7133 */
7134 @Override
7135 public void setDataRoamingEnabled(int subId, boolean isEnabled) {
Pengquan Meng44e66f12019-04-01 10:48:20 -07007136 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7137 mApp, subId, "setDataRoamingEnabled");
7138
Pengquan Menga1bb6272018-09-06 09:59:22 -07007139 final long identity = Binder.clearCallingIdentity();
7140 try {
Pengquan Menga1bb6272018-09-06 09:59:22 -07007141 Phone phone = getPhone(subId);
7142 if (phone != null) {
7143 phone.setDataRoamingEnabled(isEnabled);
7144 }
7145 } finally {
7146 Binder.restoreCallingIdentity(identity);
Pengquan Meng77b7f132018-08-22 14:49:57 -07007147 }
7148 }
7149
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00007150 @Override
Pengquan Meng6884a2c2018-10-03 12:19:13 -07007151 public boolean isManualNetworkSelectionAllowed(int subId) {
tom hsuc91afc72020-01-06 23:46:07 +08007152 TelephonyPermissions
7153 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Pengquan Meng44e66f12019-04-01 10:48:20 -07007154 mApp, subId, "isManualNetworkSelectionAllowed");
7155
Pengquan Meng6884a2c2018-10-03 12:19:13 -07007156 boolean isAllowed = true;
7157 final long identity = Binder.clearCallingIdentity();
7158 try {
Pengquan Meng6884a2c2018-10-03 12:19:13 -07007159 Phone phone = getPhone(subId);
7160 if (phone != null) {
7161 isAllowed = phone.isCspPlmnEnabled();
7162 }
7163 } finally {
7164 Binder.restoreCallingIdentity(identity);
7165 }
7166 return isAllowed;
7167 }
7168
7169 @Override
Jordan Liu75f43ea2019-01-17 16:56:37 -08007170 public List<UiccCardInfo> getUiccCardsInfo(String callingPackage) {
Jordan Liu1e142fc2019-04-22 15:10:43 -07007171 boolean hasReadPermission = false;
Jordan Liuc65bc952019-02-12 17:54:02 -08007172 try {
7173 enforceReadPrivilegedPermission("getUiccCardsInfo");
Jordan Liu1e142fc2019-04-22 15:10:43 -07007174 hasReadPermission = true;
Jordan Liuc65bc952019-02-12 17:54:02 -08007175 } catch (SecurityException e) {
7176 // even without READ_PRIVILEGED_PHONE_STATE, we allow the call to continue if the caller
7177 // has carrier privileges on an active UICC
7178 if (checkCarrierPrivilegesForPackageAnyPhone(callingPackage)
7179 != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
Jordan Liu1e142fc2019-04-22 15:10:43 -07007180 throw new SecurityException("Caller does not have permission.");
Jordan Liuc65bc952019-02-12 17:54:02 -08007181 }
Jordan Liu75f43ea2019-01-17 16:56:37 -08007182 }
Jordan Liu5aa07002018-12-18 15:44:48 -08007183
7184 final long identity = Binder.clearCallingIdentity();
7185 try {
Jordan Liu75f43ea2019-01-17 16:56:37 -08007186 UiccController uiccController = UiccController.getInstance();
7187 ArrayList<UiccCardInfo> cardInfos = uiccController.getAllUiccCardInfos();
Jordan Liu1e142fc2019-04-22 15:10:43 -07007188 if (hasReadPermission) {
7189 return cardInfos;
Jordan Liu75f43ea2019-01-17 16:56:37 -08007190 }
Jordan Liu1e142fc2019-04-22 15:10:43 -07007191
7192 // Remove private info if the caller doesn't have access
7193 ArrayList<UiccCardInfo> filteredInfos = new ArrayList<>();
7194 for (UiccCardInfo cardInfo : cardInfos) {
7195 // For an inactive eUICC, the UiccCard will be null even though the UiccCardInfo
7196 // is available
7197 UiccCard card = uiccController.getUiccCardForSlot(cardInfo.getSlotIndex());
7198 if (card == null || card.getUiccProfile() == null) {
7199 // assume no access if the card or profile is unavailable
7200 filteredInfos.add(cardInfo.getUnprivileged());
7201 continue;
7202 }
7203 UiccProfile profile = card.getUiccProfile();
7204 if (profile.getCarrierPrivilegeStatus(mApp.getPackageManager(), callingPackage)
7205 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
7206 filteredInfos.add(cardInfo);
7207 } else {
7208 filteredInfos.add(cardInfo.getUnprivileged());
7209 }
7210 }
7211 return filteredInfos;
Jordan Liu5aa07002018-12-18 15:44:48 -08007212 } finally {
7213 Binder.restoreCallingIdentity(identity);
7214 }
7215 }
7216
7217 @Override
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00007218 public UiccSlotInfo[] getUiccSlotsInfo() {
Brad Ebinger35c841c2018-10-01 10:40:55 -07007219 enforceReadPrivilegedPermission("getUiccSlotsInfo");
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00007220
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007221 final long identity = Binder.clearCallingIdentity();
7222 try {
7223 UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
7224 if (slots == null) {
7225 Rlog.i(LOG_TAG, "slots is null.");
7226 return null;
7227 }
7228
7229 UiccSlotInfo[] infos = new UiccSlotInfo[slots.length];
7230 for (int i = 0; i < slots.length; i++) {
7231 UiccSlot slot = slots[i];
7232 if (slot == null) {
7233 continue;
7234 }
7235
Jordan Liu7be7e652019-05-06 18:55:02 +00007236 String cardId;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007237 UiccCard card = slot.getUiccCard();
7238 if (card != null) {
7239 cardId = card.getCardId();
Jordan Liu7be7e652019-05-06 18:55:02 +00007240 } else {
Jordan Liu01bd00d2019-09-12 16:19:43 -07007241 cardId = slot.getEid();
7242 if (TextUtils.isEmpty(cardId)) {
7243 cardId = slot.getIccId();
7244 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007245 }
7246
Jordan Liu857451f2019-05-09 16:35:35 -07007247 if (cardId != null) {
7248 // if cardId is an ICCID, strip off trailing Fs before exposing to user
7249 // if cardId is an EID, it's all digits so this is fine
7250 cardId = IccUtils.stripTrailingFs(cardId);
7251 }
7252
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007253 int cardState = 0;
7254 switch (slot.getCardState()) {
7255 case CARDSTATE_ABSENT:
7256 cardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
7257 break;
7258 case CARDSTATE_PRESENT:
7259 cardState = UiccSlotInfo.CARD_STATE_INFO_PRESENT;
7260 break;
7261 case CARDSTATE_ERROR:
7262 cardState = UiccSlotInfo.CARD_STATE_INFO_ERROR;
7263 break;
7264 case CARDSTATE_RESTRICTED:
7265 cardState = UiccSlotInfo.CARD_STATE_INFO_RESTRICTED;
7266 break;
7267 default:
7268 break;
7269
7270 }
7271
7272 infos[i] = new UiccSlotInfo(
7273 slot.isActive(),
7274 slot.isEuicc(),
7275 cardId,
7276 cardState,
7277 slot.getPhoneId(),
Jordan Liua2619582019-02-14 12:56:40 -08007278 slot.isExtendedApduSupported(),
7279 slot.isRemovable());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007280 }
7281 return infos;
7282 } finally {
7283 Binder.restoreCallingIdentity(identity);
Holly Jiuyu Sun1d957c52018-04-04 13:52:42 -07007284 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00007285 }
7286
7287 @Override
7288 public boolean switchSlots(int[] physicalSlots) {
7289 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007290
7291 final long identity = Binder.clearCallingIdentity();
7292 try {
7293 return (Boolean) sendRequest(CMD_SWITCH_SLOTS, physicalSlots);
7294 } finally {
7295 Binder.restoreCallingIdentity(identity);
7296 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00007297 }
Jack Yu4c988042018-02-27 15:30:01 -08007298
7299 @Override
Jordan Liu7de49fa2018-12-06 14:48:49 -08007300 public int getCardIdForDefaultEuicc(int subId, String callingPackage) {
Jordan Liu7de49fa2018-12-06 14:48:49 -08007301 final long identity = Binder.clearCallingIdentity();
7302 try {
7303 return UiccController.getInstance().getCardIdForDefaultEuicc();
7304 } finally {
7305 Binder.restoreCallingIdentity(identity);
7306 }
7307 }
7308
7309 @Override
Jack Yu4c988042018-02-27 15:30:01 -08007310 public void setRadioIndicationUpdateMode(int subId, int filters, int mode) {
7311 enforceModifyPermission();
7312 final Phone phone = getPhone(subId);
7313 if (phone == null) {
7314 loge("setRadioIndicationUpdateMode fails with invalid subId: " + subId);
7315 return;
7316 }
7317
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007318 final long identity = Binder.clearCallingIdentity();
7319 try {
7320 phone.setRadioIndicationUpdateMode(filters, mode);
7321 } finally {
7322 Binder.restoreCallingIdentity(identity);
7323 }
Jack Yu4c988042018-02-27 15:30:01 -08007324 }
Pengquan Meng85728fb2018-03-12 16:31:21 -07007325
7326 /**
goneil47ffb6e2018-04-06 15:40:58 -07007327 * A test API to reload the UICC profile.
7328 *
7329 * <p>Requires that the calling app has permission
7330 * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
7331 * @hide
7332 */
7333 @Override
7334 public void refreshUiccProfile(int subId) {
7335 enforceModifyPermission();
7336
7337 final long identity = Binder.clearCallingIdentity();
7338 try {
7339 Phone phone = getPhone(subId);
7340 if (phone == null) {
7341 return;
7342 }
7343 UiccCard uiccCard = phone.getUiccCard();
7344 if (uiccCard == null) {
7345 return;
7346 }
7347 UiccProfile uiccProfile = uiccCard.getUiccProfile();
7348 if (uiccProfile == null) {
7349 return;
7350 }
7351 uiccProfile.refresh();
7352 } finally {
7353 Binder.restoreCallingIdentity(identity);
7354 }
7355 }
7356
7357 /**
Pengquan Meng85728fb2018-03-12 16:31:21 -07007358 * Returns false if the mobile data is disabled by default, otherwise return true.
7359 */
7360 private boolean getDefaultDataEnabled() {
Inseob Kim14bb3d02018-12-13 17:11:34 +09007361 return TelephonyProperties.mobile_data().orElse(true);
Pengquan Meng85728fb2018-03-12 16:31:21 -07007362 }
7363
7364 /**
7365 * Returns true if the data roaming is enabled by default, i.e the system property
7366 * of {@link #DEFAULT_DATA_ROAMING_PROPERTY_NAME} is true or the config of
7367 * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} is true.
7368 */
7369 private boolean getDefaultDataRoamingEnabled(int subId) {
7370 final CarrierConfigManager configMgr = (CarrierConfigManager)
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007371 mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Inseob Kim14bb3d02018-12-13 17:11:34 +09007372 boolean isDataRoamingEnabled = TelephonyProperties.data_roaming().orElse(true);
Pengquan Meng85728fb2018-03-12 16:31:21 -07007373 isDataRoamingEnabled |= configMgr.getConfigForSubId(subId).getBoolean(
7374 CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
7375 return isDataRoamingEnabled;
7376 }
7377
7378 /**
7379 * Returns the default network type for the given {@code subId}, if the default network type is
7380 * not set, return {@link Phone#PREFERRED_NT_MODE}.
7381 */
7382 private int getDefaultNetworkType(int subId) {
Inseob Kim14bb3d02018-12-13 17:11:34 +09007383 List<Integer> list = TelephonyProperties.default_network();
7384 int phoneId = mSubscriptionController.getPhoneId(subId);
7385 if (phoneId >= 0 && phoneId < list.size() && list.get(phoneId) != null) {
7386 return list.get(phoneId);
7387 }
7388 return Phone.PREFERRED_NT_MODE;
Pengquan Meng85728fb2018-03-12 16:31:21 -07007389 }
fionaxua13278b2018-03-21 00:08:13 -07007390
7391 @Override
7392 public void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String
chen xueaba88a2019-03-15 13:15:10 -07007393 gid1, String gid2, String plmn, String spn, String carrierPrivilegeRules, String apn) {
fionaxua13278b2018-03-21 00:08:13 -07007394 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007395
7396 final long identity = Binder.clearCallingIdentity();
7397 try {
7398 final Phone phone = getPhone(subId);
7399 if (phone == null) {
7400 loge("setCarrierTestOverride fails with invalid subId: " + subId);
7401 return;
7402 }
chen xueaba88a2019-03-15 13:15:10 -07007403 phone.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, plmn, spn,
7404 carrierPrivilegeRules, apn);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007405 } finally {
7406 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07007407 }
fionaxua13278b2018-03-21 00:08:13 -07007408 }
7409
7410 @Override
7411 public int getCarrierIdListVersion(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07007412 enforceReadPrivilegedPermission("getCarrierIdListVersion");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007413
7414 final long identity = Binder.clearCallingIdentity();
7415 try {
7416 final Phone phone = getPhone(subId);
7417 if (phone == null) {
7418 loge("getCarrierIdListVersion fails with invalid subId: " + subId);
7419 return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
7420 }
7421 return phone.getCarrierIdListVersion();
7422 } finally {
7423 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07007424 }
fionaxua13278b2018-03-21 00:08:13 -07007425 }
Malcolm Chen2c63d402018-08-14 16:00:53 -07007426
7427 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007428 public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage,
7429 String callingFeatureId) {
Malcolm Chen2c63d402018-08-14 16:00:53 -07007430 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007431 mApp, subId, callingPackage, callingFeatureId,
7432 "getNumberOfModemsWithSimultaneousDataConnections")) {
Malcolm Chen2c63d402018-08-14 16:00:53 -07007433 return -1;
7434 }
7435
7436 final long identity = Binder.clearCallingIdentity();
7437 try {
7438 return mPhoneConfigurationManager.getNumberOfModemsWithSimultaneousDataConnections();
7439 } finally {
7440 Binder.restoreCallingIdentity(identity);
7441 }
7442 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07007443
7444 @Override
7445 public int getCdmaRoamingMode(int subId) {
zoey chen7e6d4e52019-12-17 18:18:59 +08007446 TelephonyPermissions
7447 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Pengquan Menga1bb6272018-09-06 09:59:22 -07007448 mApp, subId, "getCdmaRoamingMode");
7449
7450 final long identity = Binder.clearCallingIdentity();
7451 try {
7452 return (int) sendRequest(CMD_GET_CDMA_ROAMING_MODE, null /* argument */, subId);
7453 } finally {
7454 Binder.restoreCallingIdentity(identity);
7455 }
7456 }
7457
7458 @Override
7459 public boolean setCdmaRoamingMode(int subId, int mode) {
7460 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7461 mApp, subId, "setCdmaRoamingMode");
7462
7463 final long identity = Binder.clearCallingIdentity();
7464 try {
7465 return (boolean) sendRequest(CMD_SET_CDMA_ROAMING_MODE, mode, subId);
7466 } finally {
7467 Binder.restoreCallingIdentity(identity);
7468 }
7469 }
7470
7471 @Override
7472 public boolean setCdmaSubscriptionMode(int subId, int mode) {
7473 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7474 mApp, subId, "setCdmaSubscriptionMode");
7475
7476 final long identity = Binder.clearCallingIdentity();
7477 try {
7478 return (boolean) sendRequest(CMD_SET_CDMA_SUBSCRIPTION_MODE, mode, subId);
7479 } finally {
7480 Binder.restoreCallingIdentity(identity);
7481 }
7482 }
Makoto Onukida3bf792018-09-18 16:06:29 -07007483
sqianc5eccab2018-10-19 18:46:41 -07007484 @Override
sqian8c685422019-02-22 15:55:18 -08007485 public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007486 String callingPackage, String callingFeatureId) {
sqian11b7a0e2018-12-05 18:48:28 -08007487 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007488 mApp, getDefaultSubscription(), callingPackage, callingFeatureId,
7489 "getEmergencyNumberList")) {
sqian11b7a0e2018-12-05 18:48:28 -08007490 throw new SecurityException("Requires READ_PHONE_STATE permission.");
7491 }
7492 final long identity = Binder.clearCallingIdentity();
7493 try {
sqian854d44b2018-12-12 16:48:18 -08007494 Map<Integer, List<EmergencyNumber>> emergencyNumberListInternal = new HashMap<>();
7495 for (Phone phone: PhoneFactory.getPhones()) {
7496 if (phone.getEmergencyNumberTracker() != null
7497 && phone.getEmergencyNumberTracker().getEmergencyNumberList() != null) {
7498 emergencyNumberListInternal.put(
7499 phone.getSubId(),
7500 phone.getEmergencyNumberTracker().getEmergencyNumberList());
7501 }
sqian11b7a0e2018-12-05 18:48:28 -08007502 }
sqian854d44b2018-12-12 16:48:18 -08007503 return emergencyNumberListInternal;
sqian11b7a0e2018-12-05 18:48:28 -08007504 } finally {
7505 Binder.restoreCallingIdentity(identity);
7506 }
sqianc5eccab2018-10-19 18:46:41 -07007507 }
7508
7509 @Override
sqian8c685422019-02-22 15:55:18 -08007510 public boolean isEmergencyNumber(String number, boolean exactMatch) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007511 final Phone defaultPhone = getDefaultPhone();
sqian11b7a0e2018-12-05 18:48:28 -08007512 if (!exactMatch) {
7513 TelephonyPermissions
7514 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
sqian8c685422019-02-22 15:55:18 -08007515 mApp, defaultPhone.getSubId(), "isEmergencyNumber(Potential)");
sqian11b7a0e2018-12-05 18:48:28 -08007516 }
7517 final long identity = Binder.clearCallingIdentity();
7518 try {
sqian854d44b2018-12-12 16:48:18 -08007519 for (Phone phone: PhoneFactory.getPhones()) {
7520 if (phone.getEmergencyNumberTracker() != null
7521 && phone.getEmergencyNumberTracker() != null) {
7522 if (phone.getEmergencyNumberTracker().isEmergencyNumber(
7523 number, exactMatch)) {
7524 return true;
sqian11b7a0e2018-12-05 18:48:28 -08007525 }
7526 }
sqian11b7a0e2018-12-05 18:48:28 -08007527 }
7528 return false;
7529 } finally {
7530 Binder.restoreCallingIdentity(identity);
7531 }
7532 }
7533
sqianf4ca7ed2019-01-15 18:32:07 -08007534 /**
7535 * Update emergency number list for test mode.
7536 */
7537 @Override
7538 public void updateEmergencyNumberListTestMode(int action, EmergencyNumber num) {
7539 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
7540 "updateEmergencyNumberListTestMode");
7541
7542 final long identity = Binder.clearCallingIdentity();
7543 try {
7544 for (Phone phone: PhoneFactory.getPhones()) {
7545 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
7546 if (tracker != null) {
7547 tracker.executeEmergencyNumberTestModeCommand(action, num);
7548 }
7549 }
7550 } finally {
7551 Binder.restoreCallingIdentity(identity);
7552 }
7553 }
7554
7555 /**
7556 * Get the full emergency number list for test mode.
7557 */
7558 @Override
7559 public List<String> getEmergencyNumberListTestMode() {
7560 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
7561 "getEmergencyNumberListTestMode");
7562
7563 final long identity = Binder.clearCallingIdentity();
7564 try {
7565 Set<String> emergencyNumbers = new HashSet<>();
7566 for (Phone phone: PhoneFactory.getPhones()) {
7567 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
7568 if (tracker != null) {
7569 for (EmergencyNumber num : tracker.getEmergencyNumberList()) {
7570 emergencyNumbers.add(num.getNumber());
7571 }
7572 }
7573 }
7574 return new ArrayList<>(emergencyNumbers);
7575 } finally {
7576 Binder.restoreCallingIdentity(identity);
7577 }
7578 }
7579
chen xud6b45bd2018-10-30 22:27:10 -07007580 @Override
Shuo Qian3b6ee772019-11-13 17:43:31 -08007581 public int getEmergencyNumberDbVersion(int subId) {
7582 enforceReadPrivilegedPermission("getEmergencyNumberDbVersion");
7583
7584 final long identity = Binder.clearCallingIdentity();
7585 try {
7586 final Phone phone = getPhone(subId);
7587 if (phone == null) {
7588 loge("getEmergencyNumberDbVersion fails with invalid subId: " + subId);
7589 return TelephonyManager.INVALID_EMERGENCY_NUMBER_DB_VERSION;
7590 }
7591 return phone.getEmergencyNumberDbVersion();
7592 } finally {
7593 Binder.restoreCallingIdentity(identity);
7594 }
7595 }
7596
7597 @Override
7598 public void notifyOtaEmergencyNumberDbInstalled() {
7599 enforceModifyPermission();
7600
7601 final long identity = Binder.clearCallingIdentity();
7602 try {
7603 for (Phone phone: PhoneFactory.getPhones()) {
7604 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
7605 if (tracker != null) {
7606 tracker.updateOtaEmergencyNumberDatabase();
7607 }
7608 }
7609 } finally {
7610 Binder.restoreCallingIdentity(identity);
7611 }
7612 }
7613
7614 @Override
7615 public void updateTestOtaEmergencyNumberDbFilePath(String otaFilePath) {
7616 enforceActiveEmergencySessionPermission();
7617
7618 final long identity = Binder.clearCallingIdentity();
7619 try {
7620 for (Phone phone: PhoneFactory.getPhones()) {
7621 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
7622 if (tracker != null) {
7623 tracker.updateTestOtaEmergencyNumberDbFilePath(otaFilePath);
7624 }
7625 }
7626 } finally {
7627 Binder.restoreCallingIdentity(identity);
7628 }
7629 }
7630
7631 @Override
chen xud6b45bd2018-10-30 22:27:10 -07007632 public List<String> getCertsFromCarrierPrivilegeAccessRules(int subId) {
7633 enforceReadPrivilegedPermission("getCertsFromCarrierPrivilegeAccessRules");
7634 Phone phone = getPhone(subId);
7635 if (phone == null) {
7636 return null;
7637 }
7638 final long identity = Binder.clearCallingIdentity();
7639 try {
7640 UiccProfile profile = UiccController.getInstance()
7641 .getUiccProfileForPhone(phone.getPhoneId());
7642 if (profile != null) {
7643 return profile.getCertsFromCarrierPrivilegeAccessRules();
7644 }
7645 } finally {
7646 Binder.restoreCallingIdentity(identity);
7647 }
7648 return null;
7649 }
Malcolm Chen8e4ed912019-01-15 20:22:16 -08007650
7651 /**
7652 * Enable or disable a modem stack.
7653 */
7654 @Override
7655 public boolean enableModemForSlot(int slotIndex, boolean enable) {
7656 enforceModifyPermission();
7657
7658 final long identity = Binder.clearCallingIdentity();
7659 try {
7660 Phone phone = PhoneFactory.getPhone(slotIndex);
7661 if (phone == null) {
7662 return false;
7663 } else {
7664 return (Boolean) sendRequest(CMD_REQUEST_ENABLE_MODEM, enable, phone, null);
7665 }
7666 } finally {
7667 Binder.restoreCallingIdentity(identity);
7668 }
7669 }
Michelecea4cf22018-12-21 15:00:11 -08007670
Malcolm Chen4bcd9822019-03-27 18:34:05 -07007671 /**
7672 * Whether a modem stack is enabled or not.
7673 */
7674 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007675 public boolean isModemEnabledForSlot(int slotIndex, String callingPackage,
7676 String callingFeatureId) {
Malcolm Chen4bcd9822019-03-27 18:34:05 -07007677 Phone phone = PhoneFactory.getPhone(slotIndex);
7678 if (phone == null) return false;
7679
7680 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007681 mApp, phone.getSubId(), callingPackage, callingFeatureId,
7682 "isModemEnabledForSlot")) {
Malcolm Chen4bcd9822019-03-27 18:34:05 -07007683 throw new SecurityException("Requires READ_PHONE_STATE permission.");
7684 }
7685
7686 final long identity = Binder.clearCallingIdentity();
7687 try {
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07007688 try {
7689 return mPhoneConfigurationManager.getPhoneStatusFromCache(phone.getPhoneId());
7690 } catch (NoSuchElementException ex) {
7691 return (Boolean) sendRequest(CMD_GET_MODEM_STATUS, null, phone, null);
7692 }
Malcolm Chen4bcd9822019-03-27 18:34:05 -07007693 } finally {
7694 Binder.restoreCallingIdentity(identity);
7695 }
7696 }
7697
Michelecea4cf22018-12-21 15:00:11 -08007698 @Override
Michele0ea7d782019-03-19 14:58:42 -07007699 public void setMultiSimCarrierRestriction(boolean isMultiSimCarrierRestricted) {
Michelecea4cf22018-12-21 15:00:11 -08007700 enforceModifyPermission();
7701
7702 final long identity = Binder.clearCallingIdentity();
7703 try {
7704 mTelephonySharedPreferences.edit()
Michele0ea7d782019-03-19 14:58:42 -07007705 .putBoolean(PREF_MULTI_SIM_RESTRICTED, isMultiSimCarrierRestricted)
Michelecea4cf22018-12-21 15:00:11 -08007706 .commit();
7707 } finally {
7708 Binder.restoreCallingIdentity(identity);
7709 }
7710 }
7711
7712 @Override
Michele0ea7d782019-03-19 14:58:42 -07007713 @TelephonyManager.IsMultiSimSupportedResult
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007714 public int isMultiSimSupported(String callingPackage, String callingFeatureId) {
Michele4245e952019-02-04 11:36:23 -08007715 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007716 getDefaultPhone().getSubId(), callingPackage, callingFeatureId,
7717 "isMultiSimSupported")) {
Michele0ea7d782019-03-19 14:58:42 -07007718 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele4245e952019-02-04 11:36:23 -08007719 }
Michelecea4cf22018-12-21 15:00:11 -08007720
7721 final long identity = Binder.clearCallingIdentity();
7722 try {
Michele0ea7d782019-03-19 14:58:42 -07007723 return isMultiSimSupportedInternal();
Michelecea4cf22018-12-21 15:00:11 -08007724 } finally {
7725 Binder.restoreCallingIdentity(identity);
7726 }
7727 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08007728
Michele0ea7d782019-03-19 14:58:42 -07007729 @TelephonyManager.IsMultiSimSupportedResult
7730 private int isMultiSimSupportedInternal() {
Michele30b57b22019-03-01 12:01:14 -08007731 // If the device has less than 2 SIM cards, indicate that multisim is restricted.
7732 int numPhysicalSlots = UiccController.getInstance().getUiccSlots().length;
7733 if (numPhysicalSlots < 2) {
Michele0ea7d782019-03-19 14:58:42 -07007734 loge("isMultiSimSupportedInternal: requires at least 2 cards");
7735 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -08007736 }
7737 // Check if the hardware supports multisim functionality. If usage of multisim is not
7738 // supported by the modem, indicate that it is restricted.
7739 PhoneCapability staticCapability =
7740 mPhoneConfigurationManager.getStaticPhoneCapability();
7741 if (staticCapability == null) {
Michele0ea7d782019-03-19 14:58:42 -07007742 loge("isMultiSimSupportedInternal: no static configuration available");
7743 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -08007744 }
7745 if (staticCapability.logicalModemList.size() < 2) {
Michele0ea7d782019-03-19 14:58:42 -07007746 loge("isMultiSimSupportedInternal: maximum number of modem is < 2");
7747 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -08007748 }
7749 // Check if support of multiple SIMs is restricted by carrier
7750 if (mTelephonySharedPreferences.getBoolean(PREF_MULTI_SIM_RESTRICTED, false)) {
Michele0ea7d782019-03-19 14:58:42 -07007751 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_CARRIER;
Michele30b57b22019-03-01 12:01:14 -08007752 }
7753
Michele0ea7d782019-03-19 14:58:42 -07007754 return TelephonyManager.MULTISIM_ALLOWED;
Michele30b57b22019-03-01 12:01:14 -08007755 }
7756
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08007757 /**
7758 * Switch configs to enable multi-sim or switch back to single-sim
Nazanin Bakhshi17318782019-03-01 11:56:08 -08007759 * Note: Switch from multi-sim to single-sim is only possible with MODIFY_PHONE_STATE
7760 * permission, but the other way around is possible with either MODIFY_PHONE_STATE
7761 * or carrier privileges
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08007762 * @param numOfSims number of active sims we want to switch to
7763 */
7764 @Override
7765 public void switchMultiSimConfig(int numOfSims) {
Nazanin Bakhshi17318782019-03-01 11:56:08 -08007766 if (numOfSims == 1) {
7767 enforceModifyPermission();
7768 } else {
7769 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7770 mApp, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, "switchMultiSimConfig");
7771 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08007772 final long identity = Binder.clearCallingIdentity();
Michele30b57b22019-03-01 12:01:14 -08007773
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08007774 try {
Michele30b57b22019-03-01 12:01:14 -08007775 //only proceed if multi-sim is not restricted
Michele0ea7d782019-03-19 14:58:42 -07007776 if (isMultiSimSupportedInternal() != TelephonyManager.MULTISIM_ALLOWED) {
Michele30b57b22019-03-01 12:01:14 -08007777 loge("switchMultiSimConfig not possible. It is restricted or not supported.");
7778 return;
7779 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08007780 mPhoneConfigurationManager.switchMultiSimConfig(numOfSims);
7781 } finally {
7782 Binder.restoreCallingIdentity(identity);
7783 }
7784 }
7785
Hyungjun Parkbb07fde2019-01-10 15:28:51 +09007786 @Override
7787 public boolean isApplicationOnUicc(int subId, int appType) {
7788 enforceReadPrivilegedPermission("isApplicationOnUicc");
7789 Phone phone = getPhone(subId);
7790 if (phone == null) {
7791 return false;
7792 }
7793 final long identity = Binder.clearCallingIdentity();
7794 try {
7795 UiccCard uiccCard = phone.getUiccCard();
7796 if (uiccCard == null) {
7797 return false;
7798 }
7799 UiccProfile uiccProfile = uiccCard.getUiccProfile();
7800 if (uiccProfile == null) {
7801 return false;
7802 }
7803 if (TelephonyManager.APPTYPE_SIM <= appType
7804 && appType <= TelephonyManager.APPTYPE_ISIM) {
7805 return uiccProfile.isApplicationOnIcc(AppType.values()[appType]);
7806 }
7807 return false;
7808 } finally {
7809 Binder.restoreCallingIdentity(identity);
7810 }
7811 }
7812
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08007813 /**
chen xub4baa772019-04-03 10:23:41 -07007814 * Get whether making changes to modem configurations will trigger reboot.
7815 * Return value defaults to true.
Nazanin Bakhshi5fe5ef22019-01-30 10:52:09 -08007816 */
7817 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007818 public boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage,
7819 String callingFeatureId) {
chen xub4baa772019-04-03 10:23:41 -07007820 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007821 mApp, subId, callingPackage, callingFeatureId,
7822 "doesSwitchMultiSimConfigTriggerReboot")) {
chen xub4baa772019-04-03 10:23:41 -07007823 return false;
7824 }
Nazanin Bakhshi5fe5ef22019-01-30 10:52:09 -08007825 final long identity = Binder.clearCallingIdentity();
7826 try {
7827 return mPhoneConfigurationManager.isRebootRequiredForModemConfigChange();
7828 } finally {
7829 Binder.restoreCallingIdentity(identity);
7830 }
7831 }
7832
Nathan Harold29f5f052019-02-15 13:41:57 -08007833 private void updateModemStateMetrics() {
7834 TelephonyMetrics metrics = TelephonyMetrics.getInstance();
7835 // TODO: check the state for each modem if the api is ready.
7836 metrics.updateEnabledModemBitmap((1 << TelephonyManager.from(mApp).getPhoneCount()) - 1);
7837 }
7838
Pengquan Meng3889a572019-01-23 11:16:29 -08007839 @Override
7840 public int[] getSlotsMapping() {
7841 enforceReadPrivilegedPermission("getSlotsMapping");
7842
7843 final long identity = Binder.clearCallingIdentity();
7844 try {
7845 int phoneCount = TelephonyManager.getDefault().getPhoneCount();
7846 // All logical slots should have a mapping to a physical slot.
7847 int[] logicalSlotsMapping = new int[phoneCount];
7848 UiccSlotInfo[] slotInfos = getUiccSlotsInfo();
7849 for (int i = 0; i < slotInfos.length; i++) {
7850 if (SubscriptionManager.isValidPhoneId(slotInfos[i].getLogicalSlotIdx())) {
7851 logicalSlotsMapping[slotInfos[i].getLogicalSlotIdx()] = i;
7852 }
7853 }
7854 return logicalSlotsMapping;
7855 } finally {
7856 Binder.restoreCallingIdentity(identity);
7857 }
7858 }
Nathan Harold48d6fd52019-02-06 19:01:40 -08007859
7860 /**
7861 * Get the IRadio HAL Version
7862 */
7863 @Override
7864 public int getRadioHalVersion() {
7865 Phone phone = getDefaultPhone();
7866 if (phone == null) return -1;
7867 HalVersion hv = phone.getHalVersion();
7868 if (hv.equals(HalVersion.UNKNOWN)) return -1;
7869 return hv.major * 100 + hv.minor;
7870 }
Malcolm Chendc8c10e2019-04-10 18:25:07 -07007871
7872 /**
Shuo Qianda2d6ec2020-01-14 15:18:28 -08007873 * Get the current calling package name.
7874 * @return the current calling package name
7875 */
7876 @Override
7877 public String getCurrentPackageName() {
7878 return mApp.getPackageManager().getPackagesForUid(Binder.getCallingUid())[0];
7879 }
7880
7881 /**
Malcolm Chene5ad5792019-04-18 13:51:02 -07007882 * Return whether data is enabled for certain APN type. This will tell if framework will accept
7883 * corresponding network requests on a subId.
7884 *
7885 * Data is enabled if:
Malcolm Chendc8c10e2019-04-10 18:25:07 -07007886 * 1) user data is turned on, or
Malcolm Chene5ad5792019-04-18 13:51:02 -07007887 * 2) APN is un-metered for this subscription, or
7888 * 3) APN type is whitelisted. E.g. MMS is whitelisted if
changbettyd5c246e2019-12-24 15:40:37 +08007889 * {@link TelephonyManager#setAlwaysAllowMmsData} is turned on.
Malcolm Chene5ad5792019-04-18 13:51:02 -07007890 *
7891 * @return whether data is allowed for a apn type.
7892 *
7893 * @hide
Malcolm Chendc8c10e2019-04-10 18:25:07 -07007894 */
7895 @Override
Malcolm Chene5ad5792019-04-18 13:51:02 -07007896 public boolean isDataEnabledForApn(int apnType, int subId, String callingPackage) {
Amit Mahajan5d4e1922019-10-07 16:20:43 -07007897 enforceReadPrivilegedPermission("Needs READ_PRIVILEGED_PHONE_STATE for "
7898 + "isDataEnabledForApn");
Malcolm Chendc8c10e2019-04-10 18:25:07 -07007899
7900 // Now that all security checks passes, perform the operation as ourselves.
7901 final long identity = Binder.clearCallingIdentity();
7902 try {
7903 Phone phone = getPhone(subId);
7904 if (phone == null) return false;
7905
Jack Yu41407ee2019-05-13 16:54:09 -07007906 boolean isMetered = ApnSettingUtils.isMeteredApnType(apnType, phone);
Malcolm Chene5ad5792019-04-18 13:51:02 -07007907 return !isMetered || phone.getDataEnabledSettings().isDataEnabled(apnType);
7908 } finally {
7909 Binder.restoreCallingIdentity(identity);
7910 }
7911 }
7912
7913 @Override
Jack Yu41407ee2019-05-13 16:54:09 -07007914 public boolean isApnMetered(@ApnType int apnType, int subId) {
Malcolm Chene5ad5792019-04-18 13:51:02 -07007915 enforceReadPrivilegedPermission("isApnMetered");
7916
7917 // Now that all security checks passes, perform the operation as ourselves.
7918 final long identity = Binder.clearCallingIdentity();
7919 try {
7920 Phone phone = getPhone(subId);
7921 if (phone == null) return true; // By default return true.
7922
Jack Yu41407ee2019-05-13 16:54:09 -07007923 return ApnSettingUtils.isMeteredApnType(apnType, phone);
Malcolm Chendc8c10e2019-04-10 18:25:07 -07007924 } finally {
7925 Binder.restoreCallingIdentity(identity);
7926 }
7927 }
Brad Ebingera63db5f2019-04-23 16:31:13 -07007928
7929 @Override
changbetty7157e9e2019-12-06 18:16:37 +08007930 public boolean isMvnoMatched(int subId, int mvnoType, @NonNull String mvnoMatchData) {
7931 IccRecords iccRecords = UiccController.getInstance().getIccRecords(
7932 SubscriptionManager.getPhoneId(subId), UiccController.APP_FAM_3GPP);
7933 if (iccRecords == null) {
7934 Log.d(LOG_TAG, "isMvnoMatched# IccRecords is null");
7935 return false;
7936 }
7937 return ApnSettingUtils.mvnoMatches(iccRecords, mvnoType, mvnoMatchData);
7938 }
7939
7940 @Override
Brad Ebingera63db5f2019-04-23 16:31:13 -07007941 public void enqueueSmsPickResult(String callingPackage, IIntegerConsumer pendingSubIdResult) {
Shuo Qianda2d6ec2020-01-14 15:18:28 -08007942 if (callingPackage == null) {
7943 callingPackage = getCurrentPackageName();
7944 }
Brad Ebingera63db5f2019-04-23 16:31:13 -07007945 SmsPermissions permissions = new SmsPermissions(getDefaultPhone(), mApp,
7946 (AppOpsManager) mApp.getSystemService(Context.APP_OPS_SERVICE));
7947 if (!permissions.checkCallingCanSendSms(callingPackage, "Sending message")) {
7948 throw new SecurityException("Requires SEND_SMS permission to perform this operation");
7949 }
7950 PickSmsSubscriptionActivity.addPendingResult(pendingSubIdResult);
7951 Intent intent = new Intent();
7952 intent.setClass(mApp, PickSmsSubscriptionActivity.class);
7953 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7954 // Bring up choose default SMS subscription dialog right now
7955 intent.putExtra(PickSmsSubscriptionActivity.DIALOG_TYPE_KEY,
7956 PickSmsSubscriptionActivity.SMS_PICK_FOR_MESSAGE);
7957 mApp.startActivity(intent);
7958 }
chen xud5ca2d52019-05-28 15:20:57 -07007959
7960 @Override
7961 public String getMmsUAProfUrl(int subId) {
7962 //TODO investigate if this API should require proper permission check in R b/133791609
7963 final long identity = Binder.clearCallingIdentity();
7964 try {
7965 return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
7966 .getString(com.android.internal.R.string.config_mms_user_agent_profile_url);
7967 } finally {
7968 Binder.restoreCallingIdentity(identity);
7969 }
7970 }
7971
7972 @Override
7973 public String getMmsUserAgent(int subId) {
7974 //TODO investigate if this API should require proper permission check in R b/133791609
7975 final long identity = Binder.clearCallingIdentity();
7976 try {
7977 return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
7978 .getString(com.android.internal.R.string.config_mms_user_agent);
7979 } finally {
7980 Binder.restoreCallingIdentity(identity);
7981 }
7982 }
Jack Yub07d4972019-05-28 16:12:25 -07007983
7984 @Override
7985 public boolean setDataAllowedDuringVoiceCall(int subId, boolean allow) {
7986 enforceModifyPermission();
7987
7988 // Now that all security checks passes, perform the operation as ourselves.
7989 final long identity = Binder.clearCallingIdentity();
7990 try {
7991 Phone phone = getPhone(subId);
7992 if (phone == null) return false;
7993
7994 return phone.getDataEnabledSettings().setAllowDataDuringVoiceCall(allow);
7995 } finally {
7996 Binder.restoreCallingIdentity(identity);
7997 }
7998 }
7999
8000 @Override
8001 public boolean isDataAllowedInVoiceCall(int subId) {
8002 enforceReadPrivilegedPermission("isDataAllowedInVoiceCall");
8003
8004 // Now that all security checks passes, perform the operation as ourselves.
8005 final long identity = Binder.clearCallingIdentity();
8006 try {
8007 Phone phone = getPhone(subId);
8008 if (phone == null) return false;
8009
8010 return phone.getDataEnabledSettings().isDataAllowedInVoiceCall();
8011 } finally {
8012 Binder.restoreCallingIdentity(identity);
8013 }
8014 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -07008015
changbettyd5c246e2019-12-24 15:40:37 +08008016 @Override
8017 public boolean setAlwaysAllowMmsData(int subId, boolean alwaysAllow) {
8018 enforceModifyPermission();
8019
8020 // Now that all security checks passes, perform the operation as ourselves.
8021 final long identity = Binder.clearCallingIdentity();
8022 try {
8023 Phone phone = getPhone(subId);
8024 if (phone == null) return false;
8025
8026 return phone.getDataEnabledSettings().setAlwaysAllowMmsData(alwaysAllow);
8027 } finally {
8028 Binder.restoreCallingIdentity(identity);
8029 }
8030 }
8031
Tyler Gunn7bcdc742019-10-04 15:56:59 -07008032 /**
8033 * Updates whether conference event pacakge handling is enabled.
8034 * @param isCepEnabled {@code true} if CEP handling is enabled (default), or {@code false}
8035 * otherwise.
8036 */
8037 @Override
8038 public void setCepEnabled(boolean isCepEnabled) {
8039 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setCepEnabled");
8040
8041 final long identity = Binder.clearCallingIdentity();
8042 try {
8043 Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled);
8044 for (Phone phone : PhoneFactory.getPhones()) {
8045 Phone defaultPhone = phone.getImsPhone();
8046 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
8047 ImsPhone imsPhone = (ImsPhone) defaultPhone;
8048 ImsPhoneCallTracker imsPhoneCallTracker =
8049 (ImsPhoneCallTracker) imsPhone.getCallTracker();
8050 imsPhoneCallTracker.setConferenceEventPackageEnabled(isCepEnabled);
8051 Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled + ", for imsPhone "
8052 + imsPhone.getMsisdn());
8053 }
8054 }
8055 } finally {
8056 Binder.restoreCallingIdentity(identity);
8057 }
8058 }
allenwtsu46dcc572020-01-08 18:24:03 +08008059
8060 /**
8061 * Notify that an RCS autoconfiguration XML file has been received for provisioning.
8062 *
8063 * @param config The XML file to be read. ASCII/UTF8 encoded text if not compressed.
8064 * @param isCompressed The XML file is compressed in gzip format and must be decompressed
8065 * before being read.
8066 */
8067 @Override
8068 public void notifyRcsAutoConfigurationReceived(int subId, @NonNull byte[] config, boolean
8069 isCompressed) {
8070 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8071 mApp, subId, "notifyRcsAutoConfigurationReceived");
8072 try {
8073 IImsConfig configBinder = getImsConfig(getSlotIndex(subId), ImsFeature.FEATURE_RCS);
8074 if (configBinder == null) {
8075 Rlog.e(LOG_TAG, "null result for getImsConfig");
8076 } else {
8077 configBinder.notifyRcsAutoConfigurationReceived(config, isCompressed);
8078 }
8079 } catch (RemoteException e) {
8080 Rlog.e(LOG_TAG, "fail to getImsConfig " + e.getMessage());
8081 }
8082 }
zoey chene02881a2019-12-30 16:11:23 +08008083
8084 @Override
8085 public boolean isIccLockEnabled(int subId) {
8086 enforceReadPrivilegedPermission("isIccLockEnabled");
8087
8088 // Now that all security checks passes, perform the operation as ourselves.
8089 final long identity = Binder.clearCallingIdentity();
8090 try {
8091 Phone phone = getPhone(subId);
8092 if (phone != null && phone.getIccCard() != null) {
8093 return phone.getIccCard().getIccLockEnabled();
8094 } else {
8095 return false;
8096 }
8097 } finally {
8098 Binder.restoreCallingIdentity(identity);
8099 }
8100 }
8101
8102 /**
8103 * Set the ICC pin lock enabled or disabled.
8104 *
8105 * @return an integer representing the status of IccLock enabled or disabled in the following
8106 * three cases:
8107 * - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if enabled or disabled IccLock
8108 * successfully.
8109 * - Positive number and zero for remaining password attempts.
8110 * - Negative number for other failure cases (such like enabling/disabling PIN failed).
8111 *
8112 */
8113 @Override
8114 public int setIccLockEnabled(int subId, boolean enabled, String password) {
8115 enforceModifyPermission();
8116
8117 Phone phone = getPhone(subId);
8118 if (phone == null) {
8119 return 0;
8120 }
8121 // Now that all security checks passes, perform the operation as ourselves.
8122 final long identity = Binder.clearCallingIdentity();
8123 try {
8124 int attemptsRemaining = (int) sendRequest(CMD_SET_ICC_LOCK_ENABLED,
8125 new Pair<Boolean, String>(enabled, password), phone, null);
8126 return attemptsRemaining;
8127
8128 } catch (Exception e) {
8129 Log.e(LOG_TAG, "setIccLockEnabled. Exception e =" + e);
8130 } finally {
8131 Binder.restoreCallingIdentity(identity);
8132 }
8133 return 0;
8134 }
8135
8136 /**
8137 * Change the ICC password used in ICC pin lock.
8138 *
8139 * @return an integer representing the status of IccLock changed in the following three cases:
8140 * - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if changed IccLock successfully.
8141 * - Positive number and zero for remaining password attempts.
8142 * - Negative number for other failure cases (such like enabling/disabling PIN failed).
8143 *
8144 */
8145 @Override
8146 public int changeIccLockPassword(int subId, String oldPassword, String newPassword) {
8147 enforceModifyPermission();
8148
8149 Phone phone = getPhone(subId);
8150 if (phone == null) {
8151 return 0;
8152 }
8153 // Now that all security checks passes, perform the operation as ourselves.
8154 final long identity = Binder.clearCallingIdentity();
8155 try {
8156 int attemptsRemaining = (int) sendRequest(CMD_CHANGE_ICC_LOCK_PASSWORD,
8157 new Pair<String, String>(oldPassword, newPassword), phone, null);
8158 return attemptsRemaining;
8159
8160 } catch (Exception e) {
8161 Log.e(LOG_TAG, "changeIccLockPassword. Exception e =" + e);
8162 } finally {
8163 Binder.restoreCallingIdentity(identity);
8164 }
8165 return 0;
8166 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07008167}