blob: 9082025c7961bb7d5275555bcd8e9ada7ce697c5 [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;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070038import android.net.Uri;
39import android.os.AsyncResult;
40import android.os.Binder;
Hall Liuf19c44f2018-11-27 14:38:17 -080041import android.os.Build;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070042import android.os.Bundle;
43import android.os.Handler;
yinxu504e1392017-04-12 16:03:22 -070044import android.os.IBinder;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070045import android.os.Looper;
46import android.os.Message;
yinxu504e1392017-04-12 16:03:22 -070047import android.os.Messenger;
Hall Liua1548bd2019-12-24 14:14:12 -080048import android.os.ParcelFileDescriptor;
Malcolm Chen6ca97372019-07-01 16:28:21 -070049import android.os.ParcelUuid;
Tyler Gunn65d45c22017-06-05 11:22:26 -070050import android.os.PersistableBundle;
Shuo Qiancd19c462020-01-16 20:51:11 -080051import android.os.Process;
Brad Ebinger5f64b052017-12-14 14:26:15 -080052import android.os.RemoteException;
Adam Lesinski903a54c2016-04-11 14:49:52 -070053import android.os.ResultReceiver;
Brad Ebinger1ce9c432019-07-16 13:19:44 -070054import android.os.ServiceSpecificException;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070055import android.os.UserHandle;
Stuart Scott981d8582015-04-21 14:09:50 -070056import android.os.UserManager;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070057import android.os.WorkSource;
Derek Tan97ebb422014-09-05 16:55:38 -070058import android.preference.PreferenceManager;
Naina Nallurid63128d2019-09-17 14:10:30 -070059import android.provider.DeviceConfig;
Ihab Awadf2177b72013-11-25 13:33:23 -080060import android.provider.Settings;
Amit Mahajan7dbbd822019-03-13 17:33:47 -070061import android.provider.Telephony;
Inseob Kim14bb3d02018-12-13 17:11:34 +090062import android.sysprop.TelephonyProperties;
Santos Cordon7a1885b2015-02-03 11:15:19 -080063import android.telecom.PhoneAccount;
Nancy Chen31f9ba12016-01-06 11:42:12 -080064import android.telecom.PhoneAccountHandle;
Andrew Lee9431b832015-03-09 18:46:45 -070065import android.telecom.TelecomManager;
Chen Xu227e06f2019-09-26 22:48:11 -070066import android.telephony.Annotation.ApnType;
Jack Nudelmanb0b87642020-11-12 15:04:39 -080067import android.telephony.Annotation.ThermalMitigationResult;
Shuo Qian4a594052020-01-23 11:59:30 -080068import android.telephony.CallForwardingInfo;
Sooraj Sasindran4deb8872020-10-30 13:17:53 -070069import android.telephony.CarrierBandwidth;
Junda Liu12f7d802015-05-01 12:06:44 -070070import android.telephony.CarrierConfigManager;
Michele Berionne482f8202018-11-27 18:57:59 -080071import android.telephony.CarrierRestrictionRules;
yincheng zhao2737e882019-09-06 17:06:54 -070072import android.telephony.CellIdentity;
Meng Wanga10e89e2019-12-09 13:13:01 -080073import android.telephony.CellIdentityCdma;
74import android.telephony.CellIdentityGsm;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070075import android.telephony.CellInfo;
Nathan Haroldf180aac2018-06-01 18:43:55 -070076import android.telephony.CellInfoGsm;
77import android.telephony.CellInfoWcdma;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070078import android.telephony.ClientRequestStats;
Jack Nudelmanb0b87642020-11-12 15:04:39 -080079import android.telephony.DataThrottlingRequest;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -070080import android.telephony.ICellInfoCallback;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -070081import android.telephony.IccOpenLogicalChannelResponse;
Hall Liu1aa510f2017-11-22 17:40:08 -080082import android.telephony.LocationAccessPolicy;
Ta-wei Yen87c49842016-05-13 21:19:52 -070083import android.telephony.ModemActivityInfo;
Jake Hambye994d462014-02-03 13:10:13 -080084import android.telephony.NeighboringCellInfo;
yinxu504e1392017-04-12 16:03:22 -070085import android.telephony.NetworkScanRequest;
Michele4245e952019-02-04 11:36:23 -080086import android.telephony.PhoneCapability;
Hall Liud892bec2018-11-30 14:51:45 -080087import android.telephony.PhoneNumberRange;
Wink Saville5d475dd2014-10-17 15:00:58 -070088import android.telephony.RadioAccessFamily;
Hall Liub2ac8ef2019-02-28 15:56:23 -080089import android.telephony.RadioAccessSpecifier;
Daniel Bright59e67312020-11-13 11:49:37 -080090import android.telephony.RadioInterfaceCapabilities;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070091import android.telephony.ServiceState;
Nathan Harold46b42aa2017-03-10 19:38:22 -080092import android.telephony.SignalStrength;
Wink Saville0f3b5fc2014-11-11 08:40:49 -080093import android.telephony.SubscriptionInfo;
Jeff Sharkey85190e62014-12-05 09:40:12 -080094import android.telephony.SubscriptionManager;
Peter Wangc035ce42020-01-08 21:00:22 -080095import android.telephony.TelephonyFrameworkInitializer;
Sanket Padawe99ef1e32016-05-18 16:12:33 -070096import android.telephony.TelephonyHistogram;
Ta-wei Yenb6929602016-05-24 15:48:27 -070097import android.telephony.TelephonyManager;
Hall Liub2ac8ef2019-02-28 15:56:23 -080098import android.telephony.TelephonyScanManager;
Jack Nudelmanb0b87642020-11-12 15:04:39 -080099import android.telephony.ThermalMitigationRequest;
Jordan Liu5aa07002018-12-18 15:44:48 -0800100import android.telephony.UiccCardInfo;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000101import android.telephony.UiccSlotInfo;
Tyler Gunn65d45c22017-06-05 11:22:26 -0700102import android.telephony.UssdResponse;
Ta-wei Yenb6929602016-05-24 15:48:27 -0700103import android.telephony.VisualVoicemailSmsFilterSettings;
Jack Yub5d8f642018-11-26 11:20:48 -0800104import android.telephony.data.ApnSetting;
105import android.telephony.emergency.EmergencyNumber;
Brad Ebinger1ce9c432019-07-16 13:19:44 -0700106import android.telephony.ims.ImsException;
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800107import android.telephony.ims.ProvisioningManager;
Brad Ebingera34a6c22019-10-22 17:36:18 -0700108import android.telephony.ims.RegistrationManager;
Brad Ebinger35c841c2018-10-01 10:40:55 -0700109import android.telephony.ims.aidl.IImsCapabilityCallback;
Brad Ebinger22bc3e42018-01-16 09:39:35 -0800110import android.telephony.ims.aidl.IImsConfig;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -0700111import android.telephony.ims.aidl.IImsConfigCallback;
Brad Ebinger22bc3e42018-01-16 09:39:35 -0800112import android.telephony.ims.aidl.IImsRegistration;
Brad Ebinger35c841c2018-10-01 10:40:55 -0700113import android.telephony.ims.aidl.IImsRegistrationCallback;
Brad Ebingerbc7dd582019-10-17 17:03:22 -0700114import android.telephony.ims.feature.ImsFeature;
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800115import android.telephony.ims.feature.MmTelFeature;
allenwtsu99c623b2020-01-03 18:24:23 +0800116import android.telephony.ims.feature.RcsFeature;
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800117import android.telephony.ims.stub.ImsConfigImplBase;
Brad Ebinger1f2b5082018-02-08 16:11:32 -0800118import android.telephony.ims.stub.ImsRegistrationImplBase;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700119import android.text.TextUtils;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800120import android.util.ArraySet;
Hall Liud60acc92020-05-21 17:09:35 -0700121import android.util.EventLog;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700122import android.util.Log;
Jake Hambye994d462014-02-03 13:10:13 -0800123import android.util.Pair;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800124
Andrew Lee312e8172014-10-23 17:01:36 -0700125import com.android.ims.ImsManager;
Brad Ebinger34bef922017-11-09 10:27:08 -0800126import com.android.ims.internal.IImsServiceFeatureCallback;
Shuo Qian4a594052020-01-23 11:59:30 -0800127import com.android.internal.telephony.CallForwardInfo;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700128import com.android.internal.telephony.CallManager;
Tyler Gunn52dcf772017-04-26 11:30:31 -0700129import com.android.internal.telephony.CallStateException;
pkanwar79ec0542017-07-31 14:10:01 -0700130import com.android.internal.telephony.CarrierInfoManager;
chen xu651eec72018-11-11 19:03:44 -0800131import com.android.internal.telephony.CarrierResolver;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700132import com.android.internal.telephony.CellNetworkScanResult;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700133import com.android.internal.telephony.CommandException;
Shuo Qian4a594052020-01-23 11:59:30 -0800134import com.android.internal.telephony.CommandsInterface;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700135import com.android.internal.telephony.DefaultPhoneNotifier;
Nathan Harold48d6fd52019-02-06 19:01:40 -0800136import com.android.internal.telephony.HalVersion;
Hall Liu73f5d362020-01-20 13:42:00 -0800137import com.android.internal.telephony.IBooleanConsumer;
Hall Liu27d24262020-09-18 19:04:59 -0700138import com.android.internal.telephony.ICallForwardingInfoCallback;
Brad Ebingera63db5f2019-04-23 16:31:13 -0700139import com.android.internal.telephony.IIntegerConsumer;
Hall Liud892bec2018-11-30 14:51:45 -0800140import com.android.internal.telephony.INumberVerificationCallback;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700141import com.android.internal.telephony.ITelephony;
Jake Hambye994d462014-02-03 13:10:13 -0800142import com.android.internal.telephony.IccCard;
Jack Yu5f7092c2018-04-13 14:05:37 -0700143import com.android.internal.telephony.LocaleTracker;
yinxub1bed742017-04-17 11:45:04 -0700144import com.android.internal.telephony.NetworkScanRequestTracker;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700145import com.android.internal.telephony.OperatorInfo;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700146import com.android.internal.telephony.Phone;
Malcolm Chen2c63d402018-08-14 16:00:53 -0700147import com.android.internal.telephony.PhoneConfigurationManager;
Nathan Harolda667c152016-12-14 11:27:20 -0800148import com.android.internal.telephony.PhoneConstantConversions;
Ta-wei Yen87c49842016-05-13 21:19:52 -0700149import com.android.internal.telephony.PhoneConstants;
Wink Saville36469e72014-06-11 15:17:00 -0700150import com.android.internal.telephony.PhoneFactory;
Wink Saville5d475dd2014-10-17 15:00:58 -0700151import com.android.internal.telephony.ProxyController;
Sanket Padawe99ef1e32016-05-18 16:12:33 -0700152import com.android.internal.telephony.RIL;
Svet Ganovb320e182015-04-16 12:30:10 -0700153import com.android.internal.telephony.RILConstants;
Jack Yu5f7092c2018-04-13 14:05:37 -0700154import com.android.internal.telephony.ServiceStateTracker;
Amit Mahajandccb3f12019-05-13 13:48:32 -0700155import com.android.internal.telephony.SmsController;
Brad Ebingera63db5f2019-04-23 16:31:13 -0700156import com.android.internal.telephony.SmsPermissions;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800157import com.android.internal.telephony.SubscriptionController;
Peter Wang59571be2020-01-27 12:35:15 +0800158import com.android.internal.telephony.TelephonyIntents;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800159import com.android.internal.telephony.TelephonyPermissions;
Malcolm Chendc8c10e2019-04-10 18:25:07 -0700160import com.android.internal.telephony.dataconnection.ApnSettingUtils;
sqianf4ca7ed2019-01-15 18:32:07 -0800161import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Derek Tan740e1672017-06-27 14:56:27 -0700162import com.android.internal.telephony.euicc.EuiccConnector;
Brad Ebinger9c0eb502019-01-23 15:06:19 -0800163import com.android.internal.telephony.ims.ImsResolver;
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700164import com.android.internal.telephony.imsphone.ImsPhone;
165import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
Pengquan Meng6c2dc9f2019-02-06 11:12:53 -0800166import com.android.internal.telephony.metrics.TelephonyMetrics;
Meng Wangafbc5852019-09-19 17:37:13 -0700167import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700168import com.android.internal.telephony.uicc.IccIoResult;
changbetty7157e9e2019-12-06 18:16:37 +0800169import com.android.internal.telephony.uicc.IccRecords;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700170import com.android.internal.telephony.uicc.IccUtils;
Nathan Haroldb3014052017-01-25 15:57:32 -0800171import com.android.internal.telephony.uicc.SIMRecords;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700172import com.android.internal.telephony.uicc.UiccCard;
Nathan Haroldb3014052017-01-25 15:57:32 -0800173import com.android.internal.telephony.uicc.UiccCardApplication;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700174import com.android.internal.telephony.uicc.UiccController;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800175import com.android.internal.telephony.uicc.UiccProfile;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000176import com.android.internal.telephony.uicc.UiccSlot;
zoey chenc730df82019-12-18 17:07:20 +0800177import com.android.internal.telephony.util.LocaleUtils;
fionaxu7ed723d2017-05-30 18:58:54 -0700178import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
Hall Liu27d24262020-09-18 19:04:59 -0700179import com.android.internal.util.FunctionalUtils;
Jake Hambye994d462014-02-03 13:10:13 -0800180import com.android.internal.util.HexDump;
Brad Ebingera63db5f2019-04-23 16:31:13 -0700181import com.android.phone.settings.PickSmsSubscriptionActivity;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700182import com.android.phone.vvm.PhoneAccountHandleConverter;
Ta-wei Yen527a9c02017-01-06 15:29:25 -0800183import com.android.phone.vvm.RemoteVvmTaskManager;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700184import com.android.phone.vvm.VisualVoicemailSettingsUtil;
Ta-wei Yenc8905312017-03-28 11:14:45 -0700185import com.android.phone.vvm.VisualVoicemailSmsFilterConfig;
Jack Nudelmanb0b87642020-11-12 15:04:39 -0800186import com.android.services.telephony.TelecomAccountRegistry;
187import com.android.services.telephony.TelephonyConnectionService;
Peter Wang44b186e2020-01-13 23:33:09 -0800188import com.android.telephony.Rlog;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800189
Ta-wei Yenc236d6b2016-06-21 13:33:12 -0700190import java.io.FileDescriptor;
191import java.io.PrintWriter;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700192import java.util.ArrayList;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800193import java.util.Arrays;
sqian11b7a0e2018-12-05 18:48:28 -0800194import java.util.HashMap;
sqianf4ca7ed2019-01-15 18:32:07 -0800195import java.util.HashSet;
Jake Hambye994d462014-02-03 13:10:13 -0800196import java.util.List;
Narayan Kamath1c496c22015-04-16 14:40:19 +0100197import java.util.Locale;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800198import java.util.Map;
Nazanin Bakhshif71371d2019-04-29 17:29:44 -0700199import java.util.NoSuchElementException;
sqianf4ca7ed2019-01-15 18:32:07 -0800200import java.util.Set;
Peter Wangdafb9ac2020-01-15 14:13:38 -0800201import java.util.concurrent.atomic.AtomicBoolean;
Hall Liu73f5d362020-01-20 13:42:00 -0800202import java.util.function.Consumer;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700203
204/**
205 * Implementation of the ITelephony interface.
206 */
Santos Cordon117fee72014-05-16 17:56:12 -0700207public class PhoneInterfaceManager extends ITelephony.Stub {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700208 private static final String LOG_TAG = "PhoneInterfaceManager";
209 private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
210 private static final boolean DBG_LOC = false;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800211 private static final boolean DBG_MERGE = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700212
213 // Message codes used with mMainThreadHandler
214 private static final int CMD_HANDLE_PIN_MMI = 1;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700215 private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7;
216 private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700217 private static final int CMD_OPEN_CHANNEL = 9;
218 private static final int EVENT_OPEN_CHANNEL_DONE = 10;
219 private static final int CMD_CLOSE_CHANNEL = 11;
220 private static final int EVENT_CLOSE_CHANNEL_DONE = 12;
Jake Hambye994d462014-02-03 13:10:13 -0800221 private static final int CMD_NV_READ_ITEM = 13;
222 private static final int EVENT_NV_READ_ITEM_DONE = 14;
223 private static final int CMD_NV_WRITE_ITEM = 15;
224 private static final int EVENT_NV_WRITE_ITEM_DONE = 16;
225 private static final int CMD_NV_WRITE_CDMA_PRL = 17;
226 private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18;
chen xu6dac5ab2018-10-26 17:39:23 -0700227 private static final int CMD_RESET_MODEM_CONFIG = 19;
228 private static final int EVENT_RESET_MODEM_CONFIG_DONE = 20;
Jake Hamby7c27be32014-03-03 13:25:59 -0800229 private static final int CMD_GET_PREFERRED_NETWORK_TYPE = 21;
230 private static final int EVENT_GET_PREFERRED_NETWORK_TYPE_DONE = 22;
231 private static final int CMD_SET_PREFERRED_NETWORK_TYPE = 23;
232 private static final int EVENT_SET_PREFERRED_NETWORK_TYPE_DONE = 24;
Sailesh Nepal35b59452014-03-06 09:26:56 -0800233 private static final int CMD_SEND_ENVELOPE = 25;
234 private static final int EVENT_SEND_ENVELOPE_DONE = 26;
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000235 private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27;
236 private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28;
Derek Tan6b088ee2014-09-05 14:15:18 -0700237 private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29;
238 private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30;
239 private static final int CMD_EXCHANGE_SIM_IO = 31;
240 private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800241 private static final int CMD_SET_VOICEMAIL_NUMBER = 33;
242 private static final int EVENT_SET_VOICEMAIL_NUMBER_DONE = 34;
Stuart Scott54788802015-03-30 13:18:01 -0700243 private static final int CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC = 35;
244 private static final int EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE = 36;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700245 private static final int CMD_GET_MODEM_ACTIVITY_INFO = 37;
246 private static final int EVENT_GET_MODEM_ACTIVITY_INFO_DONE = 38;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700247 private static final int CMD_PERFORM_NETWORK_SCAN = 39;
248 private static final int EVENT_PERFORM_NETWORK_SCAN_DONE = 40;
249 private static final int CMD_SET_NETWORK_SELECTION_MODE_MANUAL = 41;
250 private static final int EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE = 42;
Meng Wang1a7c35a2016-05-05 20:56:15 -0700251 private static final int CMD_SET_ALLOWED_CARRIERS = 43;
252 private static final int EVENT_SET_ALLOWED_CARRIERS_DONE = 44;
253 private static final int CMD_GET_ALLOWED_CARRIERS = 45;
254 private static final int EVENT_GET_ALLOWED_CARRIERS_DONE = 46;
pkanwar32d516d2016-10-14 19:37:38 -0700255 private static final int CMD_HANDLE_USSD_REQUEST = 47;
Nathan Haroldb3014052017-01-25 15:57:32 -0800256 private static final int CMD_GET_FORBIDDEN_PLMNS = 48;
257 private static final int EVENT_GET_FORBIDDEN_PLMNS_DONE = 49;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000258 private static final int CMD_SWITCH_SLOTS = 50;
259 private static final int EVENT_SWITCH_SLOTS_DONE = 51;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700260 private static final int CMD_GET_NETWORK_SELECTION_MODE = 52;
261 private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 53;
262 private static final int CMD_GET_CDMA_ROAMING_MODE = 54;
263 private static final int EVENT_GET_CDMA_ROAMING_MODE_DONE = 55;
264 private static final int CMD_SET_CDMA_ROAMING_MODE = 56;
265 private static final int EVENT_SET_CDMA_ROAMING_MODE_DONE = 57;
266 private static final int CMD_SET_CDMA_SUBSCRIPTION_MODE = 58;
267 private static final int EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE = 59;
Nathan Harold3ff88932018-08-14 10:19:49 -0700268 private static final int CMD_GET_ALL_CELL_INFO = 60;
269 private static final int EVENT_GET_ALL_CELL_INFO_DONE = 61;
270 private static final int CMD_GET_CELL_LOCATION = 62;
271 private static final int EVENT_GET_CELL_LOCATION_DONE = 63;
chen xu6dac5ab2018-10-26 17:39:23 -0700272 private static final int CMD_MODEM_REBOOT = 64;
273 private static final int EVENT_CMD_MODEM_REBOOT_DONE = 65;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -0700274 private static final int CMD_REQUEST_CELL_INFO_UPDATE = 66;
275 private static final int EVENT_REQUEST_CELL_INFO_UPDATE_DONE = 67;
Malcolm Chen8e4ed912019-01-15 20:22:16 -0800276 private static final int CMD_REQUEST_ENABLE_MODEM = 68;
277 private static final int EVENT_ENABLE_MODEM_DONE = 69;
Nazanin Bakhshif71371d2019-04-29 17:29:44 -0700278 private static final int CMD_GET_MODEM_STATUS = 70;
279 private static final int EVENT_GET_MODEM_STATUS_DONE = 71;
yincheng zhao2737e882019-09-06 17:06:54 -0700280 private static final int CMD_SET_FORBIDDEN_PLMNS = 72;
281 private static final int EVENT_SET_FORBIDDEN_PLMNS_DONE = 73;
Naina Nallurid63128d2019-09-17 14:10:30 -0700282 private static final int CMD_ERASE_MODEM_CONFIG = 74;
283 private static final int EVENT_ERASE_MODEM_CONFIG_DONE = 75;
zoey chene02881a2019-12-30 16:11:23 +0800284 private static final int CMD_CHANGE_ICC_LOCK_PASSWORD = 76;
285 private static final int EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE = 77;
286 private static final int CMD_SET_ICC_LOCK_ENABLED = 78;
287 private static final int EVENT_SET_ICC_LOCK_ENABLED_DONE = 79;
Hall Liu73f5d362020-01-20 13:42:00 -0800288 private static final int CMD_SET_SYSTEM_SELECTION_CHANNELS = 80;
289 private static final int EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE = 81;
Peter Wangdafb9ac2020-01-15 14:13:38 -0800290 private static final int MSG_NOTIFY_USER_ACTIVITY = 82;
Shuo Qian4a594052020-01-23 11:59:30 -0800291 private static final int CMD_GET_CALL_FORWARDING = 83;
292 private static final int EVENT_GET_CALL_FORWARDING_DONE = 84;
293 private static final int CMD_SET_CALL_FORWARDING = 85;
294 private static final int EVENT_SET_CALL_FORWARDING_DONE = 86;
295 private static final int CMD_GET_CALL_WAITING = 87;
296 private static final int EVENT_GET_CALL_WAITING_DONE = 88;
297 private static final int CMD_SET_CALL_WAITING = 89;
298 private static final int EVENT_SET_CALL_WAITING_DONE = 90;
Sooraj Sasindran37444802020-08-11 10:40:43 -0700299 private static final int CMD_ENABLE_NR_DUAL_CONNECTIVITY = 91;
300 private static final int EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE = 92;
301 private static final int CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED = 93;
302 private static final int EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE = 94;
Sarah Chinbaab1432020-10-28 13:46:24 -0700303 private static final int CMD_GET_CDMA_SUBSCRIPTION_MODE = 95;
304 private static final int EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE = 96;
Sarah Chin679c08a2020-11-18 13:39:35 -0800305 private static final int CMD_GET_SYSTEM_SELECTION_CHANNELS = 97;
306 private static final int EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE = 98;
Jack Nudelmanb0b87642020-11-12 15:04:39 -0800307 private static final int CMD_SET_DATA_THROTTLING = 99;
308 private static final int EVENT_SET_DATA_THROTTLING_DONE = 100;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700309
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -0800310 // Parameters of select command.
311 private static final int SELECT_COMMAND = 0xA4;
312 private static final int SELECT_P1 = 0x04;
313 private static final int SELECT_P2 = 0;
314 private static final int SELECT_P3 = 0x10;
315
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700316 /** The singleton instance. */
317 private static PhoneInterfaceManager sInstance;
318
Wink Saville3ab207e2014-11-20 13:07:20 -0800319 private PhoneGlobals mApp;
Wink Saville3ab207e2014-11-20 13:07:20 -0800320 private CallManager mCM;
Brad Ebinger24c29992019-12-05 13:03:21 -0800321 private ImsResolver mImsResolver;
Stuart Scott981d8582015-04-21 14:09:50 -0700322 private UserManager mUserManager;
Wink Saville3ab207e2014-11-20 13:07:20 -0800323 private AppOpsManager mAppOps;
324 private MainThreadHandler mMainThreadHandler;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800325 private SubscriptionController mSubscriptionController;
Wink Saville3ab207e2014-11-20 13:07:20 -0800326 private SharedPreferences mTelephonySharedPreferences;
Malcolm Chen2c63d402018-08-14 16:00:53 -0700327 private PhoneConfigurationManager mPhoneConfigurationManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700328
Peter Wangdafb9ac2020-01-15 14:13:38 -0800329 /** User Activity */
330 private AtomicBoolean mNotifyUserActivity;
Peter Wangdafb9ac2020-01-15 14:13:38 -0800331 private static final int USER_ACTIVITY_NOTIFICATION_DELAY = 200;
332
Jeff Davidson8ab02b22020-03-28 12:24:40 -0700333 private Set<Integer> mCarrierPrivilegeTestOverrideSubIds = new ArraySet<>();
334
Derek Tan97ebb422014-09-05 16:55:38 -0700335 private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
336 private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
Jeff Sharkey85190e62014-12-05 09:40:12 -0800337 private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800338 private static final String PREF_PROVISION_IMS_MMTEL_PREFIX = "provision_ims_mmtel_";
Derek Tan89e89d42014-07-08 17:00:10 -0700339
Michelecea4cf22018-12-21 15:00:11 -0800340 // String to store multi SIM allowed
341 private static final String PREF_MULTI_SIM_RESTRICTED = "multisim_restricted";
342
Derek Tan740e1672017-06-27 14:56:27 -0700343 // The AID of ISD-R.
344 private static final String ISDR_AID = "A0000005591010FFFFFFFF8900000100";
345
yinxub1bed742017-04-17 11:45:04 -0700346 private NetworkScanRequestTracker mNetworkScanRequestTracker;
347
David Kelly5e06a7f2018-03-12 14:10:59 +0000348 private static final int TYPE_ALLOCATION_CODE_LENGTH = 8;
349 private static final int MANUFACTURER_CODE_LENGTH = 8;
350
Jack Nudelmanb0b87642020-11-12 15:04:39 -0800351 private static final int SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS = -1;
352
Derek Tan89e89d42014-07-08 17:00:10 -0700353 /**
Naina Nallurid63128d2019-09-17 14:10:30 -0700354 * Experiment flag to enable erase modem config on reset network, default value is false
355 */
356 public static final String RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED =
357 "reset_network_erase_modem_config_enabled";
358
359 /**
Shishir Agrawal566b7612013-10-28 14:41:00 -0700360 * A request object to use for transmitting data to an ICC.
361 */
362 private static final class IccAPDUArgument {
363 public int channel, cla, command, p1, p2, p3;
364 public String data;
365
366 public IccAPDUArgument(int channel, int cla, int command,
367 int p1, int p2, int p3, String data) {
368 this.channel = channel;
369 this.cla = cla;
370 this.command = command;
371 this.p1 = p1;
372 this.p2 = p2;
373 this.p3 = p3;
374 this.data = data;
375 }
376 }
377
378 /**
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700379 * A request object to use for transmitting data to an ICC.
380 */
381 private static final class ManualNetworkSelectionArgument {
382 public OperatorInfo operatorInfo;
383 public boolean persistSelection;
384
385 public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) {
386 this.operatorInfo = operatorInfo;
387 this.persistSelection = persistSelection;
388 }
389 }
390
391 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700392 * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
393 * request after sending. The main thread will notify the request when it is complete.
394 */
395 private static final class MainThreadRequest {
396 /** The argument to use for the request */
397 public Object argument;
398 /** The result of the request that is run on the main thread */
399 public Object result;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800400 // The subscriber id that this request applies to. Defaults to
401 // SubscriptionManager.INVALID_SUBSCRIPTION_ID
402 public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700403
Nathan Harold92bed182018-10-12 18:16:49 -0700404 // In cases where subId is unavailable, the caller needs to specify the phone.
405 public Phone phone;
406
vagdeviaf9a5b92018-08-15 16:01:53 -0700407 public WorkSource workSource;
408
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700409 public MainThreadRequest(Object argument) {
410 this.argument = argument;
411 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800412
Nathan Harold92bed182018-10-12 18:16:49 -0700413 MainThreadRequest(Object argument, Phone phone, WorkSource workSource) {
414 this.argument = argument;
415 if (phone != null) {
416 this.phone = phone;
417 }
418 this.workSource = workSource;
419 }
420
vagdeviaf9a5b92018-08-15 16:01:53 -0700421 MainThreadRequest(Object argument, Integer subId, WorkSource workSource) {
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800422 this.argument = argument;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800423 if (subId != null) {
424 this.subId = subId;
425 }
vagdeviaf9a5b92018-08-15 16:01:53 -0700426 this.workSource = workSource;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800427 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700428 }
429
Sailesh Nepalcc0375f2013-11-13 09:15:18 -0800430 private static final class IncomingThirdPartyCallArgs {
431 public final ComponentName component;
432 public final String callId;
433 public final String callerDisplayName;
434
435 public IncomingThirdPartyCallArgs(ComponentName component, String callId,
436 String callerDisplayName) {
437 this.component = component;
438 this.callId = callId;
439 this.callerDisplayName = callerDisplayName;
440 }
441 }
442
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700443 /**
444 * A handler that processes messages on the main thread in the phone process. Since many
445 * of the Phone calls are not thread safe this is needed to shuttle the requests from the
446 * inbound binder threads to the main thread in the phone process. The Binder thread
447 * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
448 * on, which will be notified when the operation completes and will contain the result of the
449 * request.
450 *
451 * <p>If a MainThreadRequest object is provided in the msg.obj field,
452 * note that request.result must be set to something non-null for the calling thread to
453 * unblock.
454 */
455 private final class MainThreadHandler extends Handler {
456 @Override
457 public void handleMessage(Message msg) {
458 MainThreadRequest request;
459 Message onCompleted;
460 AsyncResult ar;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800461 UiccCard uiccCard;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700462 IccAPDUArgument iccArgument;
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800463 final Phone defaultPhone = getDefaultPhone();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700464
465 switch (msg.what) {
Pengquan Menga1bb6272018-09-06 09:59:22 -0700466 case CMD_HANDLE_USSD_REQUEST: {
467 request = (MainThreadRequest) msg.obj;
468 final Phone phone = getPhoneFromRequest(request);
469 Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
470 String ussdRequest = ussdObject.first;
471 ResultReceiver wrappedCallback = ussdObject.second;
Tyler Gunn65d45c22017-06-05 11:22:26 -0700472
Pengquan Menga1bb6272018-09-06 09:59:22 -0700473 if (!isUssdApiAllowed(request.subId)) {
474 // Carrier does not support use of this API, return failure.
475 Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
476 UssdResponse response = new UssdResponse(ussdRequest, null);
477 Bundle returnData = new Bundle();
478 returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
479 wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
Tyler Gunn65d45c22017-06-05 11:22:26 -0700480
Pengquan Menga1bb6272018-09-06 09:59:22 -0700481 request.result = true;
482 notifyRequester(request);
483 return;
484 }
Tyler Gunn65d45c22017-06-05 11:22:26 -0700485
Pengquan Menga1bb6272018-09-06 09:59:22 -0700486 try {
487 request.result = phone != null
488 ? phone.handleUssdRequest(ussdRequest, wrappedCallback) : false;
489 } catch (CallStateException cse) {
490 request.result = false;
491 }
492 // Wake up the requesting thread
493 notifyRequester(request);
494 break;
pkanwar32d516d2016-10-14 19:37:38 -0700495 }
496
Yorke Lee716f67e2015-06-17 15:39:16 -0700497 case CMD_HANDLE_PIN_MMI: {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700498 request = (MainThreadRequest) msg.obj;
Yorke Lee716f67e2015-06-17 15:39:16 -0700499 final Phone phone = getPhoneFromRequest(request);
500 request.result = phone != null ?
501 getPhoneFromRequest(request).handlePinMmi((String) request.argument)
502 : false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700503 // Wake up the requesting thread
Pengquan Menga1bb6272018-09-06 09:59:22 -0700504 notifyRequester(request);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700505 break;
Yorke Lee716f67e2015-06-17 15:39:16 -0700506 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700507
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700508 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700509 request = (MainThreadRequest) msg.obj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700510 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800511 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700512 if (uiccCard == null) {
513 loge("iccTransmitApduLogicalChannel: No UICC");
514 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700515 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700516 } else {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700517 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
518 request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700519 uiccCard.iccTransmitApduLogicalChannel(
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700520 iccArgument.channel, iccArgument.cla, iccArgument.command,
521 iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data,
Shishir Agrawal566b7612013-10-28 14:41:00 -0700522 onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700523 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700524 break;
525
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700526 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700527 ar = (AsyncResult) msg.obj;
528 request = (MainThreadRequest) ar.userObj;
529 if (ar.exception == null && ar.result != null) {
530 request.result = ar.result;
531 } else {
532 request.result = new IccIoResult(0x6F, 0, (byte[])null);
533 if (ar.result == null) {
534 loge("iccTransmitApduLogicalChannel: Empty response");
Jake Hambye994d462014-02-03 13:10:13 -0800535 } else if (ar.exception instanceof CommandException) {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700536 loge("iccTransmitApduLogicalChannel: CommandException: " +
Jake Hambye994d462014-02-03 13:10:13 -0800537 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700538 } else {
539 loge("iccTransmitApduLogicalChannel: Unknown exception");
540 }
541 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700542 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700543 break;
544
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700545 case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
546 request = (MainThreadRequest) msg.obj;
547 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800548 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700549 if (uiccCard == null) {
550 loge("iccTransmitApduBasicChannel: No UICC");
551 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700552 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700553 } else {
554 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
555 request);
556 uiccCard.iccTransmitApduBasicChannel(
557 iccArgument.cla, iccArgument.command, iccArgument.p1, iccArgument.p2,
558 iccArgument.p3, iccArgument.data, onCompleted);
559 }
560 break;
561
562 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
563 ar = (AsyncResult) msg.obj;
564 request = (MainThreadRequest) ar.userObj;
565 if (ar.exception == null && ar.result != null) {
566 request.result = ar.result;
567 } else {
568 request.result = new IccIoResult(0x6F, 0, (byte[])null);
569 if (ar.result == null) {
570 loge("iccTransmitApduBasicChannel: Empty response");
571 } else if (ar.exception instanceof CommandException) {
572 loge("iccTransmitApduBasicChannel: CommandException: " +
573 ar.exception);
574 } else {
575 loge("iccTransmitApduBasicChannel: Unknown exception");
576 }
577 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700578 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700579 break;
580
581 case CMD_EXCHANGE_SIM_IO:
582 request = (MainThreadRequest) msg.obj;
583 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800584 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700585 if (uiccCard == null) {
586 loge("iccExchangeSimIO: No UICC");
587 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700588 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700589 } else {
590 onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
591 request);
592 uiccCard.iccExchangeSimIO(iccArgument.cla, /* fileID */
593 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3,
594 iccArgument.data, onCompleted);
595 }
596 break;
597
598 case EVENT_EXCHANGE_SIM_IO_DONE:
599 ar = (AsyncResult) msg.obj;
600 request = (MainThreadRequest) ar.userObj;
601 if (ar.exception == null && ar.result != null) {
602 request.result = ar.result;
603 } else {
604 request.result = new IccIoResult(0x6f, 0, (byte[])null);
605 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700606 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700607 break;
608
Derek Tan4d5e5c12014-02-04 11:54:58 -0800609 case CMD_SEND_ENVELOPE:
610 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800611 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700612 if (uiccCard == null) {
613 loge("sendEnvelopeWithStatus: No UICC");
614 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700615 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700616 } else {
617 onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
618 uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted);
619 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800620 break;
621
622 case EVENT_SEND_ENVELOPE_DONE:
623 ar = (AsyncResult) msg.obj;
624 request = (MainThreadRequest) ar.userObj;
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700625 if (ar.exception == null && ar.result != null) {
626 request.result = ar.result;
Derek Tan4d5e5c12014-02-04 11:54:58 -0800627 } else {
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700628 request.result = new IccIoResult(0x6F, 0, (byte[])null);
629 if (ar.result == null) {
630 loge("sendEnvelopeWithStatus: Empty response");
631 } else if (ar.exception instanceof CommandException) {
632 loge("sendEnvelopeWithStatus: CommandException: " +
633 ar.exception);
634 } else {
635 loge("sendEnvelopeWithStatus: exception:" + ar.exception);
636 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800637 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700638 notifyRequester(request);
Derek Tan4d5e5c12014-02-04 11:54:58 -0800639 break;
640
Shishir Agrawal566b7612013-10-28 14:41:00 -0700641 case CMD_OPEN_CHANNEL:
642 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800643 uiccCard = getUiccCardFromRequest(request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800644 Pair<String, Integer> openChannelArgs = (Pair<String, Integer>) request.argument;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700645 if (uiccCard == null) {
646 loge("iccOpenLogicalChannel: No UICC");
Shishir Agrawalfc0492a2016-02-17 11:15:33 -0800647 request.result = new IccOpenLogicalChannelResponse(-1,
648 IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700649 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700650 } else {
651 onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800652 uiccCard.iccOpenLogicalChannel(openChannelArgs.first,
653 openChannelArgs.second, onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700654 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700655 break;
656
657 case EVENT_OPEN_CHANNEL_DONE:
658 ar = (AsyncResult) msg.obj;
659 request = (MainThreadRequest) ar.userObj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700660 IccOpenLogicalChannelResponse openChannelResp;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700661 if (ar.exception == null && ar.result != null) {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700662 int[] result = (int[]) ar.result;
663 int channelId = result[0];
664 byte[] selectResponse = null;
665 if (result.length > 1) {
666 selectResponse = new byte[result.length - 1];
667 for (int i = 1; i < result.length; ++i) {
668 selectResponse[i - 1] = (byte) result[i];
669 }
670 }
671 openChannelResp = new IccOpenLogicalChannelResponse(channelId,
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700672 IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700673 } else {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700674 if (ar.result == null) {
675 loge("iccOpenLogicalChannel: Empty response");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700676 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700677 if (ar.exception != null) {
678 loge("iccOpenLogicalChannel: Exception: " + ar.exception);
679 }
680
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700681 int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR;
Junda Liua754ba12015-05-20 01:17:52 -0700682 if (ar.exception instanceof CommandException) {
683 CommandException.Error error =
684 ((CommandException) (ar.exception)).getCommandError();
685 if (error == CommandException.Error.MISSING_RESOURCE) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700686 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE;
Junda Liua754ba12015-05-20 01:17:52 -0700687 } else if (error == CommandException.Error.NO_SUCH_ELEMENT) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700688 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700689 }
690 }
691 openChannelResp = new IccOpenLogicalChannelResponse(
692 IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700693 }
Shishir Agrawal82c8a462014-07-31 18:13:17 -0700694 request.result = openChannelResp;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700695 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700696 break;
697
698 case CMD_CLOSE_CHANNEL:
699 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800700 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700701 if (uiccCard == null) {
702 loge("iccCloseLogicalChannel: No UICC");
Yoshiaki Naka2e29d822016-09-02 19:27:39 +0900703 request.result = false;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700704 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700705 } else {
706 onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
707 uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
708 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700709 break;
710
711 case EVENT_CLOSE_CHANNEL_DONE:
Jake Hambye994d462014-02-03 13:10:13 -0800712 handleNullReturnEvent(msg, "iccCloseLogicalChannel");
713 break;
714
715 case CMD_NV_READ_ITEM:
716 request = (MainThreadRequest) msg.obj;
717 onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800718 defaultPhone.nvReadItem((Integer) request.argument, onCompleted,
719 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800720 break;
721
722 case EVENT_NV_READ_ITEM_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700723 ar = (AsyncResult) msg.obj;
724 request = (MainThreadRequest) ar.userObj;
Jake Hambye994d462014-02-03 13:10:13 -0800725 if (ar.exception == null && ar.result != null) {
726 request.result = ar.result; // String
Shishir Agrawal566b7612013-10-28 14:41:00 -0700727 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800728 request.result = "";
729 if (ar.result == null) {
730 loge("nvReadItem: Empty response");
731 } else if (ar.exception instanceof CommandException) {
732 loge("nvReadItem: CommandException: " +
733 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700734 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800735 loge("nvReadItem: Unknown exception");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700736 }
737 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700738 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700739 break;
740
Jake Hambye994d462014-02-03 13:10:13 -0800741 case CMD_NV_WRITE_ITEM:
742 request = (MainThreadRequest) msg.obj;
743 onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
744 Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800745 defaultPhone.nvWriteItem(idValue.first, idValue.second, onCompleted,
vagdeviaf9a5b92018-08-15 16:01:53 -0700746 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800747 break;
748
749 case EVENT_NV_WRITE_ITEM_DONE:
750 handleNullReturnEvent(msg, "nvWriteItem");
751 break;
752
753 case CMD_NV_WRITE_CDMA_PRL:
754 request = (MainThreadRequest) msg.obj;
755 onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800756 defaultPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
Jake Hambye994d462014-02-03 13:10:13 -0800757 break;
758
759 case EVENT_NV_WRITE_CDMA_PRL_DONE:
760 handleNullReturnEvent(msg, "nvWriteCdmaPrl");
761 break;
762
chen xu6dac5ab2018-10-26 17:39:23 -0700763 case CMD_RESET_MODEM_CONFIG:
Jake Hambye994d462014-02-03 13:10:13 -0800764 request = (MainThreadRequest) msg.obj;
chen xu6dac5ab2018-10-26 17:39:23 -0700765 onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800766 defaultPhone.resetModemConfig(onCompleted);
Jake Hambye994d462014-02-03 13:10:13 -0800767 break;
768
chen xu6dac5ab2018-10-26 17:39:23 -0700769 case EVENT_RESET_MODEM_CONFIG_DONE:
770 handleNullReturnEvent(msg, "resetModemConfig");
Jake Hambye994d462014-02-03 13:10:13 -0800771 break;
772
Sooraj Sasindran37444802020-08-11 10:40:43 -0700773 case CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED: {
774 request = (MainThreadRequest) msg.obj;
775 onCompleted = obtainMessage(EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE,
776 request);
777 Phone phone = getPhoneFromRequest(request);
778 if (phone != null) {
779 phone.isNrDualConnectivityEnabled(onCompleted, request.workSource);
780 } else {
781 loge("isNRDualConnectivityEnabled: No phone object");
782 request.result = false;
783 notifyRequester(request);
784 }
785 break;
786 }
787
788 case EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE:
789 ar = (AsyncResult) msg.obj;
790 request = (MainThreadRequest) ar.userObj;
791 if (ar.exception == null && ar.result != null) {
792 request.result = ar.result;
793 } else {
794 // request.result must be set to something non-null
795 // for the calling thread to unblock
796 if (request.result != null) {
797 request.result = ar.result;
798 } else {
799 request.result = false;
800 }
801 if (ar.result == null) {
802 loge("isNRDualConnectivityEnabled: Empty response");
803 } else if (ar.exception instanceof CommandException) {
804 loge("isNRDualConnectivityEnabled: CommandException: "
805 + ar.exception);
806 } else {
807 loge("isNRDualConnectivityEnabled: Unknown exception");
808 }
809 }
810 notifyRequester(request);
811 break;
812
813 case CMD_ENABLE_NR_DUAL_CONNECTIVITY: {
814 request = (MainThreadRequest) msg.obj;
815 onCompleted = obtainMessage(EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE, request);
816 Phone phone = getPhoneFromRequest(request);
817 if (phone != null) {
818 phone.setNrDualConnectivityState((int) request.argument, onCompleted,
819 request.workSource);
820 } else {
821 loge("enableNrDualConnectivity: No phone object");
822 request.result =
823 TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE;
824 notifyRequester(request);
825 }
826 break;
827 }
828
829 case EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE: {
830 ar = (AsyncResult) msg.obj;
831 request = (MainThreadRequest) ar.userObj;
832 if (ar.exception == null) {
833 request.result =
834 TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_SUCCESS;
835 } else {
836 request.result =
837 TelephonyManager
838 .ENABLE_NR_DUAL_CONNECTIVITY_RADIO_ERROR;
839 if (ar.exception instanceof CommandException) {
840 CommandException.Error error =
841 ((CommandException) (ar.exception)).getCommandError();
842 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
843 request.result =
844 TelephonyManager
845 .ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE;
846 }
847 loge("enableNrDualConnectivity" + ": CommandException: "
848 + ar.exception);
849 } else {
850 loge("enableNrDualConnectivity" + ": Unknown exception");
851 }
852 }
853 notifyRequester(request);
854 break;
855 }
856
Jake Hamby7c27be32014-03-03 13:25:59 -0800857 case CMD_GET_PREFERRED_NETWORK_TYPE:
858 request = (MainThreadRequest) msg.obj;
859 onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request);
Stuart Scott54788802015-03-30 13:18:01 -0700860 getPhoneFromRequest(request).getPreferredNetworkType(onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800861 break;
862
863 case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE:
864 ar = (AsyncResult) msg.obj;
865 request = (MainThreadRequest) ar.userObj;
866 if (ar.exception == null && ar.result != null) {
867 request.result = ar.result; // Integer
868 } else {
Nazish Tabassume8ba43a2020-07-28 14:49:25 +0530869 // request.result must be set to something non-null
870 // for the calling thread to unblock
871 request.result = new int[]{-1};
Jake Hamby7c27be32014-03-03 13:25:59 -0800872 if (ar.result == null) {
873 loge("getPreferredNetworkType: Empty response");
874 } else if (ar.exception instanceof CommandException) {
875 loge("getPreferredNetworkType: CommandException: " +
876 ar.exception);
877 } else {
878 loge("getPreferredNetworkType: Unknown exception");
879 }
880 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700881 notifyRequester(request);
Jake Hamby7c27be32014-03-03 13:25:59 -0800882 break;
883
884 case CMD_SET_PREFERRED_NETWORK_TYPE:
885 request = (MainThreadRequest) msg.obj;
886 onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request);
887 int networkType = (Integer) request.argument;
Stuart Scott54788802015-03-30 13:18:01 -0700888 getPhoneFromRequest(request).setPreferredNetworkType(networkType, onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800889 break;
890
891 case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE:
892 handleNullReturnEvent(msg, "setPreferredNetworkType");
893 break;
894
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000895 case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
896 request = (MainThreadRequest)msg.obj;
897 onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800898 defaultPhone.invokeOemRilRequestRaw((byte[]) request.argument, onCompleted);
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000899 break;
900
901 case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
902 ar = (AsyncResult)msg.obj;
903 request = (MainThreadRequest)ar.userObj;
904 request.result = ar;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700905 notifyRequester(request);
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000906 break;
907
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800908 case CMD_SET_VOICEMAIL_NUMBER:
909 request = (MainThreadRequest) msg.obj;
910 onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
911 Pair<String, String> tagNum = (Pair<String, String>) request.argument;
Stuart Scott584921c2015-01-15 17:10:34 -0800912 getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
913 onCompleted);
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800914 break;
915
916 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
917 handleNullReturnEvent(msg, "setVoicemailNumber");
918 break;
919
Stuart Scott54788802015-03-30 13:18:01 -0700920 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC:
921 request = (MainThreadRequest) msg.obj;
922 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE,
923 request);
924 getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted);
925 break;
926
927 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE:
928 handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic");
929 break;
930
Shishir Agrawal302c8692015-06-19 13:49:39 -0700931 case CMD_PERFORM_NETWORK_SCAN:
932 request = (MainThreadRequest) msg.obj;
933 onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request);
934 getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
935 break;
936
Hall Liu27d24262020-09-18 19:04:59 -0700937 case CMD_GET_CALL_FORWARDING: {
Shuo Qian4a594052020-01-23 11:59:30 -0800938 request = (MainThreadRequest) msg.obj;
939 onCompleted = obtainMessage(EVENT_GET_CALL_FORWARDING_DONE, request);
Hall Liu27d24262020-09-18 19:04:59 -0700940 Pair<Integer, TelephonyManager.CallForwardingInfoCallback> args =
941 (Pair<Integer, TelephonyManager.CallForwardingInfoCallback>)
942 request.argument;
943 int callForwardingReason = args.first;
944 request.phone.getCallForwardingOption(callForwardingReason, onCompleted);
Shuo Qian4a594052020-01-23 11:59:30 -0800945 break;
Hall Liu27d24262020-09-18 19:04:59 -0700946 }
947 case EVENT_GET_CALL_FORWARDING_DONE: {
Shuo Qian4a594052020-01-23 11:59:30 -0800948 ar = (AsyncResult) msg.obj;
949 request = (MainThreadRequest) ar.userObj;
Hall Liu27d24262020-09-18 19:04:59 -0700950 TelephonyManager.CallForwardingInfoCallback callback =
951 ((Pair<Integer, TelephonyManager.CallForwardingInfoCallback>)
952 request.argument).second;
Shuo Qian4a594052020-01-23 11:59:30 -0800953 if (ar.exception == null && ar.result != null) {
Hall Liu27d24262020-09-18 19:04:59 -0700954 CallForwardingInfo callForwardingInfo = null;
Shuo Qian4a594052020-01-23 11:59:30 -0800955 CallForwardInfo[] callForwardInfos = (CallForwardInfo[]) ar.result;
956 for (CallForwardInfo callForwardInfo : callForwardInfos) {
957 // Service Class is a bit mask per 3gpp 27.007. Search for
958 // any service for voice call.
959 if ((callForwardInfo.serviceClass
960 & CommandsInterface.SERVICE_CLASS_VOICE) > 0) {
Hall Liu27d24262020-09-18 19:04:59 -0700961 callForwardingInfo = new CallForwardingInfo(true,
962 callForwardInfo.reason,
963 callForwardInfo.number,
964 callForwardInfo.timeSeconds);
Shuo Qian4a594052020-01-23 11:59:30 -0800965 break;
966 }
967 }
968 // Didn't find a call forward info for voice call.
969 if (callForwardingInfo == null) {
Hall Liu27d24262020-09-18 19:04:59 -0700970 callForwardingInfo = new CallForwardingInfo(false /* enabled */,
971 0 /* reason */, null /* number */, 0 /* timeout */);
Shuo Qian4a594052020-01-23 11:59:30 -0800972 }
Hall Liu27d24262020-09-18 19:04:59 -0700973 callback.onCallForwardingInfoAvailable(callForwardingInfo);
Shuo Qian4a594052020-01-23 11:59:30 -0800974 } else {
975 if (ar.result == null) {
976 loge("EVENT_GET_CALL_FORWARDING_DONE: Empty response");
977 }
978 if (ar.exception != null) {
979 loge("EVENT_GET_CALL_FORWARDING_DONE: Exception: " + ar.exception);
980 }
Hall Liu940c4ca2020-09-29 17:10:18 -0700981 int errorCode = TelephonyManager
982 .CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN;
Shuo Qian4a594052020-01-23 11:59:30 -0800983 if (ar.exception instanceof CommandException) {
984 CommandException.Error error =
985 ((CommandException) (ar.exception)).getCommandError();
986 if (error == CommandException.Error.FDN_CHECK_FAILURE) {
Hall Liu940c4ca2020-09-29 17:10:18 -0700987 errorCode = TelephonyManager
988 .CallForwardingInfoCallback.RESULT_ERROR_FDN_CHECK_FAILURE;
Shuo Qian4a594052020-01-23 11:59:30 -0800989 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
Hall Liu940c4ca2020-09-29 17:10:18 -0700990 errorCode = TelephonyManager
991 .CallForwardingInfoCallback.RESULT_ERROR_NOT_SUPPORTED;
Shuo Qian4a594052020-01-23 11:59:30 -0800992 }
993 }
Hall Liu27d24262020-09-18 19:04:59 -0700994 callback.onError(errorCode);
Shuo Qian4a594052020-01-23 11:59:30 -0800995 }
Shuo Qian4a594052020-01-23 11:59:30 -0800996 break;
Hall Liu27d24262020-09-18 19:04:59 -0700997 }
Shuo Qian4a594052020-01-23 11:59:30 -0800998
Hall Liu27d24262020-09-18 19:04:59 -0700999 case CMD_SET_CALL_FORWARDING: {
Shuo Qian4a594052020-01-23 11:59:30 -08001000 request = (MainThreadRequest) msg.obj;
1001 onCompleted = obtainMessage(EVENT_SET_CALL_FORWARDING_DONE, request);
Hall Liu27d24262020-09-18 19:04:59 -07001002 request = (MainThreadRequest) msg.obj;
Shuo Qian4a594052020-01-23 11:59:30 -08001003 CallForwardingInfo callForwardingInfoToSet =
Hall Liu27d24262020-09-18 19:04:59 -07001004 ((Pair<CallForwardingInfo, Consumer<Integer>>)
1005 request.argument).first;
1006 request.phone.setCallForwardingOption(
1007 callForwardingInfoToSet.isEnabled()
1008 ? CommandsInterface.CF_ACTION_ENABLE
1009 : CommandsInterface.CF_ACTION_DISABLE,
Shuo Qian4a594052020-01-23 11:59:30 -08001010 callForwardingInfoToSet.getReason(),
1011 callForwardingInfoToSet.getNumber(),
1012 callForwardingInfoToSet.getTimeoutSeconds(), onCompleted);
1013 break;
Hall Liu27d24262020-09-18 19:04:59 -07001014 }
Shuo Qian4a594052020-01-23 11:59:30 -08001015
Hall Liu27d24262020-09-18 19:04:59 -07001016 case EVENT_SET_CALL_FORWARDING_DONE: {
Shuo Qian4a594052020-01-23 11:59:30 -08001017 ar = (AsyncResult) msg.obj;
1018 request = (MainThreadRequest) ar.userObj;
Hall Liu27d24262020-09-18 19:04:59 -07001019 Consumer<Integer> callback =
1020 ((Pair<CallForwardingInfo, Consumer<Integer>>)
1021 request.argument).second;
1022 if (ar.exception != null) {
Shuo Qian4a594052020-01-23 11:59:30 -08001023 loge("setCallForwarding exception: " + ar.exception);
Hall Liu940c4ca2020-09-29 17:10:18 -07001024 int errorCode = TelephonyManager.CallForwardingInfoCallback
1025 .RESULT_ERROR_UNKNOWN;
Hall Liu27d24262020-09-18 19:04:59 -07001026 if (ar.exception instanceof CommandException) {
1027 CommandException.Error error =
1028 ((CommandException) (ar.exception)).getCommandError();
1029 if (error == CommandException.Error.FDN_CHECK_FAILURE) {
Hall Liu940c4ca2020-09-29 17:10:18 -07001030 errorCode = TelephonyManager.CallForwardingInfoCallback
1031 .RESULT_ERROR_FDN_CHECK_FAILURE;
Hall Liu27d24262020-09-18 19:04:59 -07001032 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
Hall Liu940c4ca2020-09-29 17:10:18 -07001033 errorCode = TelephonyManager.CallForwardingInfoCallback
1034 .RESULT_ERROR_NOT_SUPPORTED;
Hall Liu27d24262020-09-18 19:04:59 -07001035 }
1036 }
1037 callback.accept(errorCode);
1038 } else {
Hall Liu940c4ca2020-09-29 17:10:18 -07001039 callback.accept(TelephonyManager.CallForwardingInfoCallback.RESULT_SUCCESS);
Shuo Qian4a594052020-01-23 11:59:30 -08001040 }
Shuo Qian4a594052020-01-23 11:59:30 -08001041 break;
Hall Liu27d24262020-09-18 19:04:59 -07001042 }
Shuo Qian4a594052020-01-23 11:59:30 -08001043
Hall Liu27d24262020-09-18 19:04:59 -07001044 case CMD_GET_CALL_WAITING: {
Shuo Qian4a594052020-01-23 11:59:30 -08001045 request = (MainThreadRequest) msg.obj;
1046 onCompleted = obtainMessage(EVENT_GET_CALL_WAITING_DONE, request);
1047 getPhoneFromRequest(request).getCallWaiting(onCompleted);
1048 break;
Hall Liu27d24262020-09-18 19:04:59 -07001049 }
Shuo Qian4a594052020-01-23 11:59:30 -08001050
Hall Liu27d24262020-09-18 19:04:59 -07001051 case EVENT_GET_CALL_WAITING_DONE: {
Shuo Qian4a594052020-01-23 11:59:30 -08001052 ar = (AsyncResult) msg.obj;
1053 request = (MainThreadRequest) ar.userObj;
Hall Liu27d24262020-09-18 19:04:59 -07001054 Consumer<Integer> callback = (Consumer<Integer>) request.argument;
Shuo Qian4a594052020-01-23 11:59:30 -08001055 int callForwardingStatus = TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR;
1056 if (ar.exception == null && ar.result != null) {
Shuo Qiand6a0dba2020-02-18 18:13:49 -08001057 int[] callForwardResults = (int[]) ar.result;
Shuo Qian4a594052020-01-23 11:59:30 -08001058 // Service Class is a bit mask per 3gpp 27.007.
1059 // Search for any service for voice call.
Shuo Qiand6a0dba2020-02-18 18:13:49 -08001060 if (callForwardResults.length > 1
1061 && ((callForwardResults[1]
Hall Liu27d24262020-09-18 19:04:59 -07001062 & CommandsInterface.SERVICE_CLASS_VOICE) > 0)) {
Shuo Qiand6a0dba2020-02-18 18:13:49 -08001063 callForwardingStatus = callForwardResults[0] == 0
Hall Liu27d24262020-09-18 19:04:59 -07001064 ? TelephonyManager.CALL_WAITING_STATUS_DISABLED
1065 : TelephonyManager.CALL_WAITING_STATUS_ENABLED;
Shuo Qian4a594052020-01-23 11:59:30 -08001066 } else {
Hall Liu27d24262020-09-18 19:04:59 -07001067 callForwardingStatus = TelephonyManager.CALL_WAITING_STATUS_DISABLED;
Shuo Qian4a594052020-01-23 11:59:30 -08001068 }
1069 } else {
1070 if (ar.result == null) {
1071 loge("EVENT_GET_CALL_WAITING_DONE: Empty response");
1072 }
1073 if (ar.exception != null) {
1074 loge("EVENT_GET_CALL_WAITING_DONE: Exception: " + ar.exception);
1075 }
1076 if (ar.exception instanceof CommandException) {
1077 CommandException.Error error =
1078 ((CommandException) (ar.exception)).getCommandError();
1079 if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1080 callForwardingStatus =
1081 TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED;
1082 }
1083 }
1084 }
Hall Liu27d24262020-09-18 19:04:59 -07001085 callback.accept(callForwardingStatus);
Shuo Qian4a594052020-01-23 11:59:30 -08001086 break;
Hall Liu27d24262020-09-18 19:04:59 -07001087 }
Shuo Qian4a594052020-01-23 11:59:30 -08001088
Hall Liu27d24262020-09-18 19:04:59 -07001089 case CMD_SET_CALL_WAITING: {
Shuo Qian4a594052020-01-23 11:59:30 -08001090 request = (MainThreadRequest) msg.obj;
1091 onCompleted = obtainMessage(EVENT_SET_CALL_WAITING_DONE, request);
Hall Liu27d24262020-09-18 19:04:59 -07001092 boolean enable = ((Pair<Boolean, Consumer<Integer>>) request.argument).first;
1093 getPhoneFromRequest(request).setCallWaiting(enable, onCompleted);
Shuo Qian4a594052020-01-23 11:59:30 -08001094 break;
Hall Liu27d24262020-09-18 19:04:59 -07001095 }
Shuo Qian4a594052020-01-23 11:59:30 -08001096
Hall Liu27d24262020-09-18 19:04:59 -07001097 case EVENT_SET_CALL_WAITING_DONE: {
Shuo Qian4a594052020-01-23 11:59:30 -08001098 ar = (AsyncResult) msg.obj;
1099 request = (MainThreadRequest) ar.userObj;
Hall Liu27d24262020-09-18 19:04:59 -07001100 boolean enable = ((Pair<Boolean, Consumer<Integer>>) request.argument).first;
1101 Consumer<Integer> callback =
1102 ((Pair<Boolean, Consumer<Integer>>) request.argument).second;
1103 if (ar.exception != null) {
Shuo Qian4a594052020-01-23 11:59:30 -08001104 loge("setCallWaiting exception: " + ar.exception);
Hall Liu27d24262020-09-18 19:04:59 -07001105 if (ar.exception instanceof CommandException) {
1106 CommandException.Error error =
1107 ((CommandException) (ar.exception)).getCommandError();
1108 if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1109 callback.accept(TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED);
1110 } else {
1111 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
1112 }
1113 } else {
1114 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
1115 }
1116 } else {
1117 callback.accept(enable ? TelephonyManager.CALL_WAITING_STATUS_ENABLED
1118 : TelephonyManager.CALL_WAITING_STATUS_DISABLED);
Shuo Qian4a594052020-01-23 11:59:30 -08001119 }
Shuo Qian4a594052020-01-23 11:59:30 -08001120 break;
Hall Liu27d24262020-09-18 19:04:59 -07001121 }
Shuo Qian4a594052020-01-23 11:59:30 -08001122
Shishir Agrawal302c8692015-06-19 13:49:39 -07001123 case EVENT_PERFORM_NETWORK_SCAN_DONE:
1124 ar = (AsyncResult) msg.obj;
1125 request = (MainThreadRequest) ar.userObj;
1126 CellNetworkScanResult cellScanResult;
1127 if (ar.exception == null && ar.result != null) {
1128 cellScanResult = new CellNetworkScanResult(
1129 CellNetworkScanResult.STATUS_SUCCESS,
1130 (List<OperatorInfo>) ar.result);
1131 } else {
1132 if (ar.result == null) {
1133 loge("getCellNetworkScanResults: Empty response");
1134 }
1135 if (ar.exception != null) {
1136 loge("getCellNetworkScanResults: Exception: " + ar.exception);
1137 }
1138 int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR;
1139 if (ar.exception instanceof CommandException) {
1140 CommandException.Error error =
1141 ((CommandException) (ar.exception)).getCommandError();
1142 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1143 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE;
1144 } else if (error == CommandException.Error.GENERIC_FAILURE) {
1145 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE;
1146 }
1147 }
1148 cellScanResult = new CellNetworkScanResult(errorCode, null);
1149 }
1150 request.result = cellScanResult;
Pengquan Menga1bb6272018-09-06 09:59:22 -07001151 notifyRequester(request);
Shishir Agrawal302c8692015-06-19 13:49:39 -07001152 break;
1153
1154 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
1155 request = (MainThreadRequest) msg.obj;
Shishir Agrawal77ba3172015-09-10 14:50:19 -07001156 ManualNetworkSelectionArgument selArg =
1157 (ManualNetworkSelectionArgument) request.argument;
Shishir Agrawal302c8692015-06-19 13:49:39 -07001158 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE,
1159 request);
Shishir Agrawal77ba3172015-09-10 14:50:19 -07001160 getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo,
1161 selArg.persistSelection, onCompleted);
Shishir Agrawal302c8692015-06-19 13:49:39 -07001162 break;
1163
1164 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
Pengquan Menge3d01e22018-09-20 15:25:35 -07001165 ar = (AsyncResult) msg.obj;
1166 request = (MainThreadRequest) ar.userObj;
1167 if (ar.exception == null) {
1168 request.result = true;
1169 } else {
1170 request.result = false;
1171 loge("setNetworkSelectionModeManual " + ar.exception);
1172 }
1173 notifyRequester(request);
1174 mApp.onNetworkSelectionChanged(request.subId);
Shishir Agrawal302c8692015-06-19 13:49:39 -07001175 break;
1176
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001177 case CMD_GET_MODEM_ACTIVITY_INFO:
1178 request = (MainThreadRequest) msg.obj;
1179 onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
James Mattisab947702019-04-03 14:18:34 -07001180 if (defaultPhone != null) {
1181 defaultPhone.getModemActivityInfo(onCompleted, request.workSource);
Shuo Qian8f4750a2020-02-20 17:12:10 -08001182 } else {
1183 ResultReceiver result = (ResultReceiver) request.argument;
1184 Bundle bundle = new Bundle();
1185 bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY,
Hall Liu49656c02020-10-09 19:00:11 -07001186 new ModemActivityInfo(0, 0, 0,
1187 new int[ModemActivityInfo.getNumTxPowerLevels()], 0));
Shuo Qian8f4750a2020-02-20 17:12:10 -08001188 result.send(0, bundle);
James Mattisab947702019-04-03 14:18:34 -07001189 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001190 break;
1191
Hall Liud0f208c2020-10-14 16:54:44 -07001192 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE: {
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001193 ar = (AsyncResult) msg.obj;
1194 request = (MainThreadRequest) ar.userObj;
Shuo Qian8f4750a2020-02-20 17:12:10 -08001195 ResultReceiver result = (ResultReceiver) request.argument;
1196
Hall Liud0f208c2020-10-14 16:54:44 -07001197 ModemActivityInfo ret = null;
1198 int error = 0;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001199 if (ar.exception == null && ar.result != null) {
Shuo Qian8f4750a2020-02-20 17:12:10 -08001200 // Update the last modem activity info and the result of the request.
1201 ModemActivityInfo info = (ModemActivityInfo) ar.result;
1202 if (isModemActivityInfoValid(info)) {
Hall Liu49656c02020-10-09 19:00:11 -07001203 int[] mergedTxTimeMs = new int[ModemActivityInfo.getNumTxPowerLevels()];
Shuo Qian8f4750a2020-02-20 17:12:10 -08001204 int[] txTimeMs = info.getTransmitTimeMillis();
1205 int[] lastModemTxTimeMs = mLastModemActivityInfo
1206 .getTransmitTimeMillis();
1207 for (int i = 0; i < mergedTxTimeMs.length; i++) {
1208 mergedTxTimeMs[i] = txTimeMs[i] + lastModemTxTimeMs[i];
1209 }
Hall Liu49656c02020-10-09 19:00:11 -07001210 mLastModemActivityInfo.setTimestamp(info.getTimestampMillis());
Shuo Qian8f4750a2020-02-20 17:12:10 -08001211 mLastModemActivityInfo.setSleepTimeMillis(info.getSleepTimeMillis()
1212 + mLastModemActivityInfo.getSleepTimeMillis());
1213 mLastModemActivityInfo.setIdleTimeMillis(info.getIdleTimeMillis()
1214 + mLastModemActivityInfo.getIdleTimeMillis());
1215 mLastModemActivityInfo.setTransmitTimeMillis(mergedTxTimeMs);
1216 mLastModemActivityInfo.setReceiveTimeMillis(
1217 info.getReceiveTimeMillis()
1218 + mLastModemActivityInfo.getReceiveTimeMillis());
1219 }
Hall Liu49656c02020-10-09 19:00:11 -07001220 ret = new ModemActivityInfo(mLastModemActivityInfo.getTimestampMillis(),
Shuo Qian8f4750a2020-02-20 17:12:10 -08001221 mLastModemActivityInfo.getSleepTimeMillis(),
1222 mLastModemActivityInfo.getIdleTimeMillis(),
1223 mLastModemActivityInfo.getTransmitTimeMillis(),
1224 mLastModemActivityInfo.getReceiveTimeMillis());
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001225 } else {
1226 if (ar.result == null) {
1227 loge("queryModemActivityInfo: Empty response");
Hall Liud0f208c2020-10-14 16:54:44 -07001228 error = TelephonyManager.ModemActivityInfoException
1229 .ERROR_INVALID_INFO_RECEIVED;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001230 } else if (ar.exception instanceof CommandException) {
1231 loge("queryModemActivityInfo: CommandException: " +
1232 ar.exception);
Hall Liud0f208c2020-10-14 16:54:44 -07001233 error = TelephonyManager.ModemActivityInfoException
1234 .ERROR_MODEM_RESPONSE_ERROR;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001235 } else {
1236 loge("queryModemActivityInfo: Unknown exception");
Hall Liud0f208c2020-10-14 16:54:44 -07001237 error = TelephonyManager.ModemActivityInfoException
1238 .ERROR_UNKNOWN;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001239 }
1240 }
Shuo Qian8f4750a2020-02-20 17:12:10 -08001241 Bundle bundle = new Bundle();
Hall Liud0f208c2020-10-14 16:54:44 -07001242 if (ret != null) {
1243 bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, ret);
1244 } else {
1245 bundle.putInt(TelephonyManager.EXCEPTION_RESULT_KEY, error);
1246 }
Shuo Qian8f4750a2020-02-20 17:12:10 -08001247 result.send(0, bundle);
Pengquan Menga1bb6272018-09-06 09:59:22 -07001248 notifyRequester(request);
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001249 break;
Hall Liud0f208c2020-10-14 16:54:44 -07001250 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001251
Meng Wang1a7c35a2016-05-05 20:56:15 -07001252 case CMD_SET_ALLOWED_CARRIERS:
1253 request = (MainThreadRequest) msg.obj;
Michele Berionne482f8202018-11-27 18:57:59 -08001254 CarrierRestrictionRules argument =
1255 (CarrierRestrictionRules) request.argument;
Meng Wang1a7c35a2016-05-05 20:56:15 -07001256 onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
Michele Berionne482f8202018-11-27 18:57:59 -08001257 defaultPhone.setAllowedCarriers(argument, onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -07001258 break;
1259
1260 case EVENT_SET_ALLOWED_CARRIERS_DONE:
1261 ar = (AsyncResult) msg.obj;
1262 request = (MainThreadRequest) ar.userObj;
1263 if (ar.exception == null && ar.result != null) {
1264 request.result = ar.result;
1265 } else {
Michele Berionne482f8202018-11-27 18:57:59 -08001266 request.result = TelephonyManager.SET_CARRIER_RESTRICTION_ERROR;
1267 if (ar.exception instanceof CommandException) {
1268 loge("setAllowedCarriers: CommandException: " + ar.exception);
1269 CommandException.Error error =
1270 ((CommandException) (ar.exception)).getCommandError();
1271 if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1272 request.result =
1273 TelephonyManager.SET_CARRIER_RESTRICTION_NOT_SUPPORTED;
1274 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07001275 } else {
1276 loge("setAllowedCarriers: Unknown exception");
1277 }
1278 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001279 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -07001280 break;
1281
1282 case CMD_GET_ALLOWED_CARRIERS:
1283 request = (MainThreadRequest) msg.obj;
1284 onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001285 defaultPhone.getAllowedCarriers(onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -07001286 break;
1287
1288 case EVENT_GET_ALLOWED_CARRIERS_DONE:
1289 ar = (AsyncResult) msg.obj;
1290 request = (MainThreadRequest) ar.userObj;
1291 if (ar.exception == null && ar.result != null) {
1292 request.result = ar.result;
1293 } else {
Michele Berionne482f8202018-11-27 18:57:59 -08001294 request.result = new IllegalStateException(
1295 "Failed to get carrier restrictions");
Meng Wang1a7c35a2016-05-05 20:56:15 -07001296 if (ar.result == null) {
1297 loge("getAllowedCarriers: Empty response");
1298 } else if (ar.exception instanceof CommandException) {
1299 loge("getAllowedCarriers: CommandException: " +
1300 ar.exception);
1301 } else {
1302 loge("getAllowedCarriers: Unknown exception");
1303 }
1304 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001305 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -07001306 break;
1307
Nathan Haroldb3014052017-01-25 15:57:32 -08001308 case EVENT_GET_FORBIDDEN_PLMNS_DONE:
1309 ar = (AsyncResult) msg.obj;
1310 request = (MainThreadRequest) ar.userObj;
1311 if (ar.exception == null && ar.result != null) {
1312 request.result = ar.result;
1313 } else {
1314 request.result = new IllegalArgumentException(
1315 "Failed to retrieve Forbidden Plmns");
1316 if (ar.result == null) {
1317 loge("getForbiddenPlmns: Empty response");
1318 } else {
1319 loge("getForbiddenPlmns: Unknown exception");
1320 }
1321 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001322 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -08001323 break;
1324
1325 case CMD_GET_FORBIDDEN_PLMNS:
1326 request = (MainThreadRequest) msg.obj;
1327 uiccCard = getUiccCardFromRequest(request);
1328 if (uiccCard == null) {
1329 loge("getForbiddenPlmns() UiccCard is null");
1330 request.result = new IllegalArgumentException(
1331 "getForbiddenPlmns() UiccCard is null");
Pengquan Menga1bb6272018-09-06 09:59:22 -07001332 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -08001333 break;
1334 }
1335 Integer appType = (Integer) request.argument;
1336 UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType);
1337 if (uiccApp == null) {
1338 loge("getForbiddenPlmns() no app with specified type -- "
1339 + appType);
1340 request.result = new IllegalArgumentException("Failed to get UICC App");
Pengquan Menga1bb6272018-09-06 09:59:22 -07001341 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -08001342 break;
1343 } else {
1344 if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
1345 + " specified type -- " + appType);
1346 }
1347 onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
1348 ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
1349 onCompleted);
1350 break;
1351
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001352 case CMD_SWITCH_SLOTS:
1353 request = (MainThreadRequest) msg.obj;
1354 int[] physicalSlots = (int[]) request.argument;
1355 onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
1356 UiccController.getInstance().switchSlots(physicalSlots, onCompleted);
1357 break;
1358
1359 case EVENT_SWITCH_SLOTS_DONE:
1360 ar = (AsyncResult) msg.obj;
1361 request = (MainThreadRequest) ar.userObj;
1362 request.result = (ar.exception == null);
Pengquan Menga1bb6272018-09-06 09:59:22 -07001363 notifyRequester(request);
1364 break;
1365 case CMD_GET_NETWORK_SELECTION_MODE:
1366 request = (MainThreadRequest) msg.obj;
1367 onCompleted = obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE, request);
1368 getPhoneFromRequest(request).getNetworkSelectionMode(onCompleted);
1369 break;
1370
1371 case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
1372 ar = (AsyncResult) msg.obj;
1373 request = (MainThreadRequest) ar.userObj;
1374 if (ar.exception != null) {
1375 request.result = TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
1376 } else {
1377 int mode = ((int[]) ar.result)[0];
1378 if (mode == 0) {
1379 request.result = TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
1380 } else {
1381 request.result = TelephonyManager.NETWORK_SELECTION_MODE_MANUAL;
1382 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001383 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001384 notifyRequester(request);
1385 break;
1386 case CMD_GET_CDMA_ROAMING_MODE:
1387 request = (MainThreadRequest) msg.obj;
1388 onCompleted = obtainMessage(EVENT_GET_CDMA_ROAMING_MODE_DONE, request);
1389 getPhoneFromRequest(request).queryCdmaRoamingPreference(onCompleted);
1390 break;
1391 case EVENT_GET_CDMA_ROAMING_MODE_DONE:
1392 ar = (AsyncResult) msg.obj;
1393 request = (MainThreadRequest) ar.userObj;
1394 if (ar.exception != null) {
1395 request.result = TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT;
1396 } else {
1397 request.result = ((int[]) ar.result)[0];
1398 }
1399 notifyRequester(request);
1400 break;
1401 case CMD_SET_CDMA_ROAMING_MODE:
1402 request = (MainThreadRequest) msg.obj;
1403 onCompleted = obtainMessage(EVENT_SET_CDMA_ROAMING_MODE_DONE, request);
1404 int mode = (int) request.argument;
1405 getPhoneFromRequest(request).setCdmaRoamingPreference(mode, onCompleted);
1406 break;
1407 case EVENT_SET_CDMA_ROAMING_MODE_DONE:
1408 ar = (AsyncResult) msg.obj;
1409 request = (MainThreadRequest) ar.userObj;
1410 request.result = ar.exception == null;
1411 notifyRequester(request);
1412 break;
Sarah Chinbaab1432020-10-28 13:46:24 -07001413 case CMD_GET_CDMA_SUBSCRIPTION_MODE:
1414 request = (MainThreadRequest) msg.obj;
1415 onCompleted = obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1416 getPhoneFromRequest(request).queryCdmaSubscriptionMode(onCompleted);
1417 break;
1418 case EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE:
1419 ar = (AsyncResult) msg.obj;
1420 request = (MainThreadRequest) ar.userObj;
1421 if (ar.exception != null) {
1422 request.result = TelephonyManager.CDMA_SUBSCRIPTION_RUIM_SIM;
1423 } else {
1424 request.result = ((int[]) ar.result)[0];
1425 }
1426 notifyRequester(request);
1427 break;
Pengquan Menga1bb6272018-09-06 09:59:22 -07001428 case CMD_SET_CDMA_SUBSCRIPTION_MODE:
1429 request = (MainThreadRequest) msg.obj;
1430 onCompleted = obtainMessage(EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1431 int subscriptionMode = (int) request.argument;
Sarah Chinbaab1432020-10-28 13:46:24 -07001432 getPhoneFromRequest(request).setCdmaSubscriptionMode(
1433 subscriptionMode, onCompleted);
Pengquan Menga1bb6272018-09-06 09:59:22 -07001434 break;
1435 case EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE:
1436 ar = (AsyncResult) msg.obj;
1437 request = (MainThreadRequest) ar.userObj;
1438 request.result = ar.exception == null;
1439 notifyRequester(request);
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001440 break;
Nathan Harold3ff88932018-08-14 10:19:49 -07001441 case CMD_GET_ALL_CELL_INFO:
1442 request = (MainThreadRequest) msg.obj;
Nathan Harold3ff88932018-08-14 10:19:49 -07001443 onCompleted = obtainMessage(EVENT_GET_ALL_CELL_INFO_DONE, request);
Nathan Harold92bed182018-10-12 18:16:49 -07001444 request.phone.requestCellInfoUpdate(request.workSource, onCompleted);
Nathan Harold3ff88932018-08-14 10:19:49 -07001445 break;
Nathan Harold3ff88932018-08-14 10:19:49 -07001446 case EVENT_GET_ALL_CELL_INFO_DONE:
1447 ar = (AsyncResult) msg.obj;
1448 request = (MainThreadRequest) ar.userObj;
Nathan Harold8d0f1742018-10-02 12:14:47 -07001449 // If a timeout occurs, the response will be null
1450 request.result = (ar.exception == null && ar.result != null)
1451 ? ar.result : new ArrayList<CellInfo>();
Nathan Harold3ff88932018-08-14 10:19:49 -07001452 synchronized (request) {
1453 request.notifyAll();
1454 }
1455 break;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001456 case CMD_REQUEST_CELL_INFO_UPDATE:
1457 request = (MainThreadRequest) msg.obj;
1458 request.phone.requestCellInfoUpdate(request.workSource,
1459 obtainMessage(EVENT_REQUEST_CELL_INFO_UPDATE_DONE, request));
1460 break;
1461 case EVENT_REQUEST_CELL_INFO_UPDATE_DONE:
1462 ar = (AsyncResult) msg.obj;
1463 request = (MainThreadRequest) ar.userObj;
1464 ICellInfoCallback cb = (ICellInfoCallback) request.argument;
1465 try {
1466 if (ar.exception != null) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001467 Log.e(LOG_TAG, "Exception retrieving CellInfo=" + ar.exception);
Meng Wangd8921f42019-09-30 17:13:54 -07001468 cb.onError(
1469 TelephonyManager.CellInfoCallback.ERROR_MODEM_ERROR,
1470 ar.exception.getClass().getName(),
1471 ar.exception.toString());
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001472 } else if (ar.result == null) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001473 Log.w(LOG_TAG, "Timeout Waiting for CellInfo!");
Meng Wangd8921f42019-09-30 17:13:54 -07001474 cb.onError(TelephonyManager.CellInfoCallback.ERROR_TIMEOUT, null, null);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001475 } else {
1476 // use the result as returned
1477 cb.onCellInfo((List<CellInfo>) ar.result);
1478 }
1479 } catch (RemoteException re) {
1480 Log.w(LOG_TAG, "Discarded CellInfo due to Callback RemoteException");
1481 }
1482 break;
Sarah Chin679c08a2020-11-18 13:39:35 -08001483 case CMD_GET_CELL_LOCATION: {
Nathan Harold3ff88932018-08-14 10:19:49 -07001484 request = (MainThreadRequest) msg.obj;
1485 WorkSource ws = (WorkSource) request.argument;
1486 Phone phone = getPhoneFromRequest(request);
Meng Wanga10e89e2019-12-09 13:13:01 -08001487 phone.getCellIdentity(ws, obtainMessage(EVENT_GET_CELL_LOCATION_DONE, request));
Nathan Harold3ff88932018-08-14 10:19:49 -07001488 break;
Sarah Chin679c08a2020-11-18 13:39:35 -08001489 }
1490 case EVENT_GET_CELL_LOCATION_DONE: {
Nathan Harold3ff88932018-08-14 10:19:49 -07001491 ar = (AsyncResult) msg.obj;
1492 request = (MainThreadRequest) ar.userObj;
1493 if (ar.exception == null) {
1494 request.result = ar.result;
1495 } else {
Sarah Chin679c08a2020-11-18 13:39:35 -08001496 Phone phone = getPhoneFromRequest(request);
Nathan Harold3ff88932018-08-14 10:19:49 -07001497 request.result = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
Meng Wanga10e89e2019-12-09 13:13:01 -08001498 ? new CellIdentityCdma() : new CellIdentityGsm();
Nathan Harold3ff88932018-08-14 10:19:49 -07001499 }
1500
1501 synchronized (request) {
1502 request.notifyAll();
1503 }
1504 break;
Sarah Chin679c08a2020-11-18 13:39:35 -08001505 }
chen xu6dac5ab2018-10-26 17:39:23 -07001506 case CMD_MODEM_REBOOT:
1507 request = (MainThreadRequest) msg.obj;
1508 onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001509 defaultPhone.rebootModem(onCompleted);
chen xu6dac5ab2018-10-26 17:39:23 -07001510 break;
chen xu6dac5ab2018-10-26 17:39:23 -07001511 case EVENT_CMD_MODEM_REBOOT_DONE:
1512 handleNullReturnEvent(msg, "rebootModem");
1513 break;
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001514 case CMD_REQUEST_ENABLE_MODEM:
1515 request = (MainThreadRequest) msg.obj;
1516 boolean enable = (boolean) request.argument;
1517 onCompleted = obtainMessage(EVENT_ENABLE_MODEM_DONE, request);
Nazanin Bakhshi33d584b2019-02-27 10:44:32 -08001518 onCompleted.arg1 = enable ? 1 : 0;
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001519 PhoneConfigurationManager.getInstance()
1520 .enablePhone(request.phone, enable, onCompleted);
1521 break;
1522 case EVENT_ENABLE_MODEM_DONE:
1523 ar = (AsyncResult) msg.obj;
1524 request = (MainThreadRequest) ar.userObj;
1525 request.result = (ar.exception == null);
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07001526 int phoneId = request.phone.getPhoneId();
Nazanin Bakhshi33d584b2019-02-27 10:44:32 -08001527 //update the cache as modem status has changed
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07001528 if ((boolean) request.result) {
1529 mPhoneConfigurationManager.addToPhoneStatusCache(phoneId, msg.arg1 == 1);
1530 updateModemStateMetrics();
1531 } else {
1532 Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1533 + ar.exception);
1534 }
1535 notifyRequester(request);
1536 break;
1537 case CMD_GET_MODEM_STATUS:
1538 request = (MainThreadRequest) msg.obj;
1539 onCompleted = obtainMessage(EVENT_GET_MODEM_STATUS_DONE, request);
1540 PhoneConfigurationManager.getInstance()
1541 .getPhoneStatusFromModem(request.phone, onCompleted);
1542 break;
1543 case EVENT_GET_MODEM_STATUS_DONE:
1544 ar = (AsyncResult) msg.obj;
1545 request = (MainThreadRequest) ar.userObj;
1546 int id = request.phone.getPhoneId();
1547 if (ar.exception == null && ar.result != null) {
1548 request.result = ar.result;
1549 //update the cache as modem status has changed
1550 mPhoneConfigurationManager.addToPhoneStatusCache(id,
1551 (boolean) request.result);
1552 } else {
1553 // Return true if modem status cannot be retrieved. For most cases,
1554 // modem status is on. And for older version modems, GET_MODEM_STATUS
1555 // and disable modem are not supported. Modem is always on.
1556 // TODO: this should be fixed in R to support a third
1557 // status UNKNOWN b/131631629
1558 request.result = true;
1559 Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1560 + ar.exception);
1561 }
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001562 notifyRequester(request);
1563 break;
Hall Liu73f5d362020-01-20 13:42:00 -08001564 case CMD_SET_SYSTEM_SELECTION_CHANNELS: {
1565 request = (MainThreadRequest) msg.obj;
1566 onCompleted = obtainMessage(EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE, request);
1567 Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> args =
1568 (Pair<List<RadioAccessSpecifier>, Consumer<Boolean>>) request.argument;
1569 request.phone.setSystemSelectionChannels(args.first, onCompleted);
1570 break;
1571 }
1572 case EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE: {
1573 ar = (AsyncResult) msg.obj;
1574 request = (MainThreadRequest) ar.userObj;
1575 Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> args =
1576 (Pair<List<RadioAccessSpecifier>, Consumer<Boolean>>) request.argument;
1577 args.second.accept(ar.exception == null);
1578 notifyRequester(request);
1579 break;
1580 }
Sarah Chin679c08a2020-11-18 13:39:35 -08001581 case CMD_GET_SYSTEM_SELECTION_CHANNELS: {
1582 request = (MainThreadRequest) msg.obj;
1583 onCompleted = obtainMessage(EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE, request);
1584 Phone phone = getPhoneFromRequest(request);
1585 if (phone != null) {
1586 phone.getSystemSelectionChannels(onCompleted);
1587 } else {
1588 loge("getSystemSelectionChannels: No phone object");
1589 request.result = new ArrayList<RadioAccessSpecifier>();
1590 notifyRequester(request);
1591 }
1592 break;
1593 }
1594 case EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE:
1595 ar = (AsyncResult) msg.obj;
1596 request = (MainThreadRequest) ar.userObj;
1597 if (ar.exception == null && ar.result != null) {
1598 request.result = ar.result;
1599 } else {
1600 request.result = new IllegalArgumentException(
1601 "Failed to retrieve system selection channels");
1602 if (ar.result == null) {
1603 loge("getSystemSelectionChannels: Empty response");
1604 } else {
1605 loge("getSystemSelectionChannels: Unknown exception");
1606 }
1607 }
1608 notifyRequester(request);
1609 break;
yincheng zhao2737e882019-09-06 17:06:54 -07001610 case EVENT_SET_FORBIDDEN_PLMNS_DONE:
1611 ar = (AsyncResult) msg.obj;
1612 request = (MainThreadRequest) ar.userObj;
1613 if (ar.exception == null && ar.result != null) {
1614 request.result = ar.result;
1615 } else {
1616 request.result = -1;
1617 loge("Failed to set Forbidden Plmns");
1618 if (ar.result == null) {
1619 loge("setForbidenPlmns: Empty response");
1620 } else if (ar.exception != null) {
1621 loge("setForbiddenPlmns: Exception: " + ar.exception);
1622 request.result = -1;
1623 } else {
1624 loge("setForbiddenPlmns: Unknown exception");
1625 }
1626 }
1627 notifyRequester(request);
1628 break;
1629 case CMD_SET_FORBIDDEN_PLMNS:
1630 request = (MainThreadRequest) msg.obj;
1631 uiccCard = getUiccCardFromRequest(request);
1632 if (uiccCard == null) {
1633 loge("setForbiddenPlmns: UiccCard is null");
1634 request.result = -1;
1635 notifyRequester(request);
1636 break;
1637 }
1638 Pair<Integer, List<String>> setFplmnsArgs =
1639 (Pair<Integer, List<String>>) request.argument;
1640 appType = setFplmnsArgs.first;
1641 List<String> fplmns = setFplmnsArgs.second;
1642 uiccApp = uiccCard.getApplicationByType(appType);
1643 if (uiccApp == null) {
1644 loge("setForbiddenPlmns: no app with specified type -- " + appType);
1645 request.result = -1;
1646 loge("Failed to get UICC App");
1647 notifyRequester(request);
1648 } else {
1649 onCompleted = obtainMessage(EVENT_SET_FORBIDDEN_PLMNS_DONE, request);
1650 ((SIMRecords) uiccApp.getIccRecords())
1651 .setForbiddenPlmns(onCompleted, fplmns);
1652 }
yinchengzhao4d163c02019-12-12 15:21:47 -08001653 break;
Naina Nallurid63128d2019-09-17 14:10:30 -07001654 case CMD_ERASE_MODEM_CONFIG:
1655 request = (MainThreadRequest) msg.obj;
1656 onCompleted = obtainMessage(EVENT_ERASE_MODEM_CONFIG_DONE, request);
1657 defaultPhone.eraseModemConfig(onCompleted);
1658 break;
1659 case EVENT_ERASE_MODEM_CONFIG_DONE:
1660 handleNullReturnEvent(msg, "eraseModemConfig");
yincheng zhao2737e882019-09-06 17:06:54 -07001661 break;
zoey chene02881a2019-12-30 16:11:23 +08001662
1663 case CMD_CHANGE_ICC_LOCK_PASSWORD:
1664 request = (MainThreadRequest) msg.obj;
1665 onCompleted = obtainMessage(EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE, request);
1666 Pair<String, String> changed = (Pair<String, String>) request.argument;
1667 getPhoneFromRequest(request).getIccCard().changeIccLockPassword(
1668 changed.first, changed.second, onCompleted);
1669 break;
1670 case EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE:
1671 ar = (AsyncResult) msg.obj;
1672 request = (MainThreadRequest) ar.userObj;
1673 if (ar.exception == null) {
1674 request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
1675 } else {
1676 request.result = msg.arg1;
1677 }
1678 notifyRequester(request);
1679 break;
1680
1681 case CMD_SET_ICC_LOCK_ENABLED:
1682 request = (MainThreadRequest) msg.obj;
1683 onCompleted = obtainMessage(EVENT_SET_ICC_LOCK_ENABLED_DONE, request);
1684 Pair<Boolean, String> enabled = (Pair<Boolean, String>) request.argument;
1685 getPhoneFromRequest(request).getIccCard().setIccLockEnabled(
1686 enabled.first, enabled.second, onCompleted);
1687 break;
1688 case EVENT_SET_ICC_LOCK_ENABLED_DONE:
1689 ar = (AsyncResult) msg.obj;
1690 request = (MainThreadRequest) ar.userObj;
1691 if (ar.exception == null) {
1692 request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
1693 } else {
1694 request.result = msg.arg1;
1695 }
1696 notifyRequester(request);
1697 break;
1698
Peter Wangdafb9ac2020-01-15 14:13:38 -08001699 case MSG_NOTIFY_USER_ACTIVITY:
1700 removeMessages(MSG_NOTIFY_USER_ACTIVITY);
Peter Wang59571be2020-01-27 12:35:15 +08001701 Intent intent = new Intent(TelephonyIntents.ACTION_USER_ACTIVITY_NOTIFICATION);
Peter Wangdafb9ac2020-01-15 14:13:38 -08001702 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1703 getDefaultPhone().getContext().sendBroadcastAsUser(
1704 intent, UserHandle.ALL, permission.USER_ACTIVITY);
1705 break;
Jack Nudelmanb0b87642020-11-12 15:04:39 -08001706
1707 case CMD_SET_DATA_THROTTLING: {
1708 request = (MainThreadRequest) msg.obj;
1709 onCompleted = obtainMessage(EVENT_SET_DATA_THROTTLING_DONE, request);
1710 DataThrottlingRequest dataThrottlingRequest =
1711 (DataThrottlingRequest) request.argument;
1712 Phone phone = getPhoneFromRequest(request);
1713 if (phone != null) {
1714 phone.setDataThrottling(onCompleted,
1715 request.workSource, dataThrottlingRequest.getDataThrottlingAction(),
1716 dataThrottlingRequest.getCompletionDurationMillis());
1717 } else {
1718 loge("setDataThrottling: No phone object");
1719 request.result =
1720 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
1721 notifyRequester(request);
1722 }
1723
1724 break;
1725 }
1726 case EVENT_SET_DATA_THROTTLING_DONE:
1727 ar = (AsyncResult) msg.obj;
1728 request = (MainThreadRequest) ar.userObj;
1729
1730 if (ar.exception == null) {
1731 request.result = TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
1732 } else if (ar.exception instanceof CommandException) {
1733 loge("setDataThrottling: CommandException: " + ar.exception);
1734 CommandException.Error error =
1735 ((CommandException) (ar.exception)).getCommandError();
1736
1737 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1738 request.result = TelephonyManager
1739 .THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
1740 } else if (error == CommandException.Error.INVALID_ARGUMENTS) {
1741 request.result = SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS;
1742 } else {
1743 request.result =
1744 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
1745 }
1746 } else {
1747 request.result = TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
1748 }
1749 Log.w(LOG_TAG, "DataThrottlingResult = " + request.result);
1750 notifyRequester(request);
1751 break;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001752 default:
1753 Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
1754 break;
1755 }
1756 }
Jake Hambye994d462014-02-03 13:10:13 -08001757
Pengquan Menga1bb6272018-09-06 09:59:22 -07001758 private void notifyRequester(MainThreadRequest request) {
1759 synchronized (request) {
1760 request.notifyAll();
1761 }
1762 }
1763
Jake Hambye994d462014-02-03 13:10:13 -08001764 private void handleNullReturnEvent(Message msg, String command) {
1765 AsyncResult ar = (AsyncResult) msg.obj;
1766 MainThreadRequest request = (MainThreadRequest) ar.userObj;
1767 if (ar.exception == null) {
1768 request.result = true;
1769 } else {
1770 request.result = false;
1771 if (ar.exception instanceof CommandException) {
1772 loge(command + ": CommandException: " + ar.exception);
1773 } else {
1774 loge(command + ": Unknown exception");
1775 }
1776 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001777 notifyRequester(request);
Jake Hambye994d462014-02-03 13:10:13 -08001778 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001779 }
1780
1781 /**
1782 * Posts the specified command to be executed on the main thread,
1783 * waits for the request to complete, and returns the result.
1784 * @see #sendRequestAsync
1785 */
1786 private Object sendRequest(int command, Object argument) {
Nathan Harold92bed182018-10-12 18:16:49 -07001787 return sendRequest(
1788 command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, null, null);
vagdeviaf9a5b92018-08-15 16:01:53 -07001789 }
1790
1791 /**
1792 * Posts the specified command to be executed on the main thread,
1793 * waits for the request to complete, and returns the result.
1794 * @see #sendRequestAsync
1795 */
1796 private Object sendRequest(int command, Object argument, WorkSource workSource) {
1797 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
Nathan Harold92bed182018-10-12 18:16:49 -07001798 null, workSource);
Wink Saville36469e72014-06-11 15:17:00 -07001799 }
1800
1801 /**
1802 * Posts the specified command to be executed on the main thread,
1803 * waits for the request to complete, and returns the result.
1804 * @see #sendRequestAsync
1805 */
Shishir Agrawal76d5da92014-11-09 16:17:25 -08001806 private Object sendRequest(int command, Object argument, Integer subId) {
Nathan Harold92bed182018-10-12 18:16:49 -07001807 return sendRequest(command, argument, subId, null, null);
vagdeviaf9a5b92018-08-15 16:01:53 -07001808 }
1809
1810 /**
1811 * Posts the specified command to be executed on the main thread,
1812 * waits for the request to complete, and returns the result.
1813 * @see #sendRequestAsync
1814 */
Nathan Harold92bed182018-10-12 18:16:49 -07001815 private Object sendRequest(int command, Object argument, int subId, WorkSource workSource) {
1816 return sendRequest(command, argument, subId, null, workSource);
1817 }
1818
1819 /**
1820 * Posts the specified command to be executed on the main thread,
1821 * waits for the request to complete, and returns the result.
1822 * @see #sendRequestAsync
1823 */
1824 private Object sendRequest(int command, Object argument, Phone phone, WorkSource workSource) {
1825 return sendRequest(
1826 command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phone, workSource);
1827 }
1828
1829 /**
1830 * Posts the specified command to be executed on the main thread,
1831 * waits for the request to complete, and returns the result.
1832 * @see #sendRequestAsync
1833 */
1834 private Object sendRequest(
1835 int command, Object argument, Integer subId, Phone phone, WorkSource workSource) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001836 if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
1837 throw new RuntimeException("This method will deadlock if called from the main thread.");
1838 }
1839
Nathan Harold92bed182018-10-12 18:16:49 -07001840 MainThreadRequest request = null;
1841 if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && phone != null) {
1842 throw new IllegalArgumentException("subId and phone cannot both be specified!");
1843 } else if (phone != null) {
1844 request = new MainThreadRequest(argument, phone, workSource);
1845 } else {
1846 request = new MainThreadRequest(argument, subId, workSource);
1847 }
1848
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001849 Message msg = mMainThreadHandler.obtainMessage(command, request);
1850 msg.sendToTarget();
1851
1852 // Wait for the request to complete
1853 synchronized (request) {
1854 while (request.result == null) {
1855 try {
1856 request.wait();
1857 } catch (InterruptedException e) {
1858 // Do nothing, go back and wait until the request is complete
1859 }
1860 }
1861 }
1862 return request.result;
1863 }
1864
1865 /**
1866 * Asynchronous ("fire and forget") version of sendRequest():
1867 * Posts the specified command to be executed on the main thread, and
1868 * returns immediately.
1869 * @see #sendRequest
1870 */
1871 private void sendRequestAsync(int command) {
1872 mMainThreadHandler.sendEmptyMessage(command);
1873 }
1874
1875 /**
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001876 * Same as {@link #sendRequestAsync(int)} except it takes an argument.
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001877 * @see {@link #sendRequest(int)}
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001878 */
1879 private void sendRequestAsync(int command, Object argument) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001880 sendRequestAsync(command, argument, null, null);
1881 }
1882
1883 /**
1884 * Same as {@link #sendRequestAsync(int,Object)} except it takes a Phone and WorkSource.
1885 * @see {@link #sendRequest(int,Object)}
1886 */
1887 private void sendRequestAsync(
1888 int command, Object argument, Phone phone, WorkSource workSource) {
1889 MainThreadRequest request = new MainThreadRequest(argument, phone, workSource);
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001890 Message msg = mMainThreadHandler.obtainMessage(command, request);
1891 msg.sendToTarget();
1892 }
1893
1894 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001895 * Initialize the singleton PhoneInterfaceManager instance.
1896 * This is only done once, at startup, from PhoneApp.onCreate().
1897 */
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001898 /* package */ static PhoneInterfaceManager init(PhoneGlobals app) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001899 synchronized (PhoneInterfaceManager.class) {
1900 if (sInstance == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001901 sInstance = new PhoneInterfaceManager(app);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001902 } else {
1903 Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
1904 }
1905 return sInstance;
1906 }
1907 }
1908
1909 /** Private constructor; @see init() */
Jordan Liu1979a042020-03-20 21:39:35 +00001910 private PhoneInterfaceManager(PhoneGlobals app) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001911 mApp = app;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001912 mCM = PhoneGlobals.getInstance().mCM;
Brad Ebinger24c29992019-12-05 13:03:21 -08001913 mImsResolver = PhoneGlobals.getInstance().getImsResolver();
Stuart Scott981d8582015-04-21 14:09:50 -07001914 mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001915 mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
1916 mMainThreadHandler = new MainThreadHandler();
Tobias Thiererb19e1f12018-12-11 17:54:03 +00001917 mSubscriptionController = SubscriptionController.getInstance();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001918 mTelephonySharedPreferences =
1919 PreferenceManager.getDefaultSharedPreferences(mApp);
yinxub1bed742017-04-17 11:45:04 -07001920 mNetworkScanRequestTracker = new NetworkScanRequestTracker();
Malcolm Chen2c63d402018-08-14 16:00:53 -07001921 mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
Peter Wanga3cf4ac2020-01-27 09:39:46 +08001922 mNotifyUserActivity = new AtomicBoolean(false);
Wink Saville3ab207e2014-11-20 13:07:20 -08001923
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001924 publish();
1925 }
1926
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001927 private Phone getDefaultPhone() {
1928 Phone thePhone = getPhone(getDefaultSubscription());
1929 return (thePhone != null) ? thePhone : PhoneFactory.getDefaultPhone();
1930 }
1931
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001932 private void publish() {
1933 if (DBG) log("publish: " + this);
1934
Peter Wangc035ce42020-01-08 21:00:22 -08001935 TelephonyFrameworkInitializer
1936 .getTelephonyServiceManager()
1937 .getTelephonyServiceRegisterer()
1938 .register(this);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001939 }
1940
Stuart Scott584921c2015-01-15 17:10:34 -08001941 private Phone getPhoneFromRequest(MainThreadRequest request) {
Jordan Liu4c733742019-02-28 12:03:40 -08001942 if (request.phone != null) {
1943 return request.phone;
1944 } else {
1945 return getPhoneFromSubId(request.subId);
1946 }
1947 }
1948
1949 private Phone getPhoneFromSubId(int subId) {
1950 return (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
1951 ? getDefaultPhone() : getPhone(subId);
Stuart Scott584921c2015-01-15 17:10:34 -08001952 }
1953
Shishir Agrawalc04d9752016-02-19 10:41:00 -08001954 private UiccCard getUiccCardFromRequest(MainThreadRequest request) {
1955 Phone phone = getPhoneFromRequest(request);
1956 return phone == null ? null :
1957 UiccController.getInstance().getUiccCard(phone.getPhoneId());
1958 }
1959
Wink Saville36469e72014-06-11 15:17:00 -07001960 // returns phone associated with the subId.
Wink Savilleb564aae2014-10-23 10:18:09 -07001961 private Phone getPhone(int subId) {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08001962 return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId));
Wink Saville36469e72014-06-11 15:17:00 -07001963 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001964
Naina Nallurid63128d2019-09-17 14:10:30 -07001965 private void sendEraseModemConfig(Phone phone) {
1966 if (phone != null) {
1967 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
1968 mApp, phone.getSubId(), "eraseModemConfig");
1969 final long identity = Binder.clearCallingIdentity();
1970 try {
1971 Boolean success = (Boolean) sendRequest(CMD_ERASE_MODEM_CONFIG, null);
1972 if (DBG) log("eraseModemConfig:" + ' ' + (success ? "ok" : "fail"));
1973 } finally {
1974 Binder.restoreCallingIdentity(identity);
1975 }
1976 }
1977 }
1978
Peter Wang44b186e2020-01-13 23:33:09 -08001979 private boolean isImsAvailableOnDevice() {
1980 PackageManager pm = getDefaultPhone().getContext().getPackageManager();
1981 if (pm == null) {
1982 // For some reason package manger is not available.. This will fail internally anyway,
1983 // so do not throw error and allow.
1984 return true;
1985 }
1986 return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS, 0);
1987 }
1988
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001989 public void dial(String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001990 dialForSubscriber(getPreferredVoiceSubscription(), number);
Wink Saville36469e72014-06-11 15:17:00 -07001991 }
1992
Wink Savilleb564aae2014-10-23 10:18:09 -07001993 public void dialForSubscriber(int subId, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001994 if (DBG) log("dial: " + number);
1995 // No permission check needed here: This is just a wrapper around the
1996 // ACTION_DIAL intent, which is available to any app since it puts up
1997 // the UI before it does anything.
1998
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001999 final long identity = Binder.clearCallingIdentity();
2000 try {
2001 String url = createTelUrl(number);
2002 if (url == null) {
2003 return;
2004 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002005
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002006 // PENDING: should we just silently fail if phone is offhook or ringing?
2007 PhoneConstants.State state = mCM.getState(subId);
2008 if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
2009 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
2010 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2011 mApp.startActivity(intent);
2012 }
2013 } finally {
2014 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002015 }
2016 }
2017
2018 public void call(String callingPackage, String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002019 callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number);
Wink Saville36469e72014-06-11 15:17:00 -07002020 }
2021
Wink Savilleb564aae2014-10-23 10:18:09 -07002022 public void callForSubscriber(int subId, String callingPackage, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002023 if (DBG) log("call: " + number);
2024
2025 // This is just a wrapper around the ACTION_CALL intent, but we still
2026 // need to do a permission check since we're calling startActivity()
2027 // from the context of the phone app.
2028 enforceCallPermission();
2029
Jordan Liu1617b712019-07-10 15:06:26 -07002030 if (mAppOps.noteOp(AppOpsManager.OPSTR_CALL_PHONE, Binder.getCallingUid(), callingPackage)
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002031 != AppOpsManager.MODE_ALLOWED) {
2032 return;
2033 }
2034
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002035 final long identity = Binder.clearCallingIdentity();
2036 try {
2037 String url = createTelUrl(number);
2038 if (url == null) {
2039 return;
2040 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002041
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002042 boolean isValid = false;
2043 final List<SubscriptionInfo> slist = getActiveSubscriptionInfoListPrivileged();
2044 if (slist != null) {
2045 for (SubscriptionInfo subInfoRecord : slist) {
2046 if (subInfoRecord.getSubscriptionId() == subId) {
2047 isValid = true;
2048 break;
2049 }
Wink Saville3ab207e2014-11-20 13:07:20 -08002050 }
Wink Saville08874612014-08-31 19:19:58 -07002051 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002052 if (!isValid) {
2053 return;
2054 }
Wink Saville08874612014-08-31 19:19:58 -07002055
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002056 Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
2057 intent.putExtra(SUBSCRIPTION_KEY, subId);
2058 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2059 mApp.startActivity(intent);
2060 } finally {
2061 Binder.restoreCallingIdentity(identity);
2062 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002063 }
2064
Wink Savilleb564aae2014-10-23 10:18:09 -07002065 public boolean supplyPinForSubscriber(int subId, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002066 int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07002067 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
2068 }
2069
Wink Savilleb564aae2014-10-23 10:18:09 -07002070 public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002071 int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07002072 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
2073 }
2074
Wink Savilleb564aae2014-10-23 10:18:09 -07002075 public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002076 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002077
2078 final long identity = Binder.clearCallingIdentity();
2079 try {
2080 final UnlockSim checkSimPin = new UnlockSim(getPhone(subId).getIccCard());
2081 checkSimPin.start();
2082 return checkSimPin.unlockSim(null, pin);
2083 } finally {
2084 Binder.restoreCallingIdentity(identity);
2085 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002086 }
2087
Wink Savilleb564aae2014-10-23 10:18:09 -07002088 public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002089 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002090
2091 final long identity = Binder.clearCallingIdentity();
2092 try {
2093 final UnlockSim checkSimPuk = new UnlockSim(getPhone(subId).getIccCard());
2094 checkSimPuk.start();
2095 return checkSimPuk.unlockSim(puk, pin);
2096 } finally {
2097 Binder.restoreCallingIdentity(identity);
2098 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002099 }
2100
2101 /**
Wink Saville9de0f752013-10-22 19:04:03 -07002102 * Helper thread to turn async call to SimCard#supplyPin into
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002103 * a synchronous one.
2104 */
2105 private static class UnlockSim extends Thread {
2106
2107 private final IccCard mSimCard;
2108
2109 private boolean mDone = false;
Wink Saville9de0f752013-10-22 19:04:03 -07002110 private int mResult = PhoneConstants.PIN_GENERAL_FAILURE;
2111 private int mRetryCount = -1;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002112
2113 // For replies from SimCard interface
2114 private Handler mHandler;
2115
2116 // For async handler to identify request type
2117 private static final int SUPPLY_PIN_COMPLETE = 100;
2118
2119 public UnlockSim(IccCard simCard) {
2120 mSimCard = simCard;
2121 }
2122
2123 @Override
2124 public void run() {
2125 Looper.prepare();
2126 synchronized (UnlockSim.this) {
2127 mHandler = new Handler() {
2128 @Override
2129 public void handleMessage(Message msg) {
2130 AsyncResult ar = (AsyncResult) msg.obj;
2131 switch (msg.what) {
2132 case SUPPLY_PIN_COMPLETE:
2133 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
2134 synchronized (UnlockSim.this) {
Wink Saville9de0f752013-10-22 19:04:03 -07002135 mRetryCount = msg.arg1;
2136 if (ar.exception != null) {
2137 if (ar.exception instanceof CommandException &&
2138 ((CommandException)(ar.exception)).getCommandError()
2139 == CommandException.Error.PASSWORD_INCORRECT) {
2140 mResult = PhoneConstants.PIN_PASSWORD_INCORRECT;
vivi.lib5e9ada2019-09-12 16:04:24 +08002141 } //When UiccCardApp dispose,handle message and return exception
2142 else if (ar.exception instanceof CommandException &&
2143 ((CommandException) (ar.exception)).getCommandError()
2144 == CommandException.Error.ABORTED) {
2145 mResult = PhoneConstants.PIN_OPERATION_ABORTED;
Wink Saville9de0f752013-10-22 19:04:03 -07002146 } else {
2147 mResult = PhoneConstants.PIN_GENERAL_FAILURE;
2148 }
2149 } else {
2150 mResult = PhoneConstants.PIN_RESULT_SUCCESS;
2151 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002152 mDone = true;
2153 UnlockSim.this.notifyAll();
2154 }
2155 break;
2156 }
2157 }
2158 };
2159 UnlockSim.this.notifyAll();
2160 }
2161 Looper.loop();
2162 }
2163
2164 /*
2165 * Use PIN or PUK to unlock SIM card
2166 *
2167 * If PUK is null, unlock SIM card with PIN
2168 *
2169 * If PUK is not null, unlock SIM card with PUK and set PIN code
2170 */
Wink Saville9de0f752013-10-22 19:04:03 -07002171 synchronized int[] unlockSim(String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002172
2173 while (mHandler == null) {
2174 try {
2175 wait();
2176 } catch (InterruptedException e) {
2177 Thread.currentThread().interrupt();
2178 }
2179 }
2180 Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
2181
2182 if (puk == null) {
2183 mSimCard.supplyPin(pin, callback);
2184 } else {
2185 mSimCard.supplyPuk(puk, pin, callback);
2186 }
2187
2188 while (!mDone) {
2189 try {
2190 Log.d(LOG_TAG, "wait for done");
2191 wait();
2192 } catch (InterruptedException e) {
2193 // Restore the interrupted status
2194 Thread.currentThread().interrupt();
2195 }
2196 }
2197 Log.d(LOG_TAG, "done");
Wink Saville9de0f752013-10-22 19:04:03 -07002198 int[] resultArray = new int[2];
2199 resultArray[0] = mResult;
2200 resultArray[1] = mRetryCount;
2201 return resultArray;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002202 }
2203 }
2204
Nathan Harold7c8d0f12020-05-28 20:40:31 -07002205 /**
2206 * This method has been removed due to privacy and stability concerns.
2207 */
2208 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002209 public void updateServiceLocation() {
Nathan Harold7c8d0f12020-05-28 20:40:31 -07002210 Log.e(LOG_TAG, "Call to unsupported method updateServiceLocation()");
2211 return;
Wink Saville36469e72014-06-11 15:17:00 -07002212 }
2213
Nathan Harold1f889d82020-06-04 17:05:26 -07002214 @Override
2215 public void updateServiceLocationWithPackageName(String callingPackage) {
2216 mApp.getSystemService(AppOpsManager.class)
2217 .checkPackage(Binder.getCallingUid(), callingPackage);
2218
2219 final int targetSdk = getTargetSdk(callingPackage);
2220 if (targetSdk > android.os.Build.VERSION_CODES.R) {
2221 // Callers targeting S have no business invoking this method.
2222 return;
2223 }
2224
2225 LocationAccessPolicy.LocationPermissionResult locationResult =
2226 LocationAccessPolicy.checkLocationPermission(mApp,
2227 new LocationAccessPolicy.LocationPermissionQuery.Builder()
2228 .setCallingPackage(callingPackage)
2229 .setCallingFeatureId(null)
2230 .setCallingPid(Binder.getCallingPid())
2231 .setCallingUid(Binder.getCallingUid())
2232 .setMethod("updateServiceLocation")
2233 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
2234 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2235 .build());
2236 // Apps that lack location permission have no business calling this method;
2237 // however, because no permission was declared in the public API, denials must
2238 // all be "soft".
2239 switch (locationResult) {
2240 case DENIED_HARD: /* fall through */
2241 case DENIED_SOFT:
2242 return;
2243 }
2244
2245 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002246 final long identity = Binder.clearCallingIdentity();
2247 try {
Nathan Harold1f889d82020-06-04 17:05:26 -07002248 final Phone phone = getPhone(getDefaultSubscription());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002249 if (phone != null) {
Nathan Harold1f889d82020-06-04 17:05:26 -07002250 phone.updateServiceLocation(workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002251 }
2252 } finally {
2253 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002254 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002255 }
2256
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002257 @Deprecated
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002258 @Override
2259 public boolean isRadioOn(String callingPackage) {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002260 return isRadioOnWithFeature(callingPackage, null);
2261 }
2262
2263
2264 @Override
2265 public boolean isRadioOnWithFeature(String callingPackage, String callingFeatureId) {
2266 return isRadioOnForSubscriberWithFeature(getDefaultSubscription(), callingPackage,
2267 callingFeatureId);
2268 }
2269
2270 @Deprecated
2271 @Override
2272 public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
2273 return isRadioOnForSubscriberWithFeature(subId, callingPackage, null);
Wink Saville36469e72014-06-11 15:17:00 -07002274 }
2275
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002276 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002277 public boolean isRadioOnForSubscriberWithFeature(int subId, String callingPackage,
2278 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002279 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002280 mApp, subId, callingPackage, callingFeatureId, "isRadioOnForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002281 return false;
2282 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002283
2284 final long identity = Binder.clearCallingIdentity();
2285 try {
2286 return isRadioOnForSubscriber(subId);
2287 } finally {
2288 Binder.restoreCallingIdentity(identity);
2289 }
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002290 }
2291
2292 private boolean isRadioOnForSubscriber(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002293 final long identity = Binder.clearCallingIdentity();
2294 try {
2295 final Phone phone = getPhone(subId);
2296 if (phone != null) {
2297 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
2298 } else {
2299 return false;
2300 }
2301 } finally {
2302 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002303 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002304 }
2305
2306 public void toggleRadioOnOff() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002307 toggleRadioOnOffForSubscriber(getDefaultSubscription());
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002308 }
Wink Saville36469e72014-06-11 15:17:00 -07002309
Wink Savilleb564aae2014-10-23 10:18:09 -07002310 public void toggleRadioOnOffForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002311 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002312
2313 final long identity = Binder.clearCallingIdentity();
2314 try {
2315 final Phone phone = getPhone(subId);
2316 if (phone != null) {
2317 phone.setRadioPower(!isRadioOnForSubscriber(subId));
2318 }
2319 } finally {
2320 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002321 }
Wink Saville36469e72014-06-11 15:17:00 -07002322 }
2323
2324 public boolean setRadio(boolean turnOn) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002325 return setRadioForSubscriber(getDefaultSubscription(), turnOn);
Wink Saville36469e72014-06-11 15:17:00 -07002326 }
2327
Wink Savilleb564aae2014-10-23 10:18:09 -07002328 public boolean setRadioForSubscriber(int subId, boolean turnOn) {
Wink Saville36469e72014-06-11 15:17:00 -07002329 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002330
2331 final long identity = Binder.clearCallingIdentity();
2332 try {
2333 final Phone phone = getPhone(subId);
2334 if (phone == null) {
2335 return false;
2336 }
2337 if ((phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF) != turnOn) {
2338 toggleRadioOnOffForSubscriber(subId);
2339 }
2340 return true;
2341 } finally {
2342 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002343 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002344 }
Wink Saville36469e72014-06-11 15:17:00 -07002345
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002346 public boolean needMobileRadioShutdown() {
Shuo Qianfa7b6b32019-12-10 10:40:38 -08002347 enforceReadPrivilegedPermission("needMobileRadioShutdown");
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002348 /*
2349 * If any of the Radios are available, it will need to be
2350 * shutdown. So return true if any Radio is available.
2351 */
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002352 final long identity = Binder.clearCallingIdentity();
2353 try {
2354 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
2355 Phone phone = PhoneFactory.getPhone(i);
2356 if (phone != null && phone.isRadioAvailable()) return true;
2357 }
2358 logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown.");
2359 return false;
2360 } finally {
2361 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002362 }
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002363 }
2364
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002365 @Override
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002366 public void shutdownMobileRadios() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002367 enforceModifyPermission();
2368
2369 final long identity = Binder.clearCallingIdentity();
2370 try {
2371 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
2372 logv("Shutting down Phone " + i);
2373 shutdownRadioUsingPhoneId(i);
2374 }
2375 } finally {
2376 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002377 }
2378 }
2379
2380 private void shutdownRadioUsingPhoneId(int phoneId) {
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002381 Phone phone = PhoneFactory.getPhone(phoneId);
2382 if (phone != null && phone.isRadioAvailable()) {
2383 phone.shutdownRadio();
2384 }
2385 }
2386
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002387 public boolean setRadioPower(boolean turnOn) {
Jack Yub4e16162017-05-15 12:48:40 -07002388 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002389
2390 final long identity = Binder.clearCallingIdentity();
2391 try {
2392 final Phone defaultPhone = PhoneFactory.getDefaultPhone();
2393 if (defaultPhone != null) {
2394 defaultPhone.setRadioPower(turnOn);
2395 return true;
2396 } else {
2397 loge("There's no default phone.");
2398 return false;
2399 }
2400 } finally {
2401 Binder.restoreCallingIdentity(identity);
Wei Liu9ae2a062016-08-08 11:09:34 -07002402 }
Wink Saville36469e72014-06-11 15:17:00 -07002403 }
2404
Wink Savilleb564aae2014-10-23 10:18:09 -07002405 public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002406 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002407
2408 final long identity = Binder.clearCallingIdentity();
2409 try {
2410 final Phone phone = getPhone(subId);
2411 if (phone != null) {
2412 phone.setRadioPower(turnOn);
2413 return true;
2414 } else {
2415 return false;
2416 }
2417 } finally {
2418 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002419 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002420 }
2421
Wink Saville36469e72014-06-11 15:17:00 -07002422 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07002423 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002424 public boolean enableDataConnectivity() {
2425 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002426
2427 final long identity = Binder.clearCallingIdentity();
2428 try {
2429 int subId = mSubscriptionController.getDefaultDataSubId();
2430 final Phone phone = getPhone(subId);
2431 if (phone != null) {
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00002432 phone.getDataEnabledSettings().setDataEnabled(
2433 TelephonyManager.DATA_ENABLED_REASON_USER, true);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002434 return true;
2435 } else {
2436 return false;
2437 }
2438 } finally {
2439 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002440 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002441 }
2442
Wink Saville36469e72014-06-11 15:17:00 -07002443 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07002444 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002445 public boolean disableDataConnectivity() {
2446 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002447
2448 final long identity = Binder.clearCallingIdentity();
2449 try {
2450 int subId = mSubscriptionController.getDefaultDataSubId();
2451 final Phone phone = getPhone(subId);
2452 if (phone != null) {
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00002453 phone.getDataEnabledSettings().setDataEnabled(
2454 TelephonyManager.DATA_ENABLED_REASON_USER, false);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002455 return true;
2456 } else {
2457 return false;
2458 }
2459 } finally {
2460 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002461 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002462 }
2463
Sanket Padawe356d7632015-06-22 14:03:32 -07002464 @Override
Jack Yuacf8a132017-05-01 17:00:48 -07002465 public boolean isDataConnectivityPossible(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002466 final long identity = Binder.clearCallingIdentity();
2467 try {
2468 final Phone phone = getPhone(subId);
2469 if (phone != null) {
Jack Yub5d8f642018-11-26 11:20:48 -08002470 return phone.isDataAllowed(ApnSetting.TYPE_DEFAULT);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002471 } else {
2472 return false;
2473 }
2474 } finally {
2475 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002476 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002477 }
2478
2479 public boolean handlePinMmi(String dialString) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002480 return handlePinMmiForSubscriber(getDefaultSubscription(), dialString);
Wink Saville36469e72014-06-11 15:17:00 -07002481 }
2482
pkanwarae03a6b2016-11-06 20:37:09 -08002483 public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002484 enforceCallPermission();
2485
2486 final long identity = Binder.clearCallingIdentity();
2487 try {
2488 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2489 return;
2490 }
2491 Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback);
2492 sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId);
2493 } finally {
2494 Binder.restoreCallingIdentity(identity);
2495 }
pkanwar32d516d2016-10-14 19:37:38 -07002496 };
2497
Wink Savilleb564aae2014-10-23 10:18:09 -07002498 public boolean handlePinMmiForSubscriber(int subId, String dialString) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002499 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002500
2501 final long identity = Binder.clearCallingIdentity();
2502 try {
2503 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2504 return false;
2505 }
2506 return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
2507 } finally {
2508 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002509 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002510 }
2511
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002512 public int getCallState() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07002513 return getCallStateForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002514 }
2515
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002516 public int getCallStateForSlot(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002517 final long identity = Binder.clearCallingIdentity();
2518 try {
2519 Phone phone = PhoneFactory.getPhone(slotIndex);
2520 return phone == null ? TelephonyManager.CALL_STATE_IDLE :
2521 PhoneConstantConversions.convertCallState(phone.getState());
2522 } finally {
2523 Binder.restoreCallingIdentity(identity);
2524 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002525 }
2526
Sanket Padawe356d7632015-06-22 14:03:32 -07002527 @Override
Nathan Harolde037c472019-06-26 00:41:07 +00002528 public int getDataState() {
Nathan Haroldc4689b12019-06-14 16:58:30 -07002529 return getDataStateForSubId(mSubscriptionController.getDefaultDataSubId());
2530 }
2531
2532 @Override
2533 public int getDataStateForSubId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002534 final long identity = Binder.clearCallingIdentity();
2535 try {
Nathan Haroldc4689b12019-06-14 16:58:30 -07002536 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002537 if (phone != null) {
2538 return PhoneConstantConversions.convertDataState(phone.getDataConnectionState());
2539 } else {
2540 return PhoneConstantConversions.convertDataState(
2541 PhoneConstants.DataState.DISCONNECTED);
2542 }
2543 } finally {
2544 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002545 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002546 }
2547
Sanket Padawe356d7632015-06-22 14:03:32 -07002548 @Override
Nathan Harolde037c472019-06-26 00:41:07 +00002549 public int getDataActivity() {
Nathan Haroldc4689b12019-06-14 16:58:30 -07002550 return getDataActivityForSubId(mSubscriptionController.getDefaultDataSubId());
2551 }
2552
2553 @Override
2554 public int getDataActivityForSubId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002555 final long identity = Binder.clearCallingIdentity();
2556 try {
Nathan Haroldc4689b12019-06-14 16:58:30 -07002557 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002558 if (phone != null) {
2559 return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState());
2560 } else {
2561 return TelephonyManager.DATA_ACTIVITY_NONE;
2562 }
2563 } finally {
2564 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002565 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002566 }
2567
2568 @Override
Meng Wanga10e89e2019-12-09 13:13:01 -08002569 public CellIdentity getCellLocation(String callingPackage, String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002570 mApp.getSystemService(AppOpsManager.class)
Hall Liu1aa510f2017-11-22 17:40:08 -08002571 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08002572
2573 LocationAccessPolicy.LocationPermissionResult locationResult =
2574 LocationAccessPolicy.checkLocationPermission(mApp,
2575 new LocationAccessPolicy.LocationPermissionQuery.Builder()
2576 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002577 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08002578 .setCallingPid(Binder.getCallingPid())
2579 .setCallingUid(Binder.getCallingUid())
2580 .setMethod("getCellLocation")
Hall Liu773ba022020-01-24 18:07:12 -08002581 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
Hall Liuf19c44f2018-11-27 14:38:17 -08002582 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2583 .build());
2584 switch (locationResult) {
2585 case DENIED_HARD:
2586 throw new SecurityException("Not allowed to access cell location");
2587 case DENIED_SOFT:
Meng Wanga10e89e2019-12-09 13:13:01 -08002588 return (getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
2589 ? new CellIdentityCdma() : new CellIdentityGsm();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002590 }
2591
Narayan Kamathf04b5a12018-01-09 11:47:15 +00002592 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002593 final long identity = Binder.clearCallingIdentity();
2594 try {
2595 if (DBG_LOC) log("getCellLocation: is active user");
Nathan Harold3ff88932018-08-14 10:19:49 -07002596 int subId = mSubscriptionController.getDefaultDataSubId();
Meng Wanga10e89e2019-12-09 13:13:01 -08002597 return (CellIdentity) sendRequest(CMD_GET_CELL_LOCATION, workSource, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002598 } finally {
2599 Binder.restoreCallingIdentity(identity);
2600 }
Svetoslav64fad262015-04-14 14:35:21 -07002601 }
2602
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002603 @Override
Jack Yueb1e7fe2020-02-22 19:38:58 -08002604 public String getNetworkCountryIsoForPhone(int phoneId) {
Jonathan Basseribf5362b2017-07-19 12:22:35 -07002605 // Reporting the correct network country is ambiguous when IWLAN could conflict with
2606 // registered cell info, so return a NULL country instead.
2607 final long identity = Binder.clearCallingIdentity();
2608 try {
Malcolm Chen3732c2b2018-07-18 20:15:24 -07002609 if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
2610 // Get default phone in this case.
2611 phoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
2612 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07002613 final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002614 Phone phone = PhoneFactory.getPhone(phoneId);
Nathan Harold532f51c2020-04-21 19:31:10 -07002615 if (phone == null) return "";
2616 ServiceStateTracker sst = phone.getServiceStateTracker();
2617 if (sst == null) return "";
2618 LocaleTracker lt = sst.getLocaleTracker();
2619 if (lt == null) return "";
2620 if (!TextUtils.isEmpty(lt.getCurrentCountry())) return lt.getCurrentCountry();
2621 EmergencyNumberTracker ent = phone.getEmergencyNumberTracker();
2622 return (ent == null) ? "" : ent.getEmergencyCountryIso();
Jonathan Basseribf5362b2017-07-19 12:22:35 -07002623 } finally {
2624 Binder.restoreCallingIdentity(identity);
2625 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07002626 }
2627
Nathan Harold7c8d0f12020-05-28 20:40:31 -07002628 /**
2629 * This method was removed due to potential issues caused by performing partial
2630 * updates of service state, and lack of a credible use case.
2631 *
2632 * This has the ability to break the telephony implementation by disabling notification of
2633 * changes in device connectivity. DO NOT USE THIS!
2634 */
Jonathan Basseribf5362b2017-07-19 12:22:35 -07002635 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002636 public void enableLocationUpdates() {
2637 mApp.enforceCallingOrSelfPermission(
2638 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002639 }
2640
Nathan Harold7c8d0f12020-05-28 20:40:31 -07002641 /**
2642 * This method was removed due to potential issues caused by performing partial
2643 * updates of service state, and lack of a credible use case.
2644 *
2645 * This has the ability to break the telephony implementation by disabling notification of
2646 * changes in device connectivity. DO NOT USE THIS!
2647 */
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002648 @Override
2649 public void disableLocationUpdates() {
2650 mApp.enforceCallingOrSelfPermission(
2651 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002652 }
2653
Nathan Harold31d7ff32018-10-15 20:20:30 -07002654 /**
2655 * Returns the target SDK version number for a given package name.
2656 *
Nathan Haroldec184742019-07-10 17:04:16 -07002657 * This call MUST be invoked before clearing the calling UID.
2658 *
Nathan Harold31d7ff32018-10-15 20:20:30 -07002659 * @return target SDK if the package is found or INT_MAX.
2660 */
2661 private int getTargetSdk(String packageName) {
2662 try {
Nathan Haroldec184742019-07-10 17:04:16 -07002663 final ApplicationInfo ai = mApp.getPackageManager().getApplicationInfoAsUser(
Chen Xu0150f0e2019-07-30 15:12:06 -07002664 packageName, 0, UserHandle.getUserHandleForUid(Binder.getCallingUid()));
Nathan Harold31d7ff32018-10-15 20:20:30 -07002665 if (ai != null) return ai.targetSdkVersion;
2666 } catch (PackageManager.NameNotFoundException unexpected) {
Nathan Haroldec184742019-07-10 17:04:16 -07002667 loge("Failed to get package info for pkg="
2668 + packageName + ", uid=" + Binder.getCallingUid());
Nathan Harold31d7ff32018-10-15 20:20:30 -07002669 }
2670 return Integer.MAX_VALUE;
2671 }
2672
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002673 @Override
2674 @SuppressWarnings("unchecked")
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002675 public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage,
2676 String callingFeatureId) {
Nathan Harold31d7ff32018-10-15 20:20:30 -07002677 final int targetSdk = getTargetSdk(callingPackage);
Nathan Harolddbea45a2018-08-30 14:35:07 -07002678 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
2679 throw new SecurityException(
2680 "getNeighboringCellInfo() is unavailable to callers targeting Q+ SDK levels.");
2681 }
Nathan Haroldb4d55612018-07-20 13:13:08 -07002682
Jordan Liu1617b712019-07-10 15:06:26 -07002683 if (mAppOps.noteOp(AppOpsManager.OPSTR_NEIGHBORING_CELLS, Binder.getCallingUid(),
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002684 callingPackage) != AppOpsManager.MODE_ALLOWED) {
2685 return null;
2686 }
Svetoslav64fad262015-04-14 14:35:21 -07002687
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07002688 if (DBG_LOC) log("getNeighboringCellInfo: is active user");
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002689
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002690 List<CellInfo> info = getAllCellInfo(callingPackage, callingFeatureId);
Nathan Haroldf180aac2018-06-01 18:43:55 -07002691 if (info == null) return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002692
Nathan Haroldf180aac2018-06-01 18:43:55 -07002693 List<NeighboringCellInfo> neighbors = new ArrayList<NeighboringCellInfo>();
2694 for (CellInfo ci : info) {
2695 if (ci instanceof CellInfoGsm) {
2696 neighbors.add(new NeighboringCellInfo((CellInfoGsm) ci));
2697 } else if (ci instanceof CellInfoWcdma) {
2698 neighbors.add(new NeighboringCellInfo((CellInfoWcdma) ci));
2699 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002700 }
Nathan Haroldf180aac2018-06-01 18:43:55 -07002701 return (neighbors.size()) > 0 ? neighbors : null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002702 }
2703
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002704 private List<CellInfo> getCachedCellInfo() {
2705 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
2706 for (Phone phone : PhoneFactory.getPhones()) {
2707 List<CellInfo> info = phone.getAllCellInfo();
2708 if (info != null) cellInfos.addAll(info);
2709 }
2710 return cellInfos;
2711 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002712
2713 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002714 public List<CellInfo> getAllCellInfo(String callingPackage, String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002715 mApp.getSystemService(AppOpsManager.class)
Hall Liu1aa510f2017-11-22 17:40:08 -08002716 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08002717
2718 LocationAccessPolicy.LocationPermissionResult locationResult =
2719 LocationAccessPolicy.checkLocationPermission(mApp,
2720 new LocationAccessPolicy.LocationPermissionQuery.Builder()
2721 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002722 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08002723 .setCallingPid(Binder.getCallingPid())
2724 .setCallingUid(Binder.getCallingUid())
2725 .setMethod("getAllCellInfo")
Nathan Harold5ae50b52019-02-20 15:46:36 -08002726 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
Hall Liuf19c44f2018-11-27 14:38:17 -08002727 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2728 .build());
2729 switch (locationResult) {
2730 case DENIED_HARD:
2731 throw new SecurityException("Not allowed to access cell info");
2732 case DENIED_SOFT:
2733 return new ArrayList<>();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002734 }
2735
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002736 final int targetSdk = getTargetSdk(callingPackage);
2737 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
2738 return getCachedCellInfo();
2739 }
2740
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07002741 if (DBG_LOC) log("getAllCellInfo: is active user");
Narayan Kamathf04b5a12018-01-09 11:47:15 +00002742 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002743 final long identity = Binder.clearCallingIdentity();
2744 try {
2745 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
2746 for (Phone phone : PhoneFactory.getPhones()) {
Nathan Harold3ff88932018-08-14 10:19:49 -07002747 final List<CellInfo> info = (List<CellInfo>) sendRequest(
Nathan Harold92bed182018-10-12 18:16:49 -07002748 CMD_GET_ALL_CELL_INFO, null, phone, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002749 if (info != null) cellInfos.addAll(info);
2750 }
2751 return cellInfos;
2752 } finally {
2753 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002754 }
2755 }
2756
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07002757 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002758 public void requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage,
2759 String callingFeatureId) {
2760 requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId,
2761 getWorkSource(Binder.getCallingUid()));
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002762 }
2763
2764 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002765 public void requestCellInfoUpdateWithWorkSource(int subId, ICellInfoCallback cb,
2766 String callingPackage, String callingFeatureId, WorkSource workSource) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002767 enforceModifyPermission();
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002768 requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId, workSource);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002769 }
2770
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002771 private void requestCellInfoUpdateInternal(int subId, ICellInfoCallback cb,
2772 String callingPackage, String callingFeatureId, WorkSource workSource) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002773 mApp.getSystemService(AppOpsManager.class)
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002774 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08002775
2776 LocationAccessPolicy.LocationPermissionResult locationResult =
2777 LocationAccessPolicy.checkLocationPermission(mApp,
2778 new LocationAccessPolicy.LocationPermissionQuery.Builder()
2779 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002780 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08002781 .setCallingPid(Binder.getCallingPid())
2782 .setCallingUid(Binder.getCallingUid())
2783 .setMethod("requestCellInfoUpdate")
Hall Liud60acc92020-05-21 17:09:35 -07002784 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
2785 .setMinSdkVersionForFine(Build.VERSION_CODES.BASE)
Hall Liuf19c44f2018-11-27 14:38:17 -08002786 .build());
2787 switch (locationResult) {
2788 case DENIED_HARD:
Hall Liud60acc92020-05-21 17:09:35 -07002789 if (getTargetSdk(callingPackage) < Build.VERSION_CODES.Q) {
2790 // Safetynet logging for b/154934934
2791 EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
2792 }
Hall Liuf19c44f2018-11-27 14:38:17 -08002793 throw new SecurityException("Not allowed to access cell info");
2794 case DENIED_SOFT:
Hall Liud60acc92020-05-21 17:09:35 -07002795 if (getTargetSdk(callingPackage) < Build.VERSION_CODES.Q) {
2796 // Safetynet logging for b/154934934
2797 EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
2798 }
Nathan Harold5320c422019-05-09 10:26:08 -07002799 try {
2800 cb.onCellInfo(new ArrayList<CellInfo>());
2801 } catch (RemoteException re) {
2802 // Drop without consequences
2803 }
Hall Liuf19c44f2018-11-27 14:38:17 -08002804 return;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002805 }
2806
Nathan Harolda939a962019-05-09 10:13:47 -07002807
2808 final Phone phone = getPhoneFromSubId(subId);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002809 if (phone == null) throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
2810
2811 sendRequestAsync(CMD_REQUEST_CELL_INFO_UPDATE, cb, phone, workSource);
2812 }
2813
2814 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002815 public void setCellInfoListRate(int rateInMillis) {
Jack Yua8d8cb82017-01-16 10:15:34 -08002816 enforceModifyPermission();
Narayan Kamathf04b5a12018-01-09 11:47:15 +00002817 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002818
2819 final long identity = Binder.clearCallingIdentity();
2820 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002821 getDefaultPhone().setCellInfoListRate(rateInMillis, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002822 } finally {
2823 Binder.restoreCallingIdentity(identity);
2824 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002825 }
2826
Shishir Agrawala9f32182016-04-12 12:00:16 -07002827 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002828 public String getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002829 Phone phone = PhoneFactory.getPhone(slotIndex);
2830 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002831 return null;
2832 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002833 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07002834 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002835 callingPackage, callingFeatureId, "getImeiForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002836 return null;
2837 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002838
2839 final long identity = Binder.clearCallingIdentity();
2840 try {
2841 return phone.getImei();
2842 } finally {
2843 Binder.restoreCallingIdentity(identity);
2844 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002845 }
2846
2847 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002848 public String getTypeAllocationCodeForSlot(int slotIndex) {
2849 Phone phone = PhoneFactory.getPhone(slotIndex);
2850 String tac = null;
2851 if (phone != null) {
2852 String imei = phone.getImei();
2853 tac = imei == null ? null : imei.substring(0, TYPE_ALLOCATION_CODE_LENGTH);
2854 }
2855 return tac;
2856 }
2857
2858 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002859 public String getMeidForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002860 Phone phone = PhoneFactory.getPhone(slotIndex);
2861 if (phone == null) {
Jack Yu2af8d712017-03-15 17:14:14 -07002862 return null;
2863 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002864
Jeff Davidson913390f2018-02-23 17:11:49 -08002865 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07002866 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002867 callingPackage, callingFeatureId, "getMeidForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002868 return null;
2869 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002870
2871 final long identity = Binder.clearCallingIdentity();
2872 try {
2873 return phone.getMeid();
2874 } finally {
2875 Binder.restoreCallingIdentity(identity);
2876 }
Jack Yu2af8d712017-03-15 17:14:14 -07002877 }
2878
2879 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002880 public String getManufacturerCodeForSlot(int slotIndex) {
2881 Phone phone = PhoneFactory.getPhone(slotIndex);
2882 String manufacturerCode = null;
2883 if (phone != null) {
2884 String meid = phone.getMeid();
2885 manufacturerCode = meid == null ? null : meid.substring(0, MANUFACTURER_CODE_LENGTH);
2886 }
2887 return manufacturerCode;
2888 }
2889
2890 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002891 public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage,
2892 String callingFeatureId) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002893 Phone phone = PhoneFactory.getPhone(slotIndex);
2894 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002895 return null;
2896 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002897 int subId = phone.getSubId();
2898 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002899 mApp, subId, callingPackage, callingFeatureId,
2900 "getDeviceSoftwareVersionForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002901 return null;
2902 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002903
2904 final long identity = Binder.clearCallingIdentity();
2905 try {
2906 return phone.getDeviceSvn();
2907 } finally {
2908 Binder.restoreCallingIdentity(identity);
2909 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002910 }
2911
fionaxu43304da2017-11-27 22:51:16 -08002912 @Override
2913 public int getSubscriptionCarrierId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002914 final long identity = Binder.clearCallingIdentity();
2915 try {
2916 final Phone phone = getPhone(subId);
2917 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getCarrierId();
2918 } finally {
2919 Binder.restoreCallingIdentity(identity);
2920 }
fionaxu43304da2017-11-27 22:51:16 -08002921 }
2922
2923 @Override
2924 public String getSubscriptionCarrierName(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002925 final long identity = Binder.clearCallingIdentity();
2926 try {
2927 final Phone phone = getPhone(subId);
2928 return phone == null ? null : phone.getCarrierName();
2929 } finally {
2930 Binder.restoreCallingIdentity(identity);
2931 }
fionaxu43304da2017-11-27 22:51:16 -08002932 }
2933
calvinpanffe225e2018-11-01 19:43:06 +08002934 @Override
chen xu0026ca62019-03-06 15:28:50 -08002935 public int getSubscriptionSpecificCarrierId(int subId) {
chen xu25637222018-11-04 17:17:00 -08002936 final long identity = Binder.clearCallingIdentity();
2937 try {
2938 final Phone phone = getPhone(subId);
2939 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID
chen xu0026ca62019-03-06 15:28:50 -08002940 : phone.getSpecificCarrierId();
chen xu25637222018-11-04 17:17:00 -08002941 } finally {
2942 Binder.restoreCallingIdentity(identity);
2943 }
2944 }
2945
2946 @Override
chen xu0026ca62019-03-06 15:28:50 -08002947 public String getSubscriptionSpecificCarrierName(int subId) {
chen xu25637222018-11-04 17:17:00 -08002948 final long identity = Binder.clearCallingIdentity();
2949 try {
2950 final Phone phone = getPhone(subId);
chen xu0026ca62019-03-06 15:28:50 -08002951 return phone == null ? null : phone.getSpecificCarrierName();
chen xu25637222018-11-04 17:17:00 -08002952 } finally {
2953 Binder.restoreCallingIdentity(identity);
2954 }
2955 }
2956
chen xu651eec72018-11-11 19:03:44 -08002957 @Override
chen xu864e11c2018-12-06 22:10:03 -08002958 public int getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc) {
2959 if (!isSubscriptionMccMnc) {
2960 enforceReadPrivilegedPermission("getCarrierIdFromMccMnc");
2961 }
chen xu651eec72018-11-11 19:03:44 -08002962 final Phone phone = PhoneFactory.getPhone(slotIndex);
2963 if (phone == null) {
2964 return TelephonyManager.UNKNOWN_CARRIER_ID;
2965 }
2966 final long identity = Binder.clearCallingIdentity();
2967 try {
2968 return CarrierResolver.getCarrierIdFromMccMnc(phone.getContext(), mccmnc);
2969 } finally {
2970 Binder.restoreCallingIdentity(identity);
2971 }
2972 }
2973
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002974 //
2975 // Internal helper methods.
2976 //
2977
Sanket Padaweee13a9b2016-03-08 17:30:28 -08002978 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002979 * Make sure the caller has the MODIFY_PHONE_STATE permission.
2980 *
2981 * @throws SecurityException if the caller does not have the required permission
2982 */
2983 private void enforceModifyPermission() {
2984 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
2985 }
2986
Shuo Qiancd19c462020-01-16 20:51:11 -08002987 /**
2988 * Make sure the caller is system.
2989 *
2990 * @throws SecurityException if the caller is not system.
2991 */
2992 private void enforceSystemCaller() {
2993 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
2994 throw new SecurityException("Caller must be system");
2995 }
2996 }
2997
Shuo Qian3b6ee772019-11-13 17:43:31 -08002998 private void enforceActiveEmergencySessionPermission() {
2999 mApp.enforceCallingOrSelfPermission(
3000 android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION, null);
3001 }
3002
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003003 /**
3004 * Make sure the caller has the CALL_PHONE permission.
3005 *
3006 * @throws SecurityException if the caller does not have the required permission
3007 */
3008 private void enforceCallPermission() {
3009 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
3010 }
3011
paulhu5a773602019-08-23 19:17:33 +08003012 private void enforceSettingsPermission() {
3013 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.NETWORK_SETTINGS, null);
Stuart Scott8eef64f2015-04-08 15:13:54 -07003014 }
3015
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003016 private String createTelUrl(String number) {
3017 if (TextUtils.isEmpty(number)) {
3018 return null;
3019 }
3020
Jake Hambye994d462014-02-03 13:10:13 -08003021 return "tel:" + number;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003022 }
3023
Ihab Awadf9e92732013-12-05 18:02:52 -08003024 private static void log(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003025 Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg);
3026 }
3027
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07003028 private static void logv(String msg) {
3029 Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg);
3030 }
3031
Ihab Awadf9e92732013-12-05 18:02:52 -08003032 private static void loge(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003033 Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg);
3034 }
3035
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003036 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003037 public int getActivePhoneType() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07003038 return getActivePhoneTypeForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07003039 }
3040
Sanket Padawe356d7632015-06-22 14:03:32 -07003041 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07003042 public int getActivePhoneTypeForSlot(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003043 final long identity = Binder.clearCallingIdentity();
3044 try {
3045 final Phone phone = PhoneFactory.getPhone(slotIndex);
3046 if (phone == null) {
3047 return PhoneConstants.PHONE_TYPE_NONE;
3048 } else {
3049 return phone.getPhoneType();
3050 }
3051 } finally {
3052 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003053 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003054 }
3055
3056 /**
3057 * Returns the CDMA ERI icon index to display
3058 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003059 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003060 public int getCdmaEriIconIndex(String callingPackage, String callingFeatureId) {
3061 return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage,
3062 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07003063 }
3064
Sanket Padawe356d7632015-06-22 14:03:32 -07003065 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003066 public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage,
3067 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003068 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003069 mApp, subId, callingPackage, callingFeatureId,
3070 "getCdmaEriIconIndexForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003071 return -1;
3072 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003073
3074 final long identity = Binder.clearCallingIdentity();
3075 try {
3076 final Phone phone = getPhone(subId);
3077 if (phone != null) {
3078 return phone.getCdmaEriIconIndex();
3079 } else {
3080 return -1;
3081 }
3082 } finally {
3083 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003084 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003085 }
3086
3087 /**
3088 * Returns the CDMA ERI icon mode,
3089 * 0 - ON
3090 * 1 - FLASHING
3091 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003092 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003093 public int getCdmaEriIconMode(String callingPackage, String callingFeatureId) {
3094 return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage,
3095 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07003096 }
3097
Sanket Padawe356d7632015-06-22 14:03:32 -07003098 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003099 public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage,
3100 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003101 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003102 mApp, subId, callingPackage, callingFeatureId,
3103 "getCdmaEriIconModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003104 return -1;
3105 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003106
3107 final long identity = Binder.clearCallingIdentity();
3108 try {
3109 final Phone phone = getPhone(subId);
3110 if (phone != null) {
3111 return phone.getCdmaEriIconMode();
3112 } else {
3113 return -1;
3114 }
3115 } finally {
3116 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003117 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003118 }
3119
3120 /**
3121 * Returns the CDMA ERI text,
3122 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003123 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003124 public String getCdmaEriText(String callingPackage, String callingFeatureId) {
3125 return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage,
3126 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07003127 }
3128
Sanket Padawe356d7632015-06-22 14:03:32 -07003129 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003130 public String getCdmaEriTextForSubscriber(int subId, String callingPackage,
3131 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003132 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003133 mApp, subId, callingPackage, callingFeatureId,
3134 "getCdmaEriIconTextForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003135 return null;
3136 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003137
3138 final long identity = Binder.clearCallingIdentity();
3139 try {
3140 final Phone phone = getPhone(subId);
3141 if (phone != null) {
3142 return phone.getCdmaEriText();
3143 } else {
3144 return null;
3145 }
3146 } finally {
3147 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003148 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003149 }
3150
3151 /**
Junda Liuca05d5d2014-08-14 22:36:34 -07003152 * Returns the CDMA MDN.
3153 */
Sanket Padawe356d7632015-06-22 14:03:32 -07003154 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07003155 public String getCdmaMdn(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003156 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3157 mApp, subId, "getCdmaMdn");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003158
3159 final long identity = Binder.clearCallingIdentity();
3160 try {
3161 final Phone phone = getPhone(subId);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003162 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003163 return phone.getLine1Number();
3164 } else {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003165 loge("getCdmaMdn: no phone found. Invalid subId: " + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003166 return null;
3167 }
3168 } finally {
3169 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07003170 }
3171 }
3172
3173 /**
3174 * Returns the CDMA MIN.
3175 */
Sanket Padawe356d7632015-06-22 14:03:32 -07003176 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07003177 public String getCdmaMin(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003178 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3179 mApp, subId, "getCdmaMin");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003180
3181 final long identity = Binder.clearCallingIdentity();
3182 try {
3183 final Phone phone = getPhone(subId);
3184 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
3185 return phone.getCdmaMin();
3186 } else {
3187 return null;
3188 }
3189 } finally {
3190 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07003191 }
3192 }
3193
Hall Liud892bec2018-11-30 14:51:45 -08003194 @Override
3195 public void requestNumberVerification(PhoneNumberRange range, long timeoutMillis,
3196 INumberVerificationCallback callback, String callingPackage) {
3197 if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
3198 != PERMISSION_GRANTED) {
3199 throw new SecurityException("Caller must hold the MODIFY_PHONE_STATE permission");
3200 }
3201 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3202
3203 String authorizedPackage = NumberVerificationManager.getAuthorizedPackage(mApp);
3204 if (!TextUtils.equals(callingPackage, authorizedPackage)) {
3205 throw new SecurityException("Calling package must be configured in the device config");
3206 }
3207
3208 if (range == null) {
3209 throw new NullPointerException("Range must be non-null");
3210 }
3211
3212 timeoutMillis = Math.min(timeoutMillis,
Hall Liubd069e32019-02-28 18:56:30 -08003213 TelephonyManager.getMaxNumberVerificationTimeoutMillis());
Hall Liud892bec2018-11-30 14:51:45 -08003214
3215 NumberVerificationManager.getInstance().requestVerification(range, callback, timeoutMillis);
3216 }
3217
Junda Liuca05d5d2014-08-14 22:36:34 -07003218 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003219 * Returns true if CDMA provisioning needs to run.
3220 */
3221 public boolean needsOtaServiceProvisioning() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003222 final long identity = Binder.clearCallingIdentity();
3223 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003224 return getDefaultPhone().needsOtaServiceProvisioning();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003225 } finally {
3226 Binder.restoreCallingIdentity(identity);
3227 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003228 }
3229
3230 /**
Shishir Agrawal76d5da92014-11-09 16:17:25 -08003231 * Sets the voice mail number of a given subId.
3232 */
3233 @Override
3234 public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08003235 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
3236 mApp, subId, "setVoiceMailNumber");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003237
3238 final long identity = Binder.clearCallingIdentity();
3239 try {
3240 Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
3241 new Pair<String, String>(alphaTag, number), new Integer(subId));
3242 return success;
3243 } finally {
3244 Binder.restoreCallingIdentity(identity);
3245 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08003246 }
3247
Ta-wei Yen87c49842016-05-13 21:19:52 -07003248 @Override
Ta-wei Yenc9df0432017-04-17 17:09:07 -07003249 public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
3250 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07003251 TelecomManager tm = mApp.getSystemService(TelecomManager.class);
3252 String systemDialer = tm.getSystemDialerPackage();
Ta-wei Yenc9df0432017-04-17 17:09:07 -07003253 if (!TextUtils.equals(callingPackage, systemDialer)) {
3254 throw new SecurityException("caller must be system dialer");
3255 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003256
3257 final long identity = Binder.clearCallingIdentity();
3258 try {
3259 PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
3260 if (phoneAccountHandle == null) {
3261 return null;
3262 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003263 return VisualVoicemailSettingsUtil.dump(mApp, phoneAccountHandle);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003264 } finally {
3265 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc9df0432017-04-17 17:09:07 -07003266 }
Ta-wei Yenc9df0432017-04-17 17:09:07 -07003267 }
3268
3269 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003270 public String getVisualVoicemailPackageName(String callingPackage, String callingFeatureId,
3271 int subId) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08003272 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jeff Davidson7e17e312018-02-13 18:17:36 -08003273 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003274 mApp, subId, callingPackage, callingFeatureId,
3275 "getVisualVoicemailPackageName")) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08003276 return null;
3277 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003278
Jeff Davidsona8e4e242018-03-15 17:16:18 -07003279 final long identity = Binder.clearCallingIdentity();
3280 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003281 return RemoteVvmTaskManager.getRemotePackage(mApp, subId).getPackageName();
Jeff Davidsona8e4e242018-03-15 17:16:18 -07003282 } finally {
3283 Binder.restoreCallingIdentity(identity);
3284 }
Ta-wei Yendca928f2017-01-10 16:17:08 -08003285 }
3286
3287 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07003288 public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
3289 VisualVoicemailSmsFilterSettings settings) {
3290 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003291
3292 final long identity = Binder.clearCallingIdentity();
3293 try {
3294 VisualVoicemailSmsFilterConfig.enableVisualVoicemailSmsFilter(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003295 mApp, callingPackage, subId, settings);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003296 } finally {
3297 Binder.restoreCallingIdentity(identity);
3298 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07003299 }
3300
3301 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07003302 public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
3303 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003304
3305 final long identity = Binder.clearCallingIdentity();
3306 try {
3307 VisualVoicemailSmsFilterConfig.disableVisualVoicemailSmsFilter(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003308 mApp, callingPackage, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003309 } finally {
3310 Binder.restoreCallingIdentity(identity);
3311 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07003312 }
3313
3314 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07003315 public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
3316 String callingPackage, int subId) {
3317 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003318
3319 final long identity = Binder.clearCallingIdentity();
3320 try {
3321 return VisualVoicemailSmsFilterConfig.getVisualVoicemailSmsFilterSettings(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003322 mApp, callingPackage, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003323 } finally {
3324 Binder.restoreCallingIdentity(identity);
3325 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07003326 }
3327
3328 @Override
Ta-wei Yen30a69c82016-12-27 14:52:32 -08003329 public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003330 enforceReadPrivilegedPermission("getActiveVisualVoicemailSmsFilterSettings");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003331
3332 final long identity = Binder.clearCallingIdentity();
3333 try {
3334 return VisualVoicemailSmsFilterConfig.getActiveVisualVoicemailSmsFilterSettings(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003335 mApp, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003336 } finally {
3337 Binder.restoreCallingIdentity(identity);
3338 }
Ta-wei Yen30a69c82016-12-27 14:52:32 -08003339 }
3340
3341 @Override
Philip P. Moltmann2f6f8ce2020-03-18 18:17:02 -07003342 public void sendVisualVoicemailSmsForSubscriber(String callingPackage,
3343 String callingAttributionTag, int subId, String number, int port, String text,
3344 PendingIntent sentIntent) {
Ta-wei Yen30a69c82016-12-27 14:52:32 -08003345 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Ta-wei Yen527a9c02017-01-06 15:29:25 -08003346 enforceVisualVoicemailPackage(callingPackage, subId);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08003347 enforceSendSmsPermission();
Amit Mahajandccb3f12019-05-13 13:48:32 -07003348 SmsController smsController = PhoneFactory.getSmsController();
Philip P. Moltmann2f6f8ce2020-03-18 18:17:02 -07003349 smsController.sendVisualVoicemailSmsForSubscriber(callingPackage, callingAttributionTag,
3350 subId, number, port, text, sentIntent);
Ta-wei Yen87c49842016-05-13 21:19:52 -07003351 }
Amit Mahajandccb3f12019-05-13 13:48:32 -07003352
Shishir Agrawal76d5da92014-11-09 16:17:25 -08003353 /**
fionaxu0152e512016-11-14 13:36:14 -08003354 * Sets the voice activation state of a given subId.
3355 */
3356 @Override
3357 public void setVoiceActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003358 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3359 mApp, subId, "setVoiceActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003360
3361 final long identity = Binder.clearCallingIdentity();
3362 try {
3363 final Phone phone = getPhone(subId);
3364 if (phone != null) {
3365 phone.setVoiceActivationState(activationState);
3366 } else {
3367 loge("setVoiceActivationState fails with invalid subId: " + subId);
3368 }
3369 } finally {
3370 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08003371 }
3372 }
3373
3374 /**
3375 * Sets the data activation state of a given subId.
3376 */
3377 @Override
3378 public void setDataActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003379 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3380 mApp, subId, "setDataActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003381
3382 final long identity = Binder.clearCallingIdentity();
3383 try {
3384 final Phone phone = getPhone(subId);
3385 if (phone != null) {
3386 phone.setDataActivationState(activationState);
3387 } else {
Taesu Leef8fbed92019-10-07 18:47:02 +09003388 loge("setDataActivationState fails with invalid subId: " + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003389 }
3390 } finally {
3391 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08003392 }
3393 }
3394
3395 /**
3396 * Returns the voice activation state of a given subId.
3397 */
3398 @Override
3399 public int getVoiceActivationState(int subId, String callingPackage) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003400 enforceReadPrivilegedPermission("getVoiceActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003401
fionaxu0152e512016-11-14 13:36:14 -08003402 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003403 final long identity = Binder.clearCallingIdentity();
3404 try {
3405 if (phone != null) {
3406 return phone.getVoiceActivationState();
3407 } else {
3408 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
3409 }
3410 } finally {
3411 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08003412 }
3413 }
3414
3415 /**
3416 * Returns the data activation state of a given subId.
3417 */
3418 @Override
3419 public int getDataActivationState(int subId, String callingPackage) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003420 enforceReadPrivilegedPermission("getDataActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003421
fionaxu0152e512016-11-14 13:36:14 -08003422 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003423 final long identity = Binder.clearCallingIdentity();
3424 try {
3425 if (phone != null) {
3426 return phone.getDataActivationState();
3427 } else {
3428 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
3429 }
3430 } finally {
3431 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08003432 }
3433 }
3434
3435 /**
Wink Saville36469e72014-06-11 15:17:00 -07003436 * Returns the unread count of voicemails for a subId
3437 */
Sanket Padawe356d7632015-06-22 14:03:32 -07003438 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003439 public int getVoiceMessageCountForSubscriber(int subId, String callingPackage,
3440 String callingFeatureId) {
Brad Ebingerf7664ba2018-11-29 12:43:38 -08003441 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003442 mApp, subId, callingPackage, callingFeatureId,
3443 "getVoiceMessageCountForSubscriber")) {
Brad Ebingerf7664ba2018-11-29 12:43:38 -08003444 return 0;
3445 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003446 final long identity = Binder.clearCallingIdentity();
3447 try {
3448 final Phone phone = getPhone(subId);
3449 if (phone != null) {
3450 return phone.getVoiceMessageCount();
3451 } else {
3452 return 0;
3453 }
3454 } finally {
3455 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003456 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003457 }
3458
3459 /**
pkanwar8a4dcfb2017-01-19 13:43:16 -08003460 * returns true, if the device is in a state where both voice and data
3461 * are supported simultaneously. This can change based on location or network condition.
3462 */
3463 @Override
3464 public boolean isConcurrentVoiceAndDataAllowed(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003465 final long identity = Binder.clearCallingIdentity();
3466 try {
3467 final Phone phone = getPhone(subId);
3468 return (phone == null ? false : phone.isConcurrentVoiceAndDataAllowed());
3469 } finally {
3470 Binder.restoreCallingIdentity(identity);
3471 }
pkanwar8a4dcfb2017-01-19 13:43:16 -08003472 }
3473
3474 /**
fionaxu235cc5e2017-03-06 22:25:57 -08003475 * Send the dialer code if called from the current default dialer or the caller has
3476 * carrier privilege.
3477 * @param inputCode The dialer code to send
3478 */
3479 @Override
3480 public void sendDialerSpecialCode(String callingPackage, String inputCode) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003481 final Phone defaultPhone = getDefaultPhone();
fionaxu235cc5e2017-03-06 22:25:57 -08003482 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07003483 TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
3484 String defaultDialer = tm.getDefaultDialerPackage();
fionaxu235cc5e2017-03-06 22:25:57 -08003485 if (!TextUtils.equals(callingPackage, defaultDialer)) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08003486 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
Jeff Davidson7e17e312018-02-13 18:17:36 -08003487 getDefaultSubscription(), "sendDialerSpecialCode");
fionaxu235cc5e2017-03-06 22:25:57 -08003488 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003489
3490 final long identity = Binder.clearCallingIdentity();
3491 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003492 defaultPhone.sendDialerSpecialCode(inputCode);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003493 } finally {
3494 Binder.restoreCallingIdentity(identity);
3495 }
fionaxu235cc5e2017-03-06 22:25:57 -08003496 }
3497
Pengquan Menga1bb6272018-09-06 09:59:22 -07003498 @Override
3499 public int getNetworkSelectionMode(int subId) {
shilufc958392020-01-20 11:36:01 -08003500 TelephonyPermissions
3501 .enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3502 mApp, subId, "getNetworkSelectionMode");
3503 final long identity = Binder.clearCallingIdentity();
3504 try {
3505 if (!isActiveSubscription(subId)) {
3506 return TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
3507 }
3508 return (int) sendRequest(CMD_GET_NETWORK_SELECTION_MODE, null /* argument */, subId);
3509 } finally {
3510 Binder.restoreCallingIdentity(identity);
Pengquan Menge92a50d2018-09-21 15:54:48 -07003511 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07003512 }
3513
Brad Ebinger35c841c2018-10-01 10:40:55 -07003514 @Override
Brad Ebingerb2b65522019-03-15 13:48:47 -07003515 public boolean isInEmergencySmsMode() {
3516 enforceReadPrivilegedPermission("isInEmergencySmsMode");
3517 final long identity = Binder.clearCallingIdentity();
3518 try {
3519 for (Phone phone : PhoneFactory.getPhones()) {
3520 if (phone.isInEmergencySmsMode()) {
3521 return true;
3522 }
3523 }
3524 } finally {
3525 Binder.restoreCallingIdentity(identity);
3526 }
3527 return false;
3528 }
3529
shilu366312e2019-12-17 09:28:10 -08003530 /**
3531 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3532 * @param subId The subscription to use to check the configuration.
3533 * @param c The callback that will be used to send the result.
3534 */
Brad Ebingerb2b65522019-03-15 13:48:47 -07003535 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003536 public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback c)
3537 throws RemoteException {
Rambo Wang37f9c242020-02-10 14:45:28 -08003538 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3539 mApp, subId, "registerImsRegistrationCallback");
shilu366312e2019-12-17 09:28:10 -08003540
Brad Ebingerbc7dd582019-10-17 17:03:22 -07003541 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3542 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3543 "IMS not available on device.");
3544 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07003545 final long token = Binder.clearCallingIdentity();
3546 try {
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003547 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003548 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger35c841c2018-10-01 10:40:55 -07003549 .addRegistrationCallbackForSubscription(c, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003550 } catch (ImsException e) {
3551 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003552 } finally {
3553 Binder.restoreCallingIdentity(token);
3554 }
3555 }
3556
shilu366312e2019-12-17 09:28:10 -08003557 /**
3558 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3559 * @param subId The subscription to use to check the configuration.
3560 * @param c The callback that will be used to send the result.
3561 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003562 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003563 public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c) {
Rambo Wang37f9c242020-02-10 14:45:28 -08003564 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3565 mApp, subId, "unregisterImsRegistrationCallback");
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003566 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3567 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
3568 }
Meng Wangafbc5852019-09-19 17:37:13 -07003569 final long token = Binder.clearCallingIdentity();
3570 try {
Meng Wang8ea57e32020-06-25 11:03:56 -07003571 // TODO(b/159910732): Remove ImsManager dependence and query through ImsPhone directly.
Meng Wangafbc5852019-09-19 17:37:13 -07003572 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
3573 .removeRegistrationCallbackForSubscription(c, subId);
3574 } catch (ImsException e) {
3575 Log.i(LOG_TAG, "unregisterImsRegistrationCallback: " + subId
3576 + "is inactive, ignoring unregister.");
3577 // If the subscription is no longer active, just return, since the callback
3578 // will already have been removed internally.
3579 } finally {
3580 Binder.restoreCallingIdentity(token);
3581 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07003582 }
3583
Brad Ebingera34a6c22019-10-22 17:36:18 -07003584 /**
3585 * Get the IMS service registration state for the MmTelFeature associated with this sub id.
3586 */
3587 @Override
3588 public void getImsMmTelRegistrationState(int subId, IIntegerConsumer consumer) {
3589 enforceReadPrivilegedPermission("getImsMmTelRegistrationState");
3590 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3591 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3592 "IMS not available on device.");
3593 }
3594 final long token = Binder.clearCallingIdentity();
3595 try {
3596 Phone phone = getPhone(subId);
3597 if (phone == null) {
3598 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
3599 + subId + "'");
3600 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
3601 }
3602 phone.getImsRegistrationState(regState -> {
3603 try {
3604 consumer.accept((regState == null)
3605 ? RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED : regState);
3606 } catch (RemoteException e) {
3607 // Ignore if the remote process is no longer available to call back.
3608 Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
3609 }
3610 });
3611 } finally {
3612 Binder.restoreCallingIdentity(token);
3613 }
3614 }
3615
3616 /**
3617 * Get the transport type for the IMS service registration state.
3618 */
3619 @Override
3620 public void getImsMmTelRegistrationTransportType(int subId, IIntegerConsumer consumer) {
Rambo Wang37f9c242020-02-10 14:45:28 -08003621 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3622 mApp, subId, "getImsMmTelRegistrationTransportType");
Brad Ebingera34a6c22019-10-22 17:36:18 -07003623 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3624 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3625 "IMS not available on device.");
3626 }
3627 final long token = Binder.clearCallingIdentity();
3628 try {
3629 Phone phone = getPhone(subId);
3630 if (phone == null) {
3631 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
3632 + subId + "'");
3633 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
3634 }
3635 phone.getImsRegistrationTech(regTech -> {
3636 // Convert registration tech from ImsRegistrationImplBase -> RegistrationManager
3637 int regTechConverted = (regTech == null)
3638 ? ImsRegistrationImplBase.REGISTRATION_TECH_NONE : regTech;
3639 regTechConverted = RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(
3640 regTechConverted);
3641 try {
3642 consumer.accept(regTechConverted);
3643 } catch (RemoteException e) {
3644 // Ignore if the remote process is no longer available to call back.
3645 Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
3646 }
3647 });
3648 } finally {
3649 Binder.restoreCallingIdentity(token);
3650 }
3651 }
3652
shilu366312e2019-12-17 09:28:10 -08003653 /**
3654 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3655 * @param subId The subscription to use to check the configuration.
3656 * @param c The callback that will be used to send the result.
3657 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003658 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003659 public void registerMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)
3660 throws RemoteException {
Rambo Wang37f9c242020-02-10 14:45:28 -08003661 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3662 mApp, subId, "registerMmTelCapabilityCallback");
Brad Ebingerbc7dd582019-10-17 17:03:22 -07003663 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3664 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3665 "IMS not available on device.");
3666 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07003667 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3668 final long token = Binder.clearCallingIdentity();
3669 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003670 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger35c841c2018-10-01 10:40:55 -07003671 .addCapabilitiesCallbackForSubscription(c, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003672 } catch (ImsException e) {
3673 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003674 } finally {
3675 Binder.restoreCallingIdentity(token);
3676 }
3677 }
3678
shilu366312e2019-12-17 09:28:10 -08003679 /**
3680 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3681 * @param subId The subscription to use to check the configuration.
3682 * @param c The callback that will be used to send the result.
3683 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003684 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003685 public void unregisterMmTelCapabilityCallback(int subId, IImsCapabilityCallback c) {
Rambo Wang37f9c242020-02-10 14:45:28 -08003686 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3687 mApp, subId, "unregisterMmTelCapabilityCallback");
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003688 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3689 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
3690 }
Meng Wangafbc5852019-09-19 17:37:13 -07003691
3692 final long token = Binder.clearCallingIdentity();
3693 try {
Meng Wang8ea57e32020-06-25 11:03:56 -07003694 // TODO(b/159910732): Remove ImsManager dependence and query through ImsPhone directly.
Meng Wangafbc5852019-09-19 17:37:13 -07003695 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003696 .removeCapabilitiesCallbackForSubscription(c, subId);
Meng Wangafbc5852019-09-19 17:37:13 -07003697 } catch (ImsException e) {
3698 Log.i(LOG_TAG, "unregisterMmTelCapabilityCallback: " + subId
3699 + "is inactive, ignoring unregister.");
3700 // If the subscription is no longer active, just return, since the callback
3701 // will already have been removed internally.
3702 } finally {
3703 Binder.restoreCallingIdentity(token);
3704 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07003705 }
3706
3707 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003708 public boolean isCapable(int subId, int capability, int regTech) {
3709 enforceReadPrivilegedPermission("isCapable");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003710 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3711 final long token = Binder.clearCallingIdentity();
3712 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003713 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003714 getSlotIndexOrException(subId)).queryMmTelCapability(capability, regTech);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003715 } catch (com.android.ims.ImsException e) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003716 Log.w(LOG_TAG, "IMS isCapable - service unavailable: " + e.getMessage());
3717 return false;
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003718 } catch (ImsException e) {
Brad Ebinger6b5ac222019-02-04 14:36:52 -08003719 Log.i(LOG_TAG, "isCapable: " + subId + " is inactive, returning false.");
3720 return false;
Brad Ebinger35c841c2018-10-01 10:40:55 -07003721 } finally {
3722 Binder.restoreCallingIdentity(token);
3723 }
3724 }
3725
3726 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003727 public boolean isAvailable(int subId, int capability, int regTech) {
3728 enforceReadPrivilegedPermission("isAvailable");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003729 final long token = Binder.clearCallingIdentity();
3730 try {
3731 Phone phone = getPhone(subId);
3732 if (phone == null) return false;
3733 return phone.isImsCapabilityAvailable(capability, regTech);
Daniel Bright5e40e4e2020-03-11 16:35:39 -07003734 } catch (com.android.ims.ImsException e) {
3735 Log.w(LOG_TAG, "IMS isAvailable - service unavailable: " + e.getMessage());
3736 return false;
Brad Ebinger35c841c2018-10-01 10:40:55 -07003737 } finally {
3738 Binder.restoreCallingIdentity(token);
3739 }
3740 }
3741
Brad Ebingerbc7dd582019-10-17 17:03:22 -07003742 /**
3743 * Determines if the MmTel feature capability is supported by the carrier configuration for this
3744 * subscription.
3745 * @param subId The subscription to use to check the configuration.
3746 * @param callback The callback that will be used to send the result.
3747 * @param capability The MmTelFeature capability that will be used to send the result.
3748 * @param transportType The transport type of the MmTelFeature capability.
3749 */
3750 @Override
3751 public void isMmTelCapabilitySupported(int subId, IIntegerConsumer callback, int capability,
3752 int transportType) {
3753 enforceReadPrivilegedPermission("isMmTelCapabilitySupported");
3754 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3755 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3756 "IMS not available on device.");
3757 }
3758 final long token = Binder.clearCallingIdentity();
3759 try {
3760 int slotId = getSlotIndex(subId);
3761 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
3762 Log.w(LOG_TAG, "isMmTelCapabilitySupported: called with an inactive subscription '"
3763 + subId + "'");
3764 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
3765 }
3766 ImsManager.getInstance(mApp, slotId).isSupported(capability,
3767 transportType, aBoolean -> {
3768 try {
3769 callback.accept((aBoolean == null) ? 0 : (aBoolean ? 1 : 0));
3770 } catch (RemoteException e) {
3771 Log.w(LOG_TAG, "isMmTelCapabilitySupported: remote caller is not "
3772 + "running. Ignore");
3773 }
3774 });
3775 } finally {
3776 Binder.restoreCallingIdentity(token);
3777 }
3778 }
3779
shilu366312e2019-12-17 09:28:10 -08003780 /**
3781 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3782 * @param subId The subscription to use to check the configuration.
3783 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003784 @Override
3785 public boolean isAdvancedCallingSettingEnabled(int subId) {
Rambo Wang37f9c242020-02-10 14:45:28 -08003786 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3787 mApp, subId, "isAdvancedCallingSettingEnabled");
shilu366312e2019-12-17 09:28:10 -08003788
Brad Ebinger35c841c2018-10-01 10:40:55 -07003789 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3790 final long token = Binder.clearCallingIdentity();
3791 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003792 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003793 getSlotIndexOrException(subId)).isEnhanced4gLteModeSettingEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003794 } catch (ImsException e) {
3795 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003796 } finally {
3797 Binder.restoreCallingIdentity(token);
3798 }
3799 }
3800
3801 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08003802 public void setAdvancedCallingSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003803 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08003804 "setAdvancedCallingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003805 final long identity = Binder.clearCallingIdentity();
3806 try {
3807 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003808 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003809 getSlotIndexOrException(subId)).setEnhanced4gLteModeSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003810 } catch (ImsException e) {
3811 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003812 } finally {
3813 Binder.restoreCallingIdentity(identity);
3814 }
3815 }
3816
shilu366312e2019-12-17 09:28:10 -08003817 /**
3818 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3819 * @param subId The subscription to use to check the configuration.
3820 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003821 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003822 public boolean isVtSettingEnabled(int subId) {
Rambo Wang37f9c242020-02-10 14:45:28 -08003823 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3824 mApp, subId, "isVtSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003825 final long identity = Binder.clearCallingIdentity();
3826 try {
3827 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003828 return ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).isVtEnabledByUser();
3829 } catch (ImsException e) {
3830 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003831 } finally {
3832 Binder.restoreCallingIdentity(identity);
3833 }
3834 }
3835
3836 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08003837 public void setVtSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003838 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08003839 "setVtSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003840 final long identity = Binder.clearCallingIdentity();
3841 try {
3842 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003843 ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setVtSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003844 } catch (ImsException e) {
3845 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003846 } finally {
3847 Binder.restoreCallingIdentity(identity);
3848 }
3849 }
3850
shilu366312e2019-12-17 09:28:10 -08003851 /**
3852 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3853 * @param subId The subscription to use to check the configuration.
3854 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003855 @Override
3856 public boolean isVoWiFiSettingEnabled(int subId) {
Rambo Wang37f9c242020-02-10 14:45:28 -08003857 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3858 mApp, subId, "isVoWiFiSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003859 final long identity = Binder.clearCallingIdentity();
3860 try {
3861 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003862 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003863 getSlotIndexOrException(subId)).isWfcEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003864 } catch (ImsException e) {
3865 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003866 } finally {
3867 Binder.restoreCallingIdentity(identity);
3868 }
3869 }
3870
3871 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08003872 public void setVoWiFiSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003873 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08003874 "setVoWiFiSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003875 final long identity = Binder.clearCallingIdentity();
3876 try {
3877 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003878 ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setWfcSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003879 } catch (ImsException e) {
3880 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003881 } finally {
3882 Binder.restoreCallingIdentity(identity);
3883 }
3884 }
3885
shilu366312e2019-12-17 09:28:10 -08003886 /**
3887 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3888 * @param subId The subscription to use to check the configuration.
3889 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003890 @Override
3891 public boolean isVoWiFiRoamingSettingEnabled(int subId) {
Rambo Wang37f9c242020-02-10 14:45:28 -08003892 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3893 mApp, subId, "isVoWiFiRoamingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003894 final long identity = Binder.clearCallingIdentity();
3895 try {
3896 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003897 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003898 getSlotIndexOrException(subId)).isWfcRoamingEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003899 } catch (ImsException e) {
3900 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003901 } finally {
3902 Binder.restoreCallingIdentity(identity);
3903 }
3904 }
3905
3906 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08003907 public void setVoWiFiRoamingSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003908 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08003909 "setVoWiFiRoamingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003910 final long identity = Binder.clearCallingIdentity();
3911 try {
3912 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003913 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003914 getSlotIndexOrException(subId)).setWfcRoamingSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003915 } catch (ImsException e) {
3916 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003917 } finally {
3918 Binder.restoreCallingIdentity(identity);
3919 }
3920 }
3921
3922 @Override
3923 public void setVoWiFiNonPersistent(int subId, boolean isCapable, int mode) {
3924 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3925 "setVoWiFiNonPersistent");
3926 final long identity = Binder.clearCallingIdentity();
3927 try {
3928 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003929 ImsManager.getInstance(mApp,
Brad Ebinger2d29c012019-05-07 18:33:46 -07003930 getSlotIndexOrException(subId)).setWfcNonPersistent(isCapable, mode);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003931 } catch (ImsException e) {
3932 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003933 } finally {
3934 Binder.restoreCallingIdentity(identity);
3935 }
3936 }
3937
shilu366312e2019-12-17 09:28:10 -08003938 /**
3939 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3940 * @param subId The subscription to use to check the configuration.
3941 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003942 @Override
3943 public int getVoWiFiModeSetting(int subId) {
Rambo Wang37f9c242020-02-10 14:45:28 -08003944 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3945 mApp, subId, "getVoWiFiModeSetting");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003946 final long identity = Binder.clearCallingIdentity();
3947 try {
3948 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003949 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003950 getSlotIndexOrException(subId)).getWfcMode(false /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003951 } catch (ImsException e) {
3952 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003953 } finally {
3954 Binder.restoreCallingIdentity(identity);
3955 }
3956 }
3957
3958 @Override
3959 public void setVoWiFiModeSetting(int subId, int mode) {
3960 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3961 "setVoWiFiModeSetting");
3962 final long identity = Binder.clearCallingIdentity();
3963 try {
3964 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003965 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003966 getSlotIndexOrException(subId)).setWfcMode(mode, false /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003967 } catch (ImsException e) {
3968 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003969 } finally {
3970 Binder.restoreCallingIdentity(identity);
3971 }
3972 }
3973
3974 @Override
3975 public int getVoWiFiRoamingModeSetting(int subId) {
3976 enforceReadPrivilegedPermission("getVoWiFiRoamingModeSetting");
3977 final long identity = Binder.clearCallingIdentity();
3978 try {
3979 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003980 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003981 getSlotIndexOrException(subId)).getWfcMode(true /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003982 } catch (ImsException e) {
3983 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003984 } finally {
3985 Binder.restoreCallingIdentity(identity);
3986 }
3987 }
3988
3989 @Override
3990 public void setVoWiFiRoamingModeSetting(int subId, int mode) {
3991 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3992 "setVoWiFiRoamingModeSetting");
3993 final long identity = Binder.clearCallingIdentity();
3994 try {
3995 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003996 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003997 getSlotIndexOrException(subId)).setWfcMode(mode, true /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003998 } catch (ImsException e) {
3999 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004000 } finally {
4001 Binder.restoreCallingIdentity(identity);
4002 }
4003 }
4004
4005 @Override
4006 public void setRttCapabilitySetting(int subId, boolean isEnabled) {
4007 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4008 "setRttCapabilityEnabled");
4009 final long identity = Binder.clearCallingIdentity();
4010 try {
4011 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004012 ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setRttEnabled(isEnabled);
4013 } catch (ImsException e) {
4014 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004015 } finally {
4016 Binder.restoreCallingIdentity(identity);
4017 }
4018 }
4019
shilu366312e2019-12-17 09:28:10 -08004020 /**
4021 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4022 * @param subId The subscription to use to check the configuration.
4023 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07004024 @Override
4025 public boolean isTtyOverVolteEnabled(int subId) {
Rambo Wang37f9c242020-02-10 14:45:28 -08004026 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4027 mApp, subId, "isTtyOverVolteEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004028 final long identity = Binder.clearCallingIdentity();
4029 try {
4030 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004031 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07004032 getSlotIndexOrException(subId)).isTtyOnVoLteCapable();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004033 } catch (ImsException e) {
4034 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004035 } finally {
4036 Binder.restoreCallingIdentity(identity);
4037 }
4038 }
4039
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004040 @Override
4041 public void registerImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
4042 enforceReadPrivilegedPermission("registerImsProvisioningChangedCallback");
4043 final long identity = Binder.clearCallingIdentity();
4044 try {
Brad Ebingerd0331732020-01-16 11:21:18 -08004045 if (!isImsAvailableOnDevice()) {
4046 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4047 "IMS not available on device.");
Peter Wang44b186e2020-01-13 23:33:09 -08004048 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004049 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004050 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08004051 .addProvisioningCallbackForSubscription(callback, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004052 } catch (ImsException e) {
4053 throw new ServiceSpecificException(e.getCode());
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004054 } finally {
4055 Binder.restoreCallingIdentity(identity);
4056 }
4057 }
4058
4059 @Override
4060 public void unregisterImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
4061 enforceReadPrivilegedPermission("unregisterImsProvisioningChangedCallback");
4062 final long identity = Binder.clearCallingIdentity();
Brad Ebinger4ae57f92019-01-09 16:51:30 -08004063 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4064 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
4065 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004066 try {
4067 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004068 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08004069 .removeProvisioningCallbackForSubscription(callback, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004070 } catch (ImsException e) {
Brad Ebinger4ae57f92019-01-09 16:51:30 -08004071 Log.i(LOG_TAG, "unregisterImsProvisioningChangedCallback: " + subId
4072 + "is inactive, ignoring unregister.");
4073 // If the subscription is no longer active, just return, since the callback will already
4074 // have been removed internally.
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004075 } finally {
4076 Binder.restoreCallingIdentity(identity);
4077 }
4078 }
4079
allenwtsu99c623b2020-01-03 18:24:23 +08004080
4081 private void checkModifyPhoneStatePermission(int subId, String message) {
4082 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4083 message);
4084 }
4085
4086 private boolean isImsProvisioningRequired(int subId, int capability,
4087 boolean isMmtelCapability) {
4088 Phone phone = getPhone(subId);
4089 if (phone == null) {
4090 loge("phone instance null for subid " + subId);
4091 return false;
4092 }
4093 if (isMmtelCapability) {
4094 if (!doesImsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
4095 return false;
4096 }
4097 } else {
4098 if (!doesRcsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
4099 return false;
4100 }
4101 }
4102 return true;
4103 }
4104
4105 @Override
4106 public void setRcsProvisioningStatusForCapability(int subId, int capability,
4107 boolean isProvisioned) {
4108 checkModifyPhoneStatePermission(subId, "setRcsProvisioningStatusForCapability");
4109
4110 final long identity = Binder.clearCallingIdentity();
4111 try {
4112 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4113 if (!isImsProvisioningRequired(subId, capability, false)) {
4114 return;
4115 }
4116
4117 // this capability requires provisioning, route to the correct API.
4118 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
4119 switch (capability) {
4120 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE:
4121 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
4122 ims.setEabProvisioned(isProvisioned);
4123 break;
4124 default: {
4125 throw new IllegalArgumentException("Tried to set provisioning for "
4126 + "rcs capability '" + capability + "', which does not require "
4127 + "provisioning.");
4128 }
4129 }
4130 } finally {
4131 Binder.restoreCallingIdentity(identity);
4132 }
4133
4134 }
4135
4136
4137 @Override
4138 public boolean getRcsProvisioningStatusForCapability(int subId, int capability) {
4139 enforceReadPrivilegedPermission("getRcsProvisioningStatusForCapability");
4140 final long identity = Binder.clearCallingIdentity();
4141 try {
4142 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4143 if (!isImsProvisioningRequired(subId, capability, false)) {
4144 return true;
4145 }
4146
4147 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
4148 switch (capability) {
4149 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE:
4150 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
4151 return ims.isEabProvisionedOnDevice();
4152
4153 default: {
4154 throw new IllegalArgumentException("Tried to get rcs provisioning for "
4155 + "capability '" + capability + "', which does not require "
4156 + "provisioning.");
4157 }
4158 }
4159
4160 } finally {
4161 Binder.restoreCallingIdentity(identity);
4162 }
4163 }
4164
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004165 @Override
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004166 public void setImsProvisioningStatusForCapability(int subId, int capability, int tech,
4167 boolean isProvisioned) {
4168 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
4169 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4170 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
4171 }
allenwtsu99c623b2020-01-03 18:24:23 +08004172 checkModifyPhoneStatePermission(subId, "setImsProvisioningStatusForCapability");
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004173 final long identity = Binder.clearCallingIdentity();
4174 try {
4175 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
allenwtsu99c623b2020-01-03 18:24:23 +08004176 if (!isImsProvisioningRequired(subId, capability, true)) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004177 return;
4178 }
4179
4180 // this capability requires provisioning, route to the correct API.
4181 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
4182 switch (capability) {
4183 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
4184 if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4185 ims.setVolteProvisioned(isProvisioned);
4186 } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
4187 ims.setWfcProvisioned(isProvisioned);
4188 }
4189 break;
4190 }
4191 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
4192 // There is currently no difference in VT provisioning type.
4193 ims.setVtProvisioned(isProvisioned);
4194 break;
4195 }
4196 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
4197 // There is no "deprecated" UT provisioning mechanism through ImsConfig, so
4198 // change the capability of the feature instead if needed.
4199 if (isMmTelCapabilityProvisionedInCache(subId, capability, tech)
4200 == isProvisioned) {
4201 // No change in provisioning.
4202 return;
4203 }
4204 cacheMmTelCapabilityProvisioning(subId, capability, tech, isProvisioned);
4205 try {
4206 ims.changeMmTelCapability(capability, tech, isProvisioned);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004207 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004208 loge("setImsProvisioningStatusForCapability: couldn't change UT capability"
4209 + ", Exception" + e.getMessage());
4210 }
4211 break;
4212 }
4213 default: {
allenwtsu99c623b2020-01-03 18:24:23 +08004214 throw new IllegalArgumentException("Tried to set provisioning for "
4215 + "MmTel capability '" + capability + "', which does not require "
4216 + "provisioning. ");
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004217 }
4218 }
4219
4220 } finally {
4221 Binder.restoreCallingIdentity(identity);
4222 }
4223 }
4224
4225 @Override
4226 public boolean getImsProvisioningStatusForCapability(int subId, int capability, int tech) {
4227 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
4228 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4229 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
4230 }
4231 enforceReadPrivilegedPermission("getProvisioningStatusForCapability");
4232 final long identity = Binder.clearCallingIdentity();
4233 try {
4234 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
allenwtsu99c623b2020-01-03 18:24:23 +08004235 if (!isImsProvisioningRequired(subId, capability, true)) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004236 return true;
4237 }
4238
4239 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
4240 switch (capability) {
4241 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
4242 if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4243 return ims.isVolteProvisionedOnDevice();
4244 } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
4245 return ims.isWfcProvisionedOnDevice();
4246 }
4247 // This should never happen, since we are checking tech above to make sure it
4248 // is either LTE or IWLAN.
4249 throw new IllegalArgumentException("Invalid radio technology for voice "
4250 + "capability.");
4251 }
4252 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
4253 // There is currently no difference in VT provisioning type.
4254 return ims.isVtProvisionedOnDevice();
4255 }
4256 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
4257 // There is no "deprecated" UT provisioning mechanism, so get from shared prefs.
4258 return isMmTelCapabilityProvisionedInCache(subId, capability, tech);
4259 }
4260 default: {
allenwtsu99c623b2020-01-03 18:24:23 +08004261 throw new IllegalArgumentException(
4262 "Tried to get provisioning for MmTel capability '" + capability
4263 + "', which does not require provisioning.");
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004264 }
4265 }
4266
4267 } finally {
4268 Binder.restoreCallingIdentity(identity);
4269 }
4270 }
4271
4272 @Override
4273 public boolean isMmTelCapabilityProvisionedInCache(int subId, int capability, int tech) {
4274 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
4275 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4276 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
4277 }
4278 enforceReadPrivilegedPermission("isMmTelCapabilityProvisionedInCache");
4279 int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
4280 return (provisionedBits & capability) > 0;
4281 }
4282
4283 @Override
4284 public void cacheMmTelCapabilityProvisioning(int subId, int capability, int tech,
4285 boolean isProvisioned) {
4286 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
4287 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4288 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
4289 }
4290 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4291 "setProvisioningStatusForCapability");
4292 int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
4293 // If the current provisioning status for capability already matches isProvisioned,
4294 // do nothing.
4295 if (((provisionedBits & capability) > 0) == isProvisioned) {
4296 return;
4297 }
4298 if (isProvisioned) {
4299 setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits | capability));
4300 } else {
4301 setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits & ~capability));
4302 }
4303 }
4304
4305 /**
4306 * @return the bitfield containing the MmTel provisioning for the provided subscription and
4307 * technology. The bitfield should mirror the bitfield defined by
4308 * {@link MmTelFeature.MmTelCapabilities.MmTelCapability}.
4309 */
4310 private int getMmTelCapabilityProvisioningBitfield(int subId, int tech) {
4311 String key = getMmTelProvisioningKey(subId, tech);
4312 // Default is no capabilities are provisioned.
4313 return mTelephonySharedPreferences.getInt(key, 0 /*default*/);
4314 }
4315
4316 /**
4317 * Sets the MmTel capability provisioning bitfield (defined by
4318 * {@link MmTelFeature.MmTelCapabilities.MmTelCapability}) for the subscription and
4319 * technology specified.
4320 *
4321 * Note: This is a synchronous command and should not be called on UI thread.
4322 */
4323 private void setMmTelCapabilityProvisioningBitfield(int subId, int tech, int newField) {
4324 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
4325 String key = getMmTelProvisioningKey(subId, tech);
4326 editor.putInt(key, newField);
4327 editor.commit();
4328 }
4329
4330 private static String getMmTelProvisioningKey(int subId, int tech) {
4331 // resulting key is provision_ims_mmtel_{subId}_{tech}
4332 return PREF_PROVISION_IMS_MMTEL_PREFIX + subId + "_" + tech;
4333 }
4334
4335 /**
4336 * Query CarrierConfig to see if the specified capability requires provisioning for the
4337 * carrier associated with the subscription id.
4338 */
4339 private boolean doesImsCapabilityRequireProvisioning(Context context, int subId,
4340 int capability) {
4341 CarrierConfigManager configManager = new CarrierConfigManager(context);
4342 PersistableBundle c = configManager.getConfigForSubId(subId);
4343 boolean requireUtProvisioning = c.getBoolean(
Brad Ebinger076903f2019-05-13 10:00:22 -07004344 CarrierConfigManager.KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL, false)
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004345 && c.getBoolean(CarrierConfigManager.KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL,
4346 false);
4347 boolean requireVoiceVtProvisioning = c.getBoolean(
4348 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, false);
4349
4350 // First check to make sure that the capability requires provisioning.
4351 switch (capability) {
4352 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE:
4353 // intentional fallthrough
4354 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
4355 if (requireVoiceVtProvisioning) {
4356 // Voice and Video requires provisioning
4357 return true;
4358 }
4359 break;
4360 }
4361 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
4362 if (requireUtProvisioning) {
4363 // UT requires provisioning
4364 return true;
4365 }
4366 break;
4367 }
4368 }
4369 return false;
4370 }
4371
allenwtsu99c623b2020-01-03 18:24:23 +08004372 private boolean doesRcsCapabilityRequireProvisioning(Context context, int subId,
4373 int capability) {
4374 CarrierConfigManager configManager = new CarrierConfigManager(context);
4375 PersistableBundle c = configManager.getConfigForSubId(subId);
4376
4377 boolean requireRcsProvisioning = c.getBoolean(
4378 CarrierConfigManager.KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL, false);
4379
4380 // First check to make sure that the capability requires provisioning.
4381 switch (capability) {
4382 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
4383 // intentional fallthrough
4384 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE: {
4385 if (requireRcsProvisioning) {
4386 // OPTION or PRESENCE requires provisioning
4387 return true;
4388 }
4389 break;
4390 }
4391 }
4392 return false;
4393 }
4394
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004395 @Override
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004396 public int getImsProvisioningInt(int subId, int key) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004397 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4398 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4399 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004400 enforceReadPrivilegedPermission("getImsProvisioningInt");
4401 final long identity = Binder.clearCallingIdentity();
4402 try {
4403 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004404 int slotId = getSlotIndex(subId);
4405 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4406 Log.w(LOG_TAG, "getImsProvisioningInt: called with an inactive subscription '"
4407 + subId + "' for key:" + key);
4408 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
4409 }
4410 return ImsManager.getInstance(mApp, slotId).getConfigInterface().getConfigInt(key);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004411 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004412 Log.w(LOG_TAG, "getImsProvisioningInt: ImsService is not available for subscription '"
4413 + subId + "' for key:" + key);
4414 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004415 } finally {
4416 Binder.restoreCallingIdentity(identity);
4417 }
4418 }
4419
4420 @Override
4421 public String getImsProvisioningString(int subId, int key) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004422 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4423 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4424 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004425 enforceReadPrivilegedPermission("getImsProvisioningString");
4426 final long identity = Binder.clearCallingIdentity();
4427 try {
4428 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004429 int slotId = getSlotIndex(subId);
4430 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4431 Log.w(LOG_TAG, "getImsProvisioningString: called for an inactive subscription id '"
4432 + subId + "' for key:" + key);
4433 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_GENERIC;
4434 }
4435 return ImsManager.getInstance(mApp, slotId).getConfigInterface().getConfigString(key);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004436 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004437 Log.w(LOG_TAG, "getImsProvisioningString: ImsService is not available for sub '"
4438 + subId + "' for key:" + key);
4439 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_NOT_READY;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004440 } finally {
4441 Binder.restoreCallingIdentity(identity);
4442 }
4443 }
4444
4445 @Override
4446 public int setImsProvisioningInt(int subId, int key, int value) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004447 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4448 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4449 }
Brad Ebinger3d0b34e2018-11-15 14:13:12 -08004450 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4451 "setImsProvisioningInt");
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004452 final long identity = Binder.clearCallingIdentity();
4453 try {
4454 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004455 int slotId = getSlotIndex(subId);
4456 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4457 Log.w(LOG_TAG, "setImsProvisioningInt: called with an inactive subscription id '"
4458 + subId + "' for key:" + key);
4459 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
4460 }
4461 return ImsManager.getInstance(mApp, slotId).getConfigInterface().setConfig(key, value);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004462 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004463 Log.w(LOG_TAG, "setImsProvisioningInt: ImsService unavailable for sub '" + subId
4464 + "' for key:" + key);
4465 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004466 } finally {
4467 Binder.restoreCallingIdentity(identity);
4468 }
4469 }
4470
4471 @Override
4472 public int setImsProvisioningString(int subId, int key, String value) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004473 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4474 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4475 }
Brad Ebinger3d0b34e2018-11-15 14:13:12 -08004476 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4477 "setImsProvisioningString");
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004478 final long identity = Binder.clearCallingIdentity();
4479 try {
4480 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004481 int slotId = getSlotIndex(subId);
4482 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4483 Log.w(LOG_TAG, "setImsProvisioningString: called with an inactive subscription id '"
4484 + subId + "' for key:" + key);
4485 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
4486 }
4487 return ImsManager.getInstance(mApp, slotId).getConfigInterface().setConfig(key, value);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004488 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004489 Log.w(LOG_TAG, "setImsProvisioningString: ImsService unavailable for sub '" + subId
4490 + "' for key:" + key);
4491 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004492 } finally {
4493 Binder.restoreCallingIdentity(identity);
4494 }
4495 }
4496
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004497 private int getSlotIndexOrException(int subId) throws ImsException {
Brad Ebinger35c841c2018-10-01 10:40:55 -07004498 int slotId = SubscriptionManager.getSlotIndex(subId);
4499 if (!SubscriptionManager.isValidSlotIndex(slotId)) {
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004500 throw new ImsException("Invalid Subscription Id, subId=" + subId,
4501 ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
Brad Ebinger35c841c2018-10-01 10:40:55 -07004502 }
4503 return slotId;
4504 }
4505
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004506 private int getSlotIndex(int subId) {
4507 int slotId = SubscriptionManager.getSlotIndex(subId);
4508 if (!SubscriptionManager.isValidSlotIndex(slotId)) {
4509 return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
4510 }
4511 return slotId;
4512 }
4513
Wink Saville36469e72014-06-11 15:17:00 -07004514 /**
Nathan Harold9042f0b2019-05-21 15:51:27 -07004515 * Returns the data network type for a subId; does not throw SecurityException.
Wink Saville36469e72014-06-11 15:17:00 -07004516 */
4517 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004518 public int getNetworkTypeForSubscriber(int subId, String callingPackage,
4519 String callingFeatureId) {
Nathan Haroldef60dba2019-05-22 13:55:14 -07004520 final int targetSdk = getTargetSdk(callingPackage);
4521 if (targetSdk > android.os.Build.VERSION_CODES.Q) {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004522 return getDataNetworkTypeForSubscriber(subId, callingPackage, callingFeatureId);
Nathan Haroldef60dba2019-05-22 13:55:14 -07004523 } else if (targetSdk == android.os.Build.VERSION_CODES.Q
Nathan Harold9042f0b2019-05-21 15:51:27 -07004524 && !TelephonyPermissions.checkCallingOrSelfReadPhoneStateNoThrow(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004525 mApp, subId, callingPackage, callingFeatureId,
4526 "getNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004527 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4528 }
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07004529
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004530 final long identity = Binder.clearCallingIdentity();
4531 try {
4532 final Phone phone = getPhone(subId);
4533 if (phone != null) {
4534 return phone.getServiceState().getDataNetworkType();
4535 } else {
4536 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4537 }
4538 } finally {
4539 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004540 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004541 }
4542
4543 /**
4544 * Returns the data network type
4545 */
4546 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004547 public int getDataNetworkType(String callingPackage, String callingFeatureId) {
4548 return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage,
4549 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07004550 }
4551
4552 /**
4553 * Returns the data network type for a subId
4554 */
4555 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004556 public int getDataNetworkTypeForSubscriber(int subId, String callingPackage,
4557 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004558 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004559 mApp, subId, callingPackage, callingFeatureId,
4560 "getDataNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004561 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4562 }
4563
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004564 final long identity = Binder.clearCallingIdentity();
4565 try {
4566 final Phone phone = getPhone(subId);
4567 if (phone != null) {
4568 return phone.getServiceState().getDataNetworkType();
4569 } else {
4570 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4571 }
4572 } finally {
4573 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004574 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004575 }
4576
4577 /**
Wink Saville36469e72014-06-11 15:17:00 -07004578 * Returns the Voice network type for a subId
4579 */
4580 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004581 public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage,
4582 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004583 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004584 mApp, subId, callingPackage, callingFeatureId,
4585 "getDataNetworkTypeForSubscriber")) {
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07004586 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4587 }
4588
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004589 final long identity = Binder.clearCallingIdentity();
4590 try {
4591 final Phone phone = getPhone(subId);
4592 if (phone != null) {
4593 return phone.getServiceState().getVoiceNetworkType();
4594 } else {
4595 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4596 }
4597 } finally {
4598 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004599 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004600 }
4601
4602 /**
4603 * @return true if a ICC card is present
4604 */
4605 public boolean hasIccCard() {
Wink Saville36469e72014-06-11 15:17:00 -07004606 // FIXME Make changes to pass defaultSimId of type int
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004607 return hasIccCardUsingSlotIndex(mSubscriptionController.getSlotIndex(
4608 getDefaultSubscription()));
Wink Saville36469e72014-06-11 15:17:00 -07004609 }
4610
4611 /**
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004612 * @return true if a ICC card is present for a slotIndex
Wink Saville36469e72014-06-11 15:17:00 -07004613 */
Sanket Padawe356d7632015-06-22 14:03:32 -07004614 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004615 public boolean hasIccCardUsingSlotIndex(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004616 final long identity = Binder.clearCallingIdentity();
4617 try {
4618 final Phone phone = PhoneFactory.getPhone(slotIndex);
4619 if (phone != null) {
4620 return phone.getIccCard().hasIccCard();
4621 } else {
4622 return false;
4623 }
4624 } finally {
4625 Binder.restoreCallingIdentity(identity);
Amit Mahajana6fc2a82015-01-06 11:53:51 -08004626 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004627 }
4628
4629 /**
4630 * Return if the current radio is LTE on CDMA. This
4631 * is a tri-state return value as for a period of time
4632 * the mode may be unknown.
4633 *
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004634 * @param callingPackage the name of the package making the call.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004635 * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
Jake Hambye994d462014-02-03 13:10:13 -08004636 * or {@link Phone#LTE_ON_CDMA_TRUE}
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004637 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004638 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004639 public int getLteOnCdmaMode(String callingPackage, String callingFeatureId) {
4640 return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage,
4641 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07004642 }
4643
Sanket Padawe356d7632015-06-22 14:03:32 -07004644 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004645 public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage,
4646 String callingFeatureId) {
Sarah Chin790d2922020-01-16 12:17:23 -08004647 try {
4648 enforceReadPrivilegedPermission("getLteOnCdmaModeForSubscriber");
4649 } catch (SecurityException e) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004650 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
4651 }
4652
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004653 final long identity = Binder.clearCallingIdentity();
4654 try {
4655 final Phone phone = getPhone(subId);
4656 if (phone == null) {
4657 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
4658 } else {
Nathan Harold05ad6332020-07-10 11:54:36 -07004659 return TelephonyProperties.lte_on_cdma_device()
4660 .orElse(PhoneConstants.LTE_ON_CDMA_FALSE);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004661 }
4662 } finally {
4663 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004664 }
Wink Saville36469e72014-06-11 15:17:00 -07004665 }
4666
Wink Saville36469e72014-06-11 15:17:00 -07004667 /**
4668 * {@hide}
4669 * Returns Default subId, 0 in the case of single standby.
4670 */
Wink Savilleb564aae2014-10-23 10:18:09 -07004671 private int getDefaultSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08004672 return mSubscriptionController.getDefaultSubId();
Wink Saville36469e72014-06-11 15:17:00 -07004673 }
4674
Shishir Agrawala9f32182016-04-12 12:00:16 -07004675 private int getSlotForDefaultSubscription() {
4676 return mSubscriptionController.getPhoneId(getDefaultSubscription());
4677 }
4678
Wink Savilleb564aae2014-10-23 10:18:09 -07004679 private int getPreferredVoiceSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08004680 return mSubscriptionController.getDefaultVoiceSubId();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004681 }
Ihab Awadf2177b72013-11-25 13:33:23 -08004682
Pengquan Menge92a50d2018-09-21 15:54:48 -07004683 private boolean isActiveSubscription(int subId) {
4684 return mSubscriptionController.isActiveSubId(subId);
4685 }
4686
Ihab Awadf2177b72013-11-25 13:33:23 -08004687 /**
4688 * @see android.telephony.TelephonyManager.WifiCallingChoices
4689 */
4690 public int getWhenToMakeWifiCalls() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004691 final long identity = Binder.clearCallingIdentity();
4692 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004693 return Settings.System.getInt(mApp.getContentResolver(),
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004694 Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
4695 getWhenToMakeWifiCallsDefaultPreference());
4696 } finally {
4697 Binder.restoreCallingIdentity(identity);
4698 }
Ihab Awadf2177b72013-11-25 13:33:23 -08004699 }
4700
4701 /**
4702 * @see android.telephony.TelephonyManager.WifiCallingChoices
4703 */
4704 public void setWhenToMakeWifiCalls(int preference) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004705 final long identity = Binder.clearCallingIdentity();
4706 try {
4707 if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004708 Settings.System.putInt(mApp.getContentResolver(),
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004709 Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference);
4710 } finally {
4711 Binder.restoreCallingIdentity(identity);
4712 }
Ihab Awadf9e92732013-12-05 18:02:52 -08004713 }
4714
Sailesh Nepald1e68152013-12-12 19:08:02 -08004715 private static int getWhenToMakeWifiCallsDefaultPreference() {
Santos Cordonda120f42014-08-06 04:44:34 -07004716 // TODO: Use a build property to choose this value.
Evan Charlton9829e882013-12-19 15:30:38 -08004717 return TelephonyManager.WifiCallingChoices.ALWAYS_USE;
Ihab Awadf2177b72013-11-25 13:33:23 -08004718 }
Shishir Agrawal69f68122013-12-16 17:25:49 -08004719
Jordan Liu4c733742019-02-28 12:03:40 -08004720 private Phone getPhoneFromSlotIdOrThrowException(int slotIndex) {
4721 int phoneId = UiccController.getInstance().getPhoneIdFromSlotId(slotIndex);
4722 if (phoneId == -1) {
4723 throw new IllegalArgumentException("Given slot index: " + slotIndex
4724 + " does not correspond to an active phone");
4725 }
4726 return PhoneFactory.getPhone(phoneId);
4727 }
4728
Shishir Agrawal566b7612013-10-28 14:41:00 -07004729 @Override
Derek Tan740e1672017-06-27 14:56:27 -07004730 public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
4731 int subId, String callingPackage, String aid, int p2) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004732 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4733 mApp, subId, "iccOpenLogicalChannel");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004734 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jordan Liu4c733742019-02-28 12:03:40 -08004735 if (DBG) {
4736 log("iccOpenLogicalChannel: subId=" + subId + " aid=" + aid + " p2=" + p2);
4737 }
4738 return iccOpenLogicalChannelWithPermission(getPhoneFromSubId(subId), callingPackage, aid,
4739 p2);
4740 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07004741
Jordan Liu4c733742019-02-28 12:03:40 -08004742
4743 @Override
4744 public IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(
4745 int slotIndex, String callingPackage, String aid, int p2) {
4746 enforceModifyPermission();
4747 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4748 if (DBG) {
4749 log("iccOpenLogicalChannelBySlot: slot=" + slotIndex + " aid=" + aid + " p2=" + p2);
4750 }
4751 return iccOpenLogicalChannelWithPermission(getPhoneFromSlotIdOrThrowException(slotIndex),
4752 callingPackage, aid, p2);
4753 }
4754
4755 private IccOpenLogicalChannelResponse iccOpenLogicalChannelWithPermission(Phone phone,
4756 String callingPackage, String aid, int p2) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004757 final long identity = Binder.clearCallingIdentity();
4758 try {
4759 if (TextUtils.equals(ISDR_AID, aid)) {
4760 // Only allows LPA to open logical channel to ISD-R.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004761 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
4762 .getContext().getPackageManager());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004763 if (bestComponent == null
4764 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
4765 loge("The calling package is not allowed to access ISD-R.");
4766 throw new SecurityException(
4767 "The calling package is not allowed to access ISD-R.");
4768 }
Derek Tan740e1672017-06-27 14:56:27 -07004769 }
Derek Tan740e1672017-06-27 14:56:27 -07004770
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004771 IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse) sendRequest(
Jordan Liu4c733742019-02-28 12:03:40 -08004772 CMD_OPEN_CHANNEL, new Pair<String, Integer>(aid, p2), phone,
4773 null /* workSource */);
4774 if (DBG) log("iccOpenLogicalChannelWithPermission: " + response);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004775 return response;
4776 } finally {
4777 Binder.restoreCallingIdentity(identity);
4778 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07004779 }
4780
4781 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004782 public boolean iccCloseLogicalChannel(int subId, int channel) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004783 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4784 mApp, subId, "iccCloseLogicalChannel");
Jordan Liu4c733742019-02-28 12:03:40 -08004785 if (DBG) log("iccCloseLogicalChannel: subId=" + subId + " chnl=" + channel);
4786 return iccCloseLogicalChannelWithPermission(getPhoneFromSubId(subId), channel);
4787 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07004788
Jordan Liu4c733742019-02-28 12:03:40 -08004789 @Override
4790 public boolean iccCloseLogicalChannelBySlot(int slotIndex, int channel) {
4791 enforceModifyPermission();
4792 if (DBG) log("iccCloseLogicalChannelBySlot: slotIndex=" + slotIndex + " chnl=" + channel);
4793 return iccCloseLogicalChannelWithPermission(getPhoneFromSlotIdOrThrowException(slotIndex),
4794 channel);
4795 }
4796
4797 private boolean iccCloseLogicalChannelWithPermission(Phone phone, int channel) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004798 final long identity = Binder.clearCallingIdentity();
4799 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004800 if (channel < 0) {
4801 return false;
4802 }
Jordan Liu4c733742019-02-28 12:03:40 -08004803 Boolean success = (Boolean) sendRequest(CMD_CLOSE_CHANNEL, channel, phone,
4804 null /* workSource */);
4805 if (DBG) log("iccCloseLogicalChannelWithPermission: " + success);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004806 return success;
4807 } finally {
4808 Binder.restoreCallingIdentity(identity);
Shishir Agrawal566b7612013-10-28 14:41:00 -07004809 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07004810 }
4811
4812 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004813 public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
Shishir Agrawal566b7612013-10-28 14:41:00 -07004814 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004815 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4816 mApp, subId, "iccTransmitApduLogicalChannel");
Jordan Liu4c733742019-02-28 12:03:40 -08004817 if (DBG) {
4818 log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel
4819 + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
4820 + p3 + " data=" + data);
4821 }
4822 return iccTransmitApduLogicalChannelWithPermission(getPhoneFromSubId(subId), channel, cla,
4823 command, p1, p2, p3, data);
4824 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07004825
Jordan Liu4c733742019-02-28 12:03:40 -08004826 @Override
4827 public String iccTransmitApduLogicalChannelBySlot(int slotIndex, int channel, int cla,
4828 int command, int p1, int p2, int p3, String data) {
4829 enforceModifyPermission();
4830 if (DBG) {
4831 log("iccTransmitApduLogicalChannelBySlot: slotIndex=" + slotIndex + " chnl=" + channel
4832 + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
4833 + p3 + " data=" + data);
4834 }
4835 return iccTransmitApduLogicalChannelWithPermission(
4836 getPhoneFromSlotIdOrThrowException(slotIndex), channel, cla, command, p1, p2, p3,
4837 data);
4838 }
4839
4840 private String iccTransmitApduLogicalChannelWithPermission(Phone phone, int channel, int cla,
4841 int command, int p1, int p2, int p3, String data) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004842 final long identity = Binder.clearCallingIdentity();
4843 try {
Hall Liu4fd771b2019-05-02 09:16:29 -07004844 if (channel <= 0) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004845 return "";
4846 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07004847
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004848 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL,
Jordan Liu4c733742019-02-28 12:03:40 -08004849 new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), phone,
4850 null /* workSource */);
4851 if (DBG) log("iccTransmitApduLogicalChannelWithPermission: " + response);
Shishir Agrawal566b7612013-10-28 14:41:00 -07004852
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004853 // Append the returned status code to the end of the response payload.
4854 String s = Integer.toHexString(
4855 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
4856 if (response.payload != null) {
4857 s = IccUtils.bytesToHexString(response.payload) + s;
4858 }
4859 return s;
4860 } finally {
4861 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07004862 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07004863 }
Jake Hambye994d462014-02-03 13:10:13 -08004864
Evan Charltonc66da362014-05-16 14:06:40 -07004865 @Override
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08004866 public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
4867 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004868 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4869 mApp, subId, "iccTransmitApduBasicChannel");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004870 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jordan Liu4c733742019-02-28 12:03:40 -08004871 if (DBG) {
4872 log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd="
4873 + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
4874 }
4875 return iccTransmitApduBasicChannelWithPermission(getPhoneFromSubId(subId), callingPackage,
4876 cla, command, p1, p2, p3, data);
4877 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004878
Jordan Liu4c733742019-02-28 12:03:40 -08004879 @Override
4880 public String iccTransmitApduBasicChannelBySlot(int slotIndex, String callingPackage, int cla,
4881 int command, int p1, int p2, int p3, String data) {
4882 enforceModifyPermission();
4883 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4884 if (DBG) {
4885 log("iccTransmitApduBasicChannelBySlot: slotIndex=" + slotIndex + " cla=" + cla
4886 + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3
4887 + " data=" + data);
4888 }
4889
4890 return iccTransmitApduBasicChannelWithPermission(
4891 getPhoneFromSlotIdOrThrowException(slotIndex), callingPackage, cla, command, p1,
4892 p2, p3, data);
4893 }
4894
4895 // open APDU basic channel assuming the caller has sufficient permissions
4896 private String iccTransmitApduBasicChannelWithPermission(Phone phone, String callingPackage,
4897 int cla, int command, int p1, int p2, int p3, String data) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004898 final long identity = Binder.clearCallingIdentity();
4899 try {
4900 if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
4901 && TextUtils.equals(ISDR_AID, data)) {
4902 // Only allows LPA to select ISD-R.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004903 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
4904 .getContext().getPackageManager());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004905 if (bestComponent == null
4906 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
4907 loge("The calling package is not allowed to select ISD-R.");
4908 throw new SecurityException(
4909 "The calling package is not allowed to select ISD-R.");
4910 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08004911 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08004912
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004913 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL,
Jordan Liu4c733742019-02-28 12:03:40 -08004914 new IccAPDUArgument(0, cla, command, p1, p2, p3, data), phone,
4915 null /* workSource */);
4916 if (DBG) log("iccTransmitApduBasicChannelWithPermission: " + response);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004917
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004918 // Append the returned status code to the end of the response payload.
4919 String s = Integer.toHexString(
4920 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
4921 if (response.payload != null) {
4922 s = IccUtils.bytesToHexString(response.payload) + s;
4923 }
4924 return s;
4925 } finally {
4926 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07004927 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004928 }
4929
4930 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004931 public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004932 String filePath) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004933 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4934 mApp, subId, "iccExchangeSimIO");
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004935
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004936 final long identity = Binder.clearCallingIdentity();
4937 try {
4938 if (DBG) {
4939 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " "
4940 + p1 + " " + p2 + " " + p3 + ":" + filePath);
4941 }
4942
4943 IccIoResult response =
4944 (IccIoResult) sendRequest(CMD_EXCHANGE_SIM_IO,
4945 new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath),
4946 subId);
4947
4948 if (DBG) {
4949 log("Exchange SIM_IO [R]" + response);
4950 }
4951
4952 byte[] result = null;
4953 int length = 2;
4954 if (response.payload != null) {
4955 length = 2 + response.payload.length;
4956 result = new byte[length];
4957 System.arraycopy(response.payload, 0, result, 0, response.payload.length);
4958 } else {
4959 result = new byte[length];
4960 }
4961
4962 result[length - 1] = (byte) response.sw2;
4963 result[length - 2] = (byte) response.sw1;
4964 return result;
4965 } finally {
4966 Binder.restoreCallingIdentity(identity);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004967 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004968 }
4969
Nathan Haroldb3014052017-01-25 15:57:32 -08004970 /**
4971 * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
4972 * on a particular subscription
4973 */
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004974 public String[] getForbiddenPlmns(int subId, int appType, String callingPackage,
4975 String callingFeatureId) {
sqianb6e41952018-03-12 14:54:01 -07004976 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004977 mApp, subId, callingPackage, callingFeatureId, "getForbiddenPlmns")) {
sqianb6e41952018-03-12 14:54:01 -07004978 return null;
4979 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004980
4981 final long identity = Binder.clearCallingIdentity();
4982 try {
4983 if (appType != TelephonyManager.APPTYPE_USIM
4984 && appType != TelephonyManager.APPTYPE_SIM) {
4985 loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
4986 return null;
4987 }
4988 Object response = sendRequest(
4989 CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
4990 if (response instanceof String[]) {
4991 return (String[]) response;
4992 }
yincheng zhao2737e882019-09-06 17:06:54 -07004993 // Response is an Exception of some kind
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004994 // which is signalled to the user as a NULL retval
Nathan Haroldb3014052017-01-25 15:57:32 -08004995 return null;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004996 } finally {
4997 Binder.restoreCallingIdentity(identity);
Nathan Haroldb3014052017-01-25 15:57:32 -08004998 }
Nathan Haroldb3014052017-01-25 15:57:32 -08004999 }
5000
yincheng zhao2737e882019-09-06 17:06:54 -07005001 /**
5002 * Set the forbidden PLMN list from the given app type (ex APPTYPE_USIM) on a particular
5003 * subscription.
5004 *
5005 * @param subId the id of the subscription.
5006 * @param appType the uicc app type, must be USIM or SIM.
5007 * @param fplmns the Forbiden plmns list that needed to be written to the SIM.
5008 * @param callingPackage the op Package name.
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005009 * @param callingFeatureId the feature in the package.
yincheng zhao2737e882019-09-06 17:06:54 -07005010 * @return number of fplmns that is successfully written to the SIM.
5011 */
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005012 public int setForbiddenPlmns(int subId, int appType, List<String> fplmns, String callingPackage,
5013 String callingFeatureId) {
5014 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
5015 callingFeatureId, "setForbiddenPlmns")) {
yincheng zhao2737e882019-09-06 17:06:54 -07005016 if (DBG) logv("no permissions for setForbiddenplmns");
5017 throw new IllegalStateException("No Permissions for setForbiddenPlmns");
5018 }
5019 if (appType != TelephonyManager.APPTYPE_USIM && appType != TelephonyManager.APPTYPE_SIM) {
5020 loge("setForbiddenPlmnList(): App Type must be USIM or SIM");
5021 throw new IllegalArgumentException("Invalid appType: App Type must be USIM or SIM");
5022 }
5023 if (fplmns == null) {
5024 throw new IllegalArgumentException("Fplmn List provided is null");
5025 }
5026 for (String fplmn : fplmns) {
5027 if (!CellIdentity.isValidPlmn(fplmn)) {
5028 throw new IllegalArgumentException("Invalid fplmn provided: " + fplmn);
5029 }
5030 }
5031 final long identity = Binder.clearCallingIdentity();
5032 try {
5033 Object response = sendRequest(
5034 CMD_SET_FORBIDDEN_PLMNS,
5035 new Pair<Integer, List<String>>(new Integer(appType), fplmns),
5036 subId);
5037 return (int) response;
5038 } finally {
5039 Binder.restoreCallingIdentity(identity);
5040 }
5041 }
5042
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07005043 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08005044 public String sendEnvelopeWithStatus(int subId, String content) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005045 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5046 mApp, subId, "sendEnvelopeWithStatus");
Evan Charltonc66da362014-05-16 14:06:40 -07005047
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005048 final long identity = Binder.clearCallingIdentity();
5049 try {
5050 IccIoResult response = (IccIoResult) sendRequest(CMD_SEND_ENVELOPE, content, subId);
5051 if (response.payload == null) {
5052 return "";
5053 }
Evan Charltonc66da362014-05-16 14:06:40 -07005054
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005055 // Append the returned status code to the end of the response payload.
5056 String s = Integer.toHexString(
5057 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
5058 s = IccUtils.bytesToHexString(response.payload) + s;
5059 return s;
5060 } finally {
5061 Binder.restoreCallingIdentity(identity);
5062 }
Evan Charltonc66da362014-05-16 14:06:40 -07005063 }
5064
Jake Hambye994d462014-02-03 13:10:13 -08005065 /**
5066 * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
5067 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
5068 *
5069 * @param itemID the ID of the item to read
5070 * @return the NV item as a String, or null on error.
5071 */
5072 @Override
5073 public String nvReadItem(int itemID) {
vagdeviaf9a5b92018-08-15 16:01:53 -07005074 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08005075 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5076 mApp, getDefaultSubscription(), "nvReadItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005077
5078 final long identity = Binder.clearCallingIdentity();
5079 try {
5080 if (DBG) log("nvReadItem: item " + itemID);
vagdeviaf9a5b92018-08-15 16:01:53 -07005081 String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005082 if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
5083 return value;
5084 } finally {
5085 Binder.restoreCallingIdentity(identity);
5086 }
Jake Hambye994d462014-02-03 13:10:13 -08005087 }
5088
5089 /**
5090 * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
5091 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
5092 *
5093 * @param itemID the ID of the item to read
5094 * @param itemValue the value to write, as a String
5095 * @return true on success; false on any failure
5096 */
5097 @Override
5098 public boolean nvWriteItem(int itemID, String itemValue) {
vagdeviaf9a5b92018-08-15 16:01:53 -07005099 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08005100 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5101 mApp, getDefaultSubscription(), "nvWriteItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005102
5103 final long identity = Binder.clearCallingIdentity();
5104 try {
5105 if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
5106 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
vagdeviaf9a5b92018-08-15 16:01:53 -07005107 new Pair<Integer, String>(itemID, itemValue), workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005108 if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
5109 return success;
5110 } finally {
5111 Binder.restoreCallingIdentity(identity);
5112 }
Jake Hambye994d462014-02-03 13:10:13 -08005113 }
5114
5115 /**
5116 * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
5117 * Used for device configuration by some CDMA operators.
5118 *
5119 * @param preferredRoamingList byte array containing the new PRL
5120 * @return true on success; false on any failure
5121 */
5122 @Override
5123 public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005124 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5125 mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005126
5127 final long identity = Binder.clearCallingIdentity();
5128 try {
5129 if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
5130 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
5131 if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
5132 return success;
5133 } finally {
5134 Binder.restoreCallingIdentity(identity);
5135 }
Jake Hambye994d462014-02-03 13:10:13 -08005136 }
5137
5138 /**
chen xu6dac5ab2018-10-26 17:39:23 -07005139 * Rollback modem configurations to factory default except some config which are in whitelist.
Jake Hambye994d462014-02-03 13:10:13 -08005140 * Used for device configuration by some CDMA operators.
5141 *
chen xu6dac5ab2018-10-26 17:39:23 -07005142 * @param slotIndex - device slot.
5143 *
Jake Hambye994d462014-02-03 13:10:13 -08005144 * @return true on success; false on any failure
5145 */
5146 @Override
chen xu6dac5ab2018-10-26 17:39:23 -07005147 public boolean resetModemConfig(int slotIndex) {
5148 Phone phone = PhoneFactory.getPhone(slotIndex);
5149 if (phone != null) {
5150 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5151 mApp, phone.getSubId(), "resetModemConfig");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005152
chen xu6dac5ab2018-10-26 17:39:23 -07005153 final long identity = Binder.clearCallingIdentity();
5154 try {
5155 Boolean success = (Boolean) sendRequest(CMD_RESET_MODEM_CONFIG, null);
5156 if (DBG) log("resetModemConfig:" + ' ' + (success ? "ok" : "fail"));
5157 return success;
5158 } finally {
5159 Binder.restoreCallingIdentity(identity);
5160 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005161 }
chen xu6dac5ab2018-10-26 17:39:23 -07005162 return false;
5163 }
5164
5165 /**
5166 * Generate a radio modem reset. Used for device configuration by some CDMA operators.
5167 *
5168 * @param slotIndex - device slot.
5169 *
5170 * @return true on success; false on any failure
5171 */
5172 @Override
5173 public boolean rebootModem(int slotIndex) {
5174 Phone phone = PhoneFactory.getPhone(slotIndex);
5175 if (phone != null) {
5176 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5177 mApp, phone.getSubId(), "rebootModem");
5178
5179 final long identity = Binder.clearCallingIdentity();
5180 try {
5181 Boolean success = (Boolean) sendRequest(CMD_MODEM_REBOOT, null);
5182 if (DBG) log("rebootModem:" + ' ' + (success ? "ok" : "fail"));
5183 return success;
5184 } finally {
5185 Binder.restoreCallingIdentity(identity);
5186 }
5187 }
5188 return false;
Jake Hambye994d462014-02-03 13:10:13 -08005189 }
Jake Hamby7c27be32014-03-03 13:25:59 -08005190
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005191 public String[] getPcscfAddress(String apnType, String callingPackage,
5192 String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005193 final Phone defaultPhone = getDefaultPhone();
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005194 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
5195 callingPackage, callingFeatureId, "getPcscfAddress")) {
Svet Ganovb320e182015-04-16 12:30:10 -07005196 return new String[0];
5197 }
5198
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005199 final long identity = Binder.clearCallingIdentity();
5200 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005201 return defaultPhone.getPcscfAddress(apnType);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005202 } finally {
5203 Binder.restoreCallingIdentity(identity);
5204 }
Wink Saville36469e72014-06-11 15:17:00 -07005205 }
5206
Brad Ebinger51f743a2017-01-23 13:50:20 -08005207 /**
Grace Jiaaa2eb6b2020-01-09 16:26:08 -08005208 * Toggle IMS disable and enable for the framework to reset it. See {@link #enableIms(int)} and
5209 * {@link #disableIms(int)}.
5210 * @param slotIndex device slot.
5211 */
5212 public void resetIms(int slotIndex) {
5213 enforceModifyPermission();
5214
5215 final long identity = Binder.clearCallingIdentity();
5216 try {
5217 if (mImsResolver == null) {
5218 // may happen if the does not support IMS.
5219 return;
5220 }
5221 mImsResolver.disableIms(slotIndex);
5222 mImsResolver.enableIms(slotIndex);
5223 } finally {
5224 Binder.restoreCallingIdentity(identity);
5225 }
5226 }
5227
5228 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005229 * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
5230 * status updates, if not already enabled.
Brad Ebinger51f743a2017-01-23 13:50:20 -08005231 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005232 public void enableIms(int slotId) {
Brad Ebinger51f743a2017-01-23 13:50:20 -08005233 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005234
5235 final long identity = Binder.clearCallingIdentity();
5236 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08005237 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005238 // may happen if the device does not support IMS.
5239 return;
5240 }
Brad Ebinger24c29992019-12-05 13:03:21 -08005241 mImsResolver.enableIms(slotId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005242 } finally {
5243 Binder.restoreCallingIdentity(identity);
5244 }
Brad Ebinger34bef922017-11-09 10:27:08 -08005245 }
5246
5247 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005248 * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
5249 * status updates to disabled.
Brad Ebinger34bef922017-11-09 10:27:08 -08005250 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005251 public void disableIms(int slotId) {
5252 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005253
5254 final long identity = Binder.clearCallingIdentity();
5255 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08005256 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005257 // may happen if the device does not support IMS.
5258 return;
5259 }
Brad Ebinger24c29992019-12-05 13:03:21 -08005260 mImsResolver.disableIms(slotId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005261 } finally {
5262 Binder.restoreCallingIdentity(identity);
5263 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005264 }
5265
5266 /**
Brad Ebinger67b3e042020-09-11 12:45:11 -07005267 * Registers for updates to the MmTelFeature connection through the IImsServiceFeatureCallback
5268 * callback.
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005269 */
Brad Ebinger67b3e042020-09-11 12:45:11 -07005270 @Override
Brad Ebingerf6aca002020-10-01 13:51:05 -07005271 public void registerMmTelFeatureCallback(int slotId, IImsServiceFeatureCallback callback) {
Brad Ebinger34bef922017-11-09 10:27:08 -08005272 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005273
5274 final long identity = Binder.clearCallingIdentity();
5275 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08005276 if (mImsResolver == null) {
Brad Ebinger67b3e042020-09-11 12:45:11 -07005277 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
5278 "Device does not support IMS");
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005279 }
Brad Ebingerf6aca002020-10-01 13:51:05 -07005280 mImsResolver.listenForFeature(slotId, ImsFeature.FEATURE_MMTEL, callback);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005281 } finally {
5282 Binder.restoreCallingIdentity(identity);
5283 }
Brad Ebinger34bef922017-11-09 10:27:08 -08005284 }
Brad Ebinger5f64b052017-12-14 14:26:15 -08005285 /**
Brad Ebinger075ff3a2020-05-18 17:52:58 -07005286 * Unregister a previously registered IImsServiceFeatureCallback associated with an ImsFeature.
5287 */
Brad Ebinger67b3e042020-09-11 12:45:11 -07005288 @Override
5289 public void unregisterImsFeatureCallback(IImsServiceFeatureCallback callback) {
Brad Ebinger075ff3a2020-05-18 17:52:58 -07005290 enforceModifyPermission();
5291
5292 final long identity = Binder.clearCallingIdentity();
5293 try {
5294 if (mImsResolver == null) return;
Brad Ebinger67b3e042020-09-11 12:45:11 -07005295 mImsResolver.unregisterImsFeatureCallback(callback);
Brad Ebinger075ff3a2020-05-18 17:52:58 -07005296 } finally {
5297 Binder.restoreCallingIdentity(identity);
5298 }
5299 }
5300
5301 /**
Brad Ebinger5f64b052017-12-14 14:26:15 -08005302 * Returns the {@link IImsRegistration} structure associated with the slotId and feature
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005303 * specified or null if IMS is not supported on the slot specified.
Brad Ebinger5f64b052017-12-14 14:26:15 -08005304 */
5305 public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
5306 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005307
5308 final long identity = Binder.clearCallingIdentity();
5309 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08005310 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005311 // may happen if the device does not support IMS.
5312 return null;
5313 }
Brad Ebinger24c29992019-12-05 13:03:21 -08005314 return mImsResolver.getImsRegistration(slotId, feature);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005315 } finally {
5316 Binder.restoreCallingIdentity(identity);
5317 }
Brad Ebinger5f64b052017-12-14 14:26:15 -08005318 }
5319
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005320 /**
5321 * Returns the {@link IImsConfig} structure associated with the slotId and feature
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005322 * specified or null if IMS is not supported on the slot specified.
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005323 */
5324 public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
5325 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005326
5327 final long identity = Binder.clearCallingIdentity();
5328 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08005329 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005330 // may happen if the device does not support IMS.
5331 return null;
5332 }
Brad Ebinger24c29992019-12-05 13:03:21 -08005333 return mImsResolver.getImsConfig(slotId, feature);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005334 } finally {
5335 Binder.restoreCallingIdentity(identity);
5336 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005337 }
5338
Brad Ebinger884c07b2018-02-15 16:17:40 -08005339 /**
Brad Ebingerdac2f002018-04-03 15:17:52 -07005340 * Sets the ImsService Package Name that Telephony will bind to.
5341 *
Brad Ebinger24c29992019-12-05 13:03:21 -08005342 * @param slotIndex the slot ID that the ImsService should bind for.
5343 * @param isCarrierService true if the ImsService is the carrier override, false if the
Brad Ebingerdac2f002018-04-03 15:17:52 -07005344 * ImsService is the device default ImsService.
Brad Ebinger24c29992019-12-05 13:03:21 -08005345 * @param featureTypes An integer array of feature types associated with a packageName.
5346 * @param packageName The name of the package that the current configuration will be replaced
5347 * with.
Brad Ebingerdac2f002018-04-03 15:17:52 -07005348 * @return true if setting the ImsService to bind to succeeded, false if it did not.
Brad Ebingerdac2f002018-04-03 15:17:52 -07005349 */
Brad Ebinger24c29992019-12-05 13:03:21 -08005350 public boolean setBoundImsServiceOverride(int slotIndex, boolean isCarrierService,
5351 int[] featureTypes, String packageName) {
5352 int[] subIds = SubscriptionManager.getSubId(slotIndex);
5353 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setBoundImsServiceOverride");
Brad Ebingerde696de2018-04-06 09:56:40 -07005354 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
5355 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
Brad Ebinger24c29992019-12-05 13:03:21 -08005356 "setBoundImsServiceOverride");
Brad Ebingerde696de2018-04-06 09:56:40 -07005357
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005358 final long identity = Binder.clearCallingIdentity();
5359 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08005360 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005361 // may happen if the device does not support IMS.
5362 return false;
5363 }
Brad Ebinger24c29992019-12-05 13:03:21 -08005364 Map<Integer, String> featureConfig = new HashMap<>();
5365 for (int featureType : featureTypes) {
5366 featureConfig.put(featureType, packageName);
5367 }
5368 return mImsResolver.overrideImsServiceConfiguration(slotIndex, isCarrierService,
5369 featureConfig);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005370 } finally {
5371 Binder.restoreCallingIdentity(identity);
5372 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07005373 }
5374
5375 /**
Brad Ebinger999d3302020-11-25 14:31:39 -08005376 * Clears any carrier ImsService overrides for the slot index specified that were previously
5377 * set with {@link #setBoundImsServiceOverride(int, boolean, int[], String)}.
5378 *
5379 * This should only be used for testing.
5380 *
5381 * @param slotIndex the slot ID that the ImsService should bind for.
5382 * @return true if clearing the carrier ImsService override succeeded or false if it did not.
5383 */
5384 @Override
5385 public boolean clearCarrierImsServiceOverride(int slotIndex) {
5386 int[] subIds = SubscriptionManager.getSubId(slotIndex);
5387 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
5388 "clearCarrierImsServiceOverride");
5389 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
5390 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
5391 "clearCarrierImsServiceOverride");
5392
5393 final long identity = Binder.clearCallingIdentity();
5394 try {
5395 if (mImsResolver == null) {
5396 // may happen if the device does not support IMS.
5397 return false;
5398 }
5399 return mImsResolver.clearCarrierImsServiceConfiguration(slotIndex);
5400 } finally {
5401 Binder.restoreCallingIdentity(identity);
5402 }
5403 }
5404
5405 /**
Brad Ebinger24c29992019-12-05 13:03:21 -08005406 * Return the package name of the currently bound ImsService.
Brad Ebingerdac2f002018-04-03 15:17:52 -07005407 *
5408 * @param slotId The slot that the ImsService is associated with.
5409 * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
5410 * the device default.
Brad Ebinger24c29992019-12-05 13:03:21 -08005411 * @param featureType The feature associated with the queried configuration.
Brad Ebingerdac2f002018-04-03 15:17:52 -07005412 * @return the package name of the ImsService configuration.
5413 */
Brad Ebinger24c29992019-12-05 13:03:21 -08005414 public String getBoundImsServicePackage(int slotId, boolean isCarrierImsService,
5415 @ImsFeature.FeatureType int featureType) {
Brad Ebingerde696de2018-04-06 09:56:40 -07005416 int[] subIds = SubscriptionManager.getSubId(slotId);
Brad Ebinger24c29992019-12-05 13:03:21 -08005417 TelephonyPermissions
5418 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5419 mApp, (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
5420 "getBoundImsServicePackage");
Brad Ebingerde696de2018-04-06 09:56:40 -07005421
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005422 final long identity = Binder.clearCallingIdentity();
5423 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08005424 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005425 // may happen if the device does not support IMS.
5426 return "";
5427 }
Brad Ebingera80c3312019-12-02 10:59:39 -08005428 // TODO: change API to query RCS separately.
Brad Ebinger24c29992019-12-05 13:03:21 -08005429 return mImsResolver.getImsServiceConfiguration(slotId, isCarrierImsService,
5430 featureType);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005431 } finally {
5432 Binder.restoreCallingIdentity(identity);
5433 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07005434 }
5435
Brad Ebingerbc7dd582019-10-17 17:03:22 -07005436 /**
5437 * Get the MmTelFeature state associated with the requested subscription id.
5438 * @param subId The subscription that the MmTelFeature is associated with.
5439 * @param callback A callback with an integer containing the
5440 * {@link android.telephony.ims.feature.ImsFeature.ImsState} associated with the MmTelFeature.
5441 */
5442 @Override
5443 public void getImsMmTelFeatureState(int subId, IIntegerConsumer callback) {
5444 enforceReadPrivilegedPermission("getImsMmTelFeatureState");
5445 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
5446 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
5447 "IMS not available on device.");
5448 }
5449 final long token = Binder.clearCallingIdentity();
5450 try {
5451 int slotId = getSlotIndex(subId);
5452 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5453 Log.w(LOG_TAG, "getImsMmTelFeatureState: called with an inactive subscription '"
5454 + subId + "'");
5455 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
5456 }
5457 ImsManager.getInstance(mApp, slotId).getImsServiceState(anInteger -> {
5458 try {
5459 callback.accept(anInteger == null ? ImsFeature.STATE_UNAVAILABLE : anInteger);
5460 } catch (RemoteException e) {
5461 Log.w(LOG_TAG, "getImsMmTelFeatureState: remote caller is no longer running. "
5462 + "Ignore");
5463 }
5464 });
5465 } finally {
5466 Binder.restoreCallingIdentity(token);
5467 }
5468 }
5469
Wink Saville36469e72014-06-11 15:17:00 -07005470 public void setImsRegistrationState(boolean registered) {
5471 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005472
5473 final long identity = Binder.clearCallingIdentity();
5474 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005475 getDefaultPhone().setImsRegistrationState(registered);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005476 } finally {
5477 Binder.restoreCallingIdentity(identity);
5478 }
Wink Saville36469e72014-06-11 15:17:00 -07005479 }
5480
5481 /**
Stuart Scott54788802015-03-30 13:18:01 -07005482 * Set the network selection mode to automatic.
5483 *
5484 */
5485 @Override
5486 public void setNetworkSelectionModeAutomatic(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005487 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5488 mApp, subId, "setNetworkSelectionModeAutomatic");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005489
5490 final long identity = Binder.clearCallingIdentity();
5491 try {
shilufc958392020-01-20 11:36:01 -08005492 if (!isActiveSubscription(subId)) {
5493 return;
5494 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005495 if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
5496 sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId);
5497 } finally {
5498 Binder.restoreCallingIdentity(identity);
5499 }
Stuart Scott54788802015-03-30 13:18:01 -07005500 }
5501
Jack Yud10cdd42020-09-28 20:28:01 -07005502 /**
Pengquan Mengea84e042018-09-20 14:57:26 -07005503 * Ask the radio to connect to the input network and change selection mode to manual.
5504 *
5505 * @param subId the id of the subscription.
5506 * @param operatorInfo the operator information, included the PLMN, long name and short name of
5507 * the operator to attach to.
5508 * @param persistSelection whether the selection will persist until reboot. If true, only allows
5509 * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
5510 * normal network selection next time.
5511 * @return {@code true} on success; {@code true} on any failure.
Shishir Agrawal302c8692015-06-19 13:49:39 -07005512 */
5513 @Override
Pengquan Mengea84e042018-09-20 14:57:26 -07005514 public boolean setNetworkSelectionModeManual(
5515 int subId, OperatorInfo operatorInfo, boolean persistSelection) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005516 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5517 mApp, subId, "setNetworkSelectionModeManual");
Pengquan Menge92a50d2018-09-21 15:54:48 -07005518
5519 if (!isActiveSubscription(subId)) {
5520 return false;
5521 }
5522
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005523 final long identity = Binder.clearCallingIdentity();
5524 try {
Pengquan Mengea84e042018-09-20 14:57:26 -07005525 ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operatorInfo,
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005526 persistSelection);
Pengquan Mengea84e042018-09-20 14:57:26 -07005527 if (DBG) {
5528 log("setNetworkSelectionModeManual: subId: " + subId
5529 + " operator: " + operatorInfo);
5530 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005531 return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
5532 } finally {
5533 Binder.restoreCallingIdentity(identity);
5534 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07005535 }
shilu84f6e8b2019-12-19 13:58:01 -08005536 /**
5537 * Get the manual network selection
5538 *
5539 * @param subId the id of the subscription.
5540 *
5541 * @return the previously saved user selected PLMN
5542 */
5543 @Override
5544 public String getManualNetworkSelectionPlmn(int subId) {
5545 TelephonyPermissions
5546 .enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5547 mApp, subId, "getManualNetworkSelectionPlmn");
5548
5549 final long identity = Binder.clearCallingIdentity();
5550 try {
5551 if (!isActiveSubscription(subId)) {
shilufa1c2592020-03-10 10:59:43 -07005552 throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
shilu84f6e8b2019-12-19 13:58:01 -08005553 }
5554
5555 final Phone phone = getPhone(subId);
5556 if (phone == null) {
shilufa1c2592020-03-10 10:59:43 -07005557 throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
shilu84f6e8b2019-12-19 13:58:01 -08005558 }
5559 OperatorInfo networkSelection = phone.getSavedNetworkSelection();
5560 return TextUtils.isEmpty(networkSelection.getOperatorNumeric())
5561 ? phone.getManualNetworkSelectionPlmn() : networkSelection.getOperatorNumeric();
5562 } finally {
5563 Binder.restoreCallingIdentity(identity);
5564 }
5565 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07005566
5567 /**
5568 * Scans for available networks.
5569 */
5570 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07005571 public CellNetworkScanResult getCellNetworkScanResults(int subId, String callingPackage,
5572 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005573 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5574 mApp, subId, "getCellNetworkScanResults");
Hall Liuf19c44f2018-11-27 14:38:17 -08005575 LocationAccessPolicy.LocationPermissionResult locationResult =
5576 LocationAccessPolicy.checkLocationPermission(mApp,
5577 new LocationAccessPolicy.LocationPermissionQuery.Builder()
5578 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07005579 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08005580 .setCallingPid(Binder.getCallingPid())
5581 .setCallingUid(Binder.getCallingUid())
5582 .setMethod("getCellNetworkScanResults")
5583 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
Hall Liuc4a3e422020-05-26 17:18:03 -07005584 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
5585 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
Hall Liuf19c44f2018-11-27 14:38:17 -08005586 .build());
5587 switch (locationResult) {
5588 case DENIED_HARD:
5589 throw new SecurityException("Not allowed to access scan results -- location");
5590 case DENIED_SOFT:
5591 return null;
5592 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005593
Pengquan Menga1bb6272018-09-06 09:59:22 -07005594 long identity = Binder.clearCallingIdentity();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005595 try {
5596 if (DBG) log("getCellNetworkScanResults: subId " + subId);
Pengquan Menga1bb6272018-09-06 09:59:22 -07005597 return (CellNetworkScanResult) sendRequest(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005598 CMD_PERFORM_NETWORK_SCAN, null, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005599 } finally {
5600 Binder.restoreCallingIdentity(identity);
5601 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07005602 }
5603
5604 /**
Shuo Qian4a594052020-01-23 11:59:30 -08005605 * Get the call forwarding info, given the call forwarding reason.
5606 */
5607 @Override
Hall Liu27d24262020-09-18 19:04:59 -07005608 public void getCallForwarding(int subId, int callForwardingReason,
5609 ICallForwardingInfoCallback callback) {
Shuo Qian4a594052020-01-23 11:59:30 -08005610 enforceReadPrivilegedPermission("getCallForwarding");
5611 long identity = Binder.clearCallingIdentity();
5612 try {
5613 if (DBG) {
5614 log("getCallForwarding: subId " + subId
5615 + " callForwardingReason" + callForwardingReason);
5616 }
Hall Liu27d24262020-09-18 19:04:59 -07005617
5618 Phone phone = getPhone(subId);
5619 if (phone == null) {
5620 try {
Hall Liu940c4ca2020-09-29 17:10:18 -07005621 callback.onError(
5622 TelephonyManager.CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN);
Hall Liu27d24262020-09-18 19:04:59 -07005623 } catch (RemoteException e) {
5624 // ignore
5625 }
5626 return;
5627 }
5628
5629 Pair<Integer, TelephonyManager.CallForwardingInfoCallback> argument = Pair.create(
5630 callForwardingReason, new TelephonyManager.CallForwardingInfoCallback() {
5631 @Override
5632 public void onCallForwardingInfoAvailable(CallForwardingInfo info) {
5633 try {
5634 callback.onCallForwardingInfoAvailable(info);
5635 } catch (RemoteException e) {
5636 // ignore
5637 }
5638 }
5639
5640 @Override
5641 public void onError(int error) {
5642 try {
5643 callback.onError(error);
5644 } catch (RemoteException e) {
5645 // ignore
5646 }
5647 }
5648 });
5649 sendRequestAsync(CMD_GET_CALL_FORWARDING, argument, phone, null);
Shuo Qian4a594052020-01-23 11:59:30 -08005650 } finally {
5651 Binder.restoreCallingIdentity(identity);
5652 }
5653 }
5654
5655 /**
5656 * Sets the voice call forwarding info including status (enable/disable), call forwarding
5657 * reason, the number to forward, and the timeout before the forwarding is attempted.
5658 */
5659 @Override
Hall Liu27d24262020-09-18 19:04:59 -07005660 public void setCallForwarding(int subId, CallForwardingInfo callForwardingInfo,
5661 IIntegerConsumer callback) {
Shuo Qian4a594052020-01-23 11:59:30 -08005662 enforceModifyPermission();
5663 long identity = Binder.clearCallingIdentity();
5664 try {
5665 if (DBG) {
5666 log("setCallForwarding: subId " + subId
5667 + " callForwardingInfo" + callForwardingInfo);
5668 }
Hall Liu27d24262020-09-18 19:04:59 -07005669
5670 Phone phone = getPhone(subId);
5671 if (phone == null) {
5672 try {
Hall Liu940c4ca2020-09-29 17:10:18 -07005673 callback.accept(
5674 TelephonyManager.CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN);
Hall Liu27d24262020-09-18 19:04:59 -07005675 } catch (RemoteException e) {
5676 // ignore
5677 }
5678 return;
5679 }
5680
5681 Pair<CallForwardingInfo, Consumer<Integer>> arguments = Pair.create(callForwardingInfo,
5682 FunctionalUtils.ignoreRemoteException(callback::accept));
5683
5684 sendRequestAsync(CMD_SET_CALL_FORWARDING, arguments, phone, null);
Shuo Qian4a594052020-01-23 11:59:30 -08005685 } finally {
5686 Binder.restoreCallingIdentity(identity);
5687 }
5688 }
5689
5690 /**
Hall Liu27d24262020-09-18 19:04:59 -07005691 * Get the call waiting status for a subId.
Shuo Qian4a594052020-01-23 11:59:30 -08005692 */
5693 @Override
Hall Liu27d24262020-09-18 19:04:59 -07005694 public void getCallWaitingStatus(int subId, IIntegerConsumer callback) {
Shuo Qian4a594052020-01-23 11:59:30 -08005695 enforceReadPrivilegedPermission("getCallForwarding");
5696 long identity = Binder.clearCallingIdentity();
5697 try {
Hall Liu27d24262020-09-18 19:04:59 -07005698
5699 Phone phone = getPhone(subId);
5700 if (phone == null) {
5701 try {
5702 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
5703 } catch (RemoteException e) {
5704 // ignore
5705 }
5706 return;
5707 }
5708
5709 Consumer<Integer> argument = FunctionalUtils.ignoreRemoteException(callback::accept);
5710
Shuo Qian4a594052020-01-23 11:59:30 -08005711 if (DBG) log("getCallWaitingStatus: subId " + subId);
Hall Liu27d24262020-09-18 19:04:59 -07005712 sendRequestAsync(CMD_GET_CALL_WAITING, argument, phone, null);
Shuo Qian4a594052020-01-23 11:59:30 -08005713 } finally {
5714 Binder.restoreCallingIdentity(identity);
5715 }
5716 }
5717
5718 /**
Hall Liu27d24262020-09-18 19:04:59 -07005719 * Sets whether call waiting is enabled for a given subId.
Shuo Qian4a594052020-01-23 11:59:30 -08005720 */
5721 @Override
Hall Liu27d24262020-09-18 19:04:59 -07005722 public void setCallWaitingStatus(int subId, boolean enable, IIntegerConsumer callback) {
Shuo Qian4a594052020-01-23 11:59:30 -08005723 enforceModifyPermission();
5724 long identity = Binder.clearCallingIdentity();
5725 try {
Hall Liu27d24262020-09-18 19:04:59 -07005726 if (DBG) log("setCallWaitingStatus: subId " + subId + " enable: " + enable);
5727
5728 Phone phone = getPhone(subId);
5729 if (phone == null) {
5730 try {
5731 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
5732 } catch (RemoteException e) {
5733 // ignore
5734 }
5735 return;
5736 }
5737
5738 Pair<Boolean, Consumer<Integer>> arguments = Pair.create(enable,
5739 FunctionalUtils.ignoreRemoteException(callback::accept));
5740
5741 sendRequestAsync(CMD_SET_CALL_WAITING, arguments, phone, null);
Shuo Qian4a594052020-01-23 11:59:30 -08005742 } finally {
5743 Binder.restoreCallingIdentity(identity);
5744 }
5745 }
5746
5747 /**
yinxub1bed742017-04-17 11:45:04 -07005748 * Starts a new network scan and returns the id of this scan.
yinxu504e1392017-04-12 16:03:22 -07005749 *
yinxub1bed742017-04-17 11:45:04 -07005750 * @param subId id of the subscription
5751 * @param request contains the radio access networks with bands/channels to scan
5752 * @param messenger callback messenger for scan results or errors
5753 * @param binder for the purpose of auto clean when the user thread crashes
yinxu504e1392017-04-12 16:03:22 -07005754 * @return the id of the requested scan which can be used to stop the scan.
5755 */
5756 @Override
5757 public int requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger,
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07005758 IBinder binder, String callingPackage, String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005759 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5760 mApp, subId, "requestNetworkScan");
Hall Liuf19c44f2018-11-27 14:38:17 -08005761 LocationAccessPolicy.LocationPermissionResult locationResult =
5762 LocationAccessPolicy.checkLocationPermission(mApp,
5763 new LocationAccessPolicy.LocationPermissionQuery.Builder()
5764 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07005765 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08005766 .setCallingPid(Binder.getCallingPid())
5767 .setCallingUid(Binder.getCallingUid())
5768 .setMethod("requestNetworkScan")
5769 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
James.cf Lin1d4d7392020-07-03 18:22:53 +08005770 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
5771 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
Hall Liuf19c44f2018-11-27 14:38:17 -08005772 .build());
Hall Liub2ac8ef2019-02-28 15:56:23 -08005773 if (locationResult != LocationAccessPolicy.LocationPermissionResult.ALLOWED) {
Nathan Harold1c11dba2020-09-22 17:54:53 -07005774 SecurityException e = checkNetworkRequestForSanitizedLocationAccess(
5775 request, subId, callingPackage);
Hall Liub2ac8ef2019-02-28 15:56:23 -08005776 if (e != null) {
5777 if (locationResult == LocationAccessPolicy.LocationPermissionResult.DENIED_HARD) {
5778 throw e;
5779 } else {
Hall Liu0e5abaf2019-04-04 01:25:30 -07005780 loge(e.getMessage());
Hall Liub2ac8ef2019-02-28 15:56:23 -08005781 return TelephonyScanManager.INVALID_SCAN_ID;
5782 }
5783 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005784 }
Hall Liu912dfd32019-04-25 14:02:26 -07005785 int callingUid = Binder.getCallingUid();
5786 int callingPid = Binder.getCallingPid();
Ying Xu94a46582019-04-18 17:14:56 -07005787 final long identity = Binder.clearCallingIdentity();
5788 try {
5789 return mNetworkScanRequestTracker.startNetworkScan(
5790 request, messenger, binder, getPhone(subId),
Hall Liu912dfd32019-04-25 14:02:26 -07005791 callingUid, callingPid, callingPackage);
Ying Xu94a46582019-04-18 17:14:56 -07005792 } finally {
5793 Binder.restoreCallingIdentity(identity);
5794 }
yinxu504e1392017-04-12 16:03:22 -07005795 }
5796
Hall Liub2ac8ef2019-02-28 15:56:23 -08005797 private SecurityException checkNetworkRequestForSanitizedLocationAccess(
Nathan Harold1c11dba2020-09-22 17:54:53 -07005798 NetworkScanRequest request, int subId, String callingPackage) {
5799 boolean hasCarrierPriv = checkCarrierPrivilegesForPackage(subId, callingPackage)
Hall Liu558027f2019-05-15 19:14:05 -07005800 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
5801 boolean hasNetworkScanPermission =
5802 mApp.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_SCAN)
5803 == PERMISSION_GRANTED;
5804
5805 if (!hasCarrierPriv && !hasNetworkScanPermission) {
5806 return new SecurityException("permission.NETWORK_SCAN or carrier privileges is needed"
5807 + " for network scans without location access.");
Hall Liub2ac8ef2019-02-28 15:56:23 -08005808 }
5809
5810 if (request.getSpecifiers() != null && request.getSpecifiers().length > 0) {
5811 for (RadioAccessSpecifier ras : request.getSpecifiers()) {
Hall Liub2ac8ef2019-02-28 15:56:23 -08005812 if (ras.getChannels() != null && ras.getChannels().length > 0) {
5813 return new SecurityException("Specific channels must not be"
5814 + " scanned without location access.");
5815 }
5816 }
5817 }
5818
Hall Liub2ac8ef2019-02-28 15:56:23 -08005819 return null;
5820 }
5821
yinxu504e1392017-04-12 16:03:22 -07005822 /**
5823 * Stops an existing network scan with the given scanId.
yinxub1bed742017-04-17 11:45:04 -07005824 *
5825 * @param subId id of the subscription
5826 * @param scanId id of the scan that needs to be stopped
yinxu504e1392017-04-12 16:03:22 -07005827 */
5828 @Override
5829 public void stopNetworkScan(int subId, int scanId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005830 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5831 mApp, subId, "stopNetworkScan");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005832
Hall Liu912dfd32019-04-25 14:02:26 -07005833 int callingUid = Binder.getCallingUid();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005834 final long identity = Binder.clearCallingIdentity();
5835 try {
Hall Liu912dfd32019-04-25 14:02:26 -07005836 mNetworkScanRequestTracker.stopNetworkScan(scanId, callingUid);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005837 } finally {
5838 Binder.restoreCallingIdentity(identity);
5839 }
yinxu504e1392017-04-12 16:03:22 -07005840 }
5841
5842 /**
Junda Liu84d15a22014-07-02 11:21:04 -07005843 * Get the calculated preferred network type.
5844 * Used for debugging incorrect network type.
5845 *
5846 * @return the preferred network type, defined in RILConstants.java.
5847 */
5848 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005849 public int getCalculatedPreferredNetworkType(String callingPackage, String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005850 final Phone defaultPhone = getDefaultPhone();
5851 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005852 callingPackage, callingFeatureId, "getCalculatedPreferredNetworkType")) {
Svet Ganovb320e182015-04-16 12:30:10 -07005853 return RILConstants.PREFERRED_NETWORK_MODE;
5854 }
5855
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005856 final long identity = Binder.clearCallingIdentity();
5857 try {
5858 // FIXME: need to get SubId from somewhere.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005859 return PhoneFactory.calculatePreferredNetworkType(defaultPhone.getContext(), 0);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005860 } finally {
5861 Binder.restoreCallingIdentity(identity);
5862 }
Junda Liu84d15a22014-07-02 11:21:04 -07005863 }
5864
5865 /**
Jake Hamby7c27be32014-03-03 13:25:59 -08005866 * Get the preferred network type.
5867 * Used for device configuration by some CDMA operators.
5868 *
5869 * @return the preferred network type, defined in RILConstants.java.
5870 */
5871 @Override
Stuart Scott54788802015-03-30 13:18:01 -07005872 public int getPreferredNetworkType(int subId) {
Pengquan Menga4009cb2018-12-20 11:00:24 -08005873 TelephonyPermissions
5874 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5875 mApp, subId, "getPreferredNetworkType");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005876
5877 final long identity = Binder.clearCallingIdentity();
5878 try {
5879 if (DBG) log("getPreferredNetworkType");
5880 int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null, subId);
5881 int networkType = (result != null ? result[0] : -1);
5882 if (DBG) log("getPreferredNetworkType: " + networkType);
5883 return networkType;
5884 } finally {
5885 Binder.restoreCallingIdentity(identity);
5886 }
Jake Hamby7c27be32014-03-03 13:25:59 -08005887 }
5888
5889 /**
5890 * Set the preferred network type.
Jake Hamby7c27be32014-03-03 13:25:59 -08005891 *
5892 * @param networkType the preferred network type, defined in RILConstants.java.
5893 * @return true on success; false on any failure.
5894 */
5895 @Override
Stuart Scott54788802015-03-30 13:18:01 -07005896 public boolean setPreferredNetworkType(int subId, int networkType) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005897 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5898 mApp, subId, "setPreferredNetworkType");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005899
5900 final long identity = Binder.clearCallingIdentity();
5901 try {
calvinpan8ed33732020-03-12 14:17:55 +08005902 Boolean success = (Boolean) sendRequest(
5903 CMD_SET_PREFERRED_NETWORK_TYPE, networkType, subId);
calvinpan03641a72020-08-18 16:53:59 +08005904
5905 if (success) {
5906 Settings.Global.putInt(mApp.getContentResolver(),
5907 Settings.Global.PREFERRED_NETWORK_MODE + subId, networkType);
5908 }
calvinpan8ed33732020-03-12 14:17:55 +08005909 if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail"));
5910 return success;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005911 } finally {
5912 Binder.restoreCallingIdentity(identity);
Junda Liu80bc0d12014-07-14 16:36:44 -07005913 }
Jake Hamby7c27be32014-03-03 13:25:59 -08005914 }
Robert Greenwalted86e582014-05-21 20:03:20 -07005915
5916 /**
calvinpan0ac9c1a2020-01-14 20:42:55 +08005917 * Get the allowed network types that store in the telephony provider.
5918 *
5919 * @param subId the id of the subscription.
5920 * @return allowedNetworkTypes the allowed network types.
5921 */
5922 @Override
5923 public long getAllowedNetworkTypes(int subId) {
5924 TelephonyPermissions
5925 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5926 mApp, subId, "getAllowedNetworkTypes");
5927
5928 final long identity = Binder.clearCallingIdentity();
5929 try {
5930 return SubscriptionManager.getLongSubscriptionProperty(
5931 subId, SubscriptionManager.ALLOWED_NETWORK_TYPES, -1, mApp);
5932 } finally {
5933 Binder.restoreCallingIdentity(identity);
5934 }
5935 }
5936
5937 /**
5938 * Set the allowed network types.
5939 *
5940 * @param subId the id of the subscription.
5941 * @param allowedNetworkTypes the allowed network types.
5942 * @return true on success; false on any failure.
5943 */
5944 @Override
5945 public boolean setAllowedNetworkTypes(int subId, long allowedNetworkTypes) {
5946 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5947 mApp, subId, "setAllowedNetworkTypes");
calvinpan0ac9c1a2020-01-14 20:42:55 +08005948
calvinpan8ed33732020-03-12 14:17:55 +08005949 SubscriptionManager.setSubscriptionProperty(subId,
5950 SubscriptionManager.ALLOWED_NETWORK_TYPES,
5951 String.valueOf(allowedNetworkTypes));
calvinpan0ac9c1a2020-01-14 20:42:55 +08005952
calvinpan8ed33732020-03-12 14:17:55 +08005953 int preferredNetworkMode = Settings.Global.getInt(mApp.getContentResolver(),
5954 Settings.Global.PREFERRED_NETWORK_MODE + subId,
5955 RILConstants.PREFERRED_NETWORK_MODE);
5956 return setPreferredNetworkType(subId, preferredNetworkMode);
calvinpan0ac9c1a2020-01-14 20:42:55 +08005957 }
5958
5959 /**
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07005960 * Get the allowed network types for certain reason.
5961 *
5962 * @param subId the id of the subscription.
5963 * @param reason the reason the allowed network type change is taking place
5964 * @return the allowed network types.
5965 */
5966 @Override
5967 public long getAllowedNetworkTypesForReason(int subId,
5968 @TelephonyManager.AllowedNetworkTypesReason int reason) {
5969 TelephonyPermissions
5970 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5971 mApp, subId, "getAllowedNetworkTypesForReason");
5972 final long identity = Binder.clearCallingIdentity();
5973 try {
5974 return getPhoneFromSubId(subId).getAllowedNetworkTypes(reason);
5975 } finally {
5976 Binder.restoreCallingIdentity(identity);
5977 }
5978 }
5979
5980 /**
Sooraj Sasindran37444802020-08-11 10:40:43 -07005981 * Enable/Disable E-UTRA-NR Dual Connectivity
5982 * @param subId subscription id of the sim card
5983 * @param nrDualConnectivityState expected NR dual connectivity state
5984 * This can be passed following states
5985 * <ol>
5986 * <li>Enable NR dual connectivity {@link TelephonyManager#NR_DUAL_CONNECTIVITY_ENABLE}
5987 * <li>Disable NR dual connectivity {@link TelephonyManager#NR_DUAL_CONNECTIVITY_DISABLE}
5988 * <li>Disable NR dual connectivity and force secondary cell to be released
5989 * {@link TelephonyManager#NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE}
5990 * </ol>
5991 * @return operation result.
5992 */
5993 @Override
5994 public int setNrDualConnectivityState(int subId,
5995 @TelephonyManager.NrDualConnectivityState int nrDualConnectivityState) {
5996 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5997 mApp, subId, "enableNRDualConnectivity");
5998 WorkSource workSource = getWorkSource(Binder.getCallingUid());
5999 final long identity = Binder.clearCallingIdentity();
6000 try {
6001 int result = (int) sendRequest(CMD_ENABLE_NR_DUAL_CONNECTIVITY,
6002 nrDualConnectivityState, subId,
6003 workSource);
6004 if (DBG) log("enableNRDualConnectivity result: " + result);
6005 return result;
6006 } finally {
6007 Binder.restoreCallingIdentity(identity);
6008 }
6009 }
6010
6011 /**
6012 * Is E-UTRA-NR Dual Connectivity enabled
6013 * @return true if dual connectivity is enabled else false
6014 */
6015 @Override
6016 public boolean isNrDualConnectivityEnabled(int subId) {
6017 TelephonyPermissions
6018 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
6019 mApp, subId, "isNRDualConnectivityEnabled");
6020 WorkSource workSource = getWorkSource(Binder.getCallingUid());
6021 final long identity = Binder.clearCallingIdentity();
6022 try {
6023 boolean isEnabled = (boolean) sendRequest(CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED,
6024 null, subId, workSource);
6025 if (DBG) log("isNRDualConnectivityEnabled: " + isEnabled);
6026 return isEnabled;
6027 } finally {
6028 Binder.restoreCallingIdentity(identity);
6029 }
6030 }
6031
6032 /**
Sooraj Sasindran4deb8872020-10-30 13:17:53 -07006033 * get carrier bandwidth per primary and secondary carrier
6034 * @param subId subscription id of the sim card
6035 * @return CarrierBandwidth with bandwidth of both primary and secondary carrier..
6036 */
6037 @Override
6038 public CarrierBandwidth getCarrierBandwidth(int subId) {
6039 TelephonyPermissions
6040 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
6041 mApp, subId, "isNRDualConnectivityEnabled");
6042 WorkSource workSource = getWorkSource(Binder.getCallingUid());
6043 final long identity = Binder.clearCallingIdentity();
6044 try {
6045 CarrierBandwidth carrierBandwidth =
6046 getPhoneFromSubId(subId).getCarrierBandwidth();
6047 if (DBG) log("getCarrierBandwidth: " + carrierBandwidth);
6048 return carrierBandwidth;
6049 } finally {
6050 Binder.restoreCallingIdentity(identity);
6051 }
6052 }
6053
6054 /**
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07006055 * Get the effective allowed network types on the device.
6056 * This API will return an intersection of allowed network types for all reasons,
6057 * including the configuration done through setAllowedNetworkTypes
6058 *
6059 * @param subId the id of the subscription.
6060 * @return the allowed network types
6061 */
6062 @Override
6063 public long getEffectiveAllowedNetworkTypes(int subId) {
6064 TelephonyPermissions
6065 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
6066 mApp, subId, "getEffectiveAllowedNetworkTypes");
6067 final long identity = Binder.clearCallingIdentity();
6068 try {
6069 return getPhoneFromSubId(subId).getEffectiveAllowedNetworkTypes();
6070 } finally {
6071 Binder.restoreCallingIdentity(identity);
6072 }
6073 }
6074
6075 /**
6076 * Set the allowed network types of the device and
6077 * provide the reason triggering the allowed network change.
6078 *
6079 * @param subId the id of the subscription.
6080 * @param reason the reason the allowed network type change is taking place
6081 * @param allowedNetworkTypes the allowed network types.
6082 * @return true on success; false on any failure.
6083 */
6084 @Override
6085 public boolean setAllowedNetworkTypesForReason(int subId,
6086 @TelephonyManager.AllowedNetworkTypesReason int reason, long allowedNetworkTypes) {
6087 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6088 mApp, subId, "setAllowedNetworkTypesForReason");
6089 final long identity = Binder.clearCallingIdentity();
6090 try {
6091 getPhoneFromSubId(subId).setAllowedNetworkTypes(reason, allowedNetworkTypes);
6092 int preferredNetworkMode = Settings.Global.getInt(mApp.getContentResolver(),
6093 Settings.Global.PREFERRED_NETWORK_MODE + subId,
6094 RILConstants.PREFERRED_NETWORK_MODE);
6095 return setPreferredNetworkType(subId, preferredNetworkMode);
6096 } finally {
6097 Binder.restoreCallingIdentity(identity);
6098 }
6099 }
6100
6101 /**
Miaoa84611c2019-03-15 09:21:10 +08006102 * Check whether DUN APN is required for tethering with subId.
Junda Liu475951f2014-11-07 16:45:03 -08006103 *
Miaoa84611c2019-03-15 09:21:10 +08006104 * @param subId the id of the subscription to require tethering.
Amit Mahajanfe58cdf2017-07-11 12:01:53 -07006105 * @return {@code true} if DUN APN is required for tethering.
Junda Liu475951f2014-11-07 16:45:03 -08006106 * @hide
6107 */
6108 @Override
SongFerngWangf08d8122019-11-15 14:58:44 +08006109 public boolean isTetheringApnRequiredForSubscriber(int subId) {
Shishir Agrawalc04d9752016-02-19 10:41:00 -08006110 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006111 final long identity = Binder.clearCallingIdentity();
Miaoa84611c2019-03-15 09:21:10 +08006112 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006113 try {
Miaoa84611c2019-03-15 09:21:10 +08006114 if (phone != null) {
6115 return phone.hasMatchedTetherApnSetting();
6116 } else {
6117 return false;
6118 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006119 } finally {
6120 Binder.restoreCallingIdentity(identity);
Junda Liu475951f2014-11-07 16:45:03 -08006121 }
Junda Liu475951f2014-11-07 16:45:03 -08006122 }
6123
6124 /**
Shuo Qiancd19c462020-01-16 20:51:11 -08006125 * Enable or disable always reporting signal strength changes from radio.
6126 *
6127 * @param isEnable {@code true} for enabling; {@code false} for disabling.
6128 */
6129 @Override
6130 public void setAlwaysReportSignalStrength(int subId, boolean isEnable) {
6131 enforceModifyPermission();
6132 enforceSystemCaller();
6133
6134 final long identity = Binder.clearCallingIdentity();
6135 final Phone phone = getPhone(subId);
6136 try {
6137 if (phone != null) {
6138 if (DBG) {
6139 log("setAlwaysReportSignalStrength: subId=" + subId
6140 + " isEnable=" + isEnable);
6141 }
6142 phone.setAlwaysReportSignalStrength(isEnable);
6143 } else {
6144 loge("setAlwaysReportSignalStrength: no phone found for subId="
6145 + subId);
6146 }
6147 } finally {
6148 Binder.restoreCallingIdentity(identity);
6149 }
6150 }
6151
6152 /**
Malcolm Chen964682d2017-11-28 16:20:07 -08006153 * Get the user enabled state of Mobile Data.
6154 *
6155 * TODO: remove and use isUserDataEnabled.
6156 * This can't be removed now because some vendor codes
6157 * calls through ITelephony directly while they should
6158 * use TelephonyManager.
6159 *
6160 * @return true on enabled
6161 */
6162 @Override
6163 public boolean getDataEnabled(int subId) {
6164 return isUserDataEnabled(subId);
6165 }
6166
6167 /**
6168 * Get whether mobile data is enabled per user setting.
6169 *
6170 * There are other factors deciding whether mobile data is actually enabled, but they are
6171 * not considered here. See {@link #isDataEnabled(int)} for more details.
Robert Greenwalt646120a2014-05-23 11:54:03 -07006172 *
Jeff Davidsona1920712016-11-18 17:05:56 -08006173 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
Robert Greenwalted86e582014-05-21 20:03:20 -07006174 *
6175 * @return {@code true} if data is enabled else {@code false}
6176 */
6177 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08006178 public boolean isUserDataEnabled(int subId) {
Robert Greenwalt646120a2014-05-23 11:54:03 -07006179 try {
6180 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
6181 null);
6182 } catch (Exception e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006183 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6184 mApp, subId, "isUserDataEnabled");
Robert Greenwalt646120a2014-05-23 11:54:03 -07006185 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006186
6187 final long identity = Binder.clearCallingIdentity();
6188 try {
6189 int phoneId = mSubscriptionController.getPhoneId(subId);
6190 if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
6191 Phone phone = PhoneFactory.getPhone(phoneId);
6192 if (phone != null) {
6193 boolean retVal = phone.isUserDataEnabled();
6194 if (DBG) log("isUserDataEnabled: subId=" + subId + " retVal=" + retVal);
6195 return retVal;
6196 } else {
6197 if (DBG) loge("isUserDataEnabled: no phone subId=" + subId + " retVal=false");
6198 return false;
6199 }
6200 } finally {
6201 Binder.restoreCallingIdentity(identity);
Malcolm Chen964682d2017-11-28 16:20:07 -08006202 }
6203 }
6204
6205 /**
Shuo Qian8ee4e882020-01-08 14:30:06 -08006206 * Checks if the device is capable of mobile data by considering whether whether the
6207 * user has enabled mobile data, whether the carrier has enabled mobile data, and
6208 * whether the network policy allows data connections.
Malcolm Chen964682d2017-11-28 16:20:07 -08006209 *
Shuo Qian8ee4e882020-01-08 14:30:06 -08006210 * @return {@code true} if the overall data connection is capable; {@code false} if not.
Malcolm Chen964682d2017-11-28 16:20:07 -08006211 */
6212 @Override
6213 public boolean isDataEnabled(int subId) {
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006214 try {
6215 try {
6216 mApp.enforceCallingOrSelfPermission(
6217 android.Manifest.permission.ACCESS_NETWORK_STATE,
6218 null);
6219 } catch (Exception e) {
6220 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE,
6221 "isDataEnabled");
6222 }
6223 } catch (Exception e) {
6224 enforceReadPrivilegedPermission("isDataEnabled");
6225 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006226
6227 final long identity = Binder.clearCallingIdentity();
6228 try {
6229 int phoneId = mSubscriptionController.getPhoneId(subId);
6230 if (DBG) log("isDataEnabled: subId=" + subId + " phoneId=" + phoneId);
6231 Phone phone = PhoneFactory.getPhone(phoneId);
6232 if (phone != null) {
Jack Yud79fba22018-12-13 11:51:28 -08006233 boolean retVal = phone.getDataEnabledSettings().isDataEnabled();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006234 if (DBG) log("isDataEnabled: subId=" + subId + " retVal=" + retVal);
6235 return retVal;
6236 } else {
6237 if (DBG) loge("isDataEnabled: no phone subId=" + subId + " retVal=false");
6238 return false;
6239 }
6240 } finally {
6241 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08006242 }
Robert Greenwalted86e582014-05-21 20:03:20 -07006243 }
Shishir Agrawal60f9c952014-06-23 12:00:43 -07006244
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006245 /**
6246 * Check if data is enabled for a specific reason
6247 * @param subId Subscription index
6248 * @param reason the reason the data enable change is taking place
6249 * @return {@code true} if the overall data is enabled; {@code false} if not.
6250 */
6251 @Override
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006252 public boolean isDataEnabledForReason(int subId,
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006253 @TelephonyManager.DataEnabledReason int reason) {
6254 try {
6255 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
6256 null);
6257 } catch (Exception e) {
6258 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE,
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006259 "isDataEnabledForReason");
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006260 }
6261
6262
6263 final long identity = Binder.clearCallingIdentity();
6264 try {
6265 int phoneId = mSubscriptionController.getPhoneId(subId);
6266 if (DBG) {
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006267 log("isDataEnabledForReason: subId=" + subId + " phoneId=" + phoneId
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006268 + " reason=" + reason);
6269 }
6270 Phone phone = PhoneFactory.getPhone(phoneId);
6271 if (phone != null) {
6272 boolean retVal;
6273 if (reason == TelephonyManager.DATA_ENABLED_REASON_USER) {
6274 retVal = phone.isUserDataEnabled();
6275 } else {
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006276 retVal = phone.getDataEnabledSettings().isDataEnabledForReason(reason);
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006277 }
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006278 if (DBG) log("isDataEnabledForReason: retVal=" + retVal);
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006279 return retVal;
6280 } else {
6281 if (DBG) {
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006282 loge("isDataEnabledForReason: no phone subId="
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006283 + subId + " retVal=false");
6284 }
6285 return false;
6286 }
6287 } finally {
6288 Binder.restoreCallingIdentity(identity);
6289 }
6290 }
6291
Malcolm Chendf0b4cc2020-02-24 15:12:43 -08006292 private int getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, int uid,
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006293 Phone phone) {
Hall Liu54a2a0c2020-07-13 12:13:03 -07006294 if (uid == Process.SYSTEM_UID || uid == Process.PHONE_UID) {
6295 // Skip the check if it's one of these special uids
6296 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
6297 }
6298
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006299 //load access rules from carrier configs, and check those as well: b/139133814
6300 SubscriptionController subController = SubscriptionController.getInstance();
6301 if (privilegeFromSim == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
6302 || subController == null) return privilegeFromSim;
6303
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006304 PackageManager pkgMgr = phone.getContext().getPackageManager();
6305 String[] packages = pkgMgr.getPackagesForUid(uid);
6306
6307 final long identity = Binder.clearCallingIdentity();
6308 try {
Jeff Davidson8ab02b22020-03-28 12:24:40 -07006309 int subId = phone.getSubId();
6310 if (mCarrierPrivilegeTestOverrideSubIds.contains(subId)) {
6311 // A test override is in place for the privileges for this subId, so don't try to
6312 // read the subscription privileges.
6313 return privilegeFromSim;
6314 }
6315 SubscriptionInfo subInfo = subController.getSubscriptionInfo(subId);
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006316 SubscriptionManager subManager = (SubscriptionManager)
6317 phone.getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
6318 for (String pkg : packages) {
6319 if (subManager.canManageSubscription(subInfo, pkg)) {
6320 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
6321 }
6322 }
6323 return privilegeFromSim;
6324 } finally {
6325 Binder.restoreCallingIdentity(identity);
6326 }
6327 }
6328
6329 private int getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, Phone phone,
6330 String pkgName) {
6331 //load access rules from carrier configs, and check those as well: b/139133814
6332 SubscriptionController subController = SubscriptionController.getInstance();
6333 if (privilegeFromSim == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
6334 || subController == null) return privilegeFromSim;
6335
6336 final long identity = Binder.clearCallingIdentity();
6337 try {
Jeff Davidson8ab02b22020-03-28 12:24:40 -07006338 int subId = phone.getSubId();
6339 if (mCarrierPrivilegeTestOverrideSubIds.contains(subId)) {
6340 // A test override is in place for the privileges for this subId, so don't try to
6341 // read the subscription privileges.
6342 return privilegeFromSim;
6343 }
6344 SubscriptionInfo subInfo = subController.getSubscriptionInfo(subId);
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006345 SubscriptionManager subManager = (SubscriptionManager)
6346 phone.getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
6347 return subManager.canManageSubscription(subInfo, pkgName)
6348 ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS : privilegeFromSim;
6349 } finally {
6350 Binder.restoreCallingIdentity(identity);
6351 }
6352 }
6353
Shishir Agrawal60f9c952014-06-23 12:00:43 -07006354 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08006355 public int getCarrierPrivilegeStatus(int subId) {
6356 final Phone phone = getPhone(subId);
6357 if (phone == null) {
6358 loge("getCarrierPrivilegeStatus: Invalid subId");
6359 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
6360 }
6361 UiccCard card = UiccController.getInstance().getUiccCard(phone.getPhoneId());
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07006362 if (card == null) {
Shishir Agrawal5e5becd2014-11-18 11:38:23 -08006363 loge("getCarrierPrivilegeStatus: No UICC");
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07006364 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
6365 }
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006366
6367 return getCarrierPrivilegeStatusFromCarrierConfigRules(
6368 card.getCarrierPrivilegeStatusForCurrentTransaction(
Malcolm Chendf0b4cc2020-02-24 15:12:43 -08006369 phone.getContext().getPackageManager()), Binder.getCallingUid(), phone);
Shishir Agrawal60f9c952014-06-23 12:00:43 -07006370 }
Junda Liu29340342014-07-10 15:23:27 -07006371
6372 @Override
Jeff Davidson7e17e312018-02-13 18:17:36 -08006373 public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08006374 enforceReadPrivilegedPermission("getCarrierPrivilegeStatusForUid");
Jeff Davidson7e17e312018-02-13 18:17:36 -08006375 final Phone phone = getPhone(subId);
6376 if (phone == null) {
Taesu Leef8fbed92019-10-07 18:47:02 +09006377 loge("getCarrierPrivilegeStatusForUid: Invalid subId");
Jeff Davidson7e17e312018-02-13 18:17:36 -08006378 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
6379 }
6380 UiccProfile profile =
6381 UiccController.getInstance().getUiccProfileForPhone(phone.getPhoneId());
6382 if (profile == null) {
Taesu Leef8fbed92019-10-07 18:47:02 +09006383 loge("getCarrierPrivilegeStatusForUid: No UICC");
Jeff Davidson7e17e312018-02-13 18:17:36 -08006384 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
6385 }
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006386 return getCarrierPrivilegeStatusFromCarrierConfigRules(
Shuo Qian2c0ae432019-12-05 11:40:37 -08006387 profile.getCarrierPrivilegeStatusForUid(
Malcolm Chendf0b4cc2020-02-24 15:12:43 -08006388 phone.getContext().getPackageManager(), uid), uid, phone);
Jeff Davidson7e17e312018-02-13 18:17:36 -08006389 }
6390
6391 @Override
chen xuf7e9fe82019-05-09 19:31:02 -07006392 public int checkCarrierPrivilegesForPackage(int subId, String pkgName) {
6393 if (TextUtils.isEmpty(pkgName)) {
Junda Liu317d70b2016-03-08 09:33:53 -08006394 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
chen xuf7e9fe82019-05-09 19:31:02 -07006395 }
6396
6397 int phoneId = SubscriptionManager.getPhoneId(subId);
6398 UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07006399 if (card == null) {
chen xuf7e9fe82019-05-09 19:31:02 -07006400 loge("checkCarrierPrivilegesForPackage: No UICC on subId " + subId);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07006401 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
6402 }
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006403 return getCarrierPrivilegeStatusFromCarrierConfigRules(
6404 card.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName),
6405 getPhone(phoneId), pkgName);
Zach Johnson50ecba32015-05-19 00:24:21 -07006406 }
6407
6408 @Override
6409 public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
Junda Liu317d70b2016-03-08 09:33:53 -08006410 if (TextUtils.isEmpty(pkgName))
6411 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Zach Johnson50ecba32015-05-19 00:24:21 -07006412 int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
6413 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
6414 UiccCard card = UiccController.getInstance().getUiccCard(i);
6415 if (card == null) {
Jonathan Basseri7d320df2015-06-16 12:17:08 -07006416 // No UICC in that slot.
Zach Johnson50ecba32015-05-19 00:24:21 -07006417 continue;
6418 }
6419
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006420 result = getCarrierPrivilegeStatusFromCarrierConfigRules(
6421 card.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName),
6422 getPhone(i), pkgName);
Zach Johnson50ecba32015-05-19 00:24:21 -07006423 if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
6424 break;
6425 }
6426 }
6427
6428 return result;
Junda Liu29340342014-07-10 15:23:27 -07006429 }
Derek Tan89e89d42014-07-08 17:00:10 -07006430
6431 @Override
Junda Liue64de782015-04-16 17:19:16 -07006432 public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
6433 if (!SubscriptionManager.isValidPhoneId(phoneId)) {
6434 loge("phoneId " + phoneId + " is not valid.");
6435 return null;
6436 }
6437 UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07006438 if (card == null) {
Taesu Leef8fbed92019-10-07 18:47:02 +09006439 loge("getCarrierPackageNamesForIntentAndPhone: No UICC");
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07006440 return null ;
6441 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006442 return card.getCarrierPackageNamesForIntent(mApp.getPackageManager(), intent);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07006443 }
6444
Amith Yamasani6e118872016-02-19 12:53:51 -08006445 @Override
chen xuf7e9fe82019-05-09 19:31:02 -07006446 public List<String> getPackagesWithCarrierPrivileges(int phoneId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006447 PackageManager pm = mApp.getPackageManager();
Amith Yamasani6e118872016-02-19 12:53:51 -08006448 List<String> privilegedPackages = new ArrayList<>();
6449 List<PackageInfo> packages = null;
chen xuf7e9fe82019-05-09 19:31:02 -07006450 UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
6451 // has UICC in that slot.
6452 if (card != null) {
Amith Yamasani6e118872016-02-19 12:53:51 -08006453 if (card.hasCarrierPrivilegeRules()) {
6454 if (packages == null) {
6455 // Only check packages in user 0 for now
6456 packages = pm.getInstalledPackagesAsUser(
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006457 PackageManager.MATCH_DISABLED_COMPONENTS
6458 | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
Cheonho Park17089c62019-08-01 15:23:12 +09006459 | PackageManager.GET_SIGNING_CERTIFICATES,
Amit Mahajanb8f13202020-01-27 18:16:07 -08006460 UserHandle.SYSTEM.getIdentifier());
Amith Yamasani6e118872016-02-19 12:53:51 -08006461 }
6462 for (int p = packages.size() - 1; p >= 0; p--) {
6463 PackageInfo pkgInfo = packages.get(p);
6464 if (pkgInfo != null && pkgInfo.packageName != null
6465 && card.getCarrierPrivilegeStatus(pkgInfo)
chen xuf7e9fe82019-05-09 19:31:02 -07006466 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
Amith Yamasani6e118872016-02-19 12:53:51 -08006467 privilegedPackages.add(pkgInfo.packageName);
6468 }
6469 }
6470 }
6471 }
6472 return privilegedPackages;
6473 }
6474
chen xuf7e9fe82019-05-09 19:31:02 -07006475 @Override
6476 public List<String> getPackagesWithCarrierPrivilegesForAllPhones() {
Shuo Qian067a06d2019-12-03 23:40:18 +00006477 enforceReadPrivilegedPermission("getPackagesWithCarrierPrivilegesForAllPhones");
6478
6479 final long identity = Binder.clearCallingIdentity();
6480
chen xuf7e9fe82019-05-09 19:31:02 -07006481 List<String> privilegedPackages = new ArrayList<>();
Shuo Qian067a06d2019-12-03 23:40:18 +00006482 try {
6483 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
6484 privilegedPackages.addAll(getPackagesWithCarrierPrivileges(i));
6485 }
6486 } finally {
6487 Binder.restoreCallingIdentity(identity);
chen xuf7e9fe82019-05-09 19:31:02 -07006488 }
6489 return privilegedPackages;
6490 }
6491
Wink Savilleb564aae2014-10-23 10:18:09 -07006492 private String getIccId(int subId) {
Sanket Padawe356d7632015-06-22 14:03:32 -07006493 final Phone phone = getPhone(subId);
6494 UiccCard card = phone == null ? null : phone.getUiccCard();
Derek Tan97ebb422014-09-05 16:55:38 -07006495 if (card == null) {
Derek Tan97ebb422014-09-05 16:55:38 -07006496 return null;
6497 }
6498 String iccId = card.getIccId();
6499 if (TextUtils.isEmpty(iccId)) {
Derek Tan97ebb422014-09-05 16:55:38 -07006500 return null;
6501 }
6502 return iccId;
6503 }
6504
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07006505 @Override
Jeff Sharkey85190e62014-12-05 09:40:12 -08006506 public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
6507 String number) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08006508 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
Jeff Davidson7e17e312018-02-13 18:17:36 -08006509 subId, "setLine1NumberForDisplayForSubscriber");
Derek Tan97ebb422014-09-05 16:55:38 -07006510
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006511 final long identity = Binder.clearCallingIdentity();
6512 try {
6513 final String iccId = getIccId(subId);
6514 final Phone phone = getPhone(subId);
6515 if (phone == null) {
6516 return false;
6517 }
6518 final String subscriberId = phone.getSubscriberId();
6519
6520 if (DBG_MERGE) {
Amit Mahajanb8f13202020-01-27 18:16:07 -08006521 Rlog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId="
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006522 + subscriberId + " to " + number);
6523 }
6524
6525 if (TextUtils.isEmpty(iccId)) {
6526 return false;
6527 }
6528
6529 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
6530
6531 final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
6532 if (alphaTag == null) {
6533 editor.remove(alphaTagPrefKey);
6534 } else {
6535 editor.putString(alphaTagPrefKey, alphaTag);
6536 }
6537
6538 // Record both the line number and IMSI for this ICCID, since we need to
6539 // track all merged IMSIs based on line number
6540 final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
6541 final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
6542 if (number == null) {
6543 editor.remove(numberPrefKey);
6544 editor.remove(subscriberPrefKey);
6545 } else {
6546 editor.putString(numberPrefKey, number);
6547 editor.putString(subscriberPrefKey, subscriberId);
6548 }
6549
6550 editor.commit();
6551 return true;
6552 } finally {
6553 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07006554 }
Derek Tan7226c842014-07-02 17:42:23 -07006555 }
6556
6557 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006558 public String getLine1NumberForDisplay(int subId, String callingPackage,
6559 String callingFeatureId) {
Makoto Onukifee69342015-06-29 14:44:50 -07006560 // This is open to apps with WRITE_SMS.
Jeff Davidson7e17e312018-02-13 18:17:36 -08006561 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006562 mApp, subId, callingPackage, callingFeatureId, "getLine1NumberForDisplay")) {
Amit Mahajan9cf11512015-11-09 11:40:48 -08006563 if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
Svet Ganovb320e182015-04-16 12:30:10 -07006564 return null;
6565 }
Derek Tan97ebb422014-09-05 16:55:38 -07006566
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006567 final long identity = Binder.clearCallingIdentity();
6568 try {
6569 String iccId = getIccId(subId);
6570 if (iccId != null) {
6571 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
6572 if (DBG_MERGE) {
6573 log("getLine1NumberForDisplay returning "
6574 + mTelephonySharedPreferences.getString(numberPrefKey, null));
6575 }
6576 return mTelephonySharedPreferences.getString(numberPrefKey, null);
Amit Mahajan9cf11512015-11-09 11:40:48 -08006577 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006578 if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null");
6579 return null;
6580 } finally {
6581 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07006582 }
Derek Tan7226c842014-07-02 17:42:23 -07006583 }
6584
6585 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006586 public String getLine1AlphaTagForDisplay(int subId, String callingPackage,
6587 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006588 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006589 mApp, subId, callingPackage, callingFeatureId, "getLine1AlphaTagForDisplay")) {
Svet Ganovb320e182015-04-16 12:30:10 -07006590 return null;
6591 }
Derek Tan97ebb422014-09-05 16:55:38 -07006592
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006593 final long identity = Binder.clearCallingIdentity();
6594 try {
6595 String iccId = getIccId(subId);
6596 if (iccId != null) {
6597 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
6598 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null);
6599 }
6600 return null;
6601 } finally {
6602 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07006603 }
Derek Tan7226c842014-07-02 17:42:23 -07006604 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07006605
6606 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006607 public String[] getMergedSubscriberIds(int subId, String callingPackage,
6608 String callingFeatureId) {
Jeff Davidson913390f2018-02-23 17:11:49 -08006609 // This API isn't public, so no need to provide a valid subscription ID - we're not worried
6610 // about carrier-privileged callers not having access.
Jeff Davidson7e17e312018-02-13 18:17:36 -08006611 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08006612 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006613 callingFeatureId, "getMergedSubscriberIds")) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07006614 return null;
6615 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08006616
Jordan Liub49b04b2019-05-06 14:45:15 -07006617 // Clear calling identity, when calling TelephonyManager, because callerUid must be
6618 // the process, where TelephonyManager was instantiated.
6619 // Otherwise AppOps check will fail.
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07006620 final long identity = Binder.clearCallingIdentity();
6621 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006622 final Context context = mApp;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006623 final TelephonyManager tele = TelephonyManager.from(context);
6624 final SubscriptionManager sub = SubscriptionManager.from(context);
6625
6626 // Figure out what subscribers are currently active
6627 final ArraySet<String> activeSubscriberIds = new ArraySet<>();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006628
Jordan Liub49b04b2019-05-06 14:45:15 -07006629 // Only consider subs which match the current subId
6630 // This logic can be simplified. See b/131189269 for progress.
6631 if (isActiveSubscription(subId)) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07006632 activeSubscriberIds.add(tele.getSubscriberId(subId));
6633 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006634
6635 // First pass, find a number override for an active subscriber
6636 String mergeNumber = null;
6637 final Map<String, ?> prefs = mTelephonySharedPreferences.getAll();
6638 for (String key : prefs.keySet()) {
6639 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) {
6640 final String subscriberId = (String) prefs.get(key);
6641 if (activeSubscriberIds.contains(subscriberId)) {
6642 final String iccId = key.substring(
6643 PREF_CARRIERS_SUBSCRIBER_PREFIX.length());
6644 final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
6645 mergeNumber = (String) prefs.get(numberKey);
6646 if (DBG_MERGE) {
Amit Mahajanb8f13202020-01-27 18:16:07 -08006647 Rlog.d(LOG_TAG, "Found line number " + mergeNumber
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006648 + " for active subscriber " + subscriberId);
6649 }
6650 if (!TextUtils.isEmpty(mergeNumber)) {
6651 break;
6652 }
6653 }
6654 }
6655 }
6656
6657 // Shortcut when no active merged subscribers
6658 if (TextUtils.isEmpty(mergeNumber)) {
6659 return null;
6660 }
6661
6662 // Second pass, find all subscribers under that line override
6663 final ArraySet<String> result = new ArraySet<>();
6664 for (String key : prefs.keySet()) {
6665 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) {
6666 final String number = (String) prefs.get(key);
6667 if (mergeNumber.equals(number)) {
6668 final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length());
6669 final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
6670 final String subscriberId = (String) prefs.get(subscriberKey);
6671 if (!TextUtils.isEmpty(subscriberId)) {
6672 result.add(subscriberId);
6673 }
6674 }
6675 }
6676 }
6677
6678 final String[] resultArray = result.toArray(new String[result.size()]);
6679 Arrays.sort(resultArray);
6680 if (DBG_MERGE) {
Amit Mahajanb8f13202020-01-27 18:16:07 -08006681 Rlog.d(LOG_TAG,
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006682 "Found subscribers " + Arrays.toString(resultArray) + " after merge");
6683 }
6684 return resultArray;
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07006685 } finally {
6686 Binder.restoreCallingIdentity(identity);
Jeff Sharkey85190e62014-12-05 09:40:12 -08006687 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08006688 }
6689
6690 @Override
zoey chen38003472019-12-13 17:16:31 +08006691 public String[] getMergedImsisFromGroup(int subId, String callingPackage) {
6692 enforceReadPrivilegedPermission("getMergedImsisFromGroup");
Malcolm Chen6ca97372019-07-01 16:28:21 -07006693
6694 final long identity = Binder.clearCallingIdentity();
6695 try {
6696 final TelephonyManager telephonyManager = mApp.getSystemService(
6697 TelephonyManager.class);
6698 String subscriberId = telephonyManager.getSubscriberId(subId);
6699 if (subscriberId == null) {
6700 if (DBG) {
zoey chen38003472019-12-13 17:16:31 +08006701 log("getMergedImsisFromGroup can't find subscriberId for subId "
Malcolm Chen6ca97372019-07-01 16:28:21 -07006702 + subId);
6703 }
6704 return null;
6705 }
6706
6707 final SubscriptionInfo info = SubscriptionController.getInstance()
6708 .getSubscriptionInfo(subId);
6709 final ParcelUuid groupUuid = info.getGroupUuid();
6710 // If it doesn't belong to any group, return just subscriberId of itself.
6711 if (groupUuid == null) {
6712 return new String[]{subscriberId};
6713 }
6714
6715 // Get all subscriberIds from the group.
6716 final List<String> mergedSubscriberIds = new ArrayList<>();
6717 final List<SubscriptionInfo> groupInfos = SubscriptionController.getInstance()
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006718 .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName(),
Philip P. Moltmann8d34f0c2020-03-05 16:24:02 -08006719 mApp.getAttributionTag());
Malcolm Chen6ca97372019-07-01 16:28:21 -07006720 for (SubscriptionInfo subInfo : groupInfos) {
6721 subscriberId = telephonyManager.getSubscriberId(subInfo.getSubscriptionId());
6722 if (subscriberId != null) {
6723 mergedSubscriberIds.add(subscriberId);
6724 }
6725 }
6726
6727 return mergedSubscriberIds.toArray(new String[mergedSubscriberIds.size()]);
6728 } finally {
6729 Binder.restoreCallingIdentity(identity);
6730
6731 }
6732 }
6733
6734 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08006735 public boolean setOperatorBrandOverride(int subId, String brand) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08006736 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
Jeff Davidson7e17e312018-02-13 18:17:36 -08006737 subId, "setOperatorBrandOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006738
6739 final long identity = Binder.clearCallingIdentity();
6740 try {
6741 final Phone phone = getPhone(subId);
6742 return phone == null ? false : phone.setOperatorBrandOverride(brand);
6743 } finally {
6744 Binder.restoreCallingIdentity(identity);
6745 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07006746 }
Steven Liu4bf01bc2014-07-17 11:05:29 -05006747
6748 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08006749 public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
Shishir Agrawal621a47c2014-12-01 10:25:09 -08006750 List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
6751 List<String> cdmaNonRoamingList) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08006752 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
6753 mApp, subId, "setRoamingOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006754
6755 final long identity = Binder.clearCallingIdentity();
6756 try {
6757 final Phone phone = getPhone(subId);
6758 if (phone == null) {
6759 return false;
6760 }
6761 return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList,
6762 cdmaNonRoamingList);
6763 } finally {
6764 Binder.restoreCallingIdentity(identity);
Shishir Agrawalc04d9752016-02-19 10:41:00 -08006765 }
Shishir Agrawal621a47c2014-12-01 10:25:09 -08006766 }
6767
6768 @Override
Shuo Qian850e4d6a2018-04-25 21:02:08 +00006769 @Deprecated
6770 public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
6771 enforceModifyPermission();
6772
6773 int returnValue = 0;
6774 try {
vagdeviaf9a5b92018-08-15 16:01:53 -07006775 AsyncResult result = (AsyncResult) sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
Shuo Qian850e4d6a2018-04-25 21:02:08 +00006776 if(result.exception == null) {
6777 if (result.result != null) {
6778 byte[] responseData = (byte[])(result.result);
6779 if(responseData.length > oemResp.length) {
6780 Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +
6781 responseData.length + "bytes. Buffer Size is " +
6782 oemResp.length + "bytes.");
6783 }
6784 System.arraycopy(responseData, 0, oemResp, 0, responseData.length);
6785 returnValue = responseData.length;
6786 }
6787 } else {
6788 CommandException ex = (CommandException) result.exception;
6789 returnValue = ex.getCommandError().ordinal();
6790 if(returnValue > 0) returnValue *= -1;
6791 }
6792 } catch (RuntimeException e) {
6793 Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");
6794 returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());
6795 if(returnValue > 0) returnValue *= -1;
6796 }
6797
6798 return returnValue;
6799 }
6800
6801 @Override
Wink Saville5d475dd2014-10-17 15:00:58 -07006802 public void setRadioCapability(RadioAccessFamily[] rafs) {
6803 try {
6804 ProxyController.getInstance().setRadioCapability(rafs);
6805 } catch (RuntimeException e) {
6806 Log.w(LOG_TAG, "setRadioCapability: Runtime Exception");
6807 }
6808 }
6809
6810 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07006811 public int getRadioAccessFamily(int phoneId, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08006812 Phone phone = PhoneFactory.getPhone(phoneId);
Shuo Qiandee53402020-05-29 14:08:15 -07006813 try {
6814 TelephonyPermissions
6815 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
6816 mApp, phone.getSubId(), "getRadioAccessFamily");
6817 } catch (SecurityException e) {
6818 EventLog.writeEvent(0x534e4554, "150857259", -1, "Missing Permission");
6819 throw e;
6820 }
chen xub97461a2018-10-26 14:17:57 -07006821 int raf = RadioAccessFamily.RAF_UNKNOWN;
Jeff Davidson913390f2018-02-23 17:11:49 -08006822 if (phone == null) {
chen xub97461a2018-10-26 14:17:57 -07006823 return raf;
Jeff Davidson913390f2018-02-23 17:11:49 -08006824 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006825 final long identity = Binder.clearCallingIdentity();
6826 try {
chen xub97461a2018-10-26 14:17:57 -07006827 TelephonyPermissions
6828 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
6829 mApp, phone.getSubId(), "getRadioAccessFamily");
6830 raf = ProxyController.getInstance().getRadioAccessFamily(phoneId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006831 } finally {
6832 Binder.restoreCallingIdentity(identity);
6833 }
chen xub97461a2018-10-26 14:17:57 -07006834 return raf;
Wink Saville5d475dd2014-10-17 15:00:58 -07006835 }
Andrew Leedf14ead2014-10-17 14:22:52 -07006836
6837 @Override
6838 public void enableVideoCalling(boolean enable) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006839 final Phone defaultPhone = getDefaultPhone();
Andrew Leedf14ead2014-10-17 14:22:52 -07006840 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006841
6842 final long identity = Binder.clearCallingIdentity();
6843 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006844 ImsManager.getInstance(defaultPhone.getContext(),
6845 defaultPhone.getPhoneId()).setVtSetting(enable);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006846 } finally {
6847 Binder.restoreCallingIdentity(identity);
6848 }
Andrew Leedf14ead2014-10-17 14:22:52 -07006849 }
6850
6851 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006852 public boolean isVideoCallingEnabled(String callingPackage, String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006853 final Phone defaultPhone = getDefaultPhone();
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006854 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
6855 callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
Amit Mahajan578e53d2018-03-20 16:18:38 +00006856 return false;
6857 }
Svet Ganovb320e182015-04-16 12:30:10 -07006858
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006859 final long identity = Binder.clearCallingIdentity();
6860 try {
6861 // Check the user preference and the system-level IMS setting. Even if the user has
6862 // enabled video calling, if IMS is disabled we aren't able to support video calling.
6863 // In the long run, we may instead need to check if there exists a connection service
6864 // which can support video calling.
6865 ImsManager imsManager =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006866 ImsManager.getInstance(defaultPhone.getContext(), defaultPhone.getPhoneId());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006867 return imsManager.isVtEnabledByPlatform()
6868 && imsManager.isEnhanced4gLteModeSettingEnabledByUser()
6869 && imsManager.isVtEnabledByUser();
6870 } finally {
6871 Binder.restoreCallingIdentity(identity);
6872 }
Andrew Leedf14ead2014-10-17 14:22:52 -07006873 }
Libin.Tang@motorola.comafe82642014-12-18 13:27:53 -06006874
Andrew Leea1239f22015-03-02 17:44:07 -08006875 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006876 public boolean canChangeDtmfToneLength(int subId, String callingPackage,
6877 String callingFeatureId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006878 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006879 mApp, subId, callingPackage, callingFeatureId,
6880 "isVideoCallingEnabled")) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006881 return false;
6882 }
6883
6884 final long identity = Binder.clearCallingIdentity();
6885 try {
6886 CarrierConfigManager configManager =
6887 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006888 return configManager.getConfigForSubId(subId)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006889 .getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL);
6890 } finally {
6891 Binder.restoreCallingIdentity(identity);
6892 }
Andrew Leea1239f22015-03-02 17:44:07 -08006893 }
6894
6895 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006896 public boolean isWorldPhone(int subId, String callingPackage, String callingFeatureId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006897 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006898 mApp, subId, callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006899 return false;
6900 }
6901
6902 final long identity = Binder.clearCallingIdentity();
6903 try {
6904 CarrierConfigManager configManager =
6905 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006906 return configManager.getConfigForSubId(subId)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006907 .getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL);
6908 } finally {
6909 Binder.restoreCallingIdentity(identity);
6910 }
Andrew Leea1239f22015-03-02 17:44:07 -08006911 }
6912
Andrew Lee9431b832015-03-09 18:46:45 -07006913 @Override
6914 public boolean isTtyModeSupported() {
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07006915 TelecomManager telecomManager = mApp.getSystemService(TelecomManager.class);
Wooki Wu1f82f7a2016-02-15 15:59:58 +08006916 return telecomManager.isTtySupported();
Andrew Lee9431b832015-03-09 18:46:45 -07006917 }
6918
6919 @Override
6920 public boolean isHearingAidCompatibilitySupported() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006921 final long identity = Binder.clearCallingIdentity();
6922 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006923 return mApp.getResources().getBoolean(R.bool.hac_enabled);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006924 } finally {
6925 Binder.restoreCallingIdentity(identity);
6926 }
Andrew Lee9431b832015-03-09 18:46:45 -07006927 }
6928
Hall Liuf6668912018-10-31 17:05:23 -07006929 /**
6930 * Determines whether the device currently supports RTT (Real-time text). Based both on carrier
6931 * support for the feature and device firmware support.
6932 *
6933 * @return {@code true} if the device and carrier both support RTT, {@code false} otherwise.
6934 */
6935 @Override
6936 public boolean isRttSupported(int subscriptionId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006937 final long identity = Binder.clearCallingIdentity();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006938 final Phone phone = getPhone(subscriptionId);
6939 if (phone == null) {
6940 loge("isRttSupported: no Phone found. Invalid subId:" + subscriptionId);
6941 return false;
6942 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006943 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006944 boolean isCarrierSupported = mApp.getCarrierConfigForSubId(subscriptionId).getBoolean(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006945 CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
6946 boolean isDeviceSupported =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006947 phone.getContext().getResources().getBoolean(R.bool.config_support_rtt);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006948 return isCarrierSupported && isDeviceSupported;
6949 } finally {
6950 Binder.restoreCallingIdentity(identity);
6951 }
Hall Liu98187582018-01-22 19:15:32 -08006952 }
6953
Hall Liuf6668912018-10-31 17:05:23 -07006954 /**
Hall Liuf2daa022019-07-23 18:39:00 -07006955 * Determines whether the user has turned on RTT. If the carrier wants to ignore the user-set
6956 * RTT setting, will return true if the device and carrier both support RTT.
6957 * Otherwise. only returns true if the device and carrier both also support RTT.
Hall Liuf6668912018-10-31 17:05:23 -07006958 */
6959 public boolean isRttEnabled(int subscriptionId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006960 final long identity = Binder.clearCallingIdentity();
6961 try {
Hall Liu5bab75c2019-12-11 23:58:20 +00006962 boolean isRttSupported = isRttSupported(subscriptionId);
6963 boolean isUserRttSettingOn = Settings.Secure.getInt(
6964 mApp.getContentResolver(), Settings.Secure.RTT_CALLING_MODE, 0) != 0;
6965 boolean shouldIgnoreUserRttSetting = mApp.getCarrierConfigForSubId(subscriptionId)
6966 .getBoolean(CarrierConfigManager.KEY_IGNORE_RTT_MODE_SETTING_BOOL);
6967 return isRttSupported && (isUserRttSettingOn || shouldIgnoreUserRttSetting);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006968 } finally {
6969 Binder.restoreCallingIdentity(identity);
6970 }
Hall Liu3ad5f012018-04-06 16:23:39 -07006971 }
6972
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006973 @Deprecated
6974 @Override
6975 public String getDeviceId(String callingPackage) {
6976 return getDeviceIdWithFeature(callingPackage, null);
6977 }
6978
Sanket Padawe7310cc72015-01-14 09:53:20 -08006979 /**
6980 * Returns the unique device ID of phone, for example, the IMEI for
6981 * GSM and the MEID for CDMA phones. Return null if device ID is not available.
6982 *
6983 * <p>Requires Permission:
6984 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
6985 */
6986 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006987 public String getDeviceIdWithFeature(String callingPackage, String callingFeatureId) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08006988 final Phone phone = PhoneFactory.getPhone(0);
Jeff Davidson913390f2018-02-23 17:11:49 -08006989 if (phone == null) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08006990 return null;
6991 }
Jeff Davidson913390f2018-02-23 17:11:49 -08006992 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07006993 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006994 callingPackage, callingFeatureId, "getDeviceId")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08006995 return null;
6996 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006997
6998 final long identity = Binder.clearCallingIdentity();
6999 try {
7000 return phone.getDeviceId();
7001 } finally {
7002 Binder.restoreCallingIdentity(identity);
7003 }
Sanket Padawe7310cc72015-01-14 09:53:20 -08007004 }
7005
Ping Sunc67b7c22016-03-02 19:16:45 +08007006 /**
7007 * {@hide}
7008 * Returns the IMS Registration Status on a particular subid
7009 *
7010 * @param subId
7011 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007012 public boolean isImsRegistered(int subId) {
Ping Sunc67b7c22016-03-02 19:16:45 +08007013 Phone phone = getPhone(subId);
7014 if (phone != null) {
7015 return phone.isImsRegistered();
7016 } else {
7017 return false;
7018 }
7019 }
7020
Santos Cordon7a1885b2015-02-03 11:15:19 -08007021 @Override
7022 public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007023 final long identity = Binder.clearCallingIdentity();
7024 try {
7025 return PhoneUtils.getSubIdForPhoneAccount(phoneAccount);
7026 } finally {
7027 Binder.restoreCallingIdentity(identity);
7028 }
Santos Cordon7a1885b2015-02-03 11:15:19 -08007029 }
Nathan Harolddcfc7932015-03-18 10:01:20 -07007030
Tyler Gunnf70ed162019-04-03 15:28:53 -07007031 @Override
Shuo Qian6e6137d2019-10-30 16:33:31 -07007032 public int getSubIdForPhoneAccountHandle(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007033 PhoneAccountHandle phoneAccountHandle, String callingPackage, String callingFeatureId) {
Shuo Qian6e6137d2019-10-30 16:33:31 -07007034 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, getDefaultSubscription(),
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007035 callingPackage, callingFeatureId, "getSubIdForPhoneAccountHandle")) {
Shuo Qian6e6137d2019-10-30 16:33:31 -07007036 throw new SecurityException("Requires READ_PHONE_STATE permission.");
7037 }
7038 final long identity = Binder.clearCallingIdentity();
7039 try {
7040 return PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle);
7041 } finally {
7042 Binder.restoreCallingIdentity(identity);
7043 }
7044 }
7045
7046 @Override
Tyler Gunnf70ed162019-04-03 15:28:53 -07007047 public @Nullable PhoneAccountHandle getPhoneAccountHandleForSubscriptionId(int subscriptionId) {
duki.hongfd96bde2020-07-22 17:32:19 +09007048 enforceReadPrivilegedPermission("getPhoneAccountHandleForSubscriptionId, "
7049 + "subscriptionId: " + subscriptionId);
Tyler Gunnf70ed162019-04-03 15:28:53 -07007050 final long identity = Binder.clearCallingIdentity();
7051 try {
7052 Phone phone = getPhone(subscriptionId);
7053 if (phone == null) {
7054 return null;
7055 }
7056 return PhoneUtils.makePstnPhoneAccountHandle(phone);
7057 } finally {
7058 Binder.restoreCallingIdentity(identity);
7059 }
7060 }
7061
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007062 /**
7063 * @return the VoWiFi calling availability.
Nathan Haroldc55097a2015-03-11 18:14:50 -07007064 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007065 public boolean isWifiCallingAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007066 final long identity = Binder.clearCallingIdentity();
7067 try {
7068 Phone phone = getPhone(subId);
7069 if (phone != null) {
7070 return phone.isWifiCallingEnabled();
7071 } else {
7072 return false;
7073 }
7074 } finally {
7075 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007076 }
Nathan Haroldc55097a2015-03-11 18:14:50 -07007077 }
7078
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007079 /**
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007080 * @return the VT calling availability.
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07007081 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007082 public boolean isVideoTelephonyAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007083 final long identity = Binder.clearCallingIdentity();
7084 try {
7085 Phone phone = getPhone(subId);
7086 if (phone != null) {
7087 return phone.isVideoEnabled();
7088 } else {
7089 return false;
7090 }
7091 } finally {
7092 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007093 }
7094 }
7095
7096 /**
7097 * @return the IMS registration technology for the MMTEL feature. Valid return values are
7098 * defined in {@link ImsRegistrationImplBase}.
7099 */
7100 public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007101 final long identity = Binder.clearCallingIdentity();
7102 try {
7103 Phone phone = getPhone(subId);
7104 if (phone != null) {
7105 return phone.getImsRegistrationTech();
7106 } else {
7107 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
7108 }
7109 } finally {
7110 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007111 }
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07007112 }
7113
Stuart Scott8eef64f2015-04-08 15:13:54 -07007114 @Override
7115 public void factoryReset(int subId) {
paulhu5a773602019-08-23 19:17:33 +08007116 enforceSettingsPermission();
Stuart Scott981d8582015-04-21 14:09:50 -07007117 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
7118 return;
7119 }
7120
Svet Ganovcc087f82015-05-12 20:35:54 -07007121 final long identity = Binder.clearCallingIdentity();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007122
Svet Ganovcc087f82015-05-12 20:35:54 -07007123 try {
Stuart Scott981d8582015-04-21 14:09:50 -07007124 if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
7125 UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07007126 setDataEnabledForReason(subId, TelephonyManager.DATA_ENABLED_REASON_USER,
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007127 getDefaultDataEnabled());
Svet Ganovcc087f82015-05-12 20:35:54 -07007128 setNetworkSelectionModeAutomatic(subId);
Pengquan Meng85728fb2018-03-12 16:31:21 -07007129 setPreferredNetworkType(subId, getDefaultNetworkType(subId));
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007130 setDataRoamingEnabled(subId, getDefaultDataRoamingEnabled(subId));
7131 CarrierInfoManager.deleteAllCarrierKeysForImsiEncryption(mApp);
Svet Ganovcc087f82015-05-12 20:35:54 -07007132 }
Amit Mahajan7dbbd822019-03-13 17:33:47 -07007133 // There has been issues when Sms raw table somehow stores orphan
7134 // fragments. They lead to garbled message when new fragments come
7135 // in and combined with those stale ones. In case this happens again,
7136 // user can reset all network settings which will clean up this table.
7137 cleanUpSmsRawTable(getDefaultPhone().getContext());
Brad Ebingerbc7dd582019-10-17 17:03:22 -07007138 // Clean up IMS settings as well here.
7139 int slotId = getSlotIndex(subId);
7140 if (slotId > SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
7141 ImsManager.getInstance(mApp, slotId).factoryReset();
7142 }
Naina Nallurid63128d2019-09-17 14:10:30 -07007143
7144 // Erase modem config if erase modem on network setting is enabled.
7145 String configValue = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_TELEPHONY,
7146 RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED);
7147 if (configValue != null && Boolean.parseBoolean(configValue)) {
7148 sendEraseModemConfig(getDefaultPhone());
7149 }
Svet Ganovcc087f82015-05-12 20:35:54 -07007150 } finally {
7151 Binder.restoreCallingIdentity(identity);
Stuart Scott8eef64f2015-04-08 15:13:54 -07007152 }
7153 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01007154
Amit Mahajan7dbbd822019-03-13 17:33:47 -07007155 private void cleanUpSmsRawTable(Context context) {
7156 ContentResolver resolver = context.getContentResolver();
7157 Uri uri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete");
7158 resolver.delete(uri, null, null);
7159 }
7160
Narayan Kamath1c496c22015-04-16 14:40:19 +01007161 @Override
chen xu5d3637b2019-01-21 23:31:38 -08007162 public String getSimLocaleForSubscriber(int subId) {
7163 enforceReadPrivilegedPermission("getSimLocaleForSubscriber, subId: " + subId);
7164 final Phone phone = getPhone(subId);
7165 if (phone == null) {
7166 log("getSimLocaleForSubscriber, invalid subId");
chen xu2bb91e42019-01-24 14:35:54 -08007167 return null;
chen xu5d3637b2019-01-21 23:31:38 -08007168 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007169 final long identity = Binder.clearCallingIdentity();
7170 try {
chen xu5d3637b2019-01-21 23:31:38 -08007171 final SubscriptionInfo info = mSubscriptionController.getActiveSubscriptionInfo(subId,
Philip P. Moltmann8d34f0c2020-03-05 16:24:02 -08007172 phone.getContext().getOpPackageName(), phone.getContext().getAttributionTag());
chen xu6291c472019-02-04 12:55:53 -08007173 if (info == null) {
7174 log("getSimLocaleForSubscriber, inactive subId: " + subId);
7175 return null;
7176 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007177 // Try and fetch the locale from the carrier properties or from the SIM language
7178 // preferences (EF-PL and EF-LI)...
7179 final int mcc = info.getMcc();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007180 String simLanguage = null;
chen xu5d3637b2019-01-21 23:31:38 -08007181 final Locale localeFromDefaultSim = phone.getLocaleFromSimAndCarrierPrefs();
7182 if (localeFromDefaultSim != null) {
7183 if (!localeFromDefaultSim.getCountry().isEmpty()) {
7184 if (DBG) log("Using locale from subId: " + subId + " locale: "
7185 + localeFromDefaultSim);
7186 return localeFromDefaultSim.toLanguageTag();
7187 } else {
7188 simLanguage = localeFromDefaultSim.getLanguage();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007189 }
7190 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01007191
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007192 // The SIM language preferences only store a language (e.g. fr = French), not an
7193 // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
7194 // the SIM and carrier preferences does not include a country we add the country
7195 // determined from the SIM MCC to provide an exact locale.
zoey chenc730df82019-12-18 17:07:20 +08007196 final Locale mccLocale = LocaleUtils.getLocaleFromMcc(mApp, mcc, simLanguage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007197 if (mccLocale != null) {
chen xu5d3637b2019-01-21 23:31:38 -08007198 if (DBG) log("No locale from SIM, using mcc locale:" + mccLocale);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007199 return mccLocale.toLanguageTag();
7200 }
7201
7202 if (DBG) log("No locale found - returning null");
7203 return null;
7204 } finally {
7205 Binder.restoreCallingIdentity(identity);
7206 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01007207 }
7208
7209 private List<SubscriptionInfo> getAllSubscriptionInfoList() {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007210 return mSubscriptionController.getAllSubInfoList(mApp.getOpPackageName(),
Philip P. Moltmann8d34f0c2020-03-05 16:24:02 -08007211 mApp.getAttributionTag());
Narayan Kamath1c496c22015-04-16 14:40:19 +01007212 }
7213
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007214 /**
7215 * NOTE: this method assumes permission checks are done and caller identity has been cleared.
7216 */
7217 private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007218 return mSubscriptionController.getActiveSubscriptionInfoList(mApp.getOpPackageName(),
Philip P. Moltmann8d34f0c2020-03-05 16:24:02 -08007219 mApp.getAttributionTag());
Narayan Kamath1c496c22015-04-16 14:40:19 +01007220 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07007221
Chenjie Yu1ba97252018-01-11 18:16:20 -08007222 private final ModemActivityInfo mLastModemActivityInfo =
Hall Liu49656c02020-10-09 19:00:11 -07007223 new ModemActivityInfo(0, 0, 0, new int[ModemActivityInfo.getNumTxPowerLevels()], 0);
Chenjie Yu1ba97252018-01-11 18:16:20 -08007224
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07007225 /**
Adam Lesinski903a54c2016-04-11 14:49:52 -07007226 * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
7227 * representing the state of the modem.
7228 *
Chenjie Yu1ba97252018-01-11 18:16:20 -08007229 * NOTE: The underlying implementation clears the modem state, so there should only ever be one
7230 * caller to it. Everyone should call this class to get cumulative data.
Adam Lesinski903a54c2016-04-11 14:49:52 -07007231 * @hide
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07007232 */
7233 @Override
Adam Lesinski903a54c2016-04-11 14:49:52 -07007234 public void requestModemActivityInfo(ResultReceiver result) {
7235 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07007236 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007237
7238 final long identity = Binder.clearCallingIdentity();
7239 try {
Shuo Qian8f4750a2020-02-20 17:12:10 -08007240 sendRequestAsync(CMD_GET_MODEM_ACTIVITY_INFO, result, null, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007241 } finally {
7242 Binder.restoreCallingIdentity(identity);
Chenjie Yu1ba97252018-01-11 18:16:20 -08007243 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07007244 }
Jack Yu85bd38a2015-11-09 11:34:32 -08007245
Siddharth Rayb8114062018-06-17 15:02:38 -07007246 // Checks that ModemActivityInfo is valid. Sleep time, Idle time, Rx time and Tx time should be
7247 // less than total activity duration.
7248 private boolean isModemActivityInfoValid(ModemActivityInfo info) {
7249 if (info == null) {
7250 return false;
7251 }
7252 int activityDurationMs =
Hall Liu49656c02020-10-09 19:00:11 -07007253 (int) (info.getTimestampMillis() - mLastModemActivityInfo.getTimestampMillis());
7254 int totalTxTimeMs = Arrays.stream(info.getTransmitTimeMillis()).sum();
7255
Siddharth Rayb8114062018-06-17 15:02:38 -07007256 return (info.isValid()
7257 && (info.getSleepTimeMillis() <= activityDurationMs)
7258 && (info.getIdleTimeMillis() <= activityDurationMs)
Chen Xud78231e2019-09-10 18:49:52 -07007259 && (info.getReceiveTimeMillis() <= activityDurationMs)
Siddharth Rayb8114062018-06-17 15:02:38 -07007260 && (totalTxTimeMs <= activityDurationMs));
7261 }
7262
Jack Yu85bd38a2015-11-09 11:34:32 -08007263 /**
7264 * {@hide}
7265 * Returns the service state information on specified subscription.
7266 */
7267 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07007268 public ServiceState getServiceStateForSubscriber(int subId, String callingPackage,
7269 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08007270 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007271 mApp, subId, callingPackage, callingFeatureId, "getServiceStateForSubscriber")) {
Jack Yu85bd38a2015-11-09 11:34:32 -08007272 return null;
7273 }
7274
Hall Liuf19c44f2018-11-27 14:38:17 -08007275 LocationAccessPolicy.LocationPermissionResult fineLocationResult =
7276 LocationAccessPolicy.checkLocationPermission(mApp,
7277 new LocationAccessPolicy.LocationPermissionQuery.Builder()
7278 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07007279 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08007280 .setCallingPid(Binder.getCallingPid())
7281 .setCallingUid(Binder.getCallingUid())
7282 .setMethod("getServiceStateForSubscriber")
Hall Liuf18a0cf2019-04-17 13:37:11 -07007283 .setLogAsInfo(true)
Hall Liuf19c44f2018-11-27 14:38:17 -08007284 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
Hall Liuc4a3e422020-05-26 17:18:03 -07007285 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
7286 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
Hall Liuf19c44f2018-11-27 14:38:17 -08007287 .build());
7288
7289 LocationAccessPolicy.LocationPermissionResult coarseLocationResult =
7290 LocationAccessPolicy.checkLocationPermission(mApp,
7291 new LocationAccessPolicy.LocationPermissionQuery.Builder()
7292 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07007293 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08007294 .setCallingPid(Binder.getCallingPid())
7295 .setCallingUid(Binder.getCallingUid())
7296 .setMethod("getServiceStateForSubscriber")
Hall Liuf18a0cf2019-04-17 13:37:11 -07007297 .setLogAsInfo(true)
Hall Liuf19c44f2018-11-27 14:38:17 -08007298 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
Hall Liuc4a3e422020-05-26 17:18:03 -07007299 .setMinSdkVersionForFine(Integer.MAX_VALUE)
7300 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
Hall Liuf19c44f2018-11-27 14:38:17 -08007301 .build());
7302 // We don't care about hard or soft here -- all we need to know is how much info to scrub.
7303 boolean hasFinePermission =
7304 fineLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
7305 boolean hasCoarsePermission =
7306 coarseLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
7307
Jack Yu479f40e2020-10-27 21:29:25 -07007308 final Phone phone = getPhone(subId);
7309 if (phone == null) {
7310 return null;
7311 }
7312
Jordan Liu0f2bc442020-11-18 16:47:37 -08007313 final long identity = Binder.clearCallingIdentity();
7314
Jack Yu479f40e2020-10-27 21:29:25 -07007315 boolean isCallingPackageDataService = phone.getDataServicePackages()
7316 .contains(callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007317 try {
Jordan Liuc437b192020-08-17 10:59:12 -07007318 // isActiveSubId requires READ_PHONE_STATE, which we already check for above
7319 if (!mSubscriptionController.isActiveSubId(subId, callingPackage, callingFeatureId)) {
7320 Rlog.d(LOG_TAG,
7321 "getServiceStateForSubscriber returning null for inactive subId=" + subId);
7322 return null;
7323 }
7324
Hall Liuf19c44f2018-11-27 14:38:17 -08007325 ServiceState ss = phone.getServiceState();
7326
7327 // Scrub out the location info in ServiceState depending on what level of access
7328 // the caller has.
Jack Yu479f40e2020-10-27 21:29:25 -07007329 if (hasFinePermission || isCallingPackageDataService) return ss;
Malcolm Chen5052de62019-12-30 13:56:38 -08007330 if (hasCoarsePermission) return ss.createLocationInfoSanitizedCopy(false);
7331 return ss.createLocationInfoSanitizedCopy(true);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007332 } finally {
7333 Binder.restoreCallingIdentity(identity);
7334 }
Jack Yu85bd38a2015-11-09 11:34:32 -08007335 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08007336
7337 /**
7338 * Returns the URI for the per-account voicemail ringtone set in Phone settings.
7339 *
7340 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
7341 * voicemail ringtone.
7342 * @return The URI for the ringtone to play when receiving a voicemail from a specific
7343 * PhoneAccount.
7344 */
7345 @Override
7346 public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007347 final long identity = Binder.clearCallingIdentity();
7348 try {
7349 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
7350 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007351 phone = getDefaultPhone();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007352 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08007353
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007354 return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext());
7355 } finally {
7356 Binder.restoreCallingIdentity(identity);
7357 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08007358 }
7359
7360 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08007361 * Sets the per-account voicemail ringtone.
7362 *
7363 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
7364 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
7365 *
7366 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
7367 * voicemail ringtone.
7368 * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
7369 * PhoneAccount.
7370 */
7371 @Override
7372 public void setVoicemailRingtoneUri(String callingPackage,
7373 PhoneAccountHandle phoneAccountHandle, Uri uri) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007374 final Phone defaultPhone = getDefaultPhone();
Ta-wei Yenc33877d2017-01-23 18:11:21 -08007375 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07007376 TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
7377 if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08007378 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7379 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
7380 "setVoicemailRingtoneUri");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08007381 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007382
7383 final long identity = Binder.clearCallingIdentity();
7384 try {
7385 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
7386 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007387 phone = defaultPhone;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007388 }
7389 VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri);
7390 } finally {
7391 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08007392 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08007393 }
7394
7395 /**
Nancy Chen31f9ba12016-01-06 11:42:12 -08007396 * Returns whether vibration is set for voicemail notification in Phone settings.
7397 *
7398 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
7399 * voicemail vibration setting.
7400 * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
7401 */
7402 @Override
7403 public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007404 final long identity = Binder.clearCallingIdentity();
7405 try {
7406 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
7407 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007408 phone = getDefaultPhone();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007409 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08007410
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007411 return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext());
7412 } finally {
7413 Binder.restoreCallingIdentity(identity);
7414 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08007415 }
7416
Youhan Wange64578a2016-05-02 15:32:42 -07007417 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08007418 * Sets the per-account voicemail vibration.
7419 *
7420 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
7421 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
7422 *
7423 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
7424 * voicemail vibration setting.
7425 * @param enabled Whether to enable or disable vibration for voicemail notifications from a
7426 * specific PhoneAccount.
7427 */
7428 @Override
7429 public void setVoicemailVibrationEnabled(String callingPackage,
7430 PhoneAccountHandle phoneAccountHandle, boolean enabled) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007431 final Phone defaultPhone = getDefaultPhone();
Ta-wei Yenc33877d2017-01-23 18:11:21 -08007432 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07007433 TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
7434 if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08007435 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7436 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
7437 "setVoicemailVibrationEnabled");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08007438 }
7439
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007440 final long identity = Binder.clearCallingIdentity();
7441 try {
7442 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
7443 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007444 phone = defaultPhone;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007445 }
7446 VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled);
7447 } finally {
7448 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08007449 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08007450 }
7451
7452 /**
Youhan Wange64578a2016-05-02 15:32:42 -07007453 * Make sure either called from same process as self (phone) or IPC caller has read privilege.
7454 *
7455 * @throws SecurityException if the caller does not have the required permission
7456 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07007457 private void enforceReadPrivilegedPermission(String message) {
Youhan Wange64578a2016-05-02 15:32:42 -07007458 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
Brad Ebinger35c841c2018-10-01 10:40:55 -07007459 message);
Youhan Wange64578a2016-05-02 15:32:42 -07007460 }
7461
7462 /**
Ta-wei Yen30a69c82016-12-27 14:52:32 -08007463 * Make sure either called from same process as self (phone) or IPC caller has send SMS
7464 * permission.
7465 *
7466 * @throws SecurityException if the caller does not have the required permission
7467 */
7468 private void enforceSendSmsPermission() {
7469 mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null);
7470 }
7471
7472 /**
Ta-wei Yen527a9c02017-01-06 15:29:25 -08007473 * Make sure called from the package in charge of visual voicemail.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08007474 *
Ta-wei Yen527a9c02017-01-06 15:29:25 -08007475 * @throws SecurityException if the caller is not the visual voicemail package.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08007476 */
Ta-wei Yen527a9c02017-01-06 15:29:25 -08007477 private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007478 final long identity = Binder.clearCallingIdentity();
7479 try {
7480 ComponentName componentName =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007481 RemoteVvmTaskManager.getRemotePackage(mApp, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007482 if (componentName == null) {
7483 throw new SecurityException(
7484 "Caller not current active visual voicemail package[null]");
7485 }
7486 String vvmPackage = componentName.getPackageName();
7487 if (!callingPackage.equals(vvmPackage)) {
7488 throw new SecurityException("Caller not current active visual voicemail package["
7489 + vvmPackage + "]");
7490 }
7491 } finally {
7492 Binder.restoreCallingIdentity(identity);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08007493 }
7494 }
7495
7496 /**
Youhan Wange64578a2016-05-02 15:32:42 -07007497 * Return the application ID for the app type.
7498 *
7499 * @param subId the subscription ID that this request applies to.
7500 * @param appType the uicc app type.
7501 * @return Application ID for specificied app type, or null if no uicc.
7502 */
7503 @Override
7504 public String getAidForAppType(int subId, int appType) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07007505 enforceReadPrivilegedPermission("getAidForAppType");
Youhan Wange64578a2016-05-02 15:32:42 -07007506 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007507
7508 final long identity = Binder.clearCallingIdentity();
Youhan Wange64578a2016-05-02 15:32:42 -07007509 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007510 if (phone == null) {
7511 return null;
7512 }
7513 String aid = null;
7514 try {
7515 aid = UiccController.getInstance().getUiccCard(phone.getPhoneId())
7516 .getApplicationByType(appType).getAid();
7517 } catch (Exception e) {
7518 Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e);
7519 }
7520 return aid;
7521 } finally {
7522 Binder.restoreCallingIdentity(identity);
Youhan Wange64578a2016-05-02 15:32:42 -07007523 }
Youhan Wange64578a2016-05-02 15:32:42 -07007524 }
7525
Youhan Wang4001d252016-05-11 10:29:41 -07007526 /**
7527 * Return the Electronic Serial Number.
7528 *
7529 * @param subId the subscription ID that this request applies to.
7530 * @return ESN or null if error.
7531 */
7532 @Override
7533 public String getEsn(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07007534 enforceReadPrivilegedPermission("getEsn");
Youhan Wang4001d252016-05-11 10:29:41 -07007535 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007536
7537 final long identity = Binder.clearCallingIdentity();
Youhan Wang4001d252016-05-11 10:29:41 -07007538 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007539 if (phone == null) {
7540 return null;
7541 }
7542 String esn = null;
7543 try {
7544 esn = phone.getEsn();
7545 } catch (Exception e) {
7546 Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e);
7547 }
7548 return esn;
7549 } finally {
7550 Binder.restoreCallingIdentity(identity);
Youhan Wang4001d252016-05-11 10:29:41 -07007551 }
Youhan Wang4001d252016-05-11 10:29:41 -07007552 }
7553
Sanket Padawe99ef1e32016-05-18 16:12:33 -07007554 /**
Youhan Wang66ad5d72016-07-18 17:56:58 -07007555 * Return the Preferred Roaming List Version.
7556 *
7557 * @param subId the subscription ID that this request applies to.
7558 * @return PRLVersion or null if error.
7559 */
7560 @Override
7561 public String getCdmaPrlVersion(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07007562 enforceReadPrivilegedPermission("getCdmaPrlVersion");
Youhan Wang66ad5d72016-07-18 17:56:58 -07007563 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007564
7565 final long identity = Binder.clearCallingIdentity();
Youhan Wang66ad5d72016-07-18 17:56:58 -07007566 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007567 if (phone == null) {
7568 return null;
7569 }
7570 String cdmaPrlVersion = null;
7571 try {
7572 cdmaPrlVersion = phone.getCdmaPrlVersion();
7573 } catch (Exception e) {
7574 Log.e(LOG_TAG, "Not getting PRLVersion", e);
7575 }
7576 return cdmaPrlVersion;
7577 } finally {
7578 Binder.restoreCallingIdentity(identity);
Youhan Wang66ad5d72016-07-18 17:56:58 -07007579 }
Youhan Wang66ad5d72016-07-18 17:56:58 -07007580 }
7581
7582 /**
Sanket Padawe99ef1e32016-05-18 16:12:33 -07007583 * Get snapshot of Telephony histograms
7584 * @return List of Telephony histograms
7585 * @hide
7586 */
7587 @Override
7588 public List<TelephonyHistogram> getTelephonyHistograms() {
Jeff Davidson7e17e312018-02-13 18:17:36 -08007589 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7590 mApp, getDefaultSubscription(), "getTelephonyHistograms");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007591
7592 final long identity = Binder.clearCallingIdentity();
7593 try {
7594 return RIL.getTelephonyRILTimingHistograms();
7595 } finally {
7596 Binder.restoreCallingIdentity(identity);
7597 }
Sanket Padawe99ef1e32016-05-18 16:12:33 -07007598 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07007599
7600 /**
7601 * {@hide}
Michele Berionne482f8202018-11-27 18:57:59 -08007602 * Set the allowed carrier list and the excluded carrier list, indicating the priority between
7603 * the two lists.
Meng Wang1a7c35a2016-05-05 20:56:15 -07007604 * Require system privileges. In the future we may add this to carrier APIs.
7605 *
Michele Berionne482f8202018-11-27 18:57:59 -08007606 * @return Integer with the result of the operation, as defined in {@link TelephonyManager}.
Meng Wang1a7c35a2016-05-05 20:56:15 -07007607 */
7608 @Override
Michele Berionne482f8202018-11-27 18:57:59 -08007609 @TelephonyManager.SetCarrierRestrictionResult
7610 public int setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules) {
Meng Wang1a7c35a2016-05-05 20:56:15 -07007611 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07007612 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Sanket Padawe13bac7b2017-03-20 15:04:47 -07007613
Michele Berionne482f8202018-11-27 18:57:59 -08007614 if (carrierRestrictionRules == null) {
7615 throw new NullPointerException("carrier restriction cannot be null");
Meng Wang9b7c4e92017-02-17 11:41:27 -08007616 }
Sanket Padawe13bac7b2017-03-20 15:04:47 -07007617
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007618 final long identity = Binder.clearCallingIdentity();
7619 try {
Michele Berionne482f8202018-11-27 18:57:59 -08007620 return (int) sendRequest(CMD_SET_ALLOWED_CARRIERS, carrierRestrictionRules,
vagdeviaf9a5b92018-08-15 16:01:53 -07007621 workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007622 } finally {
7623 Binder.restoreCallingIdentity(identity);
7624 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07007625 }
7626
7627 /**
7628 * {@hide}
Michele Berionne482f8202018-11-27 18:57:59 -08007629 * Get the allowed carrier list and the excluded carrier list, including the priority between
7630 * the two lists.
Meng Wang1a7c35a2016-05-05 20:56:15 -07007631 * Require system privileges. In the future we may add this to carrier APIs.
7632 *
Michele Berionne482f8202018-11-27 18:57:59 -08007633 * @return {@link android.telephony.CarrierRestrictionRules}
Meng Wang1a7c35a2016-05-05 20:56:15 -07007634 */
7635 @Override
Michele Berionne482f8202018-11-27 18:57:59 -08007636 public CarrierRestrictionRules getAllowedCarriers() {
Brad Ebinger35c841c2018-10-01 10:40:55 -07007637 enforceReadPrivilegedPermission("getAllowedCarriers");
vagdeviaf9a5b92018-08-15 16:01:53 -07007638 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007639
7640 final long identity = Binder.clearCallingIdentity();
7641 try {
Michele Berionne482f8202018-11-27 18:57:59 -08007642 Object response = sendRequest(CMD_GET_ALLOWED_CARRIERS, null, workSource);
7643 if (response instanceof CarrierRestrictionRules) {
7644 return (CarrierRestrictionRules) response;
7645 }
7646 // Response is an Exception of some kind,
7647 // which is signalled to the user as a NULL retval
7648 return null;
7649 } catch (Exception e) {
7650 Log.e(LOG_TAG, "getAllowedCarriers. Exception ex=" + e);
7651 return null;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007652 } finally {
7653 Binder.restoreCallingIdentity(identity);
7654 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07007655 }
7656
fionaxu59545b42016-05-25 15:53:37 -07007657 /**
fionaxu59545b42016-05-25 15:53:37 -07007658 * Action set from carrier signalling broadcast receivers to enable/disable radio
7659 * @param subId the subscription ID that this action applies to.
7660 * @param enabled control enable or disable radio.
7661 * {@hide}
7662 */
7663 @Override
7664 public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
7665 enforceModifyPermission();
7666 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007667
7668 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07007669 if (phone == null) {
7670 loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
7671 return;
7672 }
7673 try {
7674 phone.carrierActionSetRadioEnabled(enabled);
7675 } catch (Exception e) {
7676 Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007677 } finally {
7678 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07007679 }
7680 }
7681
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07007682 /**
fionaxu8da9cb12017-05-23 15:02:46 -07007683 * Action set from carrier signalling broadcast receivers to start/stop reporting the default
7684 * network status based on which carrier apps could apply actions accordingly,
7685 * enable/disable default url handler for example.
7686 *
7687 * @param subId the subscription ID that this action applies to.
7688 * @param report control start/stop reporting the default network status.
7689 * {@hide}
7690 */
7691 @Override
7692 public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
7693 enforceModifyPermission();
7694 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007695
7696 final long identity = Binder.clearCallingIdentity();
fionaxu8da9cb12017-05-23 15:02:46 -07007697 if (phone == null) {
7698 loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId);
7699 return;
7700 }
7701 try {
7702 phone.carrierActionReportDefaultNetworkStatus(report);
7703 } catch (Exception e) {
7704 Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007705 } finally {
7706 Binder.restoreCallingIdentity(identity);
fionaxu8da9cb12017-05-23 15:02:46 -07007707 }
7708 }
7709
7710 /**
fionaxud9622282017-07-17 17:51:30 -07007711 * Action set from carrier signalling broadcast receivers to reset all carrier actions
7712 * @param subId the subscription ID that this action applies to.
7713 * {@hide}
7714 */
7715 @Override
7716 public void carrierActionResetAll(int subId) {
7717 enforceModifyPermission();
7718 final Phone phone = getPhone(subId);
7719 if (phone == null) {
7720 loge("carrierAction: ResetAll fails with invalid sibId: " + subId);
7721 return;
7722 }
7723 try {
7724 phone.carrierActionResetAll();
7725 } catch (Exception e) {
7726 Log.e(LOG_TAG, "carrierAction: ResetAll fails. Exception ex=" + e);
7727 }
7728 }
7729
7730 /**
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07007731 * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a
7732 * bug report is being generated.
7733 */
7734 @Override
Ta-wei Yen99282e02016-06-21 18:19:35 -07007735 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007736 if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
7737 != PackageManager.PERMISSION_GRANTED) {
dcashman22b950d2016-06-27 11:39:02 -07007738 writer.println("Permission Denial: can't dump Phone from pid="
7739 + Binder.getCallingPid()
7740 + ", uid=" + Binder.getCallingUid()
7741 + "without permission "
7742 + android.Manifest.permission.DUMP);
7743 return;
7744 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007745 DumpsysHandler.dump(mApp, fd, writer, args);
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07007746 }
Jack Yueb89b242016-06-22 13:27:47 -07007747
Brad Ebingerdac2f002018-04-03 15:17:52 -07007748 @Override
Hall Liua1548bd2019-12-24 14:14:12 -08007749 public int handleShellCommand(@NonNull ParcelFileDescriptor in,
7750 @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
7751 @NonNull String[] args) {
7752 return new TelephonyShellCommand(this, getDefaultPhone().getContext()).exec(
7753 this, in.getFileDescriptor(), out.getFileDescriptor(),
7754 err.getFileDescriptor(), args);
Brad Ebingerdac2f002018-04-03 15:17:52 -07007755 }
7756
Jack Yueb89b242016-06-22 13:27:47 -07007757 /**
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007758 * Policy control of data connection with reason {@@TelephonyManager.DataEnabledReason}
Greg Kaiser17f41752020-05-05 16:47:47 +00007759 * @param subId Subscription index
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007760 * @param reason the reason the data enable change is taking place
7761 * @param enabled True if enabling the data, otherwise disabling.
7762 * @hide
Jack Yu75ab2952016-07-08 14:29:33 -07007763 */
7764 @Override
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07007765 public void setDataEnabledForReason(int subId, @TelephonyManager.DataEnabledReason int reason,
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007766 boolean enabled) {
7767 if (reason == TelephonyManager.DATA_ENABLED_REASON_USER
7768 || reason == TelephonyManager.DATA_ENABLED_REASON_CARRIER) {
7769 try {
7770 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07007771 mApp, subId, "setDataEnabledForReason");
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007772 } catch (SecurityException se) {
7773 enforceModifyPermission();
7774 }
7775 } else {
7776 enforceModifyPermission();
7777 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007778
7779 final long identity = Binder.clearCallingIdentity();
7780 try {
7781 Phone phone = getPhone(subId);
7782 if (phone != null) {
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007783 if (reason == TelephonyManager.DATA_ENABLED_REASON_CARRIER) {
7784 phone.carrierActionSetMeteredApnsEnabled(enabled);
7785 } else {
7786 phone.getDataEnabledSettings().setDataEnabled(reason, enabled);
7787 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007788 }
7789 } finally {
7790 Binder.restoreCallingIdentity(identity);
Jack Yu75ab2952016-07-08 14:29:33 -07007791 }
7792 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07007793
7794 /**
7795 * Get Client request stats
7796 * @return List of Client Request Stats
7797 * @hide
7798 */
7799 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007800 public List<ClientRequestStats> getClientRequestStats(String callingPackage,
7801 String callingFeatureId, int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08007802 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007803 mApp, subId, callingPackage, callingFeatureId, "getClientRequestStats")) {
Sooraj Sasindran9a909312016-07-18 11:57:25 -07007804 return null;
7805 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07007806 Phone phone = getPhone(subId);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07007807
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007808 final long identity = Binder.clearCallingIdentity();
7809 try {
7810 if (phone != null) {
7811 return phone.getClientRequestStats();
7812 }
7813
7814 return null;
7815 } finally {
7816 Binder.restoreCallingIdentity(identity);
7817 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07007818 }
7819
Narayan Kamathf04b5a12018-01-09 11:47:15 +00007820 private WorkSource getWorkSource(int uid) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007821 String packageName = mApp.getPackageManager().getNameForUid(uid);
Narayan Kamathf04b5a12018-01-09 11:47:15 +00007822 return new WorkSource(uid, packageName);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07007823 }
Jack Yueb4124c2017-02-16 15:32:43 -08007824
7825 /**
Grace Chen70990072017-03-24 17:21:30 -07007826 * Set SIM card power state.
Jack Yueb4124c2017-02-16 15:32:43 -08007827 *
Sanket Padawe13bac7b2017-03-20 15:04:47 -07007828 * @param slotIndex SIM slot id.
Grace Chen70990072017-03-24 17:21:30 -07007829 * @param state State of SIM (power down, power up, pass through)
7830 * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
7831 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
7832 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
Jack Yueb4124c2017-02-16 15:32:43 -08007833 *
7834 **/
7835 @Override
Grace Chen70990072017-03-24 17:21:30 -07007836 public void setSimPowerStateForSlot(int slotIndex, int state) {
Jack Yueb4124c2017-02-16 15:32:43 -08007837 enforceModifyPermission();
Sanket Padawe13bac7b2017-03-20 15:04:47 -07007838 Phone phone = PhoneFactory.getPhone(slotIndex);
7839
vagdeviaf9a5b92018-08-15 16:01:53 -07007840 WorkSource workSource = getWorkSource(Binder.getCallingUid());
7841
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007842 final long identity = Binder.clearCallingIdentity();
7843 try {
7844 if (phone != null) {
vagdeviaf9a5b92018-08-15 16:01:53 -07007845 phone.setSimPowerState(state, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007846 }
7847 } finally {
7848 Binder.restoreCallingIdentity(identity);
Jack Yueb4124c2017-02-16 15:32:43 -08007849 }
7850 }
Shuo Qiandd210312017-04-12 22:11:33 +00007851
Tyler Gunn65d45c22017-06-05 11:22:26 -07007852 private boolean isUssdApiAllowed(int subId) {
7853 CarrierConfigManager configManager =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007854 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Tyler Gunn65d45c22017-06-05 11:22:26 -07007855 if (configManager == null) {
7856 return false;
7857 }
7858 PersistableBundle pb = configManager.getConfigForSubId(subId);
7859 if (pb == null) {
7860 return false;
7861 }
7862 return pb.getBoolean(
7863 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL);
7864 }
7865
Shuo Qiandd210312017-04-12 22:11:33 +00007866 /**
7867 * Check if phone is in emergency callback mode
7868 * @return true if phone is in emergency callback mode
7869 * @param subId sub id
7870 */
goneil9c5f4872017-12-05 14:07:56 -08007871 @Override
Shuo Qiandd210312017-04-12 22:11:33 +00007872 public boolean getEmergencyCallbackMode(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07007873 enforceReadPrivilegedPermission("getEmergencyCallbackMode");
Shuo Qiandd210312017-04-12 22:11:33 +00007874 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007875
7876 final long identity = Binder.clearCallingIdentity();
7877 try {
7878 if (phone != null) {
7879 return phone.isInEcm();
7880 } else {
7881 return false;
7882 }
7883 } finally {
7884 Binder.restoreCallingIdentity(identity);
Shuo Qiandd210312017-04-12 22:11:33 +00007885 }
7886 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08007887
7888 /**
7889 * Get the current signal strength information for the given subscription.
7890 * Because this information is not updated when the device is in a low power state
7891 * it should not be relied-upon to be current.
7892 * @param subId Subscription index
7893 * @return the most recent cached signal strength info from the modem
7894 */
7895 @Override
7896 public SignalStrength getSignalStrength(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007897 final long identity = Binder.clearCallingIdentity();
7898 try {
7899 Phone p = getPhone(subId);
7900 if (p == null) {
7901 return null;
7902 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08007903
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007904 return p.getSignalStrength();
7905 } finally {
7906 Binder.restoreCallingIdentity(identity);
7907 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08007908 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00007909
Pengquan Meng77b7f132018-08-22 14:49:57 -07007910 /**
Chen Xuf792fd62018-10-17 17:54:36 +00007911 * Get the current modem radio state for the given slot.
7912 * @param slotIndex slot index.
7913 * @param callingPackage the name of the package making the call.
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007914 * @param callingFeatureId The feature in the package.
Chen Xuf792fd62018-10-17 17:54:36 +00007915 * @return the current radio power state from the modem
7916 */
7917 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007918 public int getRadioPowerState(int slotIndex, String callingPackage, String callingFeatureId) {
Chen Xuf792fd62018-10-17 17:54:36 +00007919 Phone phone = PhoneFactory.getPhone(slotIndex);
7920 if (phone != null) {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007921 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, phone.getSubId(),
7922 callingPackage, callingFeatureId, "getRadioPowerState")) {
Chen Xuf792fd62018-10-17 17:54:36 +00007923 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
7924 }
7925
7926 final long identity = Binder.clearCallingIdentity();
7927 try {
7928 return phone.getRadioPowerState();
7929 } finally {
7930 Binder.restoreCallingIdentity(identity);
7931 }
7932 }
7933 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
7934 }
7935
7936 /**
Pengquan Meng77b7f132018-08-22 14:49:57 -07007937 * Checks if data roaming is enabled on the subscription with id {@code subId}.
7938 *
7939 * <p>Requires one of the following permissions:
7940 * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
7941 * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
7942 * privileges.
7943 *
7944 * @param subId subscription id
7945 * @return {@code true} if data roaming is enabled on this subscription, otherwise return
7946 * {@code false}.
7947 */
7948 @Override
7949 public boolean isDataRoamingEnabled(int subId) {
Shuo Qian093013d2020-08-13 15:42:55 -07007950 try {
7951 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
7952 null);
7953 } catch (Exception e) {
7954 TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
7955 mApp, subId, "isDataRoamingEnabled");
7956 }
Pengquan Meng44e66f12019-04-01 10:48:20 -07007957
Pengquan Menga1bb6272018-09-06 09:59:22 -07007958 boolean isEnabled = false;
7959 final long identity = Binder.clearCallingIdentity();
Pengquan Meng77b7f132018-08-22 14:49:57 -07007960 try {
Pengquan Menga1bb6272018-09-06 09:59:22 -07007961 Phone phone = getPhone(subId);
7962 isEnabled = phone != null ? phone.getDataRoamingEnabled() : false;
Pengquan Menga1bb6272018-09-06 09:59:22 -07007963 } finally {
7964 Binder.restoreCallingIdentity(identity);
Pengquan Meng77b7f132018-08-22 14:49:57 -07007965 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07007966 return isEnabled;
Pengquan Meng77b7f132018-08-22 14:49:57 -07007967 }
7968
7969
7970 /**
7971 * Enables/Disables the data roaming on the subscription with id {@code subId}.
7972 *
7973 * <p> Requires permission:
7974 * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier
7975 * privileges.
7976 *
7977 * @param subId subscription id
7978 * @param isEnabled {@code true} means enable, {@code false} means disable.
7979 */
7980 @Override
7981 public void setDataRoamingEnabled(int subId, boolean isEnabled) {
Pengquan Meng44e66f12019-04-01 10:48:20 -07007982 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7983 mApp, subId, "setDataRoamingEnabled");
7984
Pengquan Menga1bb6272018-09-06 09:59:22 -07007985 final long identity = Binder.clearCallingIdentity();
7986 try {
Pengquan Menga1bb6272018-09-06 09:59:22 -07007987 Phone phone = getPhone(subId);
7988 if (phone != null) {
7989 phone.setDataRoamingEnabled(isEnabled);
7990 }
7991 } finally {
7992 Binder.restoreCallingIdentity(identity);
Pengquan Meng77b7f132018-08-22 14:49:57 -07007993 }
7994 }
7995
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00007996 @Override
Pengquan Meng6884a2c2018-10-03 12:19:13 -07007997 public boolean isManualNetworkSelectionAllowed(int subId) {
tom hsuc91afc72020-01-06 23:46:07 +08007998 TelephonyPermissions
7999 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Pengquan Meng44e66f12019-04-01 10:48:20 -07008000 mApp, subId, "isManualNetworkSelectionAllowed");
8001
Pengquan Meng6884a2c2018-10-03 12:19:13 -07008002 boolean isAllowed = true;
8003 final long identity = Binder.clearCallingIdentity();
8004 try {
Pengquan Meng6884a2c2018-10-03 12:19:13 -07008005 Phone phone = getPhone(subId);
8006 if (phone != null) {
8007 isAllowed = phone.isCspPlmnEnabled();
8008 }
8009 } finally {
8010 Binder.restoreCallingIdentity(identity);
8011 }
8012 return isAllowed;
8013 }
8014
8015 @Override
Jordan Liu75f43ea2019-01-17 16:56:37 -08008016 public List<UiccCardInfo> getUiccCardsInfo(String callingPackage) {
Jordan Liu4cda4552020-03-23 11:55:07 -07008017 // Verify that tha callingPackage belongs to the calling UID
8018 mApp.getSystemService(AppOpsManager.class)
8019 .checkPackage(Binder.getCallingUid(), callingPackage);
8020
Jordan Liu1e142fc2019-04-22 15:10:43 -07008021 boolean hasReadPermission = false;
Jordan Liuc65bc952019-02-12 17:54:02 -08008022 try {
8023 enforceReadPrivilegedPermission("getUiccCardsInfo");
Jordan Liu1e142fc2019-04-22 15:10:43 -07008024 hasReadPermission = true;
Jordan Liuc65bc952019-02-12 17:54:02 -08008025 } catch (SecurityException e) {
8026 // even without READ_PRIVILEGED_PHONE_STATE, we allow the call to continue if the caller
8027 // has carrier privileges on an active UICC
8028 if (checkCarrierPrivilegesForPackageAnyPhone(callingPackage)
8029 != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
Jordan Liu1e142fc2019-04-22 15:10:43 -07008030 throw new SecurityException("Caller does not have permission.");
Jordan Liuc65bc952019-02-12 17:54:02 -08008031 }
Jordan Liu75f43ea2019-01-17 16:56:37 -08008032 }
Jordan Liu5aa07002018-12-18 15:44:48 -08008033
8034 final long identity = Binder.clearCallingIdentity();
8035 try {
Jordan Liu75f43ea2019-01-17 16:56:37 -08008036 UiccController uiccController = UiccController.getInstance();
8037 ArrayList<UiccCardInfo> cardInfos = uiccController.getAllUiccCardInfos();
Jordan Liu1e142fc2019-04-22 15:10:43 -07008038 if (hasReadPermission) {
8039 return cardInfos;
Jordan Liu75f43ea2019-01-17 16:56:37 -08008040 }
Jordan Liu1e142fc2019-04-22 15:10:43 -07008041
8042 // Remove private info if the caller doesn't have access
8043 ArrayList<UiccCardInfo> filteredInfos = new ArrayList<>();
8044 for (UiccCardInfo cardInfo : cardInfos) {
8045 // For an inactive eUICC, the UiccCard will be null even though the UiccCardInfo
8046 // is available
8047 UiccCard card = uiccController.getUiccCardForSlot(cardInfo.getSlotIndex());
8048 if (card == null || card.getUiccProfile() == null) {
8049 // assume no access if the card or profile is unavailable
8050 filteredInfos.add(cardInfo.getUnprivileged());
8051 continue;
8052 }
8053 UiccProfile profile = card.getUiccProfile();
8054 if (profile.getCarrierPrivilegeStatus(mApp.getPackageManager(), callingPackage)
8055 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
8056 filteredInfos.add(cardInfo);
8057 } else {
8058 filteredInfos.add(cardInfo.getUnprivileged());
8059 }
8060 }
8061 return filteredInfos;
Jordan Liu5aa07002018-12-18 15:44:48 -08008062 } finally {
8063 Binder.restoreCallingIdentity(identity);
8064 }
8065 }
8066
8067 @Override
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00008068 public UiccSlotInfo[] getUiccSlotsInfo() {
Brad Ebinger35c841c2018-10-01 10:40:55 -07008069 enforceReadPrivilegedPermission("getUiccSlotsInfo");
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00008070
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008071 final long identity = Binder.clearCallingIdentity();
8072 try {
8073 UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
8074 if (slots == null) {
8075 Rlog.i(LOG_TAG, "slots is null.");
8076 return null;
8077 }
8078
8079 UiccSlotInfo[] infos = new UiccSlotInfo[slots.length];
8080 for (int i = 0; i < slots.length; i++) {
8081 UiccSlot slot = slots[i];
8082 if (slot == null) {
8083 continue;
8084 }
8085
Jordan Liu7be7e652019-05-06 18:55:02 +00008086 String cardId;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008087 UiccCard card = slot.getUiccCard();
8088 if (card != null) {
8089 cardId = card.getCardId();
Jordan Liu7be7e652019-05-06 18:55:02 +00008090 } else {
Jordan Liu01bd00d2019-09-12 16:19:43 -07008091 cardId = slot.getEid();
8092 if (TextUtils.isEmpty(cardId)) {
8093 cardId = slot.getIccId();
8094 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008095 }
8096
Jordan Liu857451f2019-05-09 16:35:35 -07008097 if (cardId != null) {
8098 // if cardId is an ICCID, strip off trailing Fs before exposing to user
8099 // if cardId is an EID, it's all digits so this is fine
8100 cardId = IccUtils.stripTrailingFs(cardId);
8101 }
8102
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008103 int cardState = 0;
8104 switch (slot.getCardState()) {
8105 case CARDSTATE_ABSENT:
8106 cardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
8107 break;
8108 case CARDSTATE_PRESENT:
8109 cardState = UiccSlotInfo.CARD_STATE_INFO_PRESENT;
8110 break;
8111 case CARDSTATE_ERROR:
8112 cardState = UiccSlotInfo.CARD_STATE_INFO_ERROR;
8113 break;
8114 case CARDSTATE_RESTRICTED:
8115 cardState = UiccSlotInfo.CARD_STATE_INFO_RESTRICTED;
8116 break;
8117 default:
8118 break;
8119
8120 }
8121
8122 infos[i] = new UiccSlotInfo(
8123 slot.isActive(),
8124 slot.isEuicc(),
8125 cardId,
8126 cardState,
8127 slot.getPhoneId(),
Jordan Liua2619582019-02-14 12:56:40 -08008128 slot.isExtendedApduSupported(),
8129 slot.isRemovable());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008130 }
8131 return infos;
8132 } finally {
8133 Binder.restoreCallingIdentity(identity);
Holly Jiuyu Sun1d957c52018-04-04 13:52:42 -07008134 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00008135 }
8136
8137 @Override
8138 public boolean switchSlots(int[] physicalSlots) {
8139 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008140
8141 final long identity = Binder.clearCallingIdentity();
8142 try {
8143 return (Boolean) sendRequest(CMD_SWITCH_SLOTS, physicalSlots);
8144 } finally {
8145 Binder.restoreCallingIdentity(identity);
8146 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00008147 }
Jack Yu4c988042018-02-27 15:30:01 -08008148
8149 @Override
Jordan Liu7de49fa2018-12-06 14:48:49 -08008150 public int getCardIdForDefaultEuicc(int subId, String callingPackage) {
Jordan Liu7de49fa2018-12-06 14:48:49 -08008151 final long identity = Binder.clearCallingIdentity();
8152 try {
8153 return UiccController.getInstance().getCardIdForDefaultEuicc();
8154 } finally {
8155 Binder.restoreCallingIdentity(identity);
8156 }
8157 }
8158
Pengquan Meng85728fb2018-03-12 16:31:21 -07008159 /**
goneil47ffb6e2018-04-06 15:40:58 -07008160 * A test API to reload the UICC profile.
8161 *
8162 * <p>Requires that the calling app has permission
8163 * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
8164 * @hide
8165 */
8166 @Override
8167 public void refreshUiccProfile(int subId) {
8168 enforceModifyPermission();
8169
8170 final long identity = Binder.clearCallingIdentity();
8171 try {
8172 Phone phone = getPhone(subId);
8173 if (phone == null) {
8174 return;
8175 }
8176 UiccCard uiccCard = phone.getUiccCard();
8177 if (uiccCard == null) {
8178 return;
8179 }
8180 UiccProfile uiccProfile = uiccCard.getUiccProfile();
8181 if (uiccProfile == null) {
8182 return;
8183 }
8184 uiccProfile.refresh();
8185 } finally {
8186 Binder.restoreCallingIdentity(identity);
8187 }
8188 }
8189
8190 /**
Pengquan Meng85728fb2018-03-12 16:31:21 -07008191 * Returns false if the mobile data is disabled by default, otherwise return true.
8192 */
8193 private boolean getDefaultDataEnabled() {
Inseob Kim14bb3d02018-12-13 17:11:34 +09008194 return TelephonyProperties.mobile_data().orElse(true);
Pengquan Meng85728fb2018-03-12 16:31:21 -07008195 }
8196
8197 /**
8198 * Returns true if the data roaming is enabled by default, i.e the system property
8199 * of {@link #DEFAULT_DATA_ROAMING_PROPERTY_NAME} is true or the config of
8200 * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} is true.
8201 */
8202 private boolean getDefaultDataRoamingEnabled(int subId) {
8203 final CarrierConfigManager configMgr = (CarrierConfigManager)
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008204 mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Shuo Qian1d84a0e2020-07-15 12:36:44 -07008205 boolean isDataRoamingEnabled = TelephonyProperties.data_roaming().orElse(false);
Pengquan Meng85728fb2018-03-12 16:31:21 -07008206 isDataRoamingEnabled |= configMgr.getConfigForSubId(subId).getBoolean(
8207 CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
8208 return isDataRoamingEnabled;
8209 }
8210
8211 /**
8212 * Returns the default network type for the given {@code subId}, if the default network type is
8213 * not set, return {@link Phone#PREFERRED_NT_MODE}.
8214 */
8215 private int getDefaultNetworkType(int subId) {
Inseob Kim14bb3d02018-12-13 17:11:34 +09008216 List<Integer> list = TelephonyProperties.default_network();
8217 int phoneId = mSubscriptionController.getPhoneId(subId);
8218 if (phoneId >= 0 && phoneId < list.size() && list.get(phoneId) != null) {
8219 return list.get(phoneId);
8220 }
8221 return Phone.PREFERRED_NT_MODE;
Pengquan Meng85728fb2018-03-12 16:31:21 -07008222 }
fionaxua13278b2018-03-21 00:08:13 -07008223
8224 @Override
8225 public void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String
chen xueaba88a2019-03-15 13:15:10 -07008226 gid1, String gid2, String plmn, String spn, String carrierPrivilegeRules, String apn) {
fionaxua13278b2018-03-21 00:08:13 -07008227 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008228
8229 final long identity = Binder.clearCallingIdentity();
8230 try {
8231 final Phone phone = getPhone(subId);
8232 if (phone == null) {
8233 loge("setCarrierTestOverride fails with invalid subId: " + subId);
8234 return;
8235 }
chen xueaba88a2019-03-15 13:15:10 -07008236 phone.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, plmn, spn,
8237 carrierPrivilegeRules, apn);
Jeff Davidson8ab02b22020-03-28 12:24:40 -07008238 if (carrierPrivilegeRules == null) {
8239 mCarrierPrivilegeTestOverrideSubIds.remove(subId);
8240 } else {
8241 mCarrierPrivilegeTestOverrideSubIds.add(subId);
8242 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008243 } finally {
8244 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07008245 }
fionaxua13278b2018-03-21 00:08:13 -07008246 }
8247
8248 @Override
8249 public int getCarrierIdListVersion(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07008250 enforceReadPrivilegedPermission("getCarrierIdListVersion");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008251
8252 final long identity = Binder.clearCallingIdentity();
8253 try {
8254 final Phone phone = getPhone(subId);
8255 if (phone == null) {
8256 loge("getCarrierIdListVersion fails with invalid subId: " + subId);
8257 return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
8258 }
8259 return phone.getCarrierIdListVersion();
8260 } finally {
8261 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07008262 }
fionaxua13278b2018-03-21 00:08:13 -07008263 }
Malcolm Chen2c63d402018-08-14 16:00:53 -07008264
8265 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008266 public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage,
8267 String callingFeatureId) {
Malcolm Chen2c63d402018-08-14 16:00:53 -07008268 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008269 mApp, subId, callingPackage, callingFeatureId,
8270 "getNumberOfModemsWithSimultaneousDataConnections")) {
Malcolm Chen2c63d402018-08-14 16:00:53 -07008271 return -1;
8272 }
8273
8274 final long identity = Binder.clearCallingIdentity();
8275 try {
8276 return mPhoneConfigurationManager.getNumberOfModemsWithSimultaneousDataConnections();
8277 } finally {
8278 Binder.restoreCallingIdentity(identity);
8279 }
8280 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07008281
8282 @Override
8283 public int getCdmaRoamingMode(int subId) {
zoey chen7e6d4e52019-12-17 18:18:59 +08008284 TelephonyPermissions
8285 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Pengquan Menga1bb6272018-09-06 09:59:22 -07008286 mApp, subId, "getCdmaRoamingMode");
8287
8288 final long identity = Binder.clearCallingIdentity();
8289 try {
8290 return (int) sendRequest(CMD_GET_CDMA_ROAMING_MODE, null /* argument */, subId);
8291 } finally {
8292 Binder.restoreCallingIdentity(identity);
8293 }
8294 }
8295
8296 @Override
8297 public boolean setCdmaRoamingMode(int subId, int mode) {
8298 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8299 mApp, subId, "setCdmaRoamingMode");
8300
8301 final long identity = Binder.clearCallingIdentity();
8302 try {
8303 return (boolean) sendRequest(CMD_SET_CDMA_ROAMING_MODE, mode, subId);
8304 } finally {
8305 Binder.restoreCallingIdentity(identity);
8306 }
8307 }
8308
8309 @Override
Sarah Chinbaab1432020-10-28 13:46:24 -07008310 public int getCdmaSubscriptionMode(int subId) {
8311 TelephonyPermissions
8312 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
8313 mApp, subId, "getCdmaSubscriptionMode");
8314
8315 final long identity = Binder.clearCallingIdentity();
8316 try {
8317 return (int) sendRequest(CMD_GET_CDMA_SUBSCRIPTION_MODE, null /* argument */, subId);
8318 } finally {
8319 Binder.restoreCallingIdentity(identity);
8320 }
8321 }
8322
8323 @Override
Pengquan Menga1bb6272018-09-06 09:59:22 -07008324 public boolean setCdmaSubscriptionMode(int subId, int mode) {
8325 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8326 mApp, subId, "setCdmaSubscriptionMode");
8327
8328 final long identity = Binder.clearCallingIdentity();
8329 try {
8330 return (boolean) sendRequest(CMD_SET_CDMA_SUBSCRIPTION_MODE, mode, subId);
8331 } finally {
8332 Binder.restoreCallingIdentity(identity);
8333 }
8334 }
Makoto Onukida3bf792018-09-18 16:06:29 -07008335
sqianc5eccab2018-10-19 18:46:41 -07008336 @Override
sqian8c685422019-02-22 15:55:18 -08008337 public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008338 String callingPackage, String callingFeatureId) {
sqian11b7a0e2018-12-05 18:48:28 -08008339 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008340 mApp, getDefaultSubscription(), callingPackage, callingFeatureId,
8341 "getEmergencyNumberList")) {
sqian11b7a0e2018-12-05 18:48:28 -08008342 throw new SecurityException("Requires READ_PHONE_STATE permission.");
8343 }
8344 final long identity = Binder.clearCallingIdentity();
8345 try {
sqian854d44b2018-12-12 16:48:18 -08008346 Map<Integer, List<EmergencyNumber>> emergencyNumberListInternal = new HashMap<>();
8347 for (Phone phone: PhoneFactory.getPhones()) {
8348 if (phone.getEmergencyNumberTracker() != null
8349 && phone.getEmergencyNumberTracker().getEmergencyNumberList() != null) {
8350 emergencyNumberListInternal.put(
8351 phone.getSubId(),
8352 phone.getEmergencyNumberTracker().getEmergencyNumberList());
8353 }
sqian11b7a0e2018-12-05 18:48:28 -08008354 }
sqian854d44b2018-12-12 16:48:18 -08008355 return emergencyNumberListInternal;
sqian11b7a0e2018-12-05 18:48:28 -08008356 } finally {
8357 Binder.restoreCallingIdentity(identity);
8358 }
sqianc5eccab2018-10-19 18:46:41 -07008359 }
8360
8361 @Override
sqian8c685422019-02-22 15:55:18 -08008362 public boolean isEmergencyNumber(String number, boolean exactMatch) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008363 final Phone defaultPhone = getDefaultPhone();
sqian11b7a0e2018-12-05 18:48:28 -08008364 if (!exactMatch) {
8365 TelephonyPermissions
8366 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
sqian8c685422019-02-22 15:55:18 -08008367 mApp, defaultPhone.getSubId(), "isEmergencyNumber(Potential)");
sqian11b7a0e2018-12-05 18:48:28 -08008368 }
8369 final long identity = Binder.clearCallingIdentity();
8370 try {
sqian854d44b2018-12-12 16:48:18 -08008371 for (Phone phone: PhoneFactory.getPhones()) {
8372 if (phone.getEmergencyNumberTracker() != null
Taesu Leee050c002020-10-13 17:19:35 +09008373 && phone.getEmergencyNumberTracker()
8374 .isEmergencyNumber(number, exactMatch)) {
8375 return true;
sqian11b7a0e2018-12-05 18:48:28 -08008376 }
sqian11b7a0e2018-12-05 18:48:28 -08008377 }
8378 return false;
8379 } finally {
8380 Binder.restoreCallingIdentity(identity);
8381 }
8382 }
8383
sqianf4ca7ed2019-01-15 18:32:07 -08008384 /**
8385 * Update emergency number list for test mode.
8386 */
8387 @Override
8388 public void updateEmergencyNumberListTestMode(int action, EmergencyNumber num) {
8389 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
8390 "updateEmergencyNumberListTestMode");
8391
8392 final long identity = Binder.clearCallingIdentity();
8393 try {
8394 for (Phone phone: PhoneFactory.getPhones()) {
8395 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
8396 if (tracker != null) {
8397 tracker.executeEmergencyNumberTestModeCommand(action, num);
8398 }
8399 }
8400 } finally {
8401 Binder.restoreCallingIdentity(identity);
8402 }
8403 }
8404
8405 /**
8406 * Get the full emergency number list for test mode.
8407 */
8408 @Override
8409 public List<String> getEmergencyNumberListTestMode() {
8410 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
8411 "getEmergencyNumberListTestMode");
8412
8413 final long identity = Binder.clearCallingIdentity();
8414 try {
8415 Set<String> emergencyNumbers = new HashSet<>();
8416 for (Phone phone: PhoneFactory.getPhones()) {
8417 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
8418 if (tracker != null) {
8419 for (EmergencyNumber num : tracker.getEmergencyNumberList()) {
8420 emergencyNumbers.add(num.getNumber());
8421 }
8422 }
8423 }
8424 return new ArrayList<>(emergencyNumbers);
8425 } finally {
8426 Binder.restoreCallingIdentity(identity);
8427 }
8428 }
8429
chen xud6b45bd2018-10-30 22:27:10 -07008430 @Override
Shuo Qian3b6ee772019-11-13 17:43:31 -08008431 public int getEmergencyNumberDbVersion(int subId) {
8432 enforceReadPrivilegedPermission("getEmergencyNumberDbVersion");
8433
8434 final long identity = Binder.clearCallingIdentity();
8435 try {
8436 final Phone phone = getPhone(subId);
8437 if (phone == null) {
8438 loge("getEmergencyNumberDbVersion fails with invalid subId: " + subId);
8439 return TelephonyManager.INVALID_EMERGENCY_NUMBER_DB_VERSION;
8440 }
8441 return phone.getEmergencyNumberDbVersion();
8442 } finally {
8443 Binder.restoreCallingIdentity(identity);
8444 }
8445 }
8446
8447 @Override
8448 public void notifyOtaEmergencyNumberDbInstalled() {
8449 enforceModifyPermission();
8450
8451 final long identity = Binder.clearCallingIdentity();
8452 try {
8453 for (Phone phone: PhoneFactory.getPhones()) {
8454 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
8455 if (tracker != null) {
8456 tracker.updateOtaEmergencyNumberDatabase();
8457 }
8458 }
8459 } finally {
8460 Binder.restoreCallingIdentity(identity);
8461 }
8462 }
8463
8464 @Override
Shuo Qianc373f112020-03-05 17:55:34 -08008465 public void updateOtaEmergencyNumberDbFilePath(ParcelFileDescriptor otaParcelFileDescriptor) {
Shuo Qian3b6ee772019-11-13 17:43:31 -08008466 enforceActiveEmergencySessionPermission();
8467
8468 final long identity = Binder.clearCallingIdentity();
8469 try {
8470 for (Phone phone: PhoneFactory.getPhones()) {
8471 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
8472 if (tracker != null) {
Shuo Qianc373f112020-03-05 17:55:34 -08008473 tracker.updateOtaEmergencyNumberDbFilePath(otaParcelFileDescriptor);
8474 }
8475 }
8476 } finally {
8477 Binder.restoreCallingIdentity(identity);
8478 }
8479 }
8480
8481 @Override
8482 public void resetOtaEmergencyNumberDbFilePath() {
8483 enforceActiveEmergencySessionPermission();
8484
8485 final long identity = Binder.clearCallingIdentity();
8486 try {
8487 for (Phone phone: PhoneFactory.getPhones()) {
8488 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
8489 if (tracker != null) {
8490 tracker.resetOtaEmergencyNumberDbFilePath();
Shuo Qian3b6ee772019-11-13 17:43:31 -08008491 }
8492 }
8493 } finally {
8494 Binder.restoreCallingIdentity(identity);
8495 }
8496 }
8497
8498 @Override
chen xud6b45bd2018-10-30 22:27:10 -07008499 public List<String> getCertsFromCarrierPrivilegeAccessRules(int subId) {
8500 enforceReadPrivilegedPermission("getCertsFromCarrierPrivilegeAccessRules");
8501 Phone phone = getPhone(subId);
8502 if (phone == null) {
8503 return null;
8504 }
8505 final long identity = Binder.clearCallingIdentity();
8506 try {
8507 UiccProfile profile = UiccController.getInstance()
8508 .getUiccProfileForPhone(phone.getPhoneId());
8509 if (profile != null) {
8510 return profile.getCertsFromCarrierPrivilegeAccessRules();
8511 }
8512 } finally {
8513 Binder.restoreCallingIdentity(identity);
8514 }
8515 return null;
8516 }
Malcolm Chen8e4ed912019-01-15 20:22:16 -08008517
8518 /**
8519 * Enable or disable a modem stack.
8520 */
8521 @Override
8522 public boolean enableModemForSlot(int slotIndex, boolean enable) {
8523 enforceModifyPermission();
8524
8525 final long identity = Binder.clearCallingIdentity();
8526 try {
8527 Phone phone = PhoneFactory.getPhone(slotIndex);
8528 if (phone == null) {
8529 return false;
8530 } else {
8531 return (Boolean) sendRequest(CMD_REQUEST_ENABLE_MODEM, enable, phone, null);
8532 }
8533 } finally {
8534 Binder.restoreCallingIdentity(identity);
8535 }
8536 }
Michelecea4cf22018-12-21 15:00:11 -08008537
Malcolm Chen4bcd9822019-03-27 18:34:05 -07008538 /**
8539 * Whether a modem stack is enabled or not.
8540 */
8541 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008542 public boolean isModemEnabledForSlot(int slotIndex, String callingPackage,
8543 String callingFeatureId) {
Malcolm Chen4bcd9822019-03-27 18:34:05 -07008544 Phone phone = PhoneFactory.getPhone(slotIndex);
8545 if (phone == null) return false;
8546
8547 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008548 mApp, phone.getSubId(), callingPackage, callingFeatureId,
8549 "isModemEnabledForSlot")) {
Malcolm Chen4bcd9822019-03-27 18:34:05 -07008550 throw new SecurityException("Requires READ_PHONE_STATE permission.");
8551 }
8552
8553 final long identity = Binder.clearCallingIdentity();
8554 try {
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07008555 try {
8556 return mPhoneConfigurationManager.getPhoneStatusFromCache(phone.getPhoneId());
8557 } catch (NoSuchElementException ex) {
8558 return (Boolean) sendRequest(CMD_GET_MODEM_STATUS, null, phone, null);
8559 }
Malcolm Chen4bcd9822019-03-27 18:34:05 -07008560 } finally {
8561 Binder.restoreCallingIdentity(identity);
8562 }
8563 }
8564
Michelecea4cf22018-12-21 15:00:11 -08008565 @Override
Michele0ea7d782019-03-19 14:58:42 -07008566 public void setMultiSimCarrierRestriction(boolean isMultiSimCarrierRestricted) {
Michelecea4cf22018-12-21 15:00:11 -08008567 enforceModifyPermission();
8568
8569 final long identity = Binder.clearCallingIdentity();
8570 try {
8571 mTelephonySharedPreferences.edit()
Michele0ea7d782019-03-19 14:58:42 -07008572 .putBoolean(PREF_MULTI_SIM_RESTRICTED, isMultiSimCarrierRestricted)
Michelecea4cf22018-12-21 15:00:11 -08008573 .commit();
8574 } finally {
8575 Binder.restoreCallingIdentity(identity);
8576 }
8577 }
8578
8579 @Override
Michele0ea7d782019-03-19 14:58:42 -07008580 @TelephonyManager.IsMultiSimSupportedResult
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008581 public int isMultiSimSupported(String callingPackage, String callingFeatureId) {
Michele4245e952019-02-04 11:36:23 -08008582 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008583 getDefaultPhone().getSubId(), callingPackage, callingFeatureId,
8584 "isMultiSimSupported")) {
Michele0ea7d782019-03-19 14:58:42 -07008585 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele4245e952019-02-04 11:36:23 -08008586 }
Michelecea4cf22018-12-21 15:00:11 -08008587
8588 final long identity = Binder.clearCallingIdentity();
8589 try {
Michele0ea7d782019-03-19 14:58:42 -07008590 return isMultiSimSupportedInternal();
Michelecea4cf22018-12-21 15:00:11 -08008591 } finally {
8592 Binder.restoreCallingIdentity(identity);
8593 }
8594 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08008595
Michele0ea7d782019-03-19 14:58:42 -07008596 @TelephonyManager.IsMultiSimSupportedResult
8597 private int isMultiSimSupportedInternal() {
Michele30b57b22019-03-01 12:01:14 -08008598 // If the device has less than 2 SIM cards, indicate that multisim is restricted.
8599 int numPhysicalSlots = UiccController.getInstance().getUiccSlots().length;
8600 if (numPhysicalSlots < 2) {
Michele0ea7d782019-03-19 14:58:42 -07008601 loge("isMultiSimSupportedInternal: requires at least 2 cards");
8602 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -08008603 }
8604 // Check if the hardware supports multisim functionality. If usage of multisim is not
8605 // supported by the modem, indicate that it is restricted.
8606 PhoneCapability staticCapability =
8607 mPhoneConfigurationManager.getStaticPhoneCapability();
8608 if (staticCapability == null) {
Michele0ea7d782019-03-19 14:58:42 -07008609 loge("isMultiSimSupportedInternal: no static configuration available");
8610 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -08008611 }
Sarah Chin7caee492020-02-18 20:49:02 +00008612 if (staticCapability.logicalModemList.size() < 2) {
Michele0ea7d782019-03-19 14:58:42 -07008613 loge("isMultiSimSupportedInternal: maximum number of modem is < 2");
8614 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -08008615 }
8616 // Check if support of multiple SIMs is restricted by carrier
8617 if (mTelephonySharedPreferences.getBoolean(PREF_MULTI_SIM_RESTRICTED, false)) {
Michele0ea7d782019-03-19 14:58:42 -07008618 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_CARRIER;
Michele30b57b22019-03-01 12:01:14 -08008619 }
8620
Michele0ea7d782019-03-19 14:58:42 -07008621 return TelephonyManager.MULTISIM_ALLOWED;
Michele30b57b22019-03-01 12:01:14 -08008622 }
8623
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08008624 /**
8625 * Switch configs to enable multi-sim or switch back to single-sim
Nazanin Bakhshi17318782019-03-01 11:56:08 -08008626 * Note: Switch from multi-sim to single-sim is only possible with MODIFY_PHONE_STATE
8627 * permission, but the other way around is possible with either MODIFY_PHONE_STATE
8628 * or carrier privileges
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08008629 * @param numOfSims number of active sims we want to switch to
8630 */
8631 @Override
8632 public void switchMultiSimConfig(int numOfSims) {
Nazanin Bakhshi17318782019-03-01 11:56:08 -08008633 if (numOfSims == 1) {
8634 enforceModifyPermission();
8635 } else {
8636 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8637 mApp, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, "switchMultiSimConfig");
8638 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08008639 final long identity = Binder.clearCallingIdentity();
Michele30b57b22019-03-01 12:01:14 -08008640
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08008641 try {
Michele30b57b22019-03-01 12:01:14 -08008642 //only proceed if multi-sim is not restricted
Michele0ea7d782019-03-19 14:58:42 -07008643 if (isMultiSimSupportedInternal() != TelephonyManager.MULTISIM_ALLOWED) {
Michele30b57b22019-03-01 12:01:14 -08008644 loge("switchMultiSimConfig not possible. It is restricted or not supported.");
8645 return;
8646 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08008647 mPhoneConfigurationManager.switchMultiSimConfig(numOfSims);
8648 } finally {
8649 Binder.restoreCallingIdentity(identity);
8650 }
8651 }
8652
Hyungjun Parkbb07fde2019-01-10 15:28:51 +09008653 @Override
8654 public boolean isApplicationOnUicc(int subId, int appType) {
8655 enforceReadPrivilegedPermission("isApplicationOnUicc");
8656 Phone phone = getPhone(subId);
8657 if (phone == null) {
8658 return false;
8659 }
8660 final long identity = Binder.clearCallingIdentity();
8661 try {
8662 UiccCard uiccCard = phone.getUiccCard();
8663 if (uiccCard == null) {
8664 return false;
8665 }
8666 UiccProfile uiccProfile = uiccCard.getUiccProfile();
8667 if (uiccProfile == null) {
8668 return false;
8669 }
8670 if (TelephonyManager.APPTYPE_SIM <= appType
8671 && appType <= TelephonyManager.APPTYPE_ISIM) {
8672 return uiccProfile.isApplicationOnIcc(AppType.values()[appType]);
8673 }
8674 return false;
8675 } finally {
8676 Binder.restoreCallingIdentity(identity);
8677 }
8678 }
8679
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08008680 /**
chen xub4baa772019-04-03 10:23:41 -07008681 * Get whether making changes to modem configurations will trigger reboot.
8682 * Return value defaults to true.
Nazanin Bakhshi5fe5ef22019-01-30 10:52:09 -08008683 */
8684 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008685 public boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage,
8686 String callingFeatureId) {
chen xub4baa772019-04-03 10:23:41 -07008687 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008688 mApp, subId, callingPackage, callingFeatureId,
8689 "doesSwitchMultiSimConfigTriggerReboot")) {
chen xub4baa772019-04-03 10:23:41 -07008690 return false;
8691 }
Nazanin Bakhshi5fe5ef22019-01-30 10:52:09 -08008692 final long identity = Binder.clearCallingIdentity();
8693 try {
8694 return mPhoneConfigurationManager.isRebootRequiredForModemConfigChange();
8695 } finally {
8696 Binder.restoreCallingIdentity(identity);
8697 }
8698 }
8699
Nathan Harold29f5f052019-02-15 13:41:57 -08008700 private void updateModemStateMetrics() {
8701 TelephonyMetrics metrics = TelephonyMetrics.getInstance();
8702 // TODO: check the state for each modem if the api is ready.
8703 metrics.updateEnabledModemBitmap((1 << TelephonyManager.from(mApp).getPhoneCount()) - 1);
8704 }
8705
Pengquan Meng3889a572019-01-23 11:16:29 -08008706 @Override
8707 public int[] getSlotsMapping() {
8708 enforceReadPrivilegedPermission("getSlotsMapping");
8709
8710 final long identity = Binder.clearCallingIdentity();
8711 try {
8712 int phoneCount = TelephonyManager.getDefault().getPhoneCount();
8713 // All logical slots should have a mapping to a physical slot.
8714 int[] logicalSlotsMapping = new int[phoneCount];
8715 UiccSlotInfo[] slotInfos = getUiccSlotsInfo();
8716 for (int i = 0; i < slotInfos.length; i++) {
8717 if (SubscriptionManager.isValidPhoneId(slotInfos[i].getLogicalSlotIdx())) {
8718 logicalSlotsMapping[slotInfos[i].getLogicalSlotIdx()] = i;
8719 }
8720 }
8721 return logicalSlotsMapping;
8722 } finally {
8723 Binder.restoreCallingIdentity(identity);
8724 }
8725 }
Nathan Harold48d6fd52019-02-06 19:01:40 -08008726
8727 /**
8728 * Get the IRadio HAL Version
8729 */
8730 @Override
8731 public int getRadioHalVersion() {
8732 Phone phone = getDefaultPhone();
8733 if (phone == null) return -1;
8734 HalVersion hv = phone.getHalVersion();
8735 if (hv.equals(HalVersion.UNKNOWN)) return -1;
8736 return hv.major * 100 + hv.minor;
8737 }
Malcolm Chendc8c10e2019-04-10 18:25:07 -07008738
8739 /**
Shuo Qianda2d6ec2020-01-14 15:18:28 -08008740 * Get the current calling package name.
8741 * @return the current calling package name
8742 */
8743 @Override
8744 public String getCurrentPackageName() {
8745 return mApp.getPackageManager().getPackagesForUid(Binder.getCallingUid())[0];
8746 }
8747
8748 /**
Malcolm Chene5ad5792019-04-18 13:51:02 -07008749 * Return whether data is enabled for certain APN type. This will tell if framework will accept
8750 * corresponding network requests on a subId.
8751 *
8752 * Data is enabled if:
Malcolm Chendc8c10e2019-04-10 18:25:07 -07008753 * 1) user data is turned on, or
Malcolm Chene5ad5792019-04-18 13:51:02 -07008754 * 2) APN is un-metered for this subscription, or
8755 * 3) APN type is whitelisted. E.g. MMS is whitelisted if
Hall Liu746e03c2020-09-25 11:13:49 -07008756 * {@link TelephonyManager#MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED} is enabled.
Malcolm Chene5ad5792019-04-18 13:51:02 -07008757 *
8758 * @return whether data is allowed for a apn type.
8759 *
8760 * @hide
Malcolm Chendc8c10e2019-04-10 18:25:07 -07008761 */
8762 @Override
Malcolm Chene5ad5792019-04-18 13:51:02 -07008763 public boolean isDataEnabledForApn(int apnType, int subId, String callingPackage) {
Amit Mahajan5d4e1922019-10-07 16:20:43 -07008764 enforceReadPrivilegedPermission("Needs READ_PRIVILEGED_PHONE_STATE for "
8765 + "isDataEnabledForApn");
Malcolm Chendc8c10e2019-04-10 18:25:07 -07008766
8767 // Now that all security checks passes, perform the operation as ourselves.
8768 final long identity = Binder.clearCallingIdentity();
8769 try {
8770 Phone phone = getPhone(subId);
8771 if (phone == null) return false;
8772
Jack Yu41407ee2019-05-13 16:54:09 -07008773 boolean isMetered = ApnSettingUtils.isMeteredApnType(apnType, phone);
Malcolm Chene5ad5792019-04-18 13:51:02 -07008774 return !isMetered || phone.getDataEnabledSettings().isDataEnabled(apnType);
8775 } finally {
8776 Binder.restoreCallingIdentity(identity);
8777 }
8778 }
8779
8780 @Override
Jack Yu41407ee2019-05-13 16:54:09 -07008781 public boolean isApnMetered(@ApnType int apnType, int subId) {
Malcolm Chene5ad5792019-04-18 13:51:02 -07008782 enforceReadPrivilegedPermission("isApnMetered");
8783
8784 // Now that all security checks passes, perform the operation as ourselves.
8785 final long identity = Binder.clearCallingIdentity();
8786 try {
8787 Phone phone = getPhone(subId);
8788 if (phone == null) return true; // By default return true.
8789
Jack Yu41407ee2019-05-13 16:54:09 -07008790 return ApnSettingUtils.isMeteredApnType(apnType, phone);
Malcolm Chendc8c10e2019-04-10 18:25:07 -07008791 } finally {
8792 Binder.restoreCallingIdentity(identity);
8793 }
8794 }
Brad Ebingera63db5f2019-04-23 16:31:13 -07008795
8796 @Override
Hall Liu73f5d362020-01-20 13:42:00 -08008797 public void setSystemSelectionChannels(List<RadioAccessSpecifier> specifiers,
8798 int subscriptionId, IBooleanConsumer resultCallback) {
8799 enforceModifyPermission();
8800 long token = Binder.clearCallingIdentity();
8801 try {
8802 Phone phone = getPhone(subscriptionId);
8803 if (phone == null) {
8804 try {
8805 if (resultCallback != null) {
8806 resultCallback.accept(false);
8807 }
8808 } catch (RemoteException e) {
8809 // ignore
8810 }
8811 return;
8812 }
8813 Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> argument =
8814 Pair.create(specifiers, (x) -> {
8815 try {
8816 if (resultCallback != null) {
8817 resultCallback.accept(x);
8818 }
8819 } catch (RemoteException e) {
8820 // ignore
8821 }
8822 });
8823 sendRequestAsync(CMD_SET_SYSTEM_SELECTION_CHANNELS, argument, phone, null);
8824 } finally {
8825 Binder.restoreCallingIdentity(token);
8826 }
8827 }
8828
8829 @Override
Sarah Chin679c08a2020-11-18 13:39:35 -08008830 public List<RadioAccessSpecifier> getSystemSelectionChannels(int subId) {
8831 TelephonyPermissions
8832 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
8833 mApp, subId, "getSystemSelectionChannels");
8834 WorkSource workSource = getWorkSource(Binder.getCallingUid());
8835 final long identity = Binder.clearCallingIdentity();
8836 try {
8837 List<RadioAccessSpecifier> specifiers =
8838 (List<RadioAccessSpecifier>) sendRequest(CMD_GET_SYSTEM_SELECTION_CHANNELS,
8839 null, subId, workSource);
8840 if (DBG) log("getSystemSelectionChannels: " + specifiers);
8841 return specifiers;
8842 } finally {
8843 Binder.restoreCallingIdentity(identity);
8844 }
8845 }
8846
8847 @Override
changbetty7157e9e2019-12-06 18:16:37 +08008848 public boolean isMvnoMatched(int subId, int mvnoType, @NonNull String mvnoMatchData) {
changbettyca3d40d2020-03-03 16:27:31 +08008849 enforceReadPrivilegedPermission("isMvnoMatched");
changbetty7157e9e2019-12-06 18:16:37 +08008850 IccRecords iccRecords = UiccController.getInstance().getIccRecords(
8851 SubscriptionManager.getPhoneId(subId), UiccController.APP_FAM_3GPP);
8852 if (iccRecords == null) {
8853 Log.d(LOG_TAG, "isMvnoMatched# IccRecords is null");
8854 return false;
8855 }
8856 return ApnSettingUtils.mvnoMatches(iccRecords, mvnoType, mvnoMatchData);
8857 }
8858
8859 @Override
Philip P. Moltmannd02b7372020-03-18 17:06:12 -07008860 public void enqueueSmsPickResult(String callingPackage, String callingAttributionTag,
8861 IIntegerConsumer pendingSubIdResult) {
Shuo Qianda2d6ec2020-01-14 15:18:28 -08008862 if (callingPackage == null) {
8863 callingPackage = getCurrentPackageName();
8864 }
Brad Ebingera63db5f2019-04-23 16:31:13 -07008865 SmsPermissions permissions = new SmsPermissions(getDefaultPhone(), mApp,
8866 (AppOpsManager) mApp.getSystemService(Context.APP_OPS_SERVICE));
Philip P. Moltmannd02b7372020-03-18 17:06:12 -07008867 if (!permissions.checkCallingCanSendSms(callingPackage, callingAttributionTag,
8868 "Sending message")) {
Brad Ebingera63db5f2019-04-23 16:31:13 -07008869 throw new SecurityException("Requires SEND_SMS permission to perform this operation");
8870 }
8871 PickSmsSubscriptionActivity.addPendingResult(pendingSubIdResult);
8872 Intent intent = new Intent();
8873 intent.setClass(mApp, PickSmsSubscriptionActivity.class);
8874 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8875 // Bring up choose default SMS subscription dialog right now
8876 intent.putExtra(PickSmsSubscriptionActivity.DIALOG_TYPE_KEY,
8877 PickSmsSubscriptionActivity.SMS_PICK_FOR_MESSAGE);
8878 mApp.startActivity(intent);
8879 }
chen xud5ca2d52019-05-28 15:20:57 -07008880
8881 @Override
8882 public String getMmsUAProfUrl(int subId) {
8883 //TODO investigate if this API should require proper permission check in R b/133791609
8884 final long identity = Binder.clearCallingIdentity();
8885 try {
Guoqiang.Qiu171383d2020-07-13 09:38:32 +08008886 String carrierUAProfUrl = mApp.getCarrierConfigForSubId(subId).getString(
8887 CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING);
8888 if (!TextUtils.isEmpty(carrierUAProfUrl)) {
8889 return carrierUAProfUrl;
8890 }
Daniel Brightebb4eb72020-02-18 15:16:33 -08008891 return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
8892 .getString(com.android.internal.R.string.config_mms_user_agent_profile_url);
chen xud5ca2d52019-05-28 15:20:57 -07008893 } finally {
8894 Binder.restoreCallingIdentity(identity);
8895 }
8896 }
8897
8898 @Override
8899 public String getMmsUserAgent(int subId) {
8900 //TODO investigate if this API should require proper permission check in R b/133791609
8901 final long identity = Binder.clearCallingIdentity();
8902 try {
Guoqiang.Qiu171383d2020-07-13 09:38:32 +08008903 String carrierUserAgent = mApp.getCarrierConfigForSubId(subId).getString(
8904 CarrierConfigManager.KEY_MMS_USER_AGENT_STRING);
8905 if (!TextUtils.isEmpty(carrierUserAgent)) {
8906 return carrierUserAgent;
8907 }
Daniel Brightebb4eb72020-02-18 15:16:33 -08008908 return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
8909 .getString(com.android.internal.R.string.config_mms_user_agent);
chen xud5ca2d52019-05-28 15:20:57 -07008910 } finally {
8911 Binder.restoreCallingIdentity(identity);
8912 }
8913 }
Jack Yub07d4972019-05-28 16:12:25 -07008914
8915 @Override
Hall Liua62f5da2020-09-25 10:42:19 -07008916 public boolean isMobileDataPolicyEnabled(int subscriptionId, int policy) {
8917 enforceReadPrivilegedPermission("isMobileDataPolicyEnabled");
Jack Yub07d4972019-05-28 16:12:25 -07008918
Jack Yub07d4972019-05-28 16:12:25 -07008919 final long identity = Binder.clearCallingIdentity();
8920 try {
Hall Liua62f5da2020-09-25 10:42:19 -07008921 Phone phone = getPhone(subscriptionId);
Jack Yub07d4972019-05-28 16:12:25 -07008922 if (phone == null) return false;
8923
Hall Liua62f5da2020-09-25 10:42:19 -07008924 switch (policy) {
8925 case TelephonyManager.MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL:
8926 return phone.getDataEnabledSettings().isDataAllowedInVoiceCall();
8927 case TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED:
8928 return phone.getDataEnabledSettings().isMmsAlwaysAllowed();
8929 default:
8930 throw new IllegalArgumentException(policy + " is not a valid policy");
8931 }
Jack Yub07d4972019-05-28 16:12:25 -07008932 } finally {
8933 Binder.restoreCallingIdentity(identity);
8934 }
8935 }
8936
8937 @Override
Hall Liua62f5da2020-09-25 10:42:19 -07008938 public void setMobileDataPolicyEnabledStatus(int subscriptionId, int policy,
8939 boolean enabled) {
changbettyd5c246e2019-12-24 15:40:37 +08008940 enforceModifyPermission();
8941
changbettyd5c246e2019-12-24 15:40:37 +08008942 final long identity = Binder.clearCallingIdentity();
8943 try {
Hall Liua62f5da2020-09-25 10:42:19 -07008944 Phone phone = getPhone(subscriptionId);
8945 if (phone == null) return;
changbettyd5c246e2019-12-24 15:40:37 +08008946
Hall Liua62f5da2020-09-25 10:42:19 -07008947 switch (policy) {
8948 case TelephonyManager.MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL:
8949 phone.getDataEnabledSettings().setAllowDataDuringVoiceCall(enabled);
8950 break;
8951 case TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED:
8952 phone.getDataEnabledSettings().setAlwaysAllowMmsData(enabled);
8953 break;
8954 default:
8955 throw new IllegalArgumentException(policy + " is not a valid policy");
8956 }
changbettyd5c246e2019-12-24 15:40:37 +08008957 } finally {
8958 Binder.restoreCallingIdentity(identity);
8959 }
8960 }
8961
Tyler Gunn7bcdc742019-10-04 15:56:59 -07008962 /**
Hall Liu746e03c2020-09-25 11:13:49 -07008963 * Updates whether conference event package handling is enabled.
Tyler Gunn7bcdc742019-10-04 15:56:59 -07008964 * @param isCepEnabled {@code true} if CEP handling is enabled (default), or {@code false}
8965 * otherwise.
8966 */
8967 @Override
8968 public void setCepEnabled(boolean isCepEnabled) {
8969 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setCepEnabled");
8970
8971 final long identity = Binder.clearCallingIdentity();
8972 try {
8973 Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled);
8974 for (Phone phone : PhoneFactory.getPhones()) {
8975 Phone defaultPhone = phone.getImsPhone();
8976 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
8977 ImsPhone imsPhone = (ImsPhone) defaultPhone;
8978 ImsPhoneCallTracker imsPhoneCallTracker =
8979 (ImsPhoneCallTracker) imsPhone.getCallTracker();
8980 imsPhoneCallTracker.setConferenceEventPackageEnabled(isCepEnabled);
8981 Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled + ", for imsPhone "
8982 + imsPhone.getMsisdn());
8983 }
8984 }
8985 } finally {
8986 Binder.restoreCallingIdentity(identity);
8987 }
8988 }
allenwtsu46dcc572020-01-08 18:24:03 +08008989
8990 /**
8991 * Notify that an RCS autoconfiguration XML file has been received for provisioning.
8992 *
8993 * @param config The XML file to be read. ASCII/UTF8 encoded text if not compressed.
8994 * @param isCompressed The XML file is compressed in gzip format and must be decompressed
8995 * before being read.
8996 */
8997 @Override
8998 public void notifyRcsAutoConfigurationReceived(int subId, @NonNull byte[] config, boolean
8999 isCompressed) {
9000 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
9001 mApp, subId, "notifyRcsAutoConfigurationReceived");
9002 try {
9003 IImsConfig configBinder = getImsConfig(getSlotIndex(subId), ImsFeature.FEATURE_RCS);
9004 if (configBinder == null) {
9005 Rlog.e(LOG_TAG, "null result for getImsConfig");
9006 } else {
9007 configBinder.notifyRcsAutoConfigurationReceived(config, isCompressed);
9008 }
9009 } catch (RemoteException e) {
9010 Rlog.e(LOG_TAG, "fail to getImsConfig " + e.getMessage());
9011 }
9012 }
zoey chene02881a2019-12-30 16:11:23 +08009013
9014 @Override
9015 public boolean isIccLockEnabled(int subId) {
9016 enforceReadPrivilegedPermission("isIccLockEnabled");
9017
9018 // Now that all security checks passes, perform the operation as ourselves.
9019 final long identity = Binder.clearCallingIdentity();
9020 try {
9021 Phone phone = getPhone(subId);
9022 if (phone != null && phone.getIccCard() != null) {
9023 return phone.getIccCard().getIccLockEnabled();
9024 } else {
9025 return false;
9026 }
9027 } finally {
9028 Binder.restoreCallingIdentity(identity);
9029 }
9030 }
9031
9032 /**
9033 * Set the ICC pin lock enabled or disabled.
9034 *
9035 * @return an integer representing the status of IccLock enabled or disabled in the following
9036 * three cases:
9037 * - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if enabled or disabled IccLock
9038 * successfully.
9039 * - Positive number and zero for remaining password attempts.
9040 * - Negative number for other failure cases (such like enabling/disabling PIN failed).
9041 *
9042 */
9043 @Override
9044 public int setIccLockEnabled(int subId, boolean enabled, String password) {
9045 enforceModifyPermission();
9046
9047 Phone phone = getPhone(subId);
9048 if (phone == null) {
9049 return 0;
9050 }
9051 // Now that all security checks passes, perform the operation as ourselves.
9052 final long identity = Binder.clearCallingIdentity();
9053 try {
9054 int attemptsRemaining = (int) sendRequest(CMD_SET_ICC_LOCK_ENABLED,
9055 new Pair<Boolean, String>(enabled, password), phone, null);
9056 return attemptsRemaining;
9057
9058 } catch (Exception e) {
9059 Log.e(LOG_TAG, "setIccLockEnabled. Exception e =" + e);
9060 } finally {
9061 Binder.restoreCallingIdentity(identity);
9062 }
9063 return 0;
9064 }
9065
9066 /**
9067 * Change the ICC password used in ICC pin lock.
9068 *
9069 * @return an integer representing the status of IccLock changed in the following three cases:
9070 * - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if changed IccLock successfully.
9071 * - Positive number and zero for remaining password attempts.
9072 * - Negative number for other failure cases (such like enabling/disabling PIN failed).
9073 *
9074 */
9075 @Override
9076 public int changeIccLockPassword(int subId, String oldPassword, String newPassword) {
9077 enforceModifyPermission();
9078
9079 Phone phone = getPhone(subId);
9080 if (phone == null) {
9081 return 0;
9082 }
9083 // Now that all security checks passes, perform the operation as ourselves.
9084 final long identity = Binder.clearCallingIdentity();
9085 try {
9086 int attemptsRemaining = (int) sendRequest(CMD_CHANGE_ICC_LOCK_PASSWORD,
9087 new Pair<String, String>(oldPassword, newPassword), phone, null);
9088 return attemptsRemaining;
9089
9090 } catch (Exception e) {
9091 Log.e(LOG_TAG, "changeIccLockPassword. Exception e =" + e);
9092 } finally {
9093 Binder.restoreCallingIdentity(identity);
9094 }
9095 return 0;
9096 }
Peter Wangdafb9ac2020-01-15 14:13:38 -08009097
9098 /**
9099 * Request for receiving user activity notification
9100 */
9101 @Override
9102 public void requestUserActivityNotification() {
9103 if (!mNotifyUserActivity.get()
9104 && !mMainThreadHandler.hasMessages(MSG_NOTIFY_USER_ACTIVITY)) {
9105 mNotifyUserActivity.set(true);
9106 }
9107 }
9108
9109 /**
9110 * Called when userActivity is signalled in the power manager.
9111 * This is safe to call from any thread, with any window manager locks held or not.
9112 */
9113 @Override
9114 public void userActivity() {
9115 // ***************************************
9116 // * Inherited from PhoneWindowManager *
9117 // ***************************************
9118 // THIS IS CALLED FROM DEEP IN THE POWER MANAGER
9119 // WITH ITS LOCKS HELD.
9120 //
9121 // This code must be VERY careful about the locks
9122 // it acquires.
9123 // In fact, the current code acquires way too many,
9124 // and probably has lurking deadlocks.
9125
9126 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9127 throw new SecurityException("Only the OS may call notifyUserActivity()");
9128 }
9129
9130 if (mNotifyUserActivity.getAndSet(false)) {
9131 mMainThreadHandler.sendEmptyMessageDelayed(MSG_NOTIFY_USER_ACTIVITY,
9132 USER_ACTIVITY_NOTIFICATION_DELAY);
9133 }
9134 }
Malcolm Chen4639c562020-04-13 11:59:40 -07009135
9136 @Override
9137 public boolean canConnectTo5GInDsdsMode() {
9138 return mApp.getResources().getBoolean(R.bool.config_5g_connection_in_dsds_mode);
9139 }
Jack Yud10cdd42020-09-28 20:28:01 -07009140
9141 @Override
9142 public @NonNull List<String> getEquivalentHomePlmns(int subId, String callingPackage,
9143 String callingFeatureId) {
9144 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
9145 mApp, subId, callingPackage, callingFeatureId, "getEquivalentHomePlmns")) {
9146 throw new SecurityException("Requires READ_PHONE_STATE permission.");
9147 }
9148
9149 Phone phone = getPhone(subId);
9150 if (phone == null) {
9151 throw new RuntimeException("phone is not available");
9152 }
9153 // Now that all security checks passes, perform the operation as ourselves.
9154 final long identity = Binder.clearCallingIdentity();
9155 try {
9156 return phone.getEquivalentHomePlmns();
9157 } finally {
9158 Binder.restoreCallingIdentity(identity);
9159 }
9160 }
Daniel Bright59e67312020-11-13 11:49:37 -08009161
9162 @Override
9163 public boolean isRadioInterfaceCapabilitySupported(
9164 @NonNull @TelephonyManager.RadioInterfaceCapability String capability) {
9165 RadioInterfaceCapabilities radioInterfaceCapabilities =
9166 mPhoneConfigurationManager.getRadioInterfaceCapabilities();
9167 if (radioInterfaceCapabilities == null) {
9168 throw new RuntimeException("radio interface capabilities are not available");
9169 } else {
9170 return radioInterfaceCapabilities.isSupported(capability);
9171 }
9172 }
Jack Nudelmanb0b87642020-11-12 15:04:39 -08009173
9174 /**
9175 * Attempts to set the radio power state for thermal reason. This does not guarantee that the
9176 * requested radio power state will actually be set. See {@link
9177 * PhoneInternalInterface#setRadioPowerForReason} for more details.
9178 *
9179 * @param subId the subscription ID of the phone requesting to set the radio power state.
9180 * @param enable {@code true} if trying to turn radio on.
9181 * @return {@code true} if phone setRadioPowerForReason was called. Otherwise, returns {@code
9182 * false}.
9183 */
9184 private boolean setRadioPowerForThermal(int subId, boolean enable) {
9185 Phone phone = getPhone(subId);
9186 if (phone != null) {
9187 phone.setRadioPowerForReason(enable, Phone.RADIO_POWER_REASON_THERMAL);
9188 return true;
9189 }
9190 return false;
9191 }
9192
9193 private int handleDataThrottlingRequest(int subId,
9194 DataThrottlingRequest dataThrottlingRequest) {
9195 // Ensure that radio is on. If not able to power on due to phone being unavailable, return
9196 // THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
9197 if (!setRadioPowerForThermal(subId, true)) {
9198 return TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
9199 }
9200
9201 setDataEnabledForReason(subId, TelephonyManager.DATA_ENABLED_REASON_THERMAL, true);
9202
9203 int thermalMitigationResult =
9204 (int) sendRequest(CMD_SET_DATA_THROTTLING, dataThrottlingRequest, subId);
9205 if (thermalMitigationResult == SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS) {
9206 throw new IllegalArgumentException("modem returned INVALID_ARGUMENTS");
9207 }
9208 return thermalMitigationResult;
9209 }
9210
9211 /**
9212 * Thermal mitigation request to control functionalities at modem.
9213 *
9214 * @param subId the id of the subscription.
9215 * @param thermalMitigationRequest holds all necessary information to be passed down to modem.
9216 *
9217 * @return thermalMitigationResult enum as defined in android.telephony.Annotation.
9218 */
9219 @Override
9220 @ThermalMitigationResult
9221 public int sendThermalMitigationRequest(
9222 int subId,
9223 ThermalMitigationRequest thermalMitigationRequest) throws IllegalArgumentException {
9224 enforceModifyPermission();
9225
9226 WorkSource workSource = getWorkSource(Binder.getCallingUid());
9227 final long identity = Binder.clearCallingIdentity();
9228
9229 int thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_UNKNOWN_ERROR;
9230 try {
9231 int thermalMitigationAction = thermalMitigationRequest.getThermalMitigationAction();
9232 switch (thermalMitigationAction) {
9233 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_DATA_THROTTLING:
9234 thermalMitigationResult =
9235 handleDataThrottlingRequest(subId,
9236 thermalMitigationRequest.getDataThrottlingRequest());
9237 break;
9238 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_VOICE_ONLY:
9239 if (thermalMitigationRequest.getDataThrottlingRequest() != null) {
9240 throw new IllegalArgumentException("dataThrottlingRequest must be null for "
9241 + "ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_VOICE_ONLY");
9242 }
9243
9244 // Ensure that radio is on. If not able to power on due to phone being
9245 // unavailable, return THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
9246 if (!setRadioPowerForThermal(subId, true)) {
9247 thermalMitigationResult =
9248 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
9249 break;
9250 }
9251
9252 setDataEnabledForReason(subId, TelephonyManager.DATA_ENABLED_REASON_THERMAL,
9253 false);
9254 thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
9255 break;
9256 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_RADIO_OFF:
9257 if (thermalMitigationRequest.getDataThrottlingRequest() != null) {
9258 throw new IllegalArgumentException("dataThrottlingRequest must be null for"
9259 + " ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_RADIO_OFF");
9260 }
9261
9262 TelecomAccountRegistry registry = TelecomAccountRegistry.getInstance(null);
9263 if (registry != null) {
9264 TelephonyConnectionService service =
9265 registry.getTelephonyConnectionService();
9266 Phone phone = getPhone(subId);
9267 if (phone == null) {
9268 thermalMitigationResult =
9269 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
9270 break;
9271 }
9272
9273 if (PhoneConstantConversions.convertCallState(phone.getState())
9274 != TelephonyManager.CALL_STATE_IDLE
9275 || phone.isInEmergencySmsMode() || phone.isInEcm()
9276 || (service != null && service.isEmergencyCallPending())) {
9277 String errorMessage = "Phone state is not valid. call state = "
9278 + PhoneConstantConversions.convertCallState(phone.getState())
9279 + " isInEmergencySmsMode = " + phone.isInEmergencySmsMode()
9280 + " isInEmergencyCallbackMode = " + phone.isInEcm();
9281 errorMessage += service == null
9282 ? " TelephonyConnectionService is null"
9283 : " isEmergencyCallPending = "
9284 + service.isEmergencyCallPending();
9285 Log.e(LOG_TAG, errorMessage);
9286 thermalMitigationResult =
9287 TelephonyManager.THERMAL_MITIGATION_RESULT_INVALID_STATE;
9288 break;
9289 }
9290 } else {
9291 thermalMitigationResult =
9292 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
9293 break;
9294 }
9295
9296 // Turn radio off. If not able to power off due to phone being unavailable,
9297 // return THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
9298 if (!setRadioPowerForThermal(subId, false)) {
9299 thermalMitigationResult =
9300 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
9301 break;
9302 }
9303 thermalMitigationResult =
9304 TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
9305 break;
9306 default:
9307 throw new IllegalArgumentException("the requested thermalMitigationAction does "
9308 + "not exist. Requested action: " + thermalMitigationAction);
9309 }
9310 } catch (IllegalArgumentException e) {
9311 throw e;
9312 } catch (Exception e) {
9313 Log.e(LOG_TAG, "thermalMitigationRequest. Exception e =" + e);
9314 thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
9315 } finally {
9316 Binder.restoreCallingIdentity(identity);
9317 }
9318
9319 if (DBG) {
9320 log("thermalMitigationRequest returning with thermalMitigationResult: "
9321 + thermalMitigationResult);
9322 }
9323
9324 return thermalMitigationResult;
9325 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07009326}