blob: ebea856cb869dbf3d6b57c93c69ff9762ceb1ae5 [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;
Jordan Liu109698e2020-11-24 14:50:34 -0800309 private static final int CMD_SET_SIM_POWER = 101;
310 private static final int EVENT_SET_SIM_POWER_DONE = 102;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700311
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -0800312 // Parameters of select command.
313 private static final int SELECT_COMMAND = 0xA4;
314 private static final int SELECT_P1 = 0x04;
315 private static final int SELECT_P2 = 0;
316 private static final int SELECT_P3 = 0x10;
317
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700318 /** The singleton instance. */
319 private static PhoneInterfaceManager sInstance;
320
Wink Saville3ab207e2014-11-20 13:07:20 -0800321 private PhoneGlobals mApp;
Wink Saville3ab207e2014-11-20 13:07:20 -0800322 private CallManager mCM;
Brad Ebinger24c29992019-12-05 13:03:21 -0800323 private ImsResolver mImsResolver;
Stuart Scott981d8582015-04-21 14:09:50 -0700324 private UserManager mUserManager;
Wink Saville3ab207e2014-11-20 13:07:20 -0800325 private AppOpsManager mAppOps;
326 private MainThreadHandler mMainThreadHandler;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800327 private SubscriptionController mSubscriptionController;
Wink Saville3ab207e2014-11-20 13:07:20 -0800328 private SharedPreferences mTelephonySharedPreferences;
Malcolm Chen2c63d402018-08-14 16:00:53 -0700329 private PhoneConfigurationManager mPhoneConfigurationManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700330
Peter Wangdafb9ac2020-01-15 14:13:38 -0800331 /** User Activity */
332 private AtomicBoolean mNotifyUserActivity;
Peter Wangdafb9ac2020-01-15 14:13:38 -0800333 private static final int USER_ACTIVITY_NOTIFICATION_DELAY = 200;
334
Jeff Davidson8ab02b22020-03-28 12:24:40 -0700335 private Set<Integer> mCarrierPrivilegeTestOverrideSubIds = new ArraySet<>();
336
Derek Tan97ebb422014-09-05 16:55:38 -0700337 private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
338 private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
Jeff Sharkey85190e62014-12-05 09:40:12 -0800339 private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800340 private static final String PREF_PROVISION_IMS_MMTEL_PREFIX = "provision_ims_mmtel_";
Derek Tan89e89d42014-07-08 17:00:10 -0700341
Michelecea4cf22018-12-21 15:00:11 -0800342 // String to store multi SIM allowed
343 private static final String PREF_MULTI_SIM_RESTRICTED = "multisim_restricted";
344
Derek Tan740e1672017-06-27 14:56:27 -0700345 // The AID of ISD-R.
346 private static final String ISDR_AID = "A0000005591010FFFFFFFF8900000100";
347
yinxub1bed742017-04-17 11:45:04 -0700348 private NetworkScanRequestTracker mNetworkScanRequestTracker;
349
David Kelly5e06a7f2018-03-12 14:10:59 +0000350 private static final int TYPE_ALLOCATION_CODE_LENGTH = 8;
351 private static final int MANUFACTURER_CODE_LENGTH = 8;
352
Jack Nudelmanb0b87642020-11-12 15:04:39 -0800353 private static final int SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS = -1;
354
Derek Tan89e89d42014-07-08 17:00:10 -0700355 /**
Naina Nallurid63128d2019-09-17 14:10:30 -0700356 * Experiment flag to enable erase modem config on reset network, default value is false
357 */
358 public static final String RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED =
359 "reset_network_erase_modem_config_enabled";
360
361 /**
Shishir Agrawal566b7612013-10-28 14:41:00 -0700362 * A request object to use for transmitting data to an ICC.
363 */
364 private static final class IccAPDUArgument {
365 public int channel, cla, command, p1, p2, p3;
366 public String data;
367
368 public IccAPDUArgument(int channel, int cla, int command,
369 int p1, int p2, int p3, String data) {
370 this.channel = channel;
371 this.cla = cla;
372 this.command = command;
373 this.p1 = p1;
374 this.p2 = p2;
375 this.p3 = p3;
376 this.data = data;
377 }
378 }
379
380 /**
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700381 * A request object to use for transmitting data to an ICC.
382 */
383 private static final class ManualNetworkSelectionArgument {
384 public OperatorInfo operatorInfo;
385 public boolean persistSelection;
386
387 public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) {
388 this.operatorInfo = operatorInfo;
389 this.persistSelection = persistSelection;
390 }
391 }
392
393 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700394 * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
395 * request after sending. The main thread will notify the request when it is complete.
396 */
397 private static final class MainThreadRequest {
398 /** The argument to use for the request */
399 public Object argument;
400 /** The result of the request that is run on the main thread */
401 public Object result;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800402 // The subscriber id that this request applies to. Defaults to
403 // SubscriptionManager.INVALID_SUBSCRIPTION_ID
404 public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700405
Nathan Harold92bed182018-10-12 18:16:49 -0700406 // In cases where subId is unavailable, the caller needs to specify the phone.
407 public Phone phone;
408
vagdeviaf9a5b92018-08-15 16:01:53 -0700409 public WorkSource workSource;
410
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700411 public MainThreadRequest(Object argument) {
412 this.argument = argument;
413 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800414
Nathan Harold92bed182018-10-12 18:16:49 -0700415 MainThreadRequest(Object argument, Phone phone, WorkSource workSource) {
416 this.argument = argument;
417 if (phone != null) {
418 this.phone = phone;
419 }
420 this.workSource = workSource;
421 }
422
vagdeviaf9a5b92018-08-15 16:01:53 -0700423 MainThreadRequest(Object argument, Integer subId, WorkSource workSource) {
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800424 this.argument = argument;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800425 if (subId != null) {
426 this.subId = subId;
427 }
vagdeviaf9a5b92018-08-15 16:01:53 -0700428 this.workSource = workSource;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800429 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700430 }
431
Sailesh Nepalcc0375f2013-11-13 09:15:18 -0800432 private static final class IncomingThirdPartyCallArgs {
433 public final ComponentName component;
434 public final String callId;
435 public final String callerDisplayName;
436
437 public IncomingThirdPartyCallArgs(ComponentName component, String callId,
438 String callerDisplayName) {
439 this.component = component;
440 this.callId = callId;
441 this.callerDisplayName = callerDisplayName;
442 }
443 }
444
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700445 /**
446 * A handler that processes messages on the main thread in the phone process. Since many
447 * of the Phone calls are not thread safe this is needed to shuttle the requests from the
448 * inbound binder threads to the main thread in the phone process. The Binder thread
449 * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
450 * on, which will be notified when the operation completes and will contain the result of the
451 * request.
452 *
453 * <p>If a MainThreadRequest object is provided in the msg.obj field,
454 * note that request.result must be set to something non-null for the calling thread to
455 * unblock.
456 */
457 private final class MainThreadHandler extends Handler {
458 @Override
459 public void handleMessage(Message msg) {
460 MainThreadRequest request;
461 Message onCompleted;
462 AsyncResult ar;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800463 UiccCard uiccCard;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700464 IccAPDUArgument iccArgument;
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800465 final Phone defaultPhone = getDefaultPhone();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700466
467 switch (msg.what) {
Pengquan Menga1bb6272018-09-06 09:59:22 -0700468 case CMD_HANDLE_USSD_REQUEST: {
469 request = (MainThreadRequest) msg.obj;
470 final Phone phone = getPhoneFromRequest(request);
471 Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
472 String ussdRequest = ussdObject.first;
473 ResultReceiver wrappedCallback = ussdObject.second;
Tyler Gunn65d45c22017-06-05 11:22:26 -0700474
Pengquan Menga1bb6272018-09-06 09:59:22 -0700475 if (!isUssdApiAllowed(request.subId)) {
476 // Carrier does not support use of this API, return failure.
477 Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
478 UssdResponse response = new UssdResponse(ussdRequest, null);
479 Bundle returnData = new Bundle();
480 returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
481 wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
Tyler Gunn65d45c22017-06-05 11:22:26 -0700482
Pengquan Menga1bb6272018-09-06 09:59:22 -0700483 request.result = true;
484 notifyRequester(request);
485 return;
486 }
Tyler Gunn65d45c22017-06-05 11:22:26 -0700487
Pengquan Menga1bb6272018-09-06 09:59:22 -0700488 try {
489 request.result = phone != null
490 ? phone.handleUssdRequest(ussdRequest, wrappedCallback) : false;
491 } catch (CallStateException cse) {
492 request.result = false;
493 }
494 // Wake up the requesting thread
495 notifyRequester(request);
496 break;
pkanwar32d516d2016-10-14 19:37:38 -0700497 }
498
Yorke Lee716f67e2015-06-17 15:39:16 -0700499 case CMD_HANDLE_PIN_MMI: {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700500 request = (MainThreadRequest) msg.obj;
Yorke Lee716f67e2015-06-17 15:39:16 -0700501 final Phone phone = getPhoneFromRequest(request);
502 request.result = phone != null ?
503 getPhoneFromRequest(request).handlePinMmi((String) request.argument)
504 : false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700505 // Wake up the requesting thread
Pengquan Menga1bb6272018-09-06 09:59:22 -0700506 notifyRequester(request);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700507 break;
Yorke Lee716f67e2015-06-17 15:39:16 -0700508 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700509
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700510 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700511 request = (MainThreadRequest) msg.obj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700512 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800513 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700514 if (uiccCard == null) {
515 loge("iccTransmitApduLogicalChannel: No UICC");
516 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700517 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700518 } else {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700519 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
520 request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700521 uiccCard.iccTransmitApduLogicalChannel(
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700522 iccArgument.channel, iccArgument.cla, iccArgument.command,
523 iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data,
Shishir Agrawal566b7612013-10-28 14:41:00 -0700524 onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700525 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700526 break;
527
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700528 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700529 ar = (AsyncResult) msg.obj;
530 request = (MainThreadRequest) ar.userObj;
531 if (ar.exception == null && ar.result != null) {
532 request.result = ar.result;
533 } else {
534 request.result = new IccIoResult(0x6F, 0, (byte[])null);
535 if (ar.result == null) {
536 loge("iccTransmitApduLogicalChannel: Empty response");
Jake Hambye994d462014-02-03 13:10:13 -0800537 } else if (ar.exception instanceof CommandException) {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700538 loge("iccTransmitApduLogicalChannel: CommandException: " +
Jake Hambye994d462014-02-03 13:10:13 -0800539 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700540 } else {
541 loge("iccTransmitApduLogicalChannel: Unknown exception");
542 }
543 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700544 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700545 break;
546
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700547 case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
548 request = (MainThreadRequest) msg.obj;
549 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800550 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700551 if (uiccCard == null) {
552 loge("iccTransmitApduBasicChannel: No UICC");
553 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700554 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700555 } else {
556 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
557 request);
558 uiccCard.iccTransmitApduBasicChannel(
559 iccArgument.cla, iccArgument.command, iccArgument.p1, iccArgument.p2,
560 iccArgument.p3, iccArgument.data, onCompleted);
561 }
562 break;
563
564 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
565 ar = (AsyncResult) msg.obj;
566 request = (MainThreadRequest) ar.userObj;
567 if (ar.exception == null && ar.result != null) {
568 request.result = ar.result;
569 } else {
570 request.result = new IccIoResult(0x6F, 0, (byte[])null);
571 if (ar.result == null) {
572 loge("iccTransmitApduBasicChannel: Empty response");
573 } else if (ar.exception instanceof CommandException) {
574 loge("iccTransmitApduBasicChannel: CommandException: " +
575 ar.exception);
576 } else {
577 loge("iccTransmitApduBasicChannel: Unknown exception");
578 }
579 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700580 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700581 break;
582
583 case CMD_EXCHANGE_SIM_IO:
584 request = (MainThreadRequest) msg.obj;
585 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800586 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700587 if (uiccCard == null) {
588 loge("iccExchangeSimIO: No UICC");
589 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700590 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700591 } else {
592 onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
593 request);
594 uiccCard.iccExchangeSimIO(iccArgument.cla, /* fileID */
595 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3,
596 iccArgument.data, onCompleted);
597 }
598 break;
599
600 case EVENT_EXCHANGE_SIM_IO_DONE:
601 ar = (AsyncResult) msg.obj;
602 request = (MainThreadRequest) ar.userObj;
603 if (ar.exception == null && ar.result != null) {
604 request.result = ar.result;
605 } else {
606 request.result = new IccIoResult(0x6f, 0, (byte[])null);
607 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700608 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700609 break;
610
Derek Tan4d5e5c12014-02-04 11:54:58 -0800611 case CMD_SEND_ENVELOPE:
612 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800613 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700614 if (uiccCard == null) {
615 loge("sendEnvelopeWithStatus: No UICC");
616 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700617 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700618 } else {
619 onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
620 uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted);
621 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800622 break;
623
624 case EVENT_SEND_ENVELOPE_DONE:
625 ar = (AsyncResult) msg.obj;
626 request = (MainThreadRequest) ar.userObj;
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700627 if (ar.exception == null && ar.result != null) {
628 request.result = ar.result;
Derek Tan4d5e5c12014-02-04 11:54:58 -0800629 } else {
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700630 request.result = new IccIoResult(0x6F, 0, (byte[])null);
631 if (ar.result == null) {
632 loge("sendEnvelopeWithStatus: Empty response");
633 } else if (ar.exception instanceof CommandException) {
634 loge("sendEnvelopeWithStatus: CommandException: " +
635 ar.exception);
636 } else {
637 loge("sendEnvelopeWithStatus: exception:" + ar.exception);
638 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800639 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700640 notifyRequester(request);
Derek Tan4d5e5c12014-02-04 11:54:58 -0800641 break;
642
Shishir Agrawal566b7612013-10-28 14:41:00 -0700643 case CMD_OPEN_CHANNEL:
644 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800645 uiccCard = getUiccCardFromRequest(request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800646 Pair<String, Integer> openChannelArgs = (Pair<String, Integer>) request.argument;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700647 if (uiccCard == null) {
648 loge("iccOpenLogicalChannel: No UICC");
Shishir Agrawalfc0492a2016-02-17 11:15:33 -0800649 request.result = new IccOpenLogicalChannelResponse(-1,
650 IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700651 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700652 } else {
653 onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800654 uiccCard.iccOpenLogicalChannel(openChannelArgs.first,
655 openChannelArgs.second, onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700656 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700657 break;
658
659 case EVENT_OPEN_CHANNEL_DONE:
660 ar = (AsyncResult) msg.obj;
661 request = (MainThreadRequest) ar.userObj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700662 IccOpenLogicalChannelResponse openChannelResp;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700663 if (ar.exception == null && ar.result != null) {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700664 int[] result = (int[]) ar.result;
665 int channelId = result[0];
666 byte[] selectResponse = null;
667 if (result.length > 1) {
668 selectResponse = new byte[result.length - 1];
669 for (int i = 1; i < result.length; ++i) {
670 selectResponse[i - 1] = (byte) result[i];
671 }
672 }
673 openChannelResp = new IccOpenLogicalChannelResponse(channelId,
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700674 IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700675 } else {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700676 if (ar.result == null) {
677 loge("iccOpenLogicalChannel: Empty response");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700678 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700679 if (ar.exception != null) {
680 loge("iccOpenLogicalChannel: Exception: " + ar.exception);
681 }
682
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700683 int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR;
Junda Liua754ba12015-05-20 01:17:52 -0700684 if (ar.exception instanceof CommandException) {
685 CommandException.Error error =
686 ((CommandException) (ar.exception)).getCommandError();
687 if (error == CommandException.Error.MISSING_RESOURCE) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700688 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE;
Junda Liua754ba12015-05-20 01:17:52 -0700689 } else if (error == CommandException.Error.NO_SUCH_ELEMENT) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700690 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700691 }
692 }
693 openChannelResp = new IccOpenLogicalChannelResponse(
694 IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700695 }
Shishir Agrawal82c8a462014-07-31 18:13:17 -0700696 request.result = openChannelResp;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700697 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700698 break;
699
700 case CMD_CLOSE_CHANNEL:
701 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800702 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700703 if (uiccCard == null) {
704 loge("iccCloseLogicalChannel: No UICC");
Yoshiaki Naka2e29d822016-09-02 19:27:39 +0900705 request.result = false;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700706 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700707 } else {
708 onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
709 uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
710 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700711 break;
712
713 case EVENT_CLOSE_CHANNEL_DONE:
Jake Hambye994d462014-02-03 13:10:13 -0800714 handleNullReturnEvent(msg, "iccCloseLogicalChannel");
715 break;
716
717 case CMD_NV_READ_ITEM:
718 request = (MainThreadRequest) msg.obj;
719 onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800720 defaultPhone.nvReadItem((Integer) request.argument, onCompleted,
721 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800722 break;
723
724 case EVENT_NV_READ_ITEM_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700725 ar = (AsyncResult) msg.obj;
726 request = (MainThreadRequest) ar.userObj;
Jake Hambye994d462014-02-03 13:10:13 -0800727 if (ar.exception == null && ar.result != null) {
728 request.result = ar.result; // String
Shishir Agrawal566b7612013-10-28 14:41:00 -0700729 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800730 request.result = "";
731 if (ar.result == null) {
732 loge("nvReadItem: Empty response");
733 } else if (ar.exception instanceof CommandException) {
734 loge("nvReadItem: CommandException: " +
735 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700736 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800737 loge("nvReadItem: Unknown exception");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700738 }
739 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700740 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700741 break;
742
Jake Hambye994d462014-02-03 13:10:13 -0800743 case CMD_NV_WRITE_ITEM:
744 request = (MainThreadRequest) msg.obj;
745 onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
746 Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800747 defaultPhone.nvWriteItem(idValue.first, idValue.second, onCompleted,
vagdeviaf9a5b92018-08-15 16:01:53 -0700748 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800749 break;
750
751 case EVENT_NV_WRITE_ITEM_DONE:
752 handleNullReturnEvent(msg, "nvWriteItem");
753 break;
754
755 case CMD_NV_WRITE_CDMA_PRL:
756 request = (MainThreadRequest) msg.obj;
757 onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800758 defaultPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
Jake Hambye994d462014-02-03 13:10:13 -0800759 break;
760
761 case EVENT_NV_WRITE_CDMA_PRL_DONE:
762 handleNullReturnEvent(msg, "nvWriteCdmaPrl");
763 break;
764
chen xu6dac5ab2018-10-26 17:39:23 -0700765 case CMD_RESET_MODEM_CONFIG:
Jake Hambye994d462014-02-03 13:10:13 -0800766 request = (MainThreadRequest) msg.obj;
chen xu6dac5ab2018-10-26 17:39:23 -0700767 onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800768 defaultPhone.resetModemConfig(onCompleted);
Jake Hambye994d462014-02-03 13:10:13 -0800769 break;
770
chen xu6dac5ab2018-10-26 17:39:23 -0700771 case EVENT_RESET_MODEM_CONFIG_DONE:
772 handleNullReturnEvent(msg, "resetModemConfig");
Jake Hambye994d462014-02-03 13:10:13 -0800773 break;
774
Sooraj Sasindran37444802020-08-11 10:40:43 -0700775 case CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED: {
776 request = (MainThreadRequest) msg.obj;
777 onCompleted = obtainMessage(EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE,
778 request);
779 Phone phone = getPhoneFromRequest(request);
780 if (phone != null) {
781 phone.isNrDualConnectivityEnabled(onCompleted, request.workSource);
782 } else {
783 loge("isNRDualConnectivityEnabled: No phone object");
784 request.result = false;
785 notifyRequester(request);
786 }
787 break;
788 }
789
790 case EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE:
791 ar = (AsyncResult) msg.obj;
792 request = (MainThreadRequest) ar.userObj;
793 if (ar.exception == null && ar.result != null) {
794 request.result = ar.result;
795 } else {
796 // request.result must be set to something non-null
797 // for the calling thread to unblock
798 if (request.result != null) {
799 request.result = ar.result;
800 } else {
801 request.result = false;
802 }
803 if (ar.result == null) {
804 loge("isNRDualConnectivityEnabled: Empty response");
805 } else if (ar.exception instanceof CommandException) {
806 loge("isNRDualConnectivityEnabled: CommandException: "
807 + ar.exception);
808 } else {
809 loge("isNRDualConnectivityEnabled: Unknown exception");
810 }
811 }
812 notifyRequester(request);
813 break;
814
815 case CMD_ENABLE_NR_DUAL_CONNECTIVITY: {
816 request = (MainThreadRequest) msg.obj;
817 onCompleted = obtainMessage(EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE, request);
818 Phone phone = getPhoneFromRequest(request);
819 if (phone != null) {
820 phone.setNrDualConnectivityState((int) request.argument, onCompleted,
821 request.workSource);
822 } else {
823 loge("enableNrDualConnectivity: No phone object");
824 request.result =
825 TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE;
826 notifyRequester(request);
827 }
828 break;
829 }
830
831 case EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE: {
832 ar = (AsyncResult) msg.obj;
833 request = (MainThreadRequest) ar.userObj;
834 if (ar.exception == null) {
835 request.result =
836 TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_SUCCESS;
837 } else {
838 request.result =
839 TelephonyManager
840 .ENABLE_NR_DUAL_CONNECTIVITY_RADIO_ERROR;
841 if (ar.exception instanceof CommandException) {
842 CommandException.Error error =
843 ((CommandException) (ar.exception)).getCommandError();
844 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
845 request.result =
846 TelephonyManager
847 .ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE;
848 }
849 loge("enableNrDualConnectivity" + ": CommandException: "
850 + ar.exception);
851 } else {
852 loge("enableNrDualConnectivity" + ": Unknown exception");
853 }
854 }
855 notifyRequester(request);
856 break;
857 }
858
Jake Hamby7c27be32014-03-03 13:25:59 -0800859 case CMD_GET_PREFERRED_NETWORK_TYPE:
860 request = (MainThreadRequest) msg.obj;
861 onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request);
Stuart Scott54788802015-03-30 13:18:01 -0700862 getPhoneFromRequest(request).getPreferredNetworkType(onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800863 break;
864
865 case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE:
866 ar = (AsyncResult) msg.obj;
867 request = (MainThreadRequest) ar.userObj;
868 if (ar.exception == null && ar.result != null) {
869 request.result = ar.result; // Integer
870 } else {
Nazish Tabassume8ba43a2020-07-28 14:49:25 +0530871 // request.result must be set to something non-null
872 // for the calling thread to unblock
873 request.result = new int[]{-1};
Jake Hamby7c27be32014-03-03 13:25:59 -0800874 if (ar.result == null) {
875 loge("getPreferredNetworkType: Empty response");
876 } else if (ar.exception instanceof CommandException) {
877 loge("getPreferredNetworkType: CommandException: " +
878 ar.exception);
879 } else {
880 loge("getPreferredNetworkType: Unknown exception");
881 }
882 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700883 notifyRequester(request);
Jake Hamby7c27be32014-03-03 13:25:59 -0800884 break;
885
886 case CMD_SET_PREFERRED_NETWORK_TYPE:
887 request = (MainThreadRequest) msg.obj;
888 onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request);
889 int networkType = (Integer) request.argument;
Stuart Scott54788802015-03-30 13:18:01 -0700890 getPhoneFromRequest(request).setPreferredNetworkType(networkType, onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800891 break;
892
893 case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE:
894 handleNullReturnEvent(msg, "setPreferredNetworkType");
895 break;
896
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000897 case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
898 request = (MainThreadRequest)msg.obj;
899 onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800900 defaultPhone.invokeOemRilRequestRaw((byte[]) request.argument, onCompleted);
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000901 break;
902
903 case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
904 ar = (AsyncResult)msg.obj;
905 request = (MainThreadRequest)ar.userObj;
906 request.result = ar;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700907 notifyRequester(request);
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000908 break;
909
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800910 case CMD_SET_VOICEMAIL_NUMBER:
911 request = (MainThreadRequest) msg.obj;
912 onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
913 Pair<String, String> tagNum = (Pair<String, String>) request.argument;
Stuart Scott584921c2015-01-15 17:10:34 -0800914 getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
915 onCompleted);
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800916 break;
917
918 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
919 handleNullReturnEvent(msg, "setVoicemailNumber");
920 break;
921
Stuart Scott54788802015-03-30 13:18:01 -0700922 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC:
923 request = (MainThreadRequest) msg.obj;
924 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE,
925 request);
926 getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted);
927 break;
928
929 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE:
930 handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic");
931 break;
932
Shishir Agrawal302c8692015-06-19 13:49:39 -0700933 case CMD_PERFORM_NETWORK_SCAN:
934 request = (MainThreadRequest) msg.obj;
935 onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request);
936 getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
937 break;
938
Hall Liu27d24262020-09-18 19:04:59 -0700939 case CMD_GET_CALL_FORWARDING: {
Shuo Qian4a594052020-01-23 11:59:30 -0800940 request = (MainThreadRequest) msg.obj;
941 onCompleted = obtainMessage(EVENT_GET_CALL_FORWARDING_DONE, request);
Hall Liu27d24262020-09-18 19:04:59 -0700942 Pair<Integer, TelephonyManager.CallForwardingInfoCallback> args =
943 (Pair<Integer, TelephonyManager.CallForwardingInfoCallback>)
944 request.argument;
945 int callForwardingReason = args.first;
946 request.phone.getCallForwardingOption(callForwardingReason, onCompleted);
Shuo Qian4a594052020-01-23 11:59:30 -0800947 break;
Hall Liu27d24262020-09-18 19:04:59 -0700948 }
949 case EVENT_GET_CALL_FORWARDING_DONE: {
Shuo Qian4a594052020-01-23 11:59:30 -0800950 ar = (AsyncResult) msg.obj;
951 request = (MainThreadRequest) ar.userObj;
Hall Liu27d24262020-09-18 19:04:59 -0700952 TelephonyManager.CallForwardingInfoCallback callback =
953 ((Pair<Integer, TelephonyManager.CallForwardingInfoCallback>)
954 request.argument).second;
Shuo Qian4a594052020-01-23 11:59:30 -0800955 if (ar.exception == null && ar.result != null) {
Hall Liu27d24262020-09-18 19:04:59 -0700956 CallForwardingInfo callForwardingInfo = null;
Shuo Qian4a594052020-01-23 11:59:30 -0800957 CallForwardInfo[] callForwardInfos = (CallForwardInfo[]) ar.result;
958 for (CallForwardInfo callForwardInfo : callForwardInfos) {
959 // Service Class is a bit mask per 3gpp 27.007. Search for
960 // any service for voice call.
961 if ((callForwardInfo.serviceClass
962 & CommandsInterface.SERVICE_CLASS_VOICE) > 0) {
Hall Liu27d24262020-09-18 19:04:59 -0700963 callForwardingInfo = new CallForwardingInfo(true,
964 callForwardInfo.reason,
965 callForwardInfo.number,
966 callForwardInfo.timeSeconds);
Shuo Qian4a594052020-01-23 11:59:30 -0800967 break;
968 }
969 }
970 // Didn't find a call forward info for voice call.
971 if (callForwardingInfo == null) {
Hall Liu27d24262020-09-18 19:04:59 -0700972 callForwardingInfo = new CallForwardingInfo(false /* enabled */,
973 0 /* reason */, null /* number */, 0 /* timeout */);
Shuo Qian4a594052020-01-23 11:59:30 -0800974 }
Hall Liu27d24262020-09-18 19:04:59 -0700975 callback.onCallForwardingInfoAvailable(callForwardingInfo);
Shuo Qian4a594052020-01-23 11:59:30 -0800976 } else {
977 if (ar.result == null) {
978 loge("EVENT_GET_CALL_FORWARDING_DONE: Empty response");
979 }
980 if (ar.exception != null) {
981 loge("EVENT_GET_CALL_FORWARDING_DONE: Exception: " + ar.exception);
982 }
Hall Liu940c4ca2020-09-29 17:10:18 -0700983 int errorCode = TelephonyManager
984 .CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN;
Shuo Qian4a594052020-01-23 11:59:30 -0800985 if (ar.exception instanceof CommandException) {
986 CommandException.Error error =
987 ((CommandException) (ar.exception)).getCommandError();
988 if (error == CommandException.Error.FDN_CHECK_FAILURE) {
Hall Liu940c4ca2020-09-29 17:10:18 -0700989 errorCode = TelephonyManager
990 .CallForwardingInfoCallback.RESULT_ERROR_FDN_CHECK_FAILURE;
Shuo Qian4a594052020-01-23 11:59:30 -0800991 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
Hall Liu940c4ca2020-09-29 17:10:18 -0700992 errorCode = TelephonyManager
993 .CallForwardingInfoCallback.RESULT_ERROR_NOT_SUPPORTED;
Shuo Qian4a594052020-01-23 11:59:30 -0800994 }
995 }
Hall Liu27d24262020-09-18 19:04:59 -0700996 callback.onError(errorCode);
Shuo Qian4a594052020-01-23 11:59:30 -0800997 }
Shuo Qian4a594052020-01-23 11:59:30 -0800998 break;
Hall Liu27d24262020-09-18 19:04:59 -0700999 }
Shuo Qian4a594052020-01-23 11:59:30 -08001000
Hall Liu27d24262020-09-18 19:04:59 -07001001 case CMD_SET_CALL_FORWARDING: {
Shuo Qian4a594052020-01-23 11:59:30 -08001002 request = (MainThreadRequest) msg.obj;
1003 onCompleted = obtainMessage(EVENT_SET_CALL_FORWARDING_DONE, request);
Hall Liu27d24262020-09-18 19:04:59 -07001004 request = (MainThreadRequest) msg.obj;
Shuo Qian4a594052020-01-23 11:59:30 -08001005 CallForwardingInfo callForwardingInfoToSet =
Hall Liu27d24262020-09-18 19:04:59 -07001006 ((Pair<CallForwardingInfo, Consumer<Integer>>)
1007 request.argument).first;
1008 request.phone.setCallForwardingOption(
1009 callForwardingInfoToSet.isEnabled()
1010 ? CommandsInterface.CF_ACTION_ENABLE
1011 : CommandsInterface.CF_ACTION_DISABLE,
Shuo Qian4a594052020-01-23 11:59:30 -08001012 callForwardingInfoToSet.getReason(),
1013 callForwardingInfoToSet.getNumber(),
1014 callForwardingInfoToSet.getTimeoutSeconds(), onCompleted);
1015 break;
Hall Liu27d24262020-09-18 19:04:59 -07001016 }
Shuo Qian4a594052020-01-23 11:59:30 -08001017
Hall Liu27d24262020-09-18 19:04:59 -07001018 case EVENT_SET_CALL_FORWARDING_DONE: {
Shuo Qian4a594052020-01-23 11:59:30 -08001019 ar = (AsyncResult) msg.obj;
1020 request = (MainThreadRequest) ar.userObj;
Hall Liu27d24262020-09-18 19:04:59 -07001021 Consumer<Integer> callback =
1022 ((Pair<CallForwardingInfo, Consumer<Integer>>)
1023 request.argument).second;
1024 if (ar.exception != null) {
Shuo Qian4a594052020-01-23 11:59:30 -08001025 loge("setCallForwarding exception: " + ar.exception);
Hall Liu940c4ca2020-09-29 17:10:18 -07001026 int errorCode = TelephonyManager.CallForwardingInfoCallback
1027 .RESULT_ERROR_UNKNOWN;
Hall Liu27d24262020-09-18 19:04:59 -07001028 if (ar.exception instanceof CommandException) {
1029 CommandException.Error error =
1030 ((CommandException) (ar.exception)).getCommandError();
1031 if (error == CommandException.Error.FDN_CHECK_FAILURE) {
Hall Liu940c4ca2020-09-29 17:10:18 -07001032 errorCode = TelephonyManager.CallForwardingInfoCallback
1033 .RESULT_ERROR_FDN_CHECK_FAILURE;
Hall Liu27d24262020-09-18 19:04:59 -07001034 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
Hall Liu940c4ca2020-09-29 17:10:18 -07001035 errorCode = TelephonyManager.CallForwardingInfoCallback
1036 .RESULT_ERROR_NOT_SUPPORTED;
Hall Liu27d24262020-09-18 19:04:59 -07001037 }
1038 }
1039 callback.accept(errorCode);
1040 } else {
Hall Liu940c4ca2020-09-29 17:10:18 -07001041 callback.accept(TelephonyManager.CallForwardingInfoCallback.RESULT_SUCCESS);
Shuo Qian4a594052020-01-23 11:59:30 -08001042 }
Shuo Qian4a594052020-01-23 11:59:30 -08001043 break;
Hall Liu27d24262020-09-18 19:04:59 -07001044 }
Shuo Qian4a594052020-01-23 11:59:30 -08001045
Hall Liu27d24262020-09-18 19:04:59 -07001046 case CMD_GET_CALL_WAITING: {
Shuo Qian4a594052020-01-23 11:59:30 -08001047 request = (MainThreadRequest) msg.obj;
1048 onCompleted = obtainMessage(EVENT_GET_CALL_WAITING_DONE, request);
1049 getPhoneFromRequest(request).getCallWaiting(onCompleted);
1050 break;
Hall Liu27d24262020-09-18 19:04:59 -07001051 }
Shuo Qian4a594052020-01-23 11:59:30 -08001052
Hall Liu27d24262020-09-18 19:04:59 -07001053 case EVENT_GET_CALL_WAITING_DONE: {
Shuo Qian4a594052020-01-23 11:59:30 -08001054 ar = (AsyncResult) msg.obj;
1055 request = (MainThreadRequest) ar.userObj;
Hall Liu27d24262020-09-18 19:04:59 -07001056 Consumer<Integer> callback = (Consumer<Integer>) request.argument;
Shuo Qian4a594052020-01-23 11:59:30 -08001057 int callForwardingStatus = TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR;
1058 if (ar.exception == null && ar.result != null) {
Shuo Qiand6a0dba2020-02-18 18:13:49 -08001059 int[] callForwardResults = (int[]) ar.result;
Shuo Qian4a594052020-01-23 11:59:30 -08001060 // Service Class is a bit mask per 3gpp 27.007.
1061 // Search for any service for voice call.
Shuo Qiand6a0dba2020-02-18 18:13:49 -08001062 if (callForwardResults.length > 1
1063 && ((callForwardResults[1]
Hall Liu27d24262020-09-18 19:04:59 -07001064 & CommandsInterface.SERVICE_CLASS_VOICE) > 0)) {
Shuo Qiand6a0dba2020-02-18 18:13:49 -08001065 callForwardingStatus = callForwardResults[0] == 0
Hall Liu27d24262020-09-18 19:04:59 -07001066 ? TelephonyManager.CALL_WAITING_STATUS_DISABLED
1067 : TelephonyManager.CALL_WAITING_STATUS_ENABLED;
Shuo Qian4a594052020-01-23 11:59:30 -08001068 } else {
Hall Liu27d24262020-09-18 19:04:59 -07001069 callForwardingStatus = TelephonyManager.CALL_WAITING_STATUS_DISABLED;
Shuo Qian4a594052020-01-23 11:59:30 -08001070 }
1071 } else {
1072 if (ar.result == null) {
1073 loge("EVENT_GET_CALL_WAITING_DONE: Empty response");
1074 }
1075 if (ar.exception != null) {
1076 loge("EVENT_GET_CALL_WAITING_DONE: Exception: " + ar.exception);
1077 }
1078 if (ar.exception instanceof CommandException) {
1079 CommandException.Error error =
1080 ((CommandException) (ar.exception)).getCommandError();
1081 if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1082 callForwardingStatus =
1083 TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED;
1084 }
1085 }
1086 }
Hall Liu27d24262020-09-18 19:04:59 -07001087 callback.accept(callForwardingStatus);
Shuo Qian4a594052020-01-23 11:59:30 -08001088 break;
Hall Liu27d24262020-09-18 19:04:59 -07001089 }
Shuo Qian4a594052020-01-23 11:59:30 -08001090
Hall Liu27d24262020-09-18 19:04:59 -07001091 case CMD_SET_CALL_WAITING: {
Shuo Qian4a594052020-01-23 11:59:30 -08001092 request = (MainThreadRequest) msg.obj;
1093 onCompleted = obtainMessage(EVENT_SET_CALL_WAITING_DONE, request);
Hall Liu27d24262020-09-18 19:04:59 -07001094 boolean enable = ((Pair<Boolean, Consumer<Integer>>) request.argument).first;
1095 getPhoneFromRequest(request).setCallWaiting(enable, onCompleted);
Shuo Qian4a594052020-01-23 11:59:30 -08001096 break;
Hall Liu27d24262020-09-18 19:04:59 -07001097 }
Shuo Qian4a594052020-01-23 11:59:30 -08001098
Hall Liu27d24262020-09-18 19:04:59 -07001099 case EVENT_SET_CALL_WAITING_DONE: {
Shuo Qian4a594052020-01-23 11:59:30 -08001100 ar = (AsyncResult) msg.obj;
1101 request = (MainThreadRequest) ar.userObj;
Hall Liu27d24262020-09-18 19:04:59 -07001102 boolean enable = ((Pair<Boolean, Consumer<Integer>>) request.argument).first;
1103 Consumer<Integer> callback =
1104 ((Pair<Boolean, Consumer<Integer>>) request.argument).second;
1105 if (ar.exception != null) {
Shuo Qian4a594052020-01-23 11:59:30 -08001106 loge("setCallWaiting exception: " + ar.exception);
Hall Liu27d24262020-09-18 19:04:59 -07001107 if (ar.exception instanceof CommandException) {
1108 CommandException.Error error =
1109 ((CommandException) (ar.exception)).getCommandError();
1110 if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1111 callback.accept(TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED);
1112 } else {
1113 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
1114 }
1115 } else {
1116 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
1117 }
1118 } else {
1119 callback.accept(enable ? TelephonyManager.CALL_WAITING_STATUS_ENABLED
1120 : TelephonyManager.CALL_WAITING_STATUS_DISABLED);
Shuo Qian4a594052020-01-23 11:59:30 -08001121 }
Shuo Qian4a594052020-01-23 11:59:30 -08001122 break;
Hall Liu27d24262020-09-18 19:04:59 -07001123 }
Shuo Qian4a594052020-01-23 11:59:30 -08001124
Shishir Agrawal302c8692015-06-19 13:49:39 -07001125 case EVENT_PERFORM_NETWORK_SCAN_DONE:
1126 ar = (AsyncResult) msg.obj;
1127 request = (MainThreadRequest) ar.userObj;
1128 CellNetworkScanResult cellScanResult;
1129 if (ar.exception == null && ar.result != null) {
1130 cellScanResult = new CellNetworkScanResult(
1131 CellNetworkScanResult.STATUS_SUCCESS,
1132 (List<OperatorInfo>) ar.result);
1133 } else {
1134 if (ar.result == null) {
1135 loge("getCellNetworkScanResults: Empty response");
1136 }
1137 if (ar.exception != null) {
1138 loge("getCellNetworkScanResults: Exception: " + ar.exception);
1139 }
1140 int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR;
1141 if (ar.exception instanceof CommandException) {
1142 CommandException.Error error =
1143 ((CommandException) (ar.exception)).getCommandError();
1144 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1145 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE;
1146 } else if (error == CommandException.Error.GENERIC_FAILURE) {
1147 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE;
1148 }
1149 }
1150 cellScanResult = new CellNetworkScanResult(errorCode, null);
1151 }
1152 request.result = cellScanResult;
Pengquan Menga1bb6272018-09-06 09:59:22 -07001153 notifyRequester(request);
Shishir Agrawal302c8692015-06-19 13:49:39 -07001154 break;
1155
1156 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
1157 request = (MainThreadRequest) msg.obj;
Shishir Agrawal77ba3172015-09-10 14:50:19 -07001158 ManualNetworkSelectionArgument selArg =
1159 (ManualNetworkSelectionArgument) request.argument;
Shishir Agrawal302c8692015-06-19 13:49:39 -07001160 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE,
1161 request);
Shishir Agrawal77ba3172015-09-10 14:50:19 -07001162 getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo,
1163 selArg.persistSelection, onCompleted);
Shishir Agrawal302c8692015-06-19 13:49:39 -07001164 break;
1165
1166 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
Pengquan Menge3d01e22018-09-20 15:25:35 -07001167 ar = (AsyncResult) msg.obj;
1168 request = (MainThreadRequest) ar.userObj;
1169 if (ar.exception == null) {
1170 request.result = true;
1171 } else {
1172 request.result = false;
1173 loge("setNetworkSelectionModeManual " + ar.exception);
1174 }
1175 notifyRequester(request);
1176 mApp.onNetworkSelectionChanged(request.subId);
Shishir Agrawal302c8692015-06-19 13:49:39 -07001177 break;
1178
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001179 case CMD_GET_MODEM_ACTIVITY_INFO:
1180 request = (MainThreadRequest) msg.obj;
1181 onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
James Mattisab947702019-04-03 14:18:34 -07001182 if (defaultPhone != null) {
1183 defaultPhone.getModemActivityInfo(onCompleted, request.workSource);
Shuo Qian8f4750a2020-02-20 17:12:10 -08001184 } else {
1185 ResultReceiver result = (ResultReceiver) request.argument;
1186 Bundle bundle = new Bundle();
1187 bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY,
Hall Liu49656c02020-10-09 19:00:11 -07001188 new ModemActivityInfo(0, 0, 0,
1189 new int[ModemActivityInfo.getNumTxPowerLevels()], 0));
Shuo Qian8f4750a2020-02-20 17:12:10 -08001190 result.send(0, bundle);
James Mattisab947702019-04-03 14:18:34 -07001191 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001192 break;
1193
Hall Liud0f208c2020-10-14 16:54:44 -07001194 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE: {
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001195 ar = (AsyncResult) msg.obj;
1196 request = (MainThreadRequest) ar.userObj;
Shuo Qian8f4750a2020-02-20 17:12:10 -08001197 ResultReceiver result = (ResultReceiver) request.argument;
1198
Hall Liud0f208c2020-10-14 16:54:44 -07001199 ModemActivityInfo ret = null;
1200 int error = 0;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001201 if (ar.exception == null && ar.result != null) {
Shuo Qian8f4750a2020-02-20 17:12:10 -08001202 // Update the last modem activity info and the result of the request.
1203 ModemActivityInfo info = (ModemActivityInfo) ar.result;
1204 if (isModemActivityInfoValid(info)) {
Hall Liu49656c02020-10-09 19:00:11 -07001205 int[] mergedTxTimeMs = new int[ModemActivityInfo.getNumTxPowerLevels()];
Shuo Qian8f4750a2020-02-20 17:12:10 -08001206 int[] txTimeMs = info.getTransmitTimeMillis();
1207 int[] lastModemTxTimeMs = mLastModemActivityInfo
1208 .getTransmitTimeMillis();
1209 for (int i = 0; i < mergedTxTimeMs.length; i++) {
1210 mergedTxTimeMs[i] = txTimeMs[i] + lastModemTxTimeMs[i];
1211 }
Hall Liu49656c02020-10-09 19:00:11 -07001212 mLastModemActivityInfo.setTimestamp(info.getTimestampMillis());
Shuo Qian8f4750a2020-02-20 17:12:10 -08001213 mLastModemActivityInfo.setSleepTimeMillis(info.getSleepTimeMillis()
1214 + mLastModemActivityInfo.getSleepTimeMillis());
1215 mLastModemActivityInfo.setIdleTimeMillis(info.getIdleTimeMillis()
1216 + mLastModemActivityInfo.getIdleTimeMillis());
1217 mLastModemActivityInfo.setTransmitTimeMillis(mergedTxTimeMs);
1218 mLastModemActivityInfo.setReceiveTimeMillis(
1219 info.getReceiveTimeMillis()
1220 + mLastModemActivityInfo.getReceiveTimeMillis());
1221 }
Hall Liu49656c02020-10-09 19:00:11 -07001222 ret = new ModemActivityInfo(mLastModemActivityInfo.getTimestampMillis(),
Shuo Qian8f4750a2020-02-20 17:12:10 -08001223 mLastModemActivityInfo.getSleepTimeMillis(),
1224 mLastModemActivityInfo.getIdleTimeMillis(),
1225 mLastModemActivityInfo.getTransmitTimeMillis(),
1226 mLastModemActivityInfo.getReceiveTimeMillis());
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001227 } else {
1228 if (ar.result == null) {
1229 loge("queryModemActivityInfo: Empty response");
Hall Liud0f208c2020-10-14 16:54:44 -07001230 error = TelephonyManager.ModemActivityInfoException
1231 .ERROR_INVALID_INFO_RECEIVED;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001232 } else if (ar.exception instanceof CommandException) {
1233 loge("queryModemActivityInfo: CommandException: " +
1234 ar.exception);
Hall Liud0f208c2020-10-14 16:54:44 -07001235 error = TelephonyManager.ModemActivityInfoException
1236 .ERROR_MODEM_RESPONSE_ERROR;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001237 } else {
1238 loge("queryModemActivityInfo: Unknown exception");
Hall Liud0f208c2020-10-14 16:54:44 -07001239 error = TelephonyManager.ModemActivityInfoException
1240 .ERROR_UNKNOWN;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001241 }
1242 }
Shuo Qian8f4750a2020-02-20 17:12:10 -08001243 Bundle bundle = new Bundle();
Hall Liud0f208c2020-10-14 16:54:44 -07001244 if (ret != null) {
1245 bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, ret);
1246 } else {
1247 bundle.putInt(TelephonyManager.EXCEPTION_RESULT_KEY, error);
1248 }
Shuo Qian8f4750a2020-02-20 17:12:10 -08001249 result.send(0, bundle);
Pengquan Menga1bb6272018-09-06 09:59:22 -07001250 notifyRequester(request);
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001251 break;
Hall Liud0f208c2020-10-14 16:54:44 -07001252 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001253
Meng Wang1a7c35a2016-05-05 20:56:15 -07001254 case CMD_SET_ALLOWED_CARRIERS:
1255 request = (MainThreadRequest) msg.obj;
Michele Berionne482f8202018-11-27 18:57:59 -08001256 CarrierRestrictionRules argument =
1257 (CarrierRestrictionRules) request.argument;
Meng Wang1a7c35a2016-05-05 20:56:15 -07001258 onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
Michele Berionne482f8202018-11-27 18:57:59 -08001259 defaultPhone.setAllowedCarriers(argument, onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -07001260 break;
1261
1262 case EVENT_SET_ALLOWED_CARRIERS_DONE:
1263 ar = (AsyncResult) msg.obj;
1264 request = (MainThreadRequest) ar.userObj;
1265 if (ar.exception == null && ar.result != null) {
1266 request.result = ar.result;
1267 } else {
Michele Berionne482f8202018-11-27 18:57:59 -08001268 request.result = TelephonyManager.SET_CARRIER_RESTRICTION_ERROR;
1269 if (ar.exception instanceof CommandException) {
1270 loge("setAllowedCarriers: CommandException: " + ar.exception);
1271 CommandException.Error error =
1272 ((CommandException) (ar.exception)).getCommandError();
1273 if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1274 request.result =
1275 TelephonyManager.SET_CARRIER_RESTRICTION_NOT_SUPPORTED;
1276 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07001277 } else {
1278 loge("setAllowedCarriers: Unknown exception");
1279 }
1280 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001281 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -07001282 break;
1283
1284 case CMD_GET_ALLOWED_CARRIERS:
1285 request = (MainThreadRequest) msg.obj;
1286 onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001287 defaultPhone.getAllowedCarriers(onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -07001288 break;
1289
1290 case EVENT_GET_ALLOWED_CARRIERS_DONE:
1291 ar = (AsyncResult) msg.obj;
1292 request = (MainThreadRequest) ar.userObj;
1293 if (ar.exception == null && ar.result != null) {
1294 request.result = ar.result;
1295 } else {
Michele Berionne482f8202018-11-27 18:57:59 -08001296 request.result = new IllegalStateException(
1297 "Failed to get carrier restrictions");
Meng Wang1a7c35a2016-05-05 20:56:15 -07001298 if (ar.result == null) {
1299 loge("getAllowedCarriers: Empty response");
1300 } else if (ar.exception instanceof CommandException) {
1301 loge("getAllowedCarriers: CommandException: " +
1302 ar.exception);
1303 } else {
1304 loge("getAllowedCarriers: Unknown exception");
1305 }
1306 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001307 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -07001308 break;
1309
Nathan Haroldb3014052017-01-25 15:57:32 -08001310 case EVENT_GET_FORBIDDEN_PLMNS_DONE:
1311 ar = (AsyncResult) msg.obj;
1312 request = (MainThreadRequest) ar.userObj;
1313 if (ar.exception == null && ar.result != null) {
1314 request.result = ar.result;
1315 } else {
1316 request.result = new IllegalArgumentException(
1317 "Failed to retrieve Forbidden Plmns");
1318 if (ar.result == null) {
1319 loge("getForbiddenPlmns: Empty response");
1320 } else {
1321 loge("getForbiddenPlmns: Unknown exception");
1322 }
1323 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001324 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -08001325 break;
1326
1327 case CMD_GET_FORBIDDEN_PLMNS:
1328 request = (MainThreadRequest) msg.obj;
1329 uiccCard = getUiccCardFromRequest(request);
1330 if (uiccCard == null) {
1331 loge("getForbiddenPlmns() UiccCard is null");
1332 request.result = new IllegalArgumentException(
1333 "getForbiddenPlmns() UiccCard is null");
Pengquan Menga1bb6272018-09-06 09:59:22 -07001334 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -08001335 break;
1336 }
1337 Integer appType = (Integer) request.argument;
1338 UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType);
1339 if (uiccApp == null) {
1340 loge("getForbiddenPlmns() no app with specified type -- "
1341 + appType);
1342 request.result = new IllegalArgumentException("Failed to get UICC App");
Pengquan Menga1bb6272018-09-06 09:59:22 -07001343 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -08001344 break;
1345 } else {
1346 if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
1347 + " specified type -- " + appType);
1348 }
1349 onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
1350 ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
1351 onCompleted);
1352 break;
1353
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001354 case CMD_SWITCH_SLOTS:
1355 request = (MainThreadRequest) msg.obj;
1356 int[] physicalSlots = (int[]) request.argument;
1357 onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
1358 UiccController.getInstance().switchSlots(physicalSlots, onCompleted);
1359 break;
1360
1361 case EVENT_SWITCH_SLOTS_DONE:
1362 ar = (AsyncResult) msg.obj;
1363 request = (MainThreadRequest) ar.userObj;
1364 request.result = (ar.exception == null);
Pengquan Menga1bb6272018-09-06 09:59:22 -07001365 notifyRequester(request);
1366 break;
1367 case CMD_GET_NETWORK_SELECTION_MODE:
1368 request = (MainThreadRequest) msg.obj;
1369 onCompleted = obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE, request);
1370 getPhoneFromRequest(request).getNetworkSelectionMode(onCompleted);
1371 break;
1372
1373 case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
1374 ar = (AsyncResult) msg.obj;
1375 request = (MainThreadRequest) ar.userObj;
1376 if (ar.exception != null) {
1377 request.result = TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
1378 } else {
1379 int mode = ((int[]) ar.result)[0];
1380 if (mode == 0) {
1381 request.result = TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
1382 } else {
1383 request.result = TelephonyManager.NETWORK_SELECTION_MODE_MANUAL;
1384 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001385 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001386 notifyRequester(request);
1387 break;
1388 case CMD_GET_CDMA_ROAMING_MODE:
1389 request = (MainThreadRequest) msg.obj;
1390 onCompleted = obtainMessage(EVENT_GET_CDMA_ROAMING_MODE_DONE, request);
1391 getPhoneFromRequest(request).queryCdmaRoamingPreference(onCompleted);
1392 break;
1393 case EVENT_GET_CDMA_ROAMING_MODE_DONE:
1394 ar = (AsyncResult) msg.obj;
1395 request = (MainThreadRequest) ar.userObj;
1396 if (ar.exception != null) {
1397 request.result = TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT;
1398 } else {
1399 request.result = ((int[]) ar.result)[0];
1400 }
1401 notifyRequester(request);
1402 break;
1403 case CMD_SET_CDMA_ROAMING_MODE:
1404 request = (MainThreadRequest) msg.obj;
1405 onCompleted = obtainMessage(EVENT_SET_CDMA_ROAMING_MODE_DONE, request);
1406 int mode = (int) request.argument;
1407 getPhoneFromRequest(request).setCdmaRoamingPreference(mode, onCompleted);
1408 break;
1409 case EVENT_SET_CDMA_ROAMING_MODE_DONE:
1410 ar = (AsyncResult) msg.obj;
1411 request = (MainThreadRequest) ar.userObj;
1412 request.result = ar.exception == null;
1413 notifyRequester(request);
1414 break;
Sarah Chinbaab1432020-10-28 13:46:24 -07001415 case CMD_GET_CDMA_SUBSCRIPTION_MODE:
1416 request = (MainThreadRequest) msg.obj;
1417 onCompleted = obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1418 getPhoneFromRequest(request).queryCdmaSubscriptionMode(onCompleted);
1419 break;
1420 case EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE:
1421 ar = (AsyncResult) msg.obj;
1422 request = (MainThreadRequest) ar.userObj;
1423 if (ar.exception != null) {
1424 request.result = TelephonyManager.CDMA_SUBSCRIPTION_RUIM_SIM;
1425 } else {
1426 request.result = ((int[]) ar.result)[0];
1427 }
1428 notifyRequester(request);
1429 break;
Pengquan Menga1bb6272018-09-06 09:59:22 -07001430 case CMD_SET_CDMA_SUBSCRIPTION_MODE:
1431 request = (MainThreadRequest) msg.obj;
1432 onCompleted = obtainMessage(EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1433 int subscriptionMode = (int) request.argument;
Sarah Chinbaab1432020-10-28 13:46:24 -07001434 getPhoneFromRequest(request).setCdmaSubscriptionMode(
1435 subscriptionMode, onCompleted);
Pengquan Menga1bb6272018-09-06 09:59:22 -07001436 break;
1437 case EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE:
1438 ar = (AsyncResult) msg.obj;
1439 request = (MainThreadRequest) ar.userObj;
1440 request.result = ar.exception == null;
1441 notifyRequester(request);
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001442 break;
Nathan Harold3ff88932018-08-14 10:19:49 -07001443 case CMD_GET_ALL_CELL_INFO:
1444 request = (MainThreadRequest) msg.obj;
Nathan Harold3ff88932018-08-14 10:19:49 -07001445 onCompleted = obtainMessage(EVENT_GET_ALL_CELL_INFO_DONE, request);
Nathan Harold92bed182018-10-12 18:16:49 -07001446 request.phone.requestCellInfoUpdate(request.workSource, onCompleted);
Nathan Harold3ff88932018-08-14 10:19:49 -07001447 break;
Nathan Harold3ff88932018-08-14 10:19:49 -07001448 case EVENT_GET_ALL_CELL_INFO_DONE:
1449 ar = (AsyncResult) msg.obj;
1450 request = (MainThreadRequest) ar.userObj;
Nathan Harold8d0f1742018-10-02 12:14:47 -07001451 // If a timeout occurs, the response will be null
1452 request.result = (ar.exception == null && ar.result != null)
1453 ? ar.result : new ArrayList<CellInfo>();
Nathan Harold3ff88932018-08-14 10:19:49 -07001454 synchronized (request) {
1455 request.notifyAll();
1456 }
1457 break;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001458 case CMD_REQUEST_CELL_INFO_UPDATE:
1459 request = (MainThreadRequest) msg.obj;
1460 request.phone.requestCellInfoUpdate(request.workSource,
1461 obtainMessage(EVENT_REQUEST_CELL_INFO_UPDATE_DONE, request));
1462 break;
1463 case EVENT_REQUEST_CELL_INFO_UPDATE_DONE:
1464 ar = (AsyncResult) msg.obj;
1465 request = (MainThreadRequest) ar.userObj;
1466 ICellInfoCallback cb = (ICellInfoCallback) request.argument;
1467 try {
1468 if (ar.exception != null) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001469 Log.e(LOG_TAG, "Exception retrieving CellInfo=" + ar.exception);
Meng Wangd8921f42019-09-30 17:13:54 -07001470 cb.onError(
1471 TelephonyManager.CellInfoCallback.ERROR_MODEM_ERROR,
1472 ar.exception.getClass().getName(),
1473 ar.exception.toString());
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001474 } else if (ar.result == null) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001475 Log.w(LOG_TAG, "Timeout Waiting for CellInfo!");
Meng Wangd8921f42019-09-30 17:13:54 -07001476 cb.onError(TelephonyManager.CellInfoCallback.ERROR_TIMEOUT, null, null);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001477 } else {
1478 // use the result as returned
1479 cb.onCellInfo((List<CellInfo>) ar.result);
1480 }
1481 } catch (RemoteException re) {
1482 Log.w(LOG_TAG, "Discarded CellInfo due to Callback RemoteException");
1483 }
1484 break;
Sarah Chin679c08a2020-11-18 13:39:35 -08001485 case CMD_GET_CELL_LOCATION: {
Nathan Harold3ff88932018-08-14 10:19:49 -07001486 request = (MainThreadRequest) msg.obj;
1487 WorkSource ws = (WorkSource) request.argument;
1488 Phone phone = getPhoneFromRequest(request);
Meng Wanga10e89e2019-12-09 13:13:01 -08001489 phone.getCellIdentity(ws, obtainMessage(EVENT_GET_CELL_LOCATION_DONE, request));
Nathan Harold3ff88932018-08-14 10:19:49 -07001490 break;
Sarah Chin679c08a2020-11-18 13:39:35 -08001491 }
1492 case EVENT_GET_CELL_LOCATION_DONE: {
Nathan Harold3ff88932018-08-14 10:19:49 -07001493 ar = (AsyncResult) msg.obj;
1494 request = (MainThreadRequest) ar.userObj;
1495 if (ar.exception == null) {
1496 request.result = ar.result;
1497 } else {
Sarah Chin679c08a2020-11-18 13:39:35 -08001498 Phone phone = getPhoneFromRequest(request);
Nathan Harold3ff88932018-08-14 10:19:49 -07001499 request.result = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
Meng Wanga10e89e2019-12-09 13:13:01 -08001500 ? new CellIdentityCdma() : new CellIdentityGsm();
Nathan Harold3ff88932018-08-14 10:19:49 -07001501 }
1502
1503 synchronized (request) {
1504 request.notifyAll();
1505 }
1506 break;
Sarah Chin679c08a2020-11-18 13:39:35 -08001507 }
chen xu6dac5ab2018-10-26 17:39:23 -07001508 case CMD_MODEM_REBOOT:
1509 request = (MainThreadRequest) msg.obj;
1510 onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001511 defaultPhone.rebootModem(onCompleted);
chen xu6dac5ab2018-10-26 17:39:23 -07001512 break;
chen xu6dac5ab2018-10-26 17:39:23 -07001513 case EVENT_CMD_MODEM_REBOOT_DONE:
1514 handleNullReturnEvent(msg, "rebootModem");
1515 break;
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001516 case CMD_REQUEST_ENABLE_MODEM:
1517 request = (MainThreadRequest) msg.obj;
1518 boolean enable = (boolean) request.argument;
1519 onCompleted = obtainMessage(EVENT_ENABLE_MODEM_DONE, request);
Nazanin Bakhshi33d584b2019-02-27 10:44:32 -08001520 onCompleted.arg1 = enable ? 1 : 0;
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001521 PhoneConfigurationManager.getInstance()
1522 .enablePhone(request.phone, enable, onCompleted);
1523 break;
1524 case EVENT_ENABLE_MODEM_DONE:
1525 ar = (AsyncResult) msg.obj;
1526 request = (MainThreadRequest) ar.userObj;
1527 request.result = (ar.exception == null);
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07001528 int phoneId = request.phone.getPhoneId();
Nazanin Bakhshi33d584b2019-02-27 10:44:32 -08001529 //update the cache as modem status has changed
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07001530 if ((boolean) request.result) {
1531 mPhoneConfigurationManager.addToPhoneStatusCache(phoneId, msg.arg1 == 1);
1532 updateModemStateMetrics();
1533 } else {
1534 Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1535 + ar.exception);
1536 }
1537 notifyRequester(request);
1538 break;
1539 case CMD_GET_MODEM_STATUS:
1540 request = (MainThreadRequest) msg.obj;
1541 onCompleted = obtainMessage(EVENT_GET_MODEM_STATUS_DONE, request);
1542 PhoneConfigurationManager.getInstance()
1543 .getPhoneStatusFromModem(request.phone, onCompleted);
1544 break;
1545 case EVENT_GET_MODEM_STATUS_DONE:
1546 ar = (AsyncResult) msg.obj;
1547 request = (MainThreadRequest) ar.userObj;
1548 int id = request.phone.getPhoneId();
1549 if (ar.exception == null && ar.result != null) {
1550 request.result = ar.result;
1551 //update the cache as modem status has changed
1552 mPhoneConfigurationManager.addToPhoneStatusCache(id,
1553 (boolean) request.result);
1554 } else {
1555 // Return true if modem status cannot be retrieved. For most cases,
1556 // modem status is on. And for older version modems, GET_MODEM_STATUS
1557 // and disable modem are not supported. Modem is always on.
1558 // TODO: this should be fixed in R to support a third
1559 // status UNKNOWN b/131631629
1560 request.result = true;
1561 Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1562 + ar.exception);
1563 }
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001564 notifyRequester(request);
1565 break;
Hall Liu73f5d362020-01-20 13:42:00 -08001566 case CMD_SET_SYSTEM_SELECTION_CHANNELS: {
1567 request = (MainThreadRequest) msg.obj;
1568 onCompleted = obtainMessage(EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE, request);
1569 Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> args =
1570 (Pair<List<RadioAccessSpecifier>, Consumer<Boolean>>) request.argument;
1571 request.phone.setSystemSelectionChannels(args.first, onCompleted);
1572 break;
1573 }
1574 case EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE: {
1575 ar = (AsyncResult) msg.obj;
1576 request = (MainThreadRequest) ar.userObj;
1577 Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> args =
1578 (Pair<List<RadioAccessSpecifier>, Consumer<Boolean>>) request.argument;
1579 args.second.accept(ar.exception == null);
1580 notifyRequester(request);
1581 break;
1582 }
Sarah Chin679c08a2020-11-18 13:39:35 -08001583 case CMD_GET_SYSTEM_SELECTION_CHANNELS: {
1584 request = (MainThreadRequest) msg.obj;
1585 onCompleted = obtainMessage(EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE, request);
1586 Phone phone = getPhoneFromRequest(request);
1587 if (phone != null) {
1588 phone.getSystemSelectionChannels(onCompleted);
1589 } else {
1590 loge("getSystemSelectionChannels: No phone object");
1591 request.result = new ArrayList<RadioAccessSpecifier>();
1592 notifyRequester(request);
1593 }
1594 break;
1595 }
1596 case EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE:
1597 ar = (AsyncResult) msg.obj;
1598 request = (MainThreadRequest) ar.userObj;
1599 if (ar.exception == null && ar.result != null) {
1600 request.result = ar.result;
1601 } else {
1602 request.result = new IllegalArgumentException(
1603 "Failed to retrieve system selection channels");
1604 if (ar.result == null) {
1605 loge("getSystemSelectionChannels: Empty response");
1606 } else {
1607 loge("getSystemSelectionChannels: Unknown exception");
1608 }
1609 }
1610 notifyRequester(request);
1611 break;
yincheng zhao2737e882019-09-06 17:06:54 -07001612 case EVENT_SET_FORBIDDEN_PLMNS_DONE:
1613 ar = (AsyncResult) msg.obj;
1614 request = (MainThreadRequest) ar.userObj;
1615 if (ar.exception == null && ar.result != null) {
1616 request.result = ar.result;
1617 } else {
1618 request.result = -1;
1619 loge("Failed to set Forbidden Plmns");
1620 if (ar.result == null) {
1621 loge("setForbidenPlmns: Empty response");
1622 } else if (ar.exception != null) {
1623 loge("setForbiddenPlmns: Exception: " + ar.exception);
1624 request.result = -1;
1625 } else {
1626 loge("setForbiddenPlmns: Unknown exception");
1627 }
1628 }
1629 notifyRequester(request);
1630 break;
1631 case CMD_SET_FORBIDDEN_PLMNS:
1632 request = (MainThreadRequest) msg.obj;
1633 uiccCard = getUiccCardFromRequest(request);
1634 if (uiccCard == null) {
1635 loge("setForbiddenPlmns: UiccCard is null");
1636 request.result = -1;
1637 notifyRequester(request);
1638 break;
1639 }
1640 Pair<Integer, List<String>> setFplmnsArgs =
1641 (Pair<Integer, List<String>>) request.argument;
1642 appType = setFplmnsArgs.first;
1643 List<String> fplmns = setFplmnsArgs.second;
1644 uiccApp = uiccCard.getApplicationByType(appType);
1645 if (uiccApp == null) {
1646 loge("setForbiddenPlmns: no app with specified type -- " + appType);
1647 request.result = -1;
1648 loge("Failed to get UICC App");
1649 notifyRequester(request);
1650 } else {
1651 onCompleted = obtainMessage(EVENT_SET_FORBIDDEN_PLMNS_DONE, request);
1652 ((SIMRecords) uiccApp.getIccRecords())
1653 .setForbiddenPlmns(onCompleted, fplmns);
1654 }
yinchengzhao4d163c02019-12-12 15:21:47 -08001655 break;
Naina Nallurid63128d2019-09-17 14:10:30 -07001656 case CMD_ERASE_MODEM_CONFIG:
1657 request = (MainThreadRequest) msg.obj;
1658 onCompleted = obtainMessage(EVENT_ERASE_MODEM_CONFIG_DONE, request);
1659 defaultPhone.eraseModemConfig(onCompleted);
1660 break;
1661 case EVENT_ERASE_MODEM_CONFIG_DONE:
1662 handleNullReturnEvent(msg, "eraseModemConfig");
yincheng zhao2737e882019-09-06 17:06:54 -07001663 break;
zoey chene02881a2019-12-30 16:11:23 +08001664
1665 case CMD_CHANGE_ICC_LOCK_PASSWORD:
1666 request = (MainThreadRequest) msg.obj;
1667 onCompleted = obtainMessage(EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE, request);
1668 Pair<String, String> changed = (Pair<String, String>) request.argument;
1669 getPhoneFromRequest(request).getIccCard().changeIccLockPassword(
1670 changed.first, changed.second, onCompleted);
1671 break;
1672 case EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE:
1673 ar = (AsyncResult) msg.obj;
1674 request = (MainThreadRequest) ar.userObj;
1675 if (ar.exception == null) {
1676 request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
1677 } else {
1678 request.result = msg.arg1;
1679 }
1680 notifyRequester(request);
1681 break;
1682
1683 case CMD_SET_ICC_LOCK_ENABLED:
1684 request = (MainThreadRequest) msg.obj;
1685 onCompleted = obtainMessage(EVENT_SET_ICC_LOCK_ENABLED_DONE, request);
1686 Pair<Boolean, String> enabled = (Pair<Boolean, String>) request.argument;
1687 getPhoneFromRequest(request).getIccCard().setIccLockEnabled(
1688 enabled.first, enabled.second, onCompleted);
1689 break;
1690 case EVENT_SET_ICC_LOCK_ENABLED_DONE:
1691 ar = (AsyncResult) msg.obj;
1692 request = (MainThreadRequest) ar.userObj;
1693 if (ar.exception == null) {
1694 request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
1695 } else {
1696 request.result = msg.arg1;
1697 }
1698 notifyRequester(request);
1699 break;
1700
Peter Wangdafb9ac2020-01-15 14:13:38 -08001701 case MSG_NOTIFY_USER_ACTIVITY:
1702 removeMessages(MSG_NOTIFY_USER_ACTIVITY);
Peter Wang59571be2020-01-27 12:35:15 +08001703 Intent intent = new Intent(TelephonyIntents.ACTION_USER_ACTIVITY_NOTIFICATION);
Peter Wangdafb9ac2020-01-15 14:13:38 -08001704 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1705 getDefaultPhone().getContext().sendBroadcastAsUser(
1706 intent, UserHandle.ALL, permission.USER_ACTIVITY);
1707 break;
Jack Nudelmanb0b87642020-11-12 15:04:39 -08001708
1709 case CMD_SET_DATA_THROTTLING: {
1710 request = (MainThreadRequest) msg.obj;
1711 onCompleted = obtainMessage(EVENT_SET_DATA_THROTTLING_DONE, request);
1712 DataThrottlingRequest dataThrottlingRequest =
1713 (DataThrottlingRequest) request.argument;
1714 Phone phone = getPhoneFromRequest(request);
1715 if (phone != null) {
1716 phone.setDataThrottling(onCompleted,
1717 request.workSource, dataThrottlingRequest.getDataThrottlingAction(),
1718 dataThrottlingRequest.getCompletionDurationMillis());
1719 } else {
1720 loge("setDataThrottling: No phone object");
1721 request.result =
1722 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
1723 notifyRequester(request);
1724 }
1725
1726 break;
1727 }
1728 case EVENT_SET_DATA_THROTTLING_DONE:
1729 ar = (AsyncResult) msg.obj;
1730 request = (MainThreadRequest) ar.userObj;
1731
1732 if (ar.exception == null) {
1733 request.result = TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
1734 } else if (ar.exception instanceof CommandException) {
1735 loge("setDataThrottling: CommandException: " + ar.exception);
1736 CommandException.Error error =
1737 ((CommandException) (ar.exception)).getCommandError();
1738
1739 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1740 request.result = TelephonyManager
1741 .THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
1742 } else if (error == CommandException.Error.INVALID_ARGUMENTS) {
1743 request.result = SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS;
1744 } else {
1745 request.result =
1746 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
1747 }
1748 } else {
1749 request.result = TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
1750 }
1751 Log.w(LOG_TAG, "DataThrottlingResult = " + request.result);
1752 notifyRequester(request);
1753 break;
Jordan Liu109698e2020-11-24 14:50:34 -08001754
1755 case CMD_SET_SIM_POWER: {
1756 request = (MainThreadRequest) msg.obj;
1757 onCompleted = obtainMessage(EVENT_SET_SIM_POWER_DONE, request);
1758 request = (MainThreadRequest) msg.obj;
1759 int stateToSet =
1760 ((Pair<Integer, IIntegerConsumer>)
1761 request.argument).first;
1762 request.phone.setSimPowerState(stateToSet, onCompleted, request.workSource);
1763 break;
1764 }
1765 case EVENT_SET_SIM_POWER_DONE: {
1766 ar = (AsyncResult) msg.obj;
1767 request = (MainThreadRequest) ar.userObj;
1768 IIntegerConsumer callback =
1769 ((Pair<Integer, IIntegerConsumer>) request.argument).second;
1770 if (ar.exception != null) {
1771 loge("setSimPower exception: " + ar.exception);
1772 int errorCode = TelephonyManager.CallForwardingInfoCallback
1773 .RESULT_ERROR_UNKNOWN;
1774 if (ar.exception instanceof CommandException) {
1775 CommandException.Error error =
1776 ((CommandException) (ar.exception)).getCommandError();
1777 if (error == CommandException.Error.SIM_ERR) {
1778 errorCode = TelephonyManager.SET_SIM_POWER_STATE_SIM_ERROR;
1779 } else if (error == CommandException.Error.INVALID_ARGUMENTS) {
1780 errorCode = TelephonyManager.SET_SIM_POWER_STATE_ALREADY_IN_STATE;
1781 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1782 errorCode = TelephonyManager.SET_SIM_POWER_STATE_NOT_SUPPORTED;
1783 } else {
1784 errorCode = TelephonyManager.SET_SIM_POWER_STATE_MODEM_ERROR;
1785 }
1786 }
1787 try {
1788 callback.accept(errorCode);
1789 } catch (RemoteException e) {
1790 // Ignore if the remote process is no longer available to call back.
1791 Log.w(LOG_TAG, "setSimPower: callback not available.");
1792 }
1793 } else {
1794 try {
1795 callback.accept(TelephonyManager.SET_SIM_POWER_STATE_SUCCESS);
1796 } catch (RemoteException e) {
1797 // Ignore if the remote process is no longer available to call back.
1798 Log.w(LOG_TAG, "setSimPower: callback not available.");
1799 }
1800 }
1801 break;
1802 }
1803
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001804 default:
1805 Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
1806 break;
1807 }
1808 }
Jake Hambye994d462014-02-03 13:10:13 -08001809
Pengquan Menga1bb6272018-09-06 09:59:22 -07001810 private void notifyRequester(MainThreadRequest request) {
1811 synchronized (request) {
1812 request.notifyAll();
1813 }
1814 }
1815
Jake Hambye994d462014-02-03 13:10:13 -08001816 private void handleNullReturnEvent(Message msg, String command) {
1817 AsyncResult ar = (AsyncResult) msg.obj;
1818 MainThreadRequest request = (MainThreadRequest) ar.userObj;
1819 if (ar.exception == null) {
1820 request.result = true;
1821 } else {
1822 request.result = false;
1823 if (ar.exception instanceof CommandException) {
1824 loge(command + ": CommandException: " + ar.exception);
1825 } else {
1826 loge(command + ": Unknown exception");
1827 }
1828 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001829 notifyRequester(request);
Jake Hambye994d462014-02-03 13:10:13 -08001830 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001831 }
1832
1833 /**
1834 * Posts the specified command to be executed on the main thread,
1835 * waits for the request to complete, and returns the result.
1836 * @see #sendRequestAsync
1837 */
1838 private Object sendRequest(int command, Object argument) {
Nathan Harold92bed182018-10-12 18:16:49 -07001839 return sendRequest(
1840 command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, null, null);
vagdeviaf9a5b92018-08-15 16:01:53 -07001841 }
1842
1843 /**
1844 * Posts the specified command to be executed on the main thread,
1845 * waits for the request to complete, and returns the result.
1846 * @see #sendRequestAsync
1847 */
1848 private Object sendRequest(int command, Object argument, WorkSource workSource) {
1849 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
Nathan Harold92bed182018-10-12 18:16:49 -07001850 null, workSource);
Wink Saville36469e72014-06-11 15:17:00 -07001851 }
1852
1853 /**
1854 * Posts the specified command to be executed on the main thread,
1855 * waits for the request to complete, and returns the result.
1856 * @see #sendRequestAsync
1857 */
Shishir Agrawal76d5da92014-11-09 16:17:25 -08001858 private Object sendRequest(int command, Object argument, Integer subId) {
Nathan Harold92bed182018-10-12 18:16:49 -07001859 return sendRequest(command, argument, subId, null, null);
vagdeviaf9a5b92018-08-15 16:01:53 -07001860 }
1861
1862 /**
1863 * Posts the specified command to be executed on the main thread,
1864 * waits for the request to complete, and returns the result.
1865 * @see #sendRequestAsync
1866 */
Nathan Harold92bed182018-10-12 18:16:49 -07001867 private Object sendRequest(int command, Object argument, int subId, WorkSource workSource) {
1868 return sendRequest(command, argument, subId, null, workSource);
1869 }
1870
1871 /**
1872 * Posts the specified command to be executed on the main thread,
1873 * waits for the request to complete, and returns the result.
1874 * @see #sendRequestAsync
1875 */
1876 private Object sendRequest(int command, Object argument, Phone phone, WorkSource workSource) {
1877 return sendRequest(
1878 command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phone, workSource);
1879 }
1880
1881 /**
1882 * Posts the specified command to be executed on the main thread,
1883 * waits for the request to complete, and returns the result.
1884 * @see #sendRequestAsync
1885 */
1886 private Object sendRequest(
1887 int command, Object argument, Integer subId, Phone phone, WorkSource workSource) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001888 if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
1889 throw new RuntimeException("This method will deadlock if called from the main thread.");
1890 }
1891
Nathan Harold92bed182018-10-12 18:16:49 -07001892 MainThreadRequest request = null;
1893 if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && phone != null) {
1894 throw new IllegalArgumentException("subId and phone cannot both be specified!");
1895 } else if (phone != null) {
1896 request = new MainThreadRequest(argument, phone, workSource);
1897 } else {
1898 request = new MainThreadRequest(argument, subId, workSource);
1899 }
1900
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001901 Message msg = mMainThreadHandler.obtainMessage(command, request);
1902 msg.sendToTarget();
1903
1904 // Wait for the request to complete
1905 synchronized (request) {
1906 while (request.result == null) {
1907 try {
1908 request.wait();
1909 } catch (InterruptedException e) {
1910 // Do nothing, go back and wait until the request is complete
1911 }
1912 }
1913 }
1914 return request.result;
1915 }
1916
1917 /**
1918 * Asynchronous ("fire and forget") version of sendRequest():
1919 * Posts the specified command to be executed on the main thread, and
1920 * returns immediately.
1921 * @see #sendRequest
1922 */
1923 private void sendRequestAsync(int command) {
1924 mMainThreadHandler.sendEmptyMessage(command);
1925 }
1926
1927 /**
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001928 * Same as {@link #sendRequestAsync(int)} except it takes an argument.
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001929 * @see {@link #sendRequest(int)}
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001930 */
1931 private void sendRequestAsync(int command, Object argument) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001932 sendRequestAsync(command, argument, null, null);
1933 }
1934
1935 /**
1936 * Same as {@link #sendRequestAsync(int,Object)} except it takes a Phone and WorkSource.
1937 * @see {@link #sendRequest(int,Object)}
1938 */
1939 private void sendRequestAsync(
1940 int command, Object argument, Phone phone, WorkSource workSource) {
1941 MainThreadRequest request = new MainThreadRequest(argument, phone, workSource);
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001942 Message msg = mMainThreadHandler.obtainMessage(command, request);
1943 msg.sendToTarget();
1944 }
1945
1946 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001947 * Initialize the singleton PhoneInterfaceManager instance.
1948 * This is only done once, at startup, from PhoneApp.onCreate().
1949 */
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001950 /* package */ static PhoneInterfaceManager init(PhoneGlobals app) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001951 synchronized (PhoneInterfaceManager.class) {
1952 if (sInstance == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001953 sInstance = new PhoneInterfaceManager(app);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001954 } else {
1955 Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
1956 }
1957 return sInstance;
1958 }
1959 }
1960
1961 /** Private constructor; @see init() */
Jordan Liu1979a042020-03-20 21:39:35 +00001962 private PhoneInterfaceManager(PhoneGlobals app) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001963 mApp = app;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001964 mCM = PhoneGlobals.getInstance().mCM;
Brad Ebinger24c29992019-12-05 13:03:21 -08001965 mImsResolver = PhoneGlobals.getInstance().getImsResolver();
Stuart Scott981d8582015-04-21 14:09:50 -07001966 mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001967 mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
1968 mMainThreadHandler = new MainThreadHandler();
Tobias Thiererb19e1f12018-12-11 17:54:03 +00001969 mSubscriptionController = SubscriptionController.getInstance();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001970 mTelephonySharedPreferences =
1971 PreferenceManager.getDefaultSharedPreferences(mApp);
yinxub1bed742017-04-17 11:45:04 -07001972 mNetworkScanRequestTracker = new NetworkScanRequestTracker();
Malcolm Chen2c63d402018-08-14 16:00:53 -07001973 mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
Peter Wanga3cf4ac2020-01-27 09:39:46 +08001974 mNotifyUserActivity = new AtomicBoolean(false);
Wink Saville3ab207e2014-11-20 13:07:20 -08001975
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001976 publish();
1977 }
1978
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001979 private Phone getDefaultPhone() {
1980 Phone thePhone = getPhone(getDefaultSubscription());
1981 return (thePhone != null) ? thePhone : PhoneFactory.getDefaultPhone();
1982 }
1983
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001984 private void publish() {
1985 if (DBG) log("publish: " + this);
1986
Peter Wangc035ce42020-01-08 21:00:22 -08001987 TelephonyFrameworkInitializer
1988 .getTelephonyServiceManager()
1989 .getTelephonyServiceRegisterer()
1990 .register(this);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001991 }
1992
Stuart Scott584921c2015-01-15 17:10:34 -08001993 private Phone getPhoneFromRequest(MainThreadRequest request) {
Jordan Liu4c733742019-02-28 12:03:40 -08001994 if (request.phone != null) {
1995 return request.phone;
1996 } else {
1997 return getPhoneFromSubId(request.subId);
1998 }
1999 }
2000
2001 private Phone getPhoneFromSubId(int subId) {
2002 return (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
2003 ? getDefaultPhone() : getPhone(subId);
Stuart Scott584921c2015-01-15 17:10:34 -08002004 }
2005
Shishir Agrawalc04d9752016-02-19 10:41:00 -08002006 private UiccCard getUiccCardFromRequest(MainThreadRequest request) {
2007 Phone phone = getPhoneFromRequest(request);
2008 return phone == null ? null :
2009 UiccController.getInstance().getUiccCard(phone.getPhoneId());
2010 }
2011
Wink Saville36469e72014-06-11 15:17:00 -07002012 // returns phone associated with the subId.
Wink Savilleb564aae2014-10-23 10:18:09 -07002013 private Phone getPhone(int subId) {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08002014 return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId));
Wink Saville36469e72014-06-11 15:17:00 -07002015 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002016
Naina Nallurid63128d2019-09-17 14:10:30 -07002017 private void sendEraseModemConfig(Phone phone) {
2018 if (phone != null) {
2019 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2020 mApp, phone.getSubId(), "eraseModemConfig");
2021 final long identity = Binder.clearCallingIdentity();
2022 try {
2023 Boolean success = (Boolean) sendRequest(CMD_ERASE_MODEM_CONFIG, null);
2024 if (DBG) log("eraseModemConfig:" + ' ' + (success ? "ok" : "fail"));
2025 } finally {
2026 Binder.restoreCallingIdentity(identity);
2027 }
2028 }
2029 }
2030
Peter Wang44b186e2020-01-13 23:33:09 -08002031 private boolean isImsAvailableOnDevice() {
2032 PackageManager pm = getDefaultPhone().getContext().getPackageManager();
2033 if (pm == null) {
2034 // For some reason package manger is not available.. This will fail internally anyway,
2035 // so do not throw error and allow.
2036 return true;
2037 }
2038 return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS, 0);
2039 }
2040
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002041 public void dial(String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002042 dialForSubscriber(getPreferredVoiceSubscription(), number);
Wink Saville36469e72014-06-11 15:17:00 -07002043 }
2044
Wink Savilleb564aae2014-10-23 10:18:09 -07002045 public void dialForSubscriber(int subId, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002046 if (DBG) log("dial: " + number);
2047 // No permission check needed here: This is just a wrapper around the
2048 // ACTION_DIAL intent, which is available to any app since it puts up
2049 // the UI before it does anything.
2050
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002051 final long identity = Binder.clearCallingIdentity();
2052 try {
2053 String url = createTelUrl(number);
2054 if (url == null) {
2055 return;
2056 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002057
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002058 // PENDING: should we just silently fail if phone is offhook or ringing?
2059 PhoneConstants.State state = mCM.getState(subId);
2060 if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
2061 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
2062 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2063 mApp.startActivity(intent);
2064 }
2065 } finally {
2066 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002067 }
2068 }
2069
2070 public void call(String callingPackage, String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002071 callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number);
Wink Saville36469e72014-06-11 15:17:00 -07002072 }
2073
Wink Savilleb564aae2014-10-23 10:18:09 -07002074 public void callForSubscriber(int subId, String callingPackage, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002075 if (DBG) log("call: " + number);
2076
2077 // This is just a wrapper around the ACTION_CALL intent, but we still
2078 // need to do a permission check since we're calling startActivity()
2079 // from the context of the phone app.
2080 enforceCallPermission();
2081
Jordan Liu1617b712019-07-10 15:06:26 -07002082 if (mAppOps.noteOp(AppOpsManager.OPSTR_CALL_PHONE, Binder.getCallingUid(), callingPackage)
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002083 != AppOpsManager.MODE_ALLOWED) {
2084 return;
2085 }
2086
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002087 final long identity = Binder.clearCallingIdentity();
2088 try {
2089 String url = createTelUrl(number);
2090 if (url == null) {
2091 return;
2092 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002093
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002094 boolean isValid = false;
2095 final List<SubscriptionInfo> slist = getActiveSubscriptionInfoListPrivileged();
2096 if (slist != null) {
2097 for (SubscriptionInfo subInfoRecord : slist) {
2098 if (subInfoRecord.getSubscriptionId() == subId) {
2099 isValid = true;
2100 break;
2101 }
Wink Saville3ab207e2014-11-20 13:07:20 -08002102 }
Wink Saville08874612014-08-31 19:19:58 -07002103 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002104 if (!isValid) {
2105 return;
2106 }
Wink Saville08874612014-08-31 19:19:58 -07002107
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002108 Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
2109 intent.putExtra(SUBSCRIPTION_KEY, subId);
2110 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2111 mApp.startActivity(intent);
2112 } finally {
2113 Binder.restoreCallingIdentity(identity);
2114 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002115 }
2116
Wink Savilleb564aae2014-10-23 10:18:09 -07002117 public boolean supplyPinForSubscriber(int subId, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002118 int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07002119 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
2120 }
2121
Wink Savilleb564aae2014-10-23 10:18:09 -07002122 public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002123 int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07002124 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
2125 }
2126
Wink Savilleb564aae2014-10-23 10:18:09 -07002127 public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002128 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002129
2130 final long identity = Binder.clearCallingIdentity();
2131 try {
2132 final UnlockSim checkSimPin = new UnlockSim(getPhone(subId).getIccCard());
2133 checkSimPin.start();
2134 return checkSimPin.unlockSim(null, pin);
2135 } finally {
2136 Binder.restoreCallingIdentity(identity);
2137 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002138 }
2139
Wink Savilleb564aae2014-10-23 10:18:09 -07002140 public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002141 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002142
2143 final long identity = Binder.clearCallingIdentity();
2144 try {
2145 final UnlockSim checkSimPuk = new UnlockSim(getPhone(subId).getIccCard());
2146 checkSimPuk.start();
2147 return checkSimPuk.unlockSim(puk, pin);
2148 } finally {
2149 Binder.restoreCallingIdentity(identity);
2150 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002151 }
2152
2153 /**
Wink Saville9de0f752013-10-22 19:04:03 -07002154 * Helper thread to turn async call to SimCard#supplyPin into
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002155 * a synchronous one.
2156 */
2157 private static class UnlockSim extends Thread {
2158
2159 private final IccCard mSimCard;
2160
2161 private boolean mDone = false;
Wink Saville9de0f752013-10-22 19:04:03 -07002162 private int mResult = PhoneConstants.PIN_GENERAL_FAILURE;
2163 private int mRetryCount = -1;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002164
2165 // For replies from SimCard interface
2166 private Handler mHandler;
2167
2168 // For async handler to identify request type
2169 private static final int SUPPLY_PIN_COMPLETE = 100;
2170
2171 public UnlockSim(IccCard simCard) {
2172 mSimCard = simCard;
2173 }
2174
2175 @Override
2176 public void run() {
2177 Looper.prepare();
2178 synchronized (UnlockSim.this) {
2179 mHandler = new Handler() {
2180 @Override
2181 public void handleMessage(Message msg) {
2182 AsyncResult ar = (AsyncResult) msg.obj;
2183 switch (msg.what) {
2184 case SUPPLY_PIN_COMPLETE:
2185 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
2186 synchronized (UnlockSim.this) {
Wink Saville9de0f752013-10-22 19:04:03 -07002187 mRetryCount = msg.arg1;
2188 if (ar.exception != null) {
2189 if (ar.exception instanceof CommandException &&
2190 ((CommandException)(ar.exception)).getCommandError()
2191 == CommandException.Error.PASSWORD_INCORRECT) {
2192 mResult = PhoneConstants.PIN_PASSWORD_INCORRECT;
vivi.lib5e9ada2019-09-12 16:04:24 +08002193 } //When UiccCardApp dispose,handle message and return exception
2194 else if (ar.exception instanceof CommandException &&
2195 ((CommandException) (ar.exception)).getCommandError()
2196 == CommandException.Error.ABORTED) {
2197 mResult = PhoneConstants.PIN_OPERATION_ABORTED;
Wink Saville9de0f752013-10-22 19:04:03 -07002198 } else {
2199 mResult = PhoneConstants.PIN_GENERAL_FAILURE;
2200 }
2201 } else {
2202 mResult = PhoneConstants.PIN_RESULT_SUCCESS;
2203 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002204 mDone = true;
2205 UnlockSim.this.notifyAll();
2206 }
2207 break;
2208 }
2209 }
2210 };
2211 UnlockSim.this.notifyAll();
2212 }
2213 Looper.loop();
2214 }
2215
2216 /*
2217 * Use PIN or PUK to unlock SIM card
2218 *
2219 * If PUK is null, unlock SIM card with PIN
2220 *
2221 * If PUK is not null, unlock SIM card with PUK and set PIN code
2222 */
Wink Saville9de0f752013-10-22 19:04:03 -07002223 synchronized int[] unlockSim(String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002224
2225 while (mHandler == null) {
2226 try {
2227 wait();
2228 } catch (InterruptedException e) {
2229 Thread.currentThread().interrupt();
2230 }
2231 }
2232 Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
2233
2234 if (puk == null) {
2235 mSimCard.supplyPin(pin, callback);
2236 } else {
2237 mSimCard.supplyPuk(puk, pin, callback);
2238 }
2239
2240 while (!mDone) {
2241 try {
2242 Log.d(LOG_TAG, "wait for done");
2243 wait();
2244 } catch (InterruptedException e) {
2245 // Restore the interrupted status
2246 Thread.currentThread().interrupt();
2247 }
2248 }
2249 Log.d(LOG_TAG, "done");
Wink Saville9de0f752013-10-22 19:04:03 -07002250 int[] resultArray = new int[2];
2251 resultArray[0] = mResult;
2252 resultArray[1] = mRetryCount;
2253 return resultArray;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002254 }
2255 }
2256
Nathan Harold7c8d0f12020-05-28 20:40:31 -07002257 /**
2258 * This method has been removed due to privacy and stability concerns.
2259 */
2260 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002261 public void updateServiceLocation() {
Nathan Harold7c8d0f12020-05-28 20:40:31 -07002262 Log.e(LOG_TAG, "Call to unsupported method updateServiceLocation()");
2263 return;
Wink Saville36469e72014-06-11 15:17:00 -07002264 }
2265
Nathan Harold1f889d82020-06-04 17:05:26 -07002266 @Override
2267 public void updateServiceLocationWithPackageName(String callingPackage) {
2268 mApp.getSystemService(AppOpsManager.class)
2269 .checkPackage(Binder.getCallingUid(), callingPackage);
2270
2271 final int targetSdk = getTargetSdk(callingPackage);
2272 if (targetSdk > android.os.Build.VERSION_CODES.R) {
2273 // Callers targeting S have no business invoking this method.
2274 return;
2275 }
2276
2277 LocationAccessPolicy.LocationPermissionResult locationResult =
2278 LocationAccessPolicy.checkLocationPermission(mApp,
2279 new LocationAccessPolicy.LocationPermissionQuery.Builder()
2280 .setCallingPackage(callingPackage)
2281 .setCallingFeatureId(null)
2282 .setCallingPid(Binder.getCallingPid())
2283 .setCallingUid(Binder.getCallingUid())
2284 .setMethod("updateServiceLocation")
2285 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
2286 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2287 .build());
2288 // Apps that lack location permission have no business calling this method;
2289 // however, because no permission was declared in the public API, denials must
2290 // all be "soft".
2291 switch (locationResult) {
2292 case DENIED_HARD: /* fall through */
2293 case DENIED_SOFT:
2294 return;
2295 }
2296
2297 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002298 final long identity = Binder.clearCallingIdentity();
2299 try {
Nathan Harold1f889d82020-06-04 17:05:26 -07002300 final Phone phone = getPhone(getDefaultSubscription());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002301 if (phone != null) {
Nathan Harold1f889d82020-06-04 17:05:26 -07002302 phone.updateServiceLocation(workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002303 }
2304 } finally {
2305 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002306 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002307 }
2308
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002309 @Deprecated
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002310 @Override
2311 public boolean isRadioOn(String callingPackage) {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002312 return isRadioOnWithFeature(callingPackage, null);
2313 }
2314
2315
2316 @Override
2317 public boolean isRadioOnWithFeature(String callingPackage, String callingFeatureId) {
2318 return isRadioOnForSubscriberWithFeature(getDefaultSubscription(), callingPackage,
2319 callingFeatureId);
2320 }
2321
2322 @Deprecated
2323 @Override
2324 public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
2325 return isRadioOnForSubscriberWithFeature(subId, callingPackage, null);
Wink Saville36469e72014-06-11 15:17:00 -07002326 }
2327
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002328 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002329 public boolean isRadioOnForSubscriberWithFeature(int subId, String callingPackage,
2330 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002331 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002332 mApp, subId, callingPackage, callingFeatureId, "isRadioOnForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002333 return false;
2334 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002335
2336 final long identity = Binder.clearCallingIdentity();
2337 try {
2338 return isRadioOnForSubscriber(subId);
2339 } finally {
2340 Binder.restoreCallingIdentity(identity);
2341 }
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002342 }
2343
2344 private boolean isRadioOnForSubscriber(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002345 final long identity = Binder.clearCallingIdentity();
2346 try {
2347 final Phone phone = getPhone(subId);
2348 if (phone != null) {
2349 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
2350 } else {
2351 return false;
2352 }
2353 } finally {
2354 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002355 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002356 }
2357
2358 public void toggleRadioOnOff() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002359 toggleRadioOnOffForSubscriber(getDefaultSubscription());
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002360 }
Wink Saville36469e72014-06-11 15:17:00 -07002361
Wink Savilleb564aae2014-10-23 10:18:09 -07002362 public void toggleRadioOnOffForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002363 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002364
2365 final long identity = Binder.clearCallingIdentity();
2366 try {
2367 final Phone phone = getPhone(subId);
2368 if (phone != null) {
2369 phone.setRadioPower(!isRadioOnForSubscriber(subId));
2370 }
2371 } finally {
2372 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002373 }
Wink Saville36469e72014-06-11 15:17:00 -07002374 }
2375
2376 public boolean setRadio(boolean turnOn) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002377 return setRadioForSubscriber(getDefaultSubscription(), turnOn);
Wink Saville36469e72014-06-11 15:17:00 -07002378 }
2379
Wink Savilleb564aae2014-10-23 10:18:09 -07002380 public boolean setRadioForSubscriber(int subId, boolean turnOn) {
Wink Saville36469e72014-06-11 15:17:00 -07002381 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002382
2383 final long identity = Binder.clearCallingIdentity();
2384 try {
2385 final Phone phone = getPhone(subId);
2386 if (phone == null) {
2387 return false;
2388 }
2389 if ((phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF) != turnOn) {
2390 toggleRadioOnOffForSubscriber(subId);
2391 }
2392 return true;
2393 } finally {
2394 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002395 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002396 }
Wink Saville36469e72014-06-11 15:17:00 -07002397
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002398 public boolean needMobileRadioShutdown() {
Shuo Qianfa7b6b32019-12-10 10:40:38 -08002399 enforceReadPrivilegedPermission("needMobileRadioShutdown");
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002400 /*
2401 * If any of the Radios are available, it will need to be
2402 * shutdown. So return true if any Radio is available.
2403 */
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002404 final long identity = Binder.clearCallingIdentity();
2405 try {
2406 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
2407 Phone phone = PhoneFactory.getPhone(i);
2408 if (phone != null && phone.isRadioAvailable()) return true;
2409 }
2410 logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown.");
2411 return false;
2412 } finally {
2413 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002414 }
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002415 }
2416
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002417 @Override
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002418 public void shutdownMobileRadios() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002419 enforceModifyPermission();
2420
2421 final long identity = Binder.clearCallingIdentity();
2422 try {
2423 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
2424 logv("Shutting down Phone " + i);
2425 shutdownRadioUsingPhoneId(i);
2426 }
2427 } finally {
2428 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002429 }
2430 }
2431
2432 private void shutdownRadioUsingPhoneId(int phoneId) {
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002433 Phone phone = PhoneFactory.getPhone(phoneId);
2434 if (phone != null && phone.isRadioAvailable()) {
2435 phone.shutdownRadio();
2436 }
2437 }
2438
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002439 public boolean setRadioPower(boolean turnOn) {
Jack Yub4e16162017-05-15 12:48:40 -07002440 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002441
2442 final long identity = Binder.clearCallingIdentity();
2443 try {
2444 final Phone defaultPhone = PhoneFactory.getDefaultPhone();
2445 if (defaultPhone != null) {
2446 defaultPhone.setRadioPower(turnOn);
2447 return true;
2448 } else {
2449 loge("There's no default phone.");
2450 return false;
2451 }
2452 } finally {
2453 Binder.restoreCallingIdentity(identity);
Wei Liu9ae2a062016-08-08 11:09:34 -07002454 }
Wink Saville36469e72014-06-11 15:17:00 -07002455 }
2456
Wink Savilleb564aae2014-10-23 10:18:09 -07002457 public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002458 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002459
2460 final long identity = Binder.clearCallingIdentity();
2461 try {
2462 final Phone phone = getPhone(subId);
2463 if (phone != null) {
2464 phone.setRadioPower(turnOn);
2465 return true;
2466 } else {
2467 return false;
2468 }
2469 } finally {
2470 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002471 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002472 }
2473
Wink Saville36469e72014-06-11 15:17:00 -07002474 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07002475 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002476 public boolean enableDataConnectivity() {
2477 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002478
2479 final long identity = Binder.clearCallingIdentity();
2480 try {
2481 int subId = mSubscriptionController.getDefaultDataSubId();
2482 final Phone phone = getPhone(subId);
2483 if (phone != null) {
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00002484 phone.getDataEnabledSettings().setDataEnabled(
2485 TelephonyManager.DATA_ENABLED_REASON_USER, true);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002486 return true;
2487 } else {
2488 return false;
2489 }
2490 } finally {
2491 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002492 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002493 }
2494
Wink Saville36469e72014-06-11 15:17:00 -07002495 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07002496 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002497 public boolean disableDataConnectivity() {
2498 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002499
2500 final long identity = Binder.clearCallingIdentity();
2501 try {
2502 int subId = mSubscriptionController.getDefaultDataSubId();
2503 final Phone phone = getPhone(subId);
2504 if (phone != null) {
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00002505 phone.getDataEnabledSettings().setDataEnabled(
2506 TelephonyManager.DATA_ENABLED_REASON_USER, false);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002507 return true;
2508 } else {
2509 return false;
2510 }
2511 } finally {
2512 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002513 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002514 }
2515
Sanket Padawe356d7632015-06-22 14:03:32 -07002516 @Override
Jack Yuacf8a132017-05-01 17:00:48 -07002517 public boolean isDataConnectivityPossible(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002518 final long identity = Binder.clearCallingIdentity();
2519 try {
2520 final Phone phone = getPhone(subId);
2521 if (phone != null) {
Jack Yub5d8f642018-11-26 11:20:48 -08002522 return phone.isDataAllowed(ApnSetting.TYPE_DEFAULT);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002523 } else {
2524 return false;
2525 }
2526 } finally {
2527 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002528 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002529 }
2530
2531 public boolean handlePinMmi(String dialString) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002532 return handlePinMmiForSubscriber(getDefaultSubscription(), dialString);
Wink Saville36469e72014-06-11 15:17:00 -07002533 }
2534
pkanwarae03a6b2016-11-06 20:37:09 -08002535 public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002536 enforceCallPermission();
2537
2538 final long identity = Binder.clearCallingIdentity();
2539 try {
2540 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2541 return;
2542 }
2543 Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback);
2544 sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId);
2545 } finally {
2546 Binder.restoreCallingIdentity(identity);
2547 }
pkanwar32d516d2016-10-14 19:37:38 -07002548 };
2549
Wink Savilleb564aae2014-10-23 10:18:09 -07002550 public boolean handlePinMmiForSubscriber(int subId, String dialString) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002551 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002552
2553 final long identity = Binder.clearCallingIdentity();
2554 try {
2555 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2556 return false;
2557 }
2558 return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
2559 } finally {
2560 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002561 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002562 }
2563
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002564 public int getCallState() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07002565 return getCallStateForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002566 }
2567
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002568 public int getCallStateForSlot(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002569 final long identity = Binder.clearCallingIdentity();
2570 try {
2571 Phone phone = PhoneFactory.getPhone(slotIndex);
2572 return phone == null ? TelephonyManager.CALL_STATE_IDLE :
2573 PhoneConstantConversions.convertCallState(phone.getState());
2574 } finally {
2575 Binder.restoreCallingIdentity(identity);
2576 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002577 }
2578
Sanket Padawe356d7632015-06-22 14:03:32 -07002579 @Override
Nathan Harolde037c472019-06-26 00:41:07 +00002580 public int getDataState() {
Nathan Haroldc4689b12019-06-14 16:58:30 -07002581 return getDataStateForSubId(mSubscriptionController.getDefaultDataSubId());
2582 }
2583
2584 @Override
2585 public int getDataStateForSubId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002586 final long identity = Binder.clearCallingIdentity();
2587 try {
Nathan Haroldc4689b12019-06-14 16:58:30 -07002588 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002589 if (phone != null) {
2590 return PhoneConstantConversions.convertDataState(phone.getDataConnectionState());
2591 } else {
2592 return PhoneConstantConversions.convertDataState(
2593 PhoneConstants.DataState.DISCONNECTED);
2594 }
2595 } finally {
2596 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002597 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002598 }
2599
Sanket Padawe356d7632015-06-22 14:03:32 -07002600 @Override
Nathan Harolde037c472019-06-26 00:41:07 +00002601 public int getDataActivity() {
Nathan Haroldc4689b12019-06-14 16:58:30 -07002602 return getDataActivityForSubId(mSubscriptionController.getDefaultDataSubId());
2603 }
2604
2605 @Override
2606 public int getDataActivityForSubId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002607 final long identity = Binder.clearCallingIdentity();
2608 try {
Nathan Haroldc4689b12019-06-14 16:58:30 -07002609 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002610 if (phone != null) {
2611 return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState());
2612 } else {
2613 return TelephonyManager.DATA_ACTIVITY_NONE;
2614 }
2615 } finally {
2616 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002617 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002618 }
2619
2620 @Override
Meng Wanga10e89e2019-12-09 13:13:01 -08002621 public CellIdentity getCellLocation(String callingPackage, String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002622 mApp.getSystemService(AppOpsManager.class)
Hall Liu1aa510f2017-11-22 17:40:08 -08002623 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08002624
2625 LocationAccessPolicy.LocationPermissionResult locationResult =
2626 LocationAccessPolicy.checkLocationPermission(mApp,
2627 new LocationAccessPolicy.LocationPermissionQuery.Builder()
2628 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002629 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08002630 .setCallingPid(Binder.getCallingPid())
2631 .setCallingUid(Binder.getCallingUid())
2632 .setMethod("getCellLocation")
Hall Liu773ba022020-01-24 18:07:12 -08002633 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
Hall Liuf19c44f2018-11-27 14:38:17 -08002634 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2635 .build());
2636 switch (locationResult) {
2637 case DENIED_HARD:
2638 throw new SecurityException("Not allowed to access cell location");
2639 case DENIED_SOFT:
Meng Wanga10e89e2019-12-09 13:13:01 -08002640 return (getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
2641 ? new CellIdentityCdma() : new CellIdentityGsm();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002642 }
2643
Narayan Kamathf04b5a12018-01-09 11:47:15 +00002644 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002645 final long identity = Binder.clearCallingIdentity();
2646 try {
2647 if (DBG_LOC) log("getCellLocation: is active user");
Nathan Harold3ff88932018-08-14 10:19:49 -07002648 int subId = mSubscriptionController.getDefaultDataSubId();
Meng Wanga10e89e2019-12-09 13:13:01 -08002649 return (CellIdentity) sendRequest(CMD_GET_CELL_LOCATION, workSource, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002650 } finally {
2651 Binder.restoreCallingIdentity(identity);
2652 }
Svetoslav64fad262015-04-14 14:35:21 -07002653 }
2654
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002655 @Override
Jack Yueb1e7fe2020-02-22 19:38:58 -08002656 public String getNetworkCountryIsoForPhone(int phoneId) {
Jonathan Basseribf5362b2017-07-19 12:22:35 -07002657 // Reporting the correct network country is ambiguous when IWLAN could conflict with
2658 // registered cell info, so return a NULL country instead.
2659 final long identity = Binder.clearCallingIdentity();
2660 try {
Malcolm Chen3732c2b2018-07-18 20:15:24 -07002661 if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
2662 // Get default phone in this case.
2663 phoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
2664 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07002665 final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002666 Phone phone = PhoneFactory.getPhone(phoneId);
Nathan Harold532f51c2020-04-21 19:31:10 -07002667 if (phone == null) return "";
2668 ServiceStateTracker sst = phone.getServiceStateTracker();
2669 if (sst == null) return "";
2670 LocaleTracker lt = sst.getLocaleTracker();
2671 if (lt == null) return "";
2672 if (!TextUtils.isEmpty(lt.getCurrentCountry())) return lt.getCurrentCountry();
2673 EmergencyNumberTracker ent = phone.getEmergencyNumberTracker();
2674 return (ent == null) ? "" : ent.getEmergencyCountryIso();
Jonathan Basseribf5362b2017-07-19 12:22:35 -07002675 } finally {
2676 Binder.restoreCallingIdentity(identity);
2677 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07002678 }
2679
Nathan Harold7c8d0f12020-05-28 20:40:31 -07002680 /**
2681 * This method was removed due to potential issues caused by performing partial
2682 * updates of service state, and lack of a credible use case.
2683 *
2684 * This has the ability to break the telephony implementation by disabling notification of
2685 * changes in device connectivity. DO NOT USE THIS!
2686 */
Jonathan Basseribf5362b2017-07-19 12:22:35 -07002687 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002688 public void enableLocationUpdates() {
2689 mApp.enforceCallingOrSelfPermission(
2690 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002691 }
2692
Nathan Harold7c8d0f12020-05-28 20:40:31 -07002693 /**
2694 * This method was removed due to potential issues caused by performing partial
2695 * updates of service state, and lack of a credible use case.
2696 *
2697 * This has the ability to break the telephony implementation by disabling notification of
2698 * changes in device connectivity. DO NOT USE THIS!
2699 */
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002700 @Override
2701 public void disableLocationUpdates() {
2702 mApp.enforceCallingOrSelfPermission(
2703 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002704 }
2705
Nathan Harold31d7ff32018-10-15 20:20:30 -07002706 /**
2707 * Returns the target SDK version number for a given package name.
2708 *
Nathan Haroldec184742019-07-10 17:04:16 -07002709 * This call MUST be invoked before clearing the calling UID.
2710 *
Nathan Harold31d7ff32018-10-15 20:20:30 -07002711 * @return target SDK if the package is found or INT_MAX.
2712 */
2713 private int getTargetSdk(String packageName) {
2714 try {
Nathan Haroldec184742019-07-10 17:04:16 -07002715 final ApplicationInfo ai = mApp.getPackageManager().getApplicationInfoAsUser(
Chen Xu0150f0e2019-07-30 15:12:06 -07002716 packageName, 0, UserHandle.getUserHandleForUid(Binder.getCallingUid()));
Nathan Harold31d7ff32018-10-15 20:20:30 -07002717 if (ai != null) return ai.targetSdkVersion;
2718 } catch (PackageManager.NameNotFoundException unexpected) {
Nathan Haroldec184742019-07-10 17:04:16 -07002719 loge("Failed to get package info for pkg="
2720 + packageName + ", uid=" + Binder.getCallingUid());
Nathan Harold31d7ff32018-10-15 20:20:30 -07002721 }
2722 return Integer.MAX_VALUE;
2723 }
2724
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002725 @Override
2726 @SuppressWarnings("unchecked")
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002727 public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage,
2728 String callingFeatureId) {
Nathan Harold31d7ff32018-10-15 20:20:30 -07002729 final int targetSdk = getTargetSdk(callingPackage);
Nathan Harolddbea45a2018-08-30 14:35:07 -07002730 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
2731 throw new SecurityException(
2732 "getNeighboringCellInfo() is unavailable to callers targeting Q+ SDK levels.");
2733 }
Nathan Haroldb4d55612018-07-20 13:13:08 -07002734
Jordan Liu1617b712019-07-10 15:06:26 -07002735 if (mAppOps.noteOp(AppOpsManager.OPSTR_NEIGHBORING_CELLS, Binder.getCallingUid(),
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002736 callingPackage) != AppOpsManager.MODE_ALLOWED) {
2737 return null;
2738 }
Svetoslav64fad262015-04-14 14:35:21 -07002739
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07002740 if (DBG_LOC) log("getNeighboringCellInfo: is active user");
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002741
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002742 List<CellInfo> info = getAllCellInfo(callingPackage, callingFeatureId);
Nathan Haroldf180aac2018-06-01 18:43:55 -07002743 if (info == null) return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002744
Nathan Haroldf180aac2018-06-01 18:43:55 -07002745 List<NeighboringCellInfo> neighbors = new ArrayList<NeighboringCellInfo>();
2746 for (CellInfo ci : info) {
2747 if (ci instanceof CellInfoGsm) {
2748 neighbors.add(new NeighboringCellInfo((CellInfoGsm) ci));
2749 } else if (ci instanceof CellInfoWcdma) {
2750 neighbors.add(new NeighboringCellInfo((CellInfoWcdma) ci));
2751 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002752 }
Nathan Haroldf180aac2018-06-01 18:43:55 -07002753 return (neighbors.size()) > 0 ? neighbors : null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002754 }
2755
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002756 private List<CellInfo> getCachedCellInfo() {
2757 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
2758 for (Phone phone : PhoneFactory.getPhones()) {
2759 List<CellInfo> info = phone.getAllCellInfo();
2760 if (info != null) cellInfos.addAll(info);
2761 }
2762 return cellInfos;
2763 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002764
2765 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002766 public List<CellInfo> getAllCellInfo(String callingPackage, String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002767 mApp.getSystemService(AppOpsManager.class)
Hall Liu1aa510f2017-11-22 17:40:08 -08002768 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08002769
2770 LocationAccessPolicy.LocationPermissionResult locationResult =
2771 LocationAccessPolicy.checkLocationPermission(mApp,
2772 new LocationAccessPolicy.LocationPermissionQuery.Builder()
2773 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002774 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08002775 .setCallingPid(Binder.getCallingPid())
2776 .setCallingUid(Binder.getCallingUid())
2777 .setMethod("getAllCellInfo")
Nathan Harold5ae50b52019-02-20 15:46:36 -08002778 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
Hall Liuf19c44f2018-11-27 14:38:17 -08002779 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2780 .build());
2781 switch (locationResult) {
2782 case DENIED_HARD:
2783 throw new SecurityException("Not allowed to access cell info");
2784 case DENIED_SOFT:
2785 return new ArrayList<>();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002786 }
2787
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002788 final int targetSdk = getTargetSdk(callingPackage);
2789 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
2790 return getCachedCellInfo();
2791 }
2792
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07002793 if (DBG_LOC) log("getAllCellInfo: is active user");
Narayan Kamathf04b5a12018-01-09 11:47:15 +00002794 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002795 final long identity = Binder.clearCallingIdentity();
2796 try {
2797 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
2798 for (Phone phone : PhoneFactory.getPhones()) {
Nathan Harold3ff88932018-08-14 10:19:49 -07002799 final List<CellInfo> info = (List<CellInfo>) sendRequest(
Nathan Harold92bed182018-10-12 18:16:49 -07002800 CMD_GET_ALL_CELL_INFO, null, phone, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002801 if (info != null) cellInfos.addAll(info);
2802 }
2803 return cellInfos;
2804 } finally {
2805 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002806 }
2807 }
2808
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07002809 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002810 public void requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage,
2811 String callingFeatureId) {
2812 requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId,
2813 getWorkSource(Binder.getCallingUid()));
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002814 }
2815
2816 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002817 public void requestCellInfoUpdateWithWorkSource(int subId, ICellInfoCallback cb,
2818 String callingPackage, String callingFeatureId, WorkSource workSource) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002819 enforceModifyPermission();
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002820 requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId, workSource);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002821 }
2822
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002823 private void requestCellInfoUpdateInternal(int subId, ICellInfoCallback cb,
2824 String callingPackage, String callingFeatureId, WorkSource workSource) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002825 mApp.getSystemService(AppOpsManager.class)
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002826 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08002827
2828 LocationAccessPolicy.LocationPermissionResult locationResult =
2829 LocationAccessPolicy.checkLocationPermission(mApp,
2830 new LocationAccessPolicy.LocationPermissionQuery.Builder()
2831 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07002832 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08002833 .setCallingPid(Binder.getCallingPid())
2834 .setCallingUid(Binder.getCallingUid())
2835 .setMethod("requestCellInfoUpdate")
Hall Liud60acc92020-05-21 17:09:35 -07002836 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
2837 .setMinSdkVersionForFine(Build.VERSION_CODES.BASE)
Hall Liuf19c44f2018-11-27 14:38:17 -08002838 .build());
2839 switch (locationResult) {
2840 case DENIED_HARD:
Hall Liud60acc92020-05-21 17:09:35 -07002841 if (getTargetSdk(callingPackage) < Build.VERSION_CODES.Q) {
2842 // Safetynet logging for b/154934934
2843 EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
2844 }
Hall Liuf19c44f2018-11-27 14:38:17 -08002845 throw new SecurityException("Not allowed to access cell info");
2846 case DENIED_SOFT:
Hall Liud60acc92020-05-21 17:09:35 -07002847 if (getTargetSdk(callingPackage) < Build.VERSION_CODES.Q) {
2848 // Safetynet logging for b/154934934
2849 EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
2850 }
Nathan Harold5320c422019-05-09 10:26:08 -07002851 try {
2852 cb.onCellInfo(new ArrayList<CellInfo>());
2853 } catch (RemoteException re) {
2854 // Drop without consequences
2855 }
Hall Liuf19c44f2018-11-27 14:38:17 -08002856 return;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002857 }
2858
Nathan Harolda939a962019-05-09 10:13:47 -07002859
2860 final Phone phone = getPhoneFromSubId(subId);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002861 if (phone == null) throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
2862
2863 sendRequestAsync(CMD_REQUEST_CELL_INFO_UPDATE, cb, phone, workSource);
2864 }
2865
2866 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002867 public void setCellInfoListRate(int rateInMillis) {
Jack Yua8d8cb82017-01-16 10:15:34 -08002868 enforceModifyPermission();
Narayan Kamathf04b5a12018-01-09 11:47:15 +00002869 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002870
2871 final long identity = Binder.clearCallingIdentity();
2872 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002873 getDefaultPhone().setCellInfoListRate(rateInMillis, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002874 } finally {
2875 Binder.restoreCallingIdentity(identity);
2876 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002877 }
2878
Shishir Agrawala9f32182016-04-12 12:00:16 -07002879 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002880 public String getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002881 Phone phone = PhoneFactory.getPhone(slotIndex);
2882 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002883 return null;
2884 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002885 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07002886 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002887 callingPackage, callingFeatureId, "getImeiForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002888 return null;
2889 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002890
2891 final long identity = Binder.clearCallingIdentity();
2892 try {
2893 return phone.getImei();
2894 } finally {
2895 Binder.restoreCallingIdentity(identity);
2896 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002897 }
2898
2899 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002900 public String getTypeAllocationCodeForSlot(int slotIndex) {
2901 Phone phone = PhoneFactory.getPhone(slotIndex);
2902 String tac = null;
2903 if (phone != null) {
2904 String imei = phone.getImei();
2905 tac = imei == null ? null : imei.substring(0, TYPE_ALLOCATION_CODE_LENGTH);
2906 }
2907 return tac;
2908 }
2909
2910 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002911 public String getMeidForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002912 Phone phone = PhoneFactory.getPhone(slotIndex);
2913 if (phone == null) {
Jack Yu2af8d712017-03-15 17:14:14 -07002914 return null;
2915 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002916
Jeff Davidson913390f2018-02-23 17:11:49 -08002917 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07002918 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002919 callingPackage, callingFeatureId, "getMeidForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002920 return null;
2921 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002922
2923 final long identity = Binder.clearCallingIdentity();
2924 try {
2925 return phone.getMeid();
2926 } finally {
2927 Binder.restoreCallingIdentity(identity);
2928 }
Jack Yu2af8d712017-03-15 17:14:14 -07002929 }
2930
2931 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002932 public String getManufacturerCodeForSlot(int slotIndex) {
2933 Phone phone = PhoneFactory.getPhone(slotIndex);
2934 String manufacturerCode = null;
2935 if (phone != null) {
2936 String meid = phone.getMeid();
2937 manufacturerCode = meid == null ? null : meid.substring(0, MANUFACTURER_CODE_LENGTH);
2938 }
2939 return manufacturerCode;
2940 }
2941
2942 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002943 public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage,
2944 String callingFeatureId) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002945 Phone phone = PhoneFactory.getPhone(slotIndex);
2946 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002947 return null;
2948 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002949 int subId = phone.getSubId();
2950 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002951 mApp, subId, callingPackage, callingFeatureId,
2952 "getDeviceSoftwareVersionForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002953 return null;
2954 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002955
2956 final long identity = Binder.clearCallingIdentity();
2957 try {
2958 return phone.getDeviceSvn();
2959 } finally {
2960 Binder.restoreCallingIdentity(identity);
2961 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002962 }
2963
fionaxu43304da2017-11-27 22:51:16 -08002964 @Override
2965 public int getSubscriptionCarrierId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002966 final long identity = Binder.clearCallingIdentity();
2967 try {
2968 final Phone phone = getPhone(subId);
2969 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getCarrierId();
2970 } finally {
2971 Binder.restoreCallingIdentity(identity);
2972 }
fionaxu43304da2017-11-27 22:51:16 -08002973 }
2974
2975 @Override
2976 public String getSubscriptionCarrierName(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002977 final long identity = Binder.clearCallingIdentity();
2978 try {
2979 final Phone phone = getPhone(subId);
2980 return phone == null ? null : phone.getCarrierName();
2981 } finally {
2982 Binder.restoreCallingIdentity(identity);
2983 }
fionaxu43304da2017-11-27 22:51:16 -08002984 }
2985
calvinpanffe225e2018-11-01 19:43:06 +08002986 @Override
chen xu0026ca62019-03-06 15:28:50 -08002987 public int getSubscriptionSpecificCarrierId(int subId) {
chen xu25637222018-11-04 17:17:00 -08002988 final long identity = Binder.clearCallingIdentity();
2989 try {
2990 final Phone phone = getPhone(subId);
2991 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID
chen xu0026ca62019-03-06 15:28:50 -08002992 : phone.getSpecificCarrierId();
chen xu25637222018-11-04 17:17:00 -08002993 } finally {
2994 Binder.restoreCallingIdentity(identity);
2995 }
2996 }
2997
2998 @Override
chen xu0026ca62019-03-06 15:28:50 -08002999 public String getSubscriptionSpecificCarrierName(int subId) {
chen xu25637222018-11-04 17:17:00 -08003000 final long identity = Binder.clearCallingIdentity();
3001 try {
3002 final Phone phone = getPhone(subId);
chen xu0026ca62019-03-06 15:28:50 -08003003 return phone == null ? null : phone.getSpecificCarrierName();
chen xu25637222018-11-04 17:17:00 -08003004 } finally {
3005 Binder.restoreCallingIdentity(identity);
3006 }
3007 }
3008
chen xu651eec72018-11-11 19:03:44 -08003009 @Override
chen xu864e11c2018-12-06 22:10:03 -08003010 public int getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc) {
3011 if (!isSubscriptionMccMnc) {
3012 enforceReadPrivilegedPermission("getCarrierIdFromMccMnc");
3013 }
chen xu651eec72018-11-11 19:03:44 -08003014 final Phone phone = PhoneFactory.getPhone(slotIndex);
3015 if (phone == null) {
3016 return TelephonyManager.UNKNOWN_CARRIER_ID;
3017 }
3018 final long identity = Binder.clearCallingIdentity();
3019 try {
3020 return CarrierResolver.getCarrierIdFromMccMnc(phone.getContext(), mccmnc);
3021 } finally {
3022 Binder.restoreCallingIdentity(identity);
3023 }
3024 }
3025
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003026 //
3027 // Internal helper methods.
3028 //
3029
Sanket Padaweee13a9b2016-03-08 17:30:28 -08003030 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003031 * Make sure the caller has the MODIFY_PHONE_STATE permission.
3032 *
3033 * @throws SecurityException if the caller does not have the required permission
3034 */
3035 private void enforceModifyPermission() {
3036 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
3037 }
3038
Shuo Qiancd19c462020-01-16 20:51:11 -08003039 /**
3040 * Make sure the caller is system.
3041 *
3042 * @throws SecurityException if the caller is not system.
3043 */
3044 private void enforceSystemCaller() {
3045 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
3046 throw new SecurityException("Caller must be system");
3047 }
3048 }
3049
Shuo Qian3b6ee772019-11-13 17:43:31 -08003050 private void enforceActiveEmergencySessionPermission() {
3051 mApp.enforceCallingOrSelfPermission(
3052 android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION, null);
3053 }
3054
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003055 /**
3056 * Make sure the caller has the CALL_PHONE permission.
3057 *
3058 * @throws SecurityException if the caller does not have the required permission
3059 */
3060 private void enforceCallPermission() {
3061 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
3062 }
3063
paulhu5a773602019-08-23 19:17:33 +08003064 private void enforceSettingsPermission() {
3065 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.NETWORK_SETTINGS, null);
Stuart Scott8eef64f2015-04-08 15:13:54 -07003066 }
3067
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003068 private String createTelUrl(String number) {
3069 if (TextUtils.isEmpty(number)) {
3070 return null;
3071 }
3072
Jake Hambye994d462014-02-03 13:10:13 -08003073 return "tel:" + number;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003074 }
3075
Ihab Awadf9e92732013-12-05 18:02:52 -08003076 private static void log(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003077 Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg);
3078 }
3079
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07003080 private static void logv(String msg) {
3081 Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg);
3082 }
3083
Ihab Awadf9e92732013-12-05 18:02:52 -08003084 private static void loge(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003085 Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg);
3086 }
3087
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003088 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003089 public int getActivePhoneType() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07003090 return getActivePhoneTypeForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07003091 }
3092
Sanket Padawe356d7632015-06-22 14:03:32 -07003093 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07003094 public int getActivePhoneTypeForSlot(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003095 final long identity = Binder.clearCallingIdentity();
3096 try {
3097 final Phone phone = PhoneFactory.getPhone(slotIndex);
3098 if (phone == null) {
3099 return PhoneConstants.PHONE_TYPE_NONE;
3100 } else {
3101 return phone.getPhoneType();
3102 }
3103 } finally {
3104 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003105 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003106 }
3107
3108 /**
3109 * Returns the CDMA ERI icon index to display
3110 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003111 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003112 public int getCdmaEriIconIndex(String callingPackage, String callingFeatureId) {
3113 return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage,
3114 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07003115 }
3116
Sanket Padawe356d7632015-06-22 14:03:32 -07003117 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003118 public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage,
3119 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003120 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003121 mApp, subId, callingPackage, callingFeatureId,
3122 "getCdmaEriIconIndexForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003123 return -1;
3124 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003125
3126 final long identity = Binder.clearCallingIdentity();
3127 try {
3128 final Phone phone = getPhone(subId);
3129 if (phone != null) {
3130 return phone.getCdmaEriIconIndex();
3131 } else {
3132 return -1;
3133 }
3134 } finally {
3135 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003136 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003137 }
3138
3139 /**
3140 * Returns the CDMA ERI icon mode,
3141 * 0 - ON
3142 * 1 - FLASHING
3143 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003144 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003145 public int getCdmaEriIconMode(String callingPackage, String callingFeatureId) {
3146 return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage,
3147 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07003148 }
3149
Sanket Padawe356d7632015-06-22 14:03:32 -07003150 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003151 public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage,
3152 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003153 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003154 mApp, subId, callingPackage, callingFeatureId,
3155 "getCdmaEriIconModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003156 return -1;
3157 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003158
3159 final long identity = Binder.clearCallingIdentity();
3160 try {
3161 final Phone phone = getPhone(subId);
3162 if (phone != null) {
3163 return phone.getCdmaEriIconMode();
3164 } else {
3165 return -1;
3166 }
3167 } finally {
3168 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003169 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003170 }
3171
3172 /**
3173 * Returns the CDMA ERI text,
3174 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003175 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003176 public String getCdmaEriText(String callingPackage, String callingFeatureId) {
3177 return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage,
3178 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07003179 }
3180
Sanket Padawe356d7632015-06-22 14:03:32 -07003181 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003182 public String getCdmaEriTextForSubscriber(int subId, String callingPackage,
3183 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003184 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003185 mApp, subId, callingPackage, callingFeatureId,
3186 "getCdmaEriIconTextForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003187 return null;
3188 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003189
3190 final long identity = Binder.clearCallingIdentity();
3191 try {
3192 final Phone phone = getPhone(subId);
3193 if (phone != null) {
3194 return phone.getCdmaEriText();
3195 } else {
3196 return null;
3197 }
3198 } finally {
3199 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003200 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003201 }
3202
3203 /**
Junda Liuca05d5d2014-08-14 22:36:34 -07003204 * Returns the CDMA MDN.
3205 */
Sanket Padawe356d7632015-06-22 14:03:32 -07003206 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07003207 public String getCdmaMdn(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003208 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3209 mApp, subId, "getCdmaMdn");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003210
3211 final long identity = Binder.clearCallingIdentity();
3212 try {
3213 final Phone phone = getPhone(subId);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003214 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003215 return phone.getLine1Number();
3216 } else {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003217 loge("getCdmaMdn: no phone found. Invalid subId: " + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003218 return null;
3219 }
3220 } finally {
3221 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07003222 }
3223 }
3224
3225 /**
3226 * Returns the CDMA MIN.
3227 */
Sanket Padawe356d7632015-06-22 14:03:32 -07003228 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07003229 public String getCdmaMin(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003230 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3231 mApp, subId, "getCdmaMin");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003232
3233 final long identity = Binder.clearCallingIdentity();
3234 try {
3235 final Phone phone = getPhone(subId);
3236 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
3237 return phone.getCdmaMin();
3238 } else {
3239 return null;
3240 }
3241 } finally {
3242 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07003243 }
3244 }
3245
Hall Liud892bec2018-11-30 14:51:45 -08003246 @Override
3247 public void requestNumberVerification(PhoneNumberRange range, long timeoutMillis,
3248 INumberVerificationCallback callback, String callingPackage) {
3249 if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
3250 != PERMISSION_GRANTED) {
3251 throw new SecurityException("Caller must hold the MODIFY_PHONE_STATE permission");
3252 }
3253 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3254
3255 String authorizedPackage = NumberVerificationManager.getAuthorizedPackage(mApp);
3256 if (!TextUtils.equals(callingPackage, authorizedPackage)) {
3257 throw new SecurityException("Calling package must be configured in the device config");
3258 }
3259
3260 if (range == null) {
3261 throw new NullPointerException("Range must be non-null");
3262 }
3263
3264 timeoutMillis = Math.min(timeoutMillis,
Hall Liubd069e32019-02-28 18:56:30 -08003265 TelephonyManager.getMaxNumberVerificationTimeoutMillis());
Hall Liud892bec2018-11-30 14:51:45 -08003266
3267 NumberVerificationManager.getInstance().requestVerification(range, callback, timeoutMillis);
3268 }
3269
Junda Liuca05d5d2014-08-14 22:36:34 -07003270 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003271 * Returns true if CDMA provisioning needs to run.
3272 */
3273 public boolean needsOtaServiceProvisioning() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003274 final long identity = Binder.clearCallingIdentity();
3275 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003276 return getDefaultPhone().needsOtaServiceProvisioning();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003277 } finally {
3278 Binder.restoreCallingIdentity(identity);
3279 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003280 }
3281
3282 /**
Shishir Agrawal76d5da92014-11-09 16:17:25 -08003283 * Sets the voice mail number of a given subId.
3284 */
3285 @Override
3286 public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08003287 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
3288 mApp, subId, "setVoiceMailNumber");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003289
3290 final long identity = Binder.clearCallingIdentity();
3291 try {
3292 Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
3293 new Pair<String, String>(alphaTag, number), new Integer(subId));
3294 return success;
3295 } finally {
3296 Binder.restoreCallingIdentity(identity);
3297 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08003298 }
3299
Ta-wei Yen87c49842016-05-13 21:19:52 -07003300 @Override
Ta-wei Yenc9df0432017-04-17 17:09:07 -07003301 public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
3302 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07003303 TelecomManager tm = mApp.getSystemService(TelecomManager.class);
3304 String systemDialer = tm.getSystemDialerPackage();
Ta-wei Yenc9df0432017-04-17 17:09:07 -07003305 if (!TextUtils.equals(callingPackage, systemDialer)) {
3306 throw new SecurityException("caller must be system dialer");
3307 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003308
3309 final long identity = Binder.clearCallingIdentity();
3310 try {
3311 PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
3312 if (phoneAccountHandle == null) {
3313 return null;
3314 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003315 return VisualVoicemailSettingsUtil.dump(mApp, phoneAccountHandle);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003316 } finally {
3317 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc9df0432017-04-17 17:09:07 -07003318 }
Ta-wei Yenc9df0432017-04-17 17:09:07 -07003319 }
3320
3321 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003322 public String getVisualVoicemailPackageName(String callingPackage, String callingFeatureId,
3323 int subId) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08003324 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jeff Davidson7e17e312018-02-13 18:17:36 -08003325 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003326 mApp, subId, callingPackage, callingFeatureId,
3327 "getVisualVoicemailPackageName")) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08003328 return null;
3329 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003330
Jeff Davidsona8e4e242018-03-15 17:16:18 -07003331 final long identity = Binder.clearCallingIdentity();
3332 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003333 return RemoteVvmTaskManager.getRemotePackage(mApp, subId).getPackageName();
Jeff Davidsona8e4e242018-03-15 17:16:18 -07003334 } finally {
3335 Binder.restoreCallingIdentity(identity);
3336 }
Ta-wei Yendca928f2017-01-10 16:17:08 -08003337 }
3338
3339 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07003340 public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
3341 VisualVoicemailSmsFilterSettings settings) {
3342 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003343
3344 final long identity = Binder.clearCallingIdentity();
3345 try {
3346 VisualVoicemailSmsFilterConfig.enableVisualVoicemailSmsFilter(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003347 mApp, callingPackage, subId, settings);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003348 } finally {
3349 Binder.restoreCallingIdentity(identity);
3350 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07003351 }
3352
3353 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07003354 public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
3355 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003356
3357 final long identity = Binder.clearCallingIdentity();
3358 try {
3359 VisualVoicemailSmsFilterConfig.disableVisualVoicemailSmsFilter(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003360 mApp, callingPackage, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003361 } finally {
3362 Binder.restoreCallingIdentity(identity);
3363 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07003364 }
3365
3366 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07003367 public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
3368 String callingPackage, int subId) {
3369 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003370
3371 final long identity = Binder.clearCallingIdentity();
3372 try {
3373 return VisualVoicemailSmsFilterConfig.getVisualVoicemailSmsFilterSettings(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003374 mApp, callingPackage, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003375 } finally {
3376 Binder.restoreCallingIdentity(identity);
3377 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07003378 }
3379
3380 @Override
Ta-wei Yen30a69c82016-12-27 14:52:32 -08003381 public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003382 enforceReadPrivilegedPermission("getActiveVisualVoicemailSmsFilterSettings");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003383
3384 final long identity = Binder.clearCallingIdentity();
3385 try {
3386 return VisualVoicemailSmsFilterConfig.getActiveVisualVoicemailSmsFilterSettings(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003387 mApp, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003388 } finally {
3389 Binder.restoreCallingIdentity(identity);
3390 }
Ta-wei Yen30a69c82016-12-27 14:52:32 -08003391 }
3392
3393 @Override
Philip P. Moltmann2f6f8ce2020-03-18 18:17:02 -07003394 public void sendVisualVoicemailSmsForSubscriber(String callingPackage,
3395 String callingAttributionTag, int subId, String number, int port, String text,
3396 PendingIntent sentIntent) {
Ta-wei Yen30a69c82016-12-27 14:52:32 -08003397 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Ta-wei Yen527a9c02017-01-06 15:29:25 -08003398 enforceVisualVoicemailPackage(callingPackage, subId);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08003399 enforceSendSmsPermission();
Amit Mahajandccb3f12019-05-13 13:48:32 -07003400 SmsController smsController = PhoneFactory.getSmsController();
Philip P. Moltmann2f6f8ce2020-03-18 18:17:02 -07003401 smsController.sendVisualVoicemailSmsForSubscriber(callingPackage, callingAttributionTag,
3402 subId, number, port, text, sentIntent);
Ta-wei Yen87c49842016-05-13 21:19:52 -07003403 }
Amit Mahajandccb3f12019-05-13 13:48:32 -07003404
Shishir Agrawal76d5da92014-11-09 16:17:25 -08003405 /**
fionaxu0152e512016-11-14 13:36:14 -08003406 * Sets the voice activation state of a given subId.
3407 */
3408 @Override
3409 public void setVoiceActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003410 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3411 mApp, subId, "setVoiceActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003412
3413 final long identity = Binder.clearCallingIdentity();
3414 try {
3415 final Phone phone = getPhone(subId);
3416 if (phone != null) {
3417 phone.setVoiceActivationState(activationState);
3418 } else {
3419 loge("setVoiceActivationState fails with invalid subId: " + subId);
3420 }
3421 } finally {
3422 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08003423 }
3424 }
3425
3426 /**
3427 * Sets the data activation state of a given subId.
3428 */
3429 @Override
3430 public void setDataActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003431 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3432 mApp, subId, "setDataActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003433
3434 final long identity = Binder.clearCallingIdentity();
3435 try {
3436 final Phone phone = getPhone(subId);
3437 if (phone != null) {
3438 phone.setDataActivationState(activationState);
3439 } else {
Taesu Leef8fbed92019-10-07 18:47:02 +09003440 loge("setDataActivationState fails with invalid subId: " + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003441 }
3442 } finally {
3443 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08003444 }
3445 }
3446
3447 /**
3448 * Returns the voice activation state of a given subId.
3449 */
3450 @Override
3451 public int getVoiceActivationState(int subId, String callingPackage) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003452 enforceReadPrivilegedPermission("getVoiceActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003453
fionaxu0152e512016-11-14 13:36:14 -08003454 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003455 final long identity = Binder.clearCallingIdentity();
3456 try {
3457 if (phone != null) {
3458 return phone.getVoiceActivationState();
3459 } else {
3460 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
3461 }
3462 } finally {
3463 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08003464 }
3465 }
3466
3467 /**
3468 * Returns the data activation state of a given subId.
3469 */
3470 @Override
3471 public int getDataActivationState(int subId, String callingPackage) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003472 enforceReadPrivilegedPermission("getDataActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003473
fionaxu0152e512016-11-14 13:36:14 -08003474 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003475 final long identity = Binder.clearCallingIdentity();
3476 try {
3477 if (phone != null) {
3478 return phone.getDataActivationState();
3479 } else {
3480 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
3481 }
3482 } finally {
3483 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08003484 }
3485 }
3486
3487 /**
Wink Saville36469e72014-06-11 15:17:00 -07003488 * Returns the unread count of voicemails for a subId
3489 */
Sanket Padawe356d7632015-06-22 14:03:32 -07003490 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003491 public int getVoiceMessageCountForSubscriber(int subId, String callingPackage,
3492 String callingFeatureId) {
Brad Ebingerf7664ba2018-11-29 12:43:38 -08003493 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003494 mApp, subId, callingPackage, callingFeatureId,
3495 "getVoiceMessageCountForSubscriber")) {
Brad Ebingerf7664ba2018-11-29 12:43:38 -08003496 return 0;
3497 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003498 final long identity = Binder.clearCallingIdentity();
3499 try {
3500 final Phone phone = getPhone(subId);
3501 if (phone != null) {
3502 return phone.getVoiceMessageCount();
3503 } else {
3504 return 0;
3505 }
3506 } finally {
3507 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003508 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003509 }
3510
3511 /**
pkanwar8a4dcfb2017-01-19 13:43:16 -08003512 * returns true, if the device is in a state where both voice and data
3513 * are supported simultaneously. This can change based on location or network condition.
3514 */
3515 @Override
3516 public boolean isConcurrentVoiceAndDataAllowed(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003517 final long identity = Binder.clearCallingIdentity();
3518 try {
3519 final Phone phone = getPhone(subId);
3520 return (phone == null ? false : phone.isConcurrentVoiceAndDataAllowed());
3521 } finally {
3522 Binder.restoreCallingIdentity(identity);
3523 }
pkanwar8a4dcfb2017-01-19 13:43:16 -08003524 }
3525
3526 /**
fionaxu235cc5e2017-03-06 22:25:57 -08003527 * Send the dialer code if called from the current default dialer or the caller has
3528 * carrier privilege.
3529 * @param inputCode The dialer code to send
3530 */
3531 @Override
3532 public void sendDialerSpecialCode(String callingPackage, String inputCode) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003533 final Phone defaultPhone = getDefaultPhone();
fionaxu235cc5e2017-03-06 22:25:57 -08003534 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07003535 TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
3536 String defaultDialer = tm.getDefaultDialerPackage();
fionaxu235cc5e2017-03-06 22:25:57 -08003537 if (!TextUtils.equals(callingPackage, defaultDialer)) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08003538 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
Jeff Davidson7e17e312018-02-13 18:17:36 -08003539 getDefaultSubscription(), "sendDialerSpecialCode");
fionaxu235cc5e2017-03-06 22:25:57 -08003540 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003541
3542 final long identity = Binder.clearCallingIdentity();
3543 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003544 defaultPhone.sendDialerSpecialCode(inputCode);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003545 } finally {
3546 Binder.restoreCallingIdentity(identity);
3547 }
fionaxu235cc5e2017-03-06 22:25:57 -08003548 }
3549
Pengquan Menga1bb6272018-09-06 09:59:22 -07003550 @Override
3551 public int getNetworkSelectionMode(int subId) {
shilufc958392020-01-20 11:36:01 -08003552 TelephonyPermissions
3553 .enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3554 mApp, subId, "getNetworkSelectionMode");
3555 final long identity = Binder.clearCallingIdentity();
3556 try {
3557 if (!isActiveSubscription(subId)) {
3558 return TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
3559 }
3560 return (int) sendRequest(CMD_GET_NETWORK_SELECTION_MODE, null /* argument */, subId);
3561 } finally {
3562 Binder.restoreCallingIdentity(identity);
Pengquan Menge92a50d2018-09-21 15:54:48 -07003563 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07003564 }
3565
Brad Ebinger35c841c2018-10-01 10:40:55 -07003566 @Override
Brad Ebingerb2b65522019-03-15 13:48:47 -07003567 public boolean isInEmergencySmsMode() {
3568 enforceReadPrivilegedPermission("isInEmergencySmsMode");
3569 final long identity = Binder.clearCallingIdentity();
3570 try {
3571 for (Phone phone : PhoneFactory.getPhones()) {
3572 if (phone.isInEmergencySmsMode()) {
3573 return true;
3574 }
3575 }
3576 } finally {
3577 Binder.restoreCallingIdentity(identity);
3578 }
3579 return false;
3580 }
3581
shilu366312e2019-12-17 09:28:10 -08003582 /**
3583 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3584 * @param subId The subscription to use to check the configuration.
3585 * @param c The callback that will be used to send the result.
3586 */
Brad Ebingerb2b65522019-03-15 13:48:47 -07003587 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003588 public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback c)
3589 throws RemoteException {
Rambo Wang37f9c242020-02-10 14:45:28 -08003590 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3591 mApp, subId, "registerImsRegistrationCallback");
shilu366312e2019-12-17 09:28:10 -08003592
Brad Ebingerbc7dd582019-10-17 17:03:22 -07003593 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3594 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3595 "IMS not available on device.");
3596 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07003597 final long token = Binder.clearCallingIdentity();
3598 try {
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003599 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003600 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger35c841c2018-10-01 10:40:55 -07003601 .addRegistrationCallbackForSubscription(c, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003602 } catch (ImsException e) {
3603 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003604 } finally {
3605 Binder.restoreCallingIdentity(token);
3606 }
3607 }
3608
shilu366312e2019-12-17 09:28:10 -08003609 /**
3610 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3611 * @param subId The subscription to use to check the configuration.
3612 * @param c The callback that will be used to send the result.
3613 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003614 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003615 public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c) {
Rambo Wang37f9c242020-02-10 14:45:28 -08003616 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3617 mApp, subId, "unregisterImsRegistrationCallback");
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003618 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3619 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
3620 }
Meng Wangafbc5852019-09-19 17:37:13 -07003621 final long token = Binder.clearCallingIdentity();
3622 try {
Meng Wang8ea57e32020-06-25 11:03:56 -07003623 // TODO(b/159910732): Remove ImsManager dependence and query through ImsPhone directly.
Meng Wangafbc5852019-09-19 17:37:13 -07003624 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
3625 .removeRegistrationCallbackForSubscription(c, subId);
3626 } catch (ImsException e) {
3627 Log.i(LOG_TAG, "unregisterImsRegistrationCallback: " + subId
3628 + "is inactive, ignoring unregister.");
3629 // If the subscription is no longer active, just return, since the callback
3630 // will already have been removed internally.
3631 } finally {
3632 Binder.restoreCallingIdentity(token);
3633 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07003634 }
3635
Brad Ebingera34a6c22019-10-22 17:36:18 -07003636 /**
3637 * Get the IMS service registration state for the MmTelFeature associated with this sub id.
3638 */
3639 @Override
3640 public void getImsMmTelRegistrationState(int subId, IIntegerConsumer consumer) {
3641 enforceReadPrivilegedPermission("getImsMmTelRegistrationState");
3642 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3643 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3644 "IMS not available on device.");
3645 }
3646 final long token = Binder.clearCallingIdentity();
3647 try {
3648 Phone phone = getPhone(subId);
3649 if (phone == null) {
3650 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
3651 + subId + "'");
3652 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
3653 }
3654 phone.getImsRegistrationState(regState -> {
3655 try {
3656 consumer.accept((regState == null)
3657 ? RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED : regState);
3658 } catch (RemoteException e) {
3659 // Ignore if the remote process is no longer available to call back.
3660 Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
3661 }
3662 });
3663 } finally {
3664 Binder.restoreCallingIdentity(token);
3665 }
3666 }
3667
3668 /**
3669 * Get the transport type for the IMS service registration state.
3670 */
3671 @Override
3672 public void getImsMmTelRegistrationTransportType(int subId, IIntegerConsumer consumer) {
Rambo Wang37f9c242020-02-10 14:45:28 -08003673 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3674 mApp, subId, "getImsMmTelRegistrationTransportType");
Brad Ebingera34a6c22019-10-22 17:36:18 -07003675 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3676 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3677 "IMS not available on device.");
3678 }
3679 final long token = Binder.clearCallingIdentity();
3680 try {
3681 Phone phone = getPhone(subId);
3682 if (phone == null) {
3683 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
3684 + subId + "'");
3685 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
3686 }
3687 phone.getImsRegistrationTech(regTech -> {
3688 // Convert registration tech from ImsRegistrationImplBase -> RegistrationManager
3689 int regTechConverted = (regTech == null)
3690 ? ImsRegistrationImplBase.REGISTRATION_TECH_NONE : regTech;
3691 regTechConverted = RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(
3692 regTechConverted);
3693 try {
3694 consumer.accept(regTechConverted);
3695 } catch (RemoteException e) {
3696 // Ignore if the remote process is no longer available to call back.
3697 Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
3698 }
3699 });
3700 } finally {
3701 Binder.restoreCallingIdentity(token);
3702 }
3703 }
3704
shilu366312e2019-12-17 09:28:10 -08003705 /**
3706 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3707 * @param subId The subscription to use to check the configuration.
3708 * @param c The callback that will be used to send the result.
3709 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003710 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003711 public void registerMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)
3712 throws RemoteException {
Rambo Wang37f9c242020-02-10 14:45:28 -08003713 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3714 mApp, subId, "registerMmTelCapabilityCallback");
Brad Ebingerbc7dd582019-10-17 17:03:22 -07003715 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3716 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3717 "IMS not available on device.");
3718 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07003719 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3720 final long token = Binder.clearCallingIdentity();
3721 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003722 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger35c841c2018-10-01 10:40:55 -07003723 .addCapabilitiesCallbackForSubscription(c, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003724 } catch (ImsException e) {
3725 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003726 } finally {
3727 Binder.restoreCallingIdentity(token);
3728 }
3729 }
3730
shilu366312e2019-12-17 09:28:10 -08003731 /**
3732 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3733 * @param subId The subscription to use to check the configuration.
3734 * @param c The callback that will be used to send the result.
3735 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003736 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003737 public void unregisterMmTelCapabilityCallback(int subId, IImsCapabilityCallback c) {
Rambo Wang37f9c242020-02-10 14:45:28 -08003738 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3739 mApp, subId, "unregisterMmTelCapabilityCallback");
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003740 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3741 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
3742 }
Meng Wangafbc5852019-09-19 17:37:13 -07003743
3744 final long token = Binder.clearCallingIdentity();
3745 try {
Meng Wang8ea57e32020-06-25 11:03:56 -07003746 // TODO(b/159910732): Remove ImsManager dependence and query through ImsPhone directly.
Meng Wangafbc5852019-09-19 17:37:13 -07003747 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08003748 .removeCapabilitiesCallbackForSubscription(c, subId);
Meng Wangafbc5852019-09-19 17:37:13 -07003749 } catch (ImsException e) {
3750 Log.i(LOG_TAG, "unregisterMmTelCapabilityCallback: " + subId
3751 + "is inactive, ignoring unregister.");
3752 // If the subscription is no longer active, just return, since the callback
3753 // will already have been removed internally.
3754 } finally {
3755 Binder.restoreCallingIdentity(token);
3756 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07003757 }
3758
3759 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003760 public boolean isCapable(int subId, int capability, int regTech) {
3761 enforceReadPrivilegedPermission("isCapable");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003762 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3763 final long token = Binder.clearCallingIdentity();
3764 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003765 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003766 getSlotIndexOrException(subId)).queryMmTelCapability(capability, regTech);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003767 } catch (com.android.ims.ImsException e) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003768 Log.w(LOG_TAG, "IMS isCapable - service unavailable: " + e.getMessage());
3769 return false;
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003770 } catch (ImsException e) {
Brad Ebinger6b5ac222019-02-04 14:36:52 -08003771 Log.i(LOG_TAG, "isCapable: " + subId + " is inactive, returning false.");
3772 return false;
Brad Ebinger35c841c2018-10-01 10:40:55 -07003773 } finally {
3774 Binder.restoreCallingIdentity(token);
3775 }
3776 }
3777
3778 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003779 public boolean isAvailable(int subId, int capability, int regTech) {
3780 enforceReadPrivilegedPermission("isAvailable");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003781 final long token = Binder.clearCallingIdentity();
3782 try {
3783 Phone phone = getPhone(subId);
3784 if (phone == null) return false;
3785 return phone.isImsCapabilityAvailable(capability, regTech);
Daniel Bright5e40e4e2020-03-11 16:35:39 -07003786 } catch (com.android.ims.ImsException e) {
3787 Log.w(LOG_TAG, "IMS isAvailable - service unavailable: " + e.getMessage());
3788 return false;
Brad Ebinger35c841c2018-10-01 10:40:55 -07003789 } finally {
3790 Binder.restoreCallingIdentity(token);
3791 }
3792 }
3793
Brad Ebingerbc7dd582019-10-17 17:03:22 -07003794 /**
3795 * Determines if the MmTel feature capability is supported by the carrier configuration for this
3796 * subscription.
3797 * @param subId The subscription to use to check the configuration.
3798 * @param callback The callback that will be used to send the result.
3799 * @param capability The MmTelFeature capability that will be used to send the result.
3800 * @param transportType The transport type of the MmTelFeature capability.
3801 */
3802 @Override
3803 public void isMmTelCapabilitySupported(int subId, IIntegerConsumer callback, int capability,
3804 int transportType) {
3805 enforceReadPrivilegedPermission("isMmTelCapabilitySupported");
3806 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3807 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3808 "IMS not available on device.");
3809 }
3810 final long token = Binder.clearCallingIdentity();
3811 try {
3812 int slotId = getSlotIndex(subId);
3813 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
3814 Log.w(LOG_TAG, "isMmTelCapabilitySupported: called with an inactive subscription '"
3815 + subId + "'");
3816 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
3817 }
3818 ImsManager.getInstance(mApp, slotId).isSupported(capability,
3819 transportType, aBoolean -> {
3820 try {
3821 callback.accept((aBoolean == null) ? 0 : (aBoolean ? 1 : 0));
3822 } catch (RemoteException e) {
3823 Log.w(LOG_TAG, "isMmTelCapabilitySupported: remote caller is not "
3824 + "running. Ignore");
3825 }
3826 });
3827 } finally {
3828 Binder.restoreCallingIdentity(token);
3829 }
3830 }
3831
shilu366312e2019-12-17 09:28:10 -08003832 /**
3833 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3834 * @param subId The subscription to use to check the configuration.
3835 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003836 @Override
3837 public boolean isAdvancedCallingSettingEnabled(int subId) {
Rambo Wang37f9c242020-02-10 14:45:28 -08003838 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3839 mApp, subId, "isAdvancedCallingSettingEnabled");
shilu366312e2019-12-17 09:28:10 -08003840
Brad Ebinger35c841c2018-10-01 10:40:55 -07003841 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3842 final long token = Binder.clearCallingIdentity();
3843 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003844 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003845 getSlotIndexOrException(subId)).isEnhanced4gLteModeSettingEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003846 } catch (ImsException e) {
3847 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003848 } finally {
3849 Binder.restoreCallingIdentity(token);
3850 }
3851 }
3852
3853 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08003854 public void setAdvancedCallingSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003855 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08003856 "setAdvancedCallingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003857 final long identity = Binder.clearCallingIdentity();
3858 try {
3859 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003860 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003861 getSlotIndexOrException(subId)).setEnhanced4gLteModeSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003862 } catch (ImsException e) {
3863 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003864 } finally {
3865 Binder.restoreCallingIdentity(identity);
3866 }
3867 }
3868
shilu366312e2019-12-17 09:28:10 -08003869 /**
3870 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3871 * @param subId The subscription to use to check the configuration.
3872 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003873 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08003874 public boolean isVtSettingEnabled(int subId) {
Rambo Wang37f9c242020-02-10 14:45:28 -08003875 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3876 mApp, subId, "isVtSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003877 final long identity = Binder.clearCallingIdentity();
3878 try {
3879 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003880 return ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).isVtEnabledByUser();
3881 } catch (ImsException e) {
3882 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003883 } finally {
3884 Binder.restoreCallingIdentity(identity);
3885 }
3886 }
3887
3888 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08003889 public void setVtSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003890 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08003891 "setVtSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003892 final long identity = Binder.clearCallingIdentity();
3893 try {
3894 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003895 ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setVtSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003896 } catch (ImsException e) {
3897 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003898 } finally {
3899 Binder.restoreCallingIdentity(identity);
3900 }
3901 }
3902
shilu366312e2019-12-17 09:28:10 -08003903 /**
3904 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3905 * @param subId The subscription to use to check the configuration.
3906 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003907 @Override
3908 public boolean isVoWiFiSettingEnabled(int subId) {
Rambo Wang37f9c242020-02-10 14:45:28 -08003909 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3910 mApp, subId, "isVoWiFiSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003911 final long identity = Binder.clearCallingIdentity();
3912 try {
3913 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003914 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07003915 getSlotIndexOrException(subId)).isWfcEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003916 } catch (ImsException e) {
3917 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003918 } finally {
3919 Binder.restoreCallingIdentity(identity);
3920 }
3921 }
3922
3923 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08003924 public void setVoWiFiSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003925 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08003926 "setVoWiFiSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003927 final long identity = Binder.clearCallingIdentity();
3928 try {
3929 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003930 ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setWfcSetting(isEnabled);
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 boolean isVoWiFiRoamingSettingEnabled(int subId) {
Rambo Wang37f9c242020-02-10 14:45:28 -08003944 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3945 mApp, subId, "isVoWiFiRoamingSettingEnabled");
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)).isWfcRoamingEnabledByUser();
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
Brad Ebinger1c162042019-02-21 14:49:10 -08003959 public void setVoWiFiRoamingSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003960 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08003961 "setVoWiFiRoamingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003962 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)).setWfcRoamingSetting(isEnabled);
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 void setVoWiFiNonPersistent(int subId, boolean isCapable, int mode) {
3976 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3977 "setVoWiFiNonPersistent");
3978 final long identity = Binder.clearCallingIdentity();
3979 try {
3980 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003981 ImsManager.getInstance(mApp,
Brad Ebinger2d29c012019-05-07 18:33:46 -07003982 getSlotIndexOrException(subId)).setWfcNonPersistent(isCapable, mode);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07003983 } catch (ImsException e) {
3984 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07003985 } finally {
3986 Binder.restoreCallingIdentity(identity);
3987 }
3988 }
3989
shilu366312e2019-12-17 09:28:10 -08003990 /**
3991 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3992 * @param subId The subscription to use to check the configuration.
3993 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07003994 @Override
3995 public int getVoWiFiModeSetting(int subId) {
Rambo Wang37f9c242020-02-10 14:45:28 -08003996 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3997 mApp, subId, "getVoWiFiModeSetting");
Brad Ebinger35c841c2018-10-01 10:40:55 -07003998 final long identity = Binder.clearCallingIdentity();
3999 try {
4000 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004001 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07004002 getSlotIndexOrException(subId)).getWfcMode(false /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004003 } catch (ImsException e) {
4004 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004005 } finally {
4006 Binder.restoreCallingIdentity(identity);
4007 }
4008 }
4009
4010 @Override
4011 public void setVoWiFiModeSetting(int subId, int mode) {
4012 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4013 "setVoWiFiModeSetting");
4014 final long identity = Binder.clearCallingIdentity();
4015 try {
4016 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004017 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07004018 getSlotIndexOrException(subId)).setWfcMode(mode, false /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004019 } catch (ImsException e) {
4020 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004021 } finally {
4022 Binder.restoreCallingIdentity(identity);
4023 }
4024 }
4025
4026 @Override
4027 public int getVoWiFiRoamingModeSetting(int subId) {
4028 enforceReadPrivilegedPermission("getVoWiFiRoamingModeSetting");
4029 final long identity = Binder.clearCallingIdentity();
4030 try {
4031 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004032 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07004033 getSlotIndexOrException(subId)).getWfcMode(true /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004034 } catch (ImsException e) {
4035 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004036 } finally {
4037 Binder.restoreCallingIdentity(identity);
4038 }
4039 }
4040
4041 @Override
4042 public void setVoWiFiRoamingModeSetting(int subId, int mode) {
4043 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4044 "setVoWiFiRoamingModeSetting");
4045 final long identity = Binder.clearCallingIdentity();
4046 try {
4047 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004048 ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07004049 getSlotIndexOrException(subId)).setWfcMode(mode, true /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004050 } catch (ImsException e) {
4051 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004052 } finally {
4053 Binder.restoreCallingIdentity(identity);
4054 }
4055 }
4056
4057 @Override
4058 public void setRttCapabilitySetting(int subId, boolean isEnabled) {
4059 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4060 "setRttCapabilityEnabled");
4061 final long identity = Binder.clearCallingIdentity();
4062 try {
4063 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004064 ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setRttEnabled(isEnabled);
4065 } catch (ImsException e) {
4066 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004067 } finally {
4068 Binder.restoreCallingIdentity(identity);
4069 }
4070 }
4071
shilu366312e2019-12-17 09:28:10 -08004072 /**
4073 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4074 * @param subId The subscription to use to check the configuration.
4075 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07004076 @Override
4077 public boolean isTtyOverVolteEnabled(int subId) {
Rambo Wang37f9c242020-02-10 14:45:28 -08004078 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4079 mApp, subId, "isTtyOverVolteEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004080 final long identity = Binder.clearCallingIdentity();
4081 try {
4082 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004083 return ImsManager.getInstance(mApp,
Brad Ebinger35c841c2018-10-01 10:40:55 -07004084 getSlotIndexOrException(subId)).isTtyOnVoLteCapable();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004085 } catch (ImsException e) {
4086 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004087 } finally {
4088 Binder.restoreCallingIdentity(identity);
4089 }
4090 }
4091
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004092 @Override
4093 public void registerImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
4094 enforceReadPrivilegedPermission("registerImsProvisioningChangedCallback");
4095 final long identity = Binder.clearCallingIdentity();
4096 try {
Brad Ebingerd0331732020-01-16 11:21:18 -08004097 if (!isImsAvailableOnDevice()) {
4098 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4099 "IMS not available on device.");
Peter Wang44b186e2020-01-13 23:33:09 -08004100 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004101 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004102 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08004103 .addProvisioningCallbackForSubscription(callback, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004104 } catch (ImsException e) {
4105 throw new ServiceSpecificException(e.getCode());
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004106 } finally {
4107 Binder.restoreCallingIdentity(identity);
4108 }
4109 }
4110
4111 @Override
4112 public void unregisterImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
4113 enforceReadPrivilegedPermission("unregisterImsProvisioningChangedCallback");
4114 final long identity = Binder.clearCallingIdentity();
Brad Ebinger4ae57f92019-01-09 16:51:30 -08004115 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4116 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
4117 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004118 try {
4119 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004120 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08004121 .removeProvisioningCallbackForSubscription(callback, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004122 } catch (ImsException e) {
Brad Ebinger4ae57f92019-01-09 16:51:30 -08004123 Log.i(LOG_TAG, "unregisterImsProvisioningChangedCallback: " + subId
4124 + "is inactive, ignoring unregister.");
4125 // If the subscription is no longer active, just return, since the callback will already
4126 // have been removed internally.
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004127 } finally {
4128 Binder.restoreCallingIdentity(identity);
4129 }
4130 }
4131
allenwtsu99c623b2020-01-03 18:24:23 +08004132
4133 private void checkModifyPhoneStatePermission(int subId, String message) {
4134 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4135 message);
4136 }
4137
4138 private boolean isImsProvisioningRequired(int subId, int capability,
4139 boolean isMmtelCapability) {
4140 Phone phone = getPhone(subId);
4141 if (phone == null) {
4142 loge("phone instance null for subid " + subId);
4143 return false;
4144 }
4145 if (isMmtelCapability) {
4146 if (!doesImsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
4147 return false;
4148 }
4149 } else {
4150 if (!doesRcsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
4151 return false;
4152 }
4153 }
4154 return true;
4155 }
4156
4157 @Override
4158 public void setRcsProvisioningStatusForCapability(int subId, int capability,
4159 boolean isProvisioned) {
4160 checkModifyPhoneStatePermission(subId, "setRcsProvisioningStatusForCapability");
4161
4162 final long identity = Binder.clearCallingIdentity();
4163 try {
4164 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4165 if (!isImsProvisioningRequired(subId, capability, false)) {
4166 return;
4167 }
4168
4169 // this capability requires provisioning, route to the correct API.
4170 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
4171 switch (capability) {
4172 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE:
4173 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
4174 ims.setEabProvisioned(isProvisioned);
4175 break;
4176 default: {
4177 throw new IllegalArgumentException("Tried to set provisioning for "
4178 + "rcs capability '" + capability + "', which does not require "
4179 + "provisioning.");
4180 }
4181 }
4182 } finally {
4183 Binder.restoreCallingIdentity(identity);
4184 }
4185
4186 }
4187
4188
4189 @Override
4190 public boolean getRcsProvisioningStatusForCapability(int subId, int capability) {
4191 enforceReadPrivilegedPermission("getRcsProvisioningStatusForCapability");
4192 final long identity = Binder.clearCallingIdentity();
4193 try {
4194 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4195 if (!isImsProvisioningRequired(subId, capability, false)) {
4196 return true;
4197 }
4198
4199 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
4200 switch (capability) {
4201 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE:
4202 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
4203 return ims.isEabProvisionedOnDevice();
4204
4205 default: {
4206 throw new IllegalArgumentException("Tried to get rcs provisioning for "
4207 + "capability '" + capability + "', which does not require "
4208 + "provisioning.");
4209 }
4210 }
4211
4212 } finally {
4213 Binder.restoreCallingIdentity(identity);
4214 }
4215 }
4216
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004217 @Override
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004218 public void setImsProvisioningStatusForCapability(int subId, int capability, int tech,
4219 boolean isProvisioned) {
4220 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
4221 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4222 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
4223 }
allenwtsu99c623b2020-01-03 18:24:23 +08004224 checkModifyPhoneStatePermission(subId, "setImsProvisioningStatusForCapability");
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004225 final long identity = Binder.clearCallingIdentity();
4226 try {
4227 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
allenwtsu99c623b2020-01-03 18:24:23 +08004228 if (!isImsProvisioningRequired(subId, capability, true)) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004229 return;
4230 }
4231
4232 // this capability requires provisioning, route to the correct API.
4233 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
4234 switch (capability) {
4235 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
4236 if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4237 ims.setVolteProvisioned(isProvisioned);
4238 } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
4239 ims.setWfcProvisioned(isProvisioned);
4240 }
4241 break;
4242 }
4243 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
4244 // There is currently no difference in VT provisioning type.
4245 ims.setVtProvisioned(isProvisioned);
4246 break;
4247 }
4248 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
4249 // There is no "deprecated" UT provisioning mechanism through ImsConfig, so
4250 // change the capability of the feature instead if needed.
4251 if (isMmTelCapabilityProvisionedInCache(subId, capability, tech)
4252 == isProvisioned) {
4253 // No change in provisioning.
4254 return;
4255 }
4256 cacheMmTelCapabilityProvisioning(subId, capability, tech, isProvisioned);
4257 try {
4258 ims.changeMmTelCapability(capability, tech, isProvisioned);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004259 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004260 loge("setImsProvisioningStatusForCapability: couldn't change UT capability"
4261 + ", Exception" + e.getMessage());
4262 }
4263 break;
4264 }
4265 default: {
allenwtsu99c623b2020-01-03 18:24:23 +08004266 throw new IllegalArgumentException("Tried to set provisioning for "
4267 + "MmTel capability '" + capability + "', which does not require "
4268 + "provisioning. ");
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004269 }
4270 }
4271
4272 } finally {
4273 Binder.restoreCallingIdentity(identity);
4274 }
4275 }
4276
4277 @Override
4278 public boolean getImsProvisioningStatusForCapability(int subId, int capability, int tech) {
4279 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
4280 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4281 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
4282 }
4283 enforceReadPrivilegedPermission("getProvisioningStatusForCapability");
4284 final long identity = Binder.clearCallingIdentity();
4285 try {
4286 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
allenwtsu99c623b2020-01-03 18:24:23 +08004287 if (!isImsProvisioningRequired(subId, capability, true)) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004288 return true;
4289 }
4290
4291 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
4292 switch (capability) {
4293 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
4294 if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4295 return ims.isVolteProvisionedOnDevice();
4296 } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
4297 return ims.isWfcProvisionedOnDevice();
4298 }
4299 // This should never happen, since we are checking tech above to make sure it
4300 // is either LTE or IWLAN.
4301 throw new IllegalArgumentException("Invalid radio technology for voice "
4302 + "capability.");
4303 }
4304 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
4305 // There is currently no difference in VT provisioning type.
4306 return ims.isVtProvisionedOnDevice();
4307 }
4308 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
4309 // There is no "deprecated" UT provisioning mechanism, so get from shared prefs.
4310 return isMmTelCapabilityProvisionedInCache(subId, capability, tech);
4311 }
4312 default: {
allenwtsu99c623b2020-01-03 18:24:23 +08004313 throw new IllegalArgumentException(
4314 "Tried to get provisioning for MmTel capability '" + capability
4315 + "', which does not require provisioning.");
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004316 }
4317 }
4318
4319 } finally {
4320 Binder.restoreCallingIdentity(identity);
4321 }
4322 }
4323
4324 @Override
4325 public boolean isMmTelCapabilityProvisionedInCache(int subId, int capability, int tech) {
4326 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
4327 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4328 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
4329 }
4330 enforceReadPrivilegedPermission("isMmTelCapabilityProvisionedInCache");
4331 int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
4332 return (provisionedBits & capability) > 0;
4333 }
4334
4335 @Override
4336 public void cacheMmTelCapabilityProvisioning(int subId, int capability, int tech,
4337 boolean isProvisioned) {
4338 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
4339 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4340 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
4341 }
4342 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4343 "setProvisioningStatusForCapability");
4344 int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
4345 // If the current provisioning status for capability already matches isProvisioned,
4346 // do nothing.
4347 if (((provisionedBits & capability) > 0) == isProvisioned) {
4348 return;
4349 }
4350 if (isProvisioned) {
4351 setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits | capability));
4352 } else {
4353 setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits & ~capability));
4354 }
4355 }
4356
4357 /**
4358 * @return the bitfield containing the MmTel provisioning for the provided subscription and
4359 * technology. The bitfield should mirror the bitfield defined by
4360 * {@link MmTelFeature.MmTelCapabilities.MmTelCapability}.
4361 */
4362 private int getMmTelCapabilityProvisioningBitfield(int subId, int tech) {
4363 String key = getMmTelProvisioningKey(subId, tech);
4364 // Default is no capabilities are provisioned.
4365 return mTelephonySharedPreferences.getInt(key, 0 /*default*/);
4366 }
4367
4368 /**
4369 * Sets the MmTel capability provisioning bitfield (defined by
4370 * {@link MmTelFeature.MmTelCapabilities.MmTelCapability}) for the subscription and
4371 * technology specified.
4372 *
4373 * Note: This is a synchronous command and should not be called on UI thread.
4374 */
4375 private void setMmTelCapabilityProvisioningBitfield(int subId, int tech, int newField) {
4376 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
4377 String key = getMmTelProvisioningKey(subId, tech);
4378 editor.putInt(key, newField);
4379 editor.commit();
4380 }
4381
4382 private static String getMmTelProvisioningKey(int subId, int tech) {
4383 // resulting key is provision_ims_mmtel_{subId}_{tech}
4384 return PREF_PROVISION_IMS_MMTEL_PREFIX + subId + "_" + tech;
4385 }
4386
4387 /**
4388 * Query CarrierConfig to see if the specified capability requires provisioning for the
4389 * carrier associated with the subscription id.
4390 */
4391 private boolean doesImsCapabilityRequireProvisioning(Context context, int subId,
4392 int capability) {
4393 CarrierConfigManager configManager = new CarrierConfigManager(context);
4394 PersistableBundle c = configManager.getConfigForSubId(subId);
4395 boolean requireUtProvisioning = c.getBoolean(
Brad Ebinger076903f2019-05-13 10:00:22 -07004396 CarrierConfigManager.KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL, false)
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004397 && c.getBoolean(CarrierConfigManager.KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL,
4398 false);
4399 boolean requireVoiceVtProvisioning = c.getBoolean(
4400 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, false);
4401
4402 // First check to make sure that the capability requires provisioning.
4403 switch (capability) {
4404 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE:
4405 // intentional fallthrough
4406 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
4407 if (requireVoiceVtProvisioning) {
4408 // Voice and Video requires provisioning
4409 return true;
4410 }
4411 break;
4412 }
4413 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
4414 if (requireUtProvisioning) {
4415 // UT requires provisioning
4416 return true;
4417 }
4418 break;
4419 }
4420 }
4421 return false;
4422 }
4423
allenwtsu99c623b2020-01-03 18:24:23 +08004424 private boolean doesRcsCapabilityRequireProvisioning(Context context, int subId,
4425 int capability) {
4426 CarrierConfigManager configManager = new CarrierConfigManager(context);
4427 PersistableBundle c = configManager.getConfigForSubId(subId);
4428
4429 boolean requireRcsProvisioning = c.getBoolean(
4430 CarrierConfigManager.KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL, false);
4431
4432 // First check to make sure that the capability requires provisioning.
4433 switch (capability) {
4434 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
4435 // intentional fallthrough
4436 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE: {
4437 if (requireRcsProvisioning) {
4438 // OPTION or PRESENCE requires provisioning
4439 return true;
4440 }
4441 break;
4442 }
4443 }
4444 return false;
4445 }
4446
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004447 @Override
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004448 public int getImsProvisioningInt(int subId, int key) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004449 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4450 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4451 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004452 enforceReadPrivilegedPermission("getImsProvisioningInt");
4453 final long identity = Binder.clearCallingIdentity();
4454 try {
4455 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004456 int slotId = getSlotIndex(subId);
4457 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4458 Log.w(LOG_TAG, "getImsProvisioningInt: called with an inactive subscription '"
4459 + subId + "' for key:" + key);
4460 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
4461 }
4462 return ImsManager.getInstance(mApp, slotId).getConfigInterface().getConfigInt(key);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004463 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004464 Log.w(LOG_TAG, "getImsProvisioningInt: ImsService is not available for subscription '"
4465 + subId + "' for key:" + key);
4466 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004467 } finally {
4468 Binder.restoreCallingIdentity(identity);
4469 }
4470 }
4471
4472 @Override
4473 public String getImsProvisioningString(int subId, int key) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004474 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4475 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4476 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004477 enforceReadPrivilegedPermission("getImsProvisioningString");
4478 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, "getImsProvisioningString: called for an inactive subscription id '"
4484 + subId + "' for key:" + key);
4485 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_GENERIC;
4486 }
4487 return ImsManager.getInstance(mApp, slotId).getConfigInterface().getConfigString(key);
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, "getImsProvisioningString: ImsService is not available for sub '"
4490 + subId + "' for key:" + key);
4491 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_NOT_READY;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004492 } finally {
4493 Binder.restoreCallingIdentity(identity);
4494 }
4495 }
4496
4497 @Override
4498 public int setImsProvisioningInt(int subId, int key, int value) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004499 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4500 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4501 }
Brad Ebinger3d0b34e2018-11-15 14:13:12 -08004502 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4503 "setImsProvisioningInt");
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004504 final long identity = Binder.clearCallingIdentity();
4505 try {
4506 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004507 int slotId = getSlotIndex(subId);
4508 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4509 Log.w(LOG_TAG, "setImsProvisioningInt: called with an inactive subscription id '"
4510 + subId + "' for key:" + key);
4511 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
4512 }
4513 return ImsManager.getInstance(mApp, slotId).getConfigInterface().setConfig(key, value);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004514 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004515 Log.w(LOG_TAG, "setImsProvisioningInt: ImsService unavailable for sub '" + subId
4516 + "' for key:" + key);
4517 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004518 } finally {
4519 Binder.restoreCallingIdentity(identity);
4520 }
4521 }
4522
4523 @Override
4524 public int setImsProvisioningString(int subId, int key, String value) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004525 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4526 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4527 }
Brad Ebinger3d0b34e2018-11-15 14:13:12 -08004528 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4529 "setImsProvisioningString");
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004530 final long identity = Binder.clearCallingIdentity();
4531 try {
4532 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004533 int slotId = getSlotIndex(subId);
4534 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4535 Log.w(LOG_TAG, "setImsProvisioningString: called with an inactive subscription id '"
4536 + subId + "' for key:" + key);
4537 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
4538 }
4539 return ImsManager.getInstance(mApp, slotId).getConfigInterface().setConfig(key, value);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004540 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004541 Log.w(LOG_TAG, "setImsProvisioningString: ImsService unavailable for sub '" + subId
4542 + "' for key:" + key);
4543 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004544 } finally {
4545 Binder.restoreCallingIdentity(identity);
4546 }
4547 }
4548
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004549 private int getSlotIndexOrException(int subId) throws ImsException {
Brad Ebinger35c841c2018-10-01 10:40:55 -07004550 int slotId = SubscriptionManager.getSlotIndex(subId);
4551 if (!SubscriptionManager.isValidSlotIndex(slotId)) {
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004552 throw new ImsException("Invalid Subscription Id, subId=" + subId,
4553 ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
Brad Ebinger35c841c2018-10-01 10:40:55 -07004554 }
4555 return slotId;
4556 }
4557
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004558 private int getSlotIndex(int subId) {
4559 int slotId = SubscriptionManager.getSlotIndex(subId);
4560 if (!SubscriptionManager.isValidSlotIndex(slotId)) {
4561 return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
4562 }
4563 return slotId;
4564 }
4565
Wink Saville36469e72014-06-11 15:17:00 -07004566 /**
Nathan Harold9042f0b2019-05-21 15:51:27 -07004567 * Returns the data network type for a subId; does not throw SecurityException.
Wink Saville36469e72014-06-11 15:17:00 -07004568 */
4569 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004570 public int getNetworkTypeForSubscriber(int subId, String callingPackage,
4571 String callingFeatureId) {
Nathan Haroldef60dba2019-05-22 13:55:14 -07004572 final int targetSdk = getTargetSdk(callingPackage);
4573 if (targetSdk > android.os.Build.VERSION_CODES.Q) {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004574 return getDataNetworkTypeForSubscriber(subId, callingPackage, callingFeatureId);
Nathan Haroldef60dba2019-05-22 13:55:14 -07004575 } else if (targetSdk == android.os.Build.VERSION_CODES.Q
Nathan Harold9042f0b2019-05-21 15:51:27 -07004576 && !TelephonyPermissions.checkCallingOrSelfReadPhoneStateNoThrow(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004577 mApp, subId, callingPackage, callingFeatureId,
4578 "getNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004579 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4580 }
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07004581
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004582 final long identity = Binder.clearCallingIdentity();
4583 try {
4584 final Phone phone = getPhone(subId);
4585 if (phone != null) {
4586 return phone.getServiceState().getDataNetworkType();
4587 } else {
4588 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4589 }
4590 } finally {
4591 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004592 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004593 }
4594
4595 /**
4596 * Returns the data network type
4597 */
4598 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004599 public int getDataNetworkType(String callingPackage, String callingFeatureId) {
4600 return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage,
4601 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07004602 }
4603
4604 /**
4605 * Returns the data network type for a subId
4606 */
4607 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004608 public int getDataNetworkTypeForSubscriber(int subId, String callingPackage,
4609 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004610 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004611 mApp, subId, callingPackage, callingFeatureId,
4612 "getDataNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004613 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4614 }
4615
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004616 final long identity = Binder.clearCallingIdentity();
4617 try {
4618 final Phone phone = getPhone(subId);
4619 if (phone != null) {
4620 return phone.getServiceState().getDataNetworkType();
4621 } else {
4622 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4623 }
4624 } finally {
4625 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004626 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004627 }
4628
4629 /**
Wink Saville36469e72014-06-11 15:17:00 -07004630 * Returns the Voice network type for a subId
4631 */
4632 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004633 public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage,
4634 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004635 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004636 mApp, subId, callingPackage, callingFeatureId,
4637 "getDataNetworkTypeForSubscriber")) {
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07004638 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4639 }
4640
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004641 final long identity = Binder.clearCallingIdentity();
4642 try {
4643 final Phone phone = getPhone(subId);
4644 if (phone != null) {
4645 return phone.getServiceState().getVoiceNetworkType();
4646 } else {
4647 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4648 }
4649 } finally {
4650 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004651 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004652 }
4653
4654 /**
4655 * @return true if a ICC card is present
4656 */
4657 public boolean hasIccCard() {
Wink Saville36469e72014-06-11 15:17:00 -07004658 // FIXME Make changes to pass defaultSimId of type int
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004659 return hasIccCardUsingSlotIndex(mSubscriptionController.getSlotIndex(
4660 getDefaultSubscription()));
Wink Saville36469e72014-06-11 15:17:00 -07004661 }
4662
4663 /**
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004664 * @return true if a ICC card is present for a slotIndex
Wink Saville36469e72014-06-11 15:17:00 -07004665 */
Sanket Padawe356d7632015-06-22 14:03:32 -07004666 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004667 public boolean hasIccCardUsingSlotIndex(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004668 final long identity = Binder.clearCallingIdentity();
4669 try {
4670 final Phone phone = PhoneFactory.getPhone(slotIndex);
4671 if (phone != null) {
4672 return phone.getIccCard().hasIccCard();
4673 } else {
4674 return false;
4675 }
4676 } finally {
4677 Binder.restoreCallingIdentity(identity);
Amit Mahajana6fc2a82015-01-06 11:53:51 -08004678 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004679 }
4680
4681 /**
4682 * Return if the current radio is LTE on CDMA. This
4683 * is a tri-state return value as for a period of time
4684 * the mode may be unknown.
4685 *
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004686 * @param callingPackage the name of the package making the call.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004687 * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
Jake Hambye994d462014-02-03 13:10:13 -08004688 * or {@link Phone#LTE_ON_CDMA_TRUE}
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004689 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004690 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004691 public int getLteOnCdmaMode(String callingPackage, String callingFeatureId) {
4692 return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage,
4693 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07004694 }
4695
Sanket Padawe356d7632015-06-22 14:03:32 -07004696 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004697 public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage,
4698 String callingFeatureId) {
Sarah Chin790d2922020-01-16 12:17:23 -08004699 try {
4700 enforceReadPrivilegedPermission("getLteOnCdmaModeForSubscriber");
4701 } catch (SecurityException e) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004702 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
4703 }
4704
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004705 final long identity = Binder.clearCallingIdentity();
4706 try {
4707 final Phone phone = getPhone(subId);
4708 if (phone == null) {
4709 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
4710 } else {
Nathan Harold05ad6332020-07-10 11:54:36 -07004711 return TelephonyProperties.lte_on_cdma_device()
4712 .orElse(PhoneConstants.LTE_ON_CDMA_FALSE);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004713 }
4714 } finally {
4715 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004716 }
Wink Saville36469e72014-06-11 15:17:00 -07004717 }
4718
Wink Saville36469e72014-06-11 15:17:00 -07004719 /**
4720 * {@hide}
4721 * Returns Default subId, 0 in the case of single standby.
4722 */
Wink Savilleb564aae2014-10-23 10:18:09 -07004723 private int getDefaultSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08004724 return mSubscriptionController.getDefaultSubId();
Wink Saville36469e72014-06-11 15:17:00 -07004725 }
4726
Shishir Agrawala9f32182016-04-12 12:00:16 -07004727 private int getSlotForDefaultSubscription() {
4728 return mSubscriptionController.getPhoneId(getDefaultSubscription());
4729 }
4730
Wink Savilleb564aae2014-10-23 10:18:09 -07004731 private int getPreferredVoiceSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08004732 return mSubscriptionController.getDefaultVoiceSubId();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004733 }
Ihab Awadf2177b72013-11-25 13:33:23 -08004734
Pengquan Menge92a50d2018-09-21 15:54:48 -07004735 private boolean isActiveSubscription(int subId) {
4736 return mSubscriptionController.isActiveSubId(subId);
4737 }
4738
Ihab Awadf2177b72013-11-25 13:33:23 -08004739 /**
4740 * @see android.telephony.TelephonyManager.WifiCallingChoices
4741 */
4742 public int getWhenToMakeWifiCalls() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004743 final long identity = Binder.clearCallingIdentity();
4744 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004745 return Settings.System.getInt(mApp.getContentResolver(),
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004746 Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
4747 getWhenToMakeWifiCallsDefaultPreference());
4748 } finally {
4749 Binder.restoreCallingIdentity(identity);
4750 }
Ihab Awadf2177b72013-11-25 13:33:23 -08004751 }
4752
4753 /**
4754 * @see android.telephony.TelephonyManager.WifiCallingChoices
4755 */
4756 public void setWhenToMakeWifiCalls(int preference) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004757 final long identity = Binder.clearCallingIdentity();
4758 try {
4759 if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004760 Settings.System.putInt(mApp.getContentResolver(),
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004761 Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference);
4762 } finally {
4763 Binder.restoreCallingIdentity(identity);
4764 }
Ihab Awadf9e92732013-12-05 18:02:52 -08004765 }
4766
Sailesh Nepald1e68152013-12-12 19:08:02 -08004767 private static int getWhenToMakeWifiCallsDefaultPreference() {
Santos Cordonda120f42014-08-06 04:44:34 -07004768 // TODO: Use a build property to choose this value.
Evan Charlton9829e882013-12-19 15:30:38 -08004769 return TelephonyManager.WifiCallingChoices.ALWAYS_USE;
Ihab Awadf2177b72013-11-25 13:33:23 -08004770 }
Shishir Agrawal69f68122013-12-16 17:25:49 -08004771
Jordan Liu4c733742019-02-28 12:03:40 -08004772 private Phone getPhoneFromSlotIdOrThrowException(int slotIndex) {
4773 int phoneId = UiccController.getInstance().getPhoneIdFromSlotId(slotIndex);
4774 if (phoneId == -1) {
4775 throw new IllegalArgumentException("Given slot index: " + slotIndex
4776 + " does not correspond to an active phone");
4777 }
4778 return PhoneFactory.getPhone(phoneId);
4779 }
4780
Shishir Agrawal566b7612013-10-28 14:41:00 -07004781 @Override
Derek Tan740e1672017-06-27 14:56:27 -07004782 public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
4783 int subId, String callingPackage, String aid, int p2) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004784 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4785 mApp, subId, "iccOpenLogicalChannel");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004786 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jordan Liu4c733742019-02-28 12:03:40 -08004787 if (DBG) {
4788 log("iccOpenLogicalChannel: subId=" + subId + " aid=" + aid + " p2=" + p2);
4789 }
4790 return iccOpenLogicalChannelWithPermission(getPhoneFromSubId(subId), callingPackage, aid,
4791 p2);
4792 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07004793
Jordan Liu4c733742019-02-28 12:03:40 -08004794
4795 @Override
4796 public IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(
4797 int slotIndex, String callingPackage, String aid, int p2) {
4798 enforceModifyPermission();
4799 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4800 if (DBG) {
4801 log("iccOpenLogicalChannelBySlot: slot=" + slotIndex + " aid=" + aid + " p2=" + p2);
4802 }
4803 return iccOpenLogicalChannelWithPermission(getPhoneFromSlotIdOrThrowException(slotIndex),
4804 callingPackage, aid, p2);
4805 }
4806
4807 private IccOpenLogicalChannelResponse iccOpenLogicalChannelWithPermission(Phone phone,
4808 String callingPackage, String aid, int p2) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004809 final long identity = Binder.clearCallingIdentity();
4810 try {
4811 if (TextUtils.equals(ISDR_AID, aid)) {
4812 // Only allows LPA to open logical channel to ISD-R.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004813 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
4814 .getContext().getPackageManager());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004815 if (bestComponent == null
4816 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
4817 loge("The calling package is not allowed to access ISD-R.");
4818 throw new SecurityException(
4819 "The calling package is not allowed to access ISD-R.");
4820 }
Derek Tan740e1672017-06-27 14:56:27 -07004821 }
Derek Tan740e1672017-06-27 14:56:27 -07004822
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004823 IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse) sendRequest(
Jordan Liu4c733742019-02-28 12:03:40 -08004824 CMD_OPEN_CHANNEL, new Pair<String, Integer>(aid, p2), phone,
4825 null /* workSource */);
4826 if (DBG) log("iccOpenLogicalChannelWithPermission: " + response);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004827 return response;
4828 } finally {
4829 Binder.restoreCallingIdentity(identity);
4830 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07004831 }
4832
4833 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004834 public boolean iccCloseLogicalChannel(int subId, int channel) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004835 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4836 mApp, subId, "iccCloseLogicalChannel");
Jordan Liu4c733742019-02-28 12:03:40 -08004837 if (DBG) log("iccCloseLogicalChannel: subId=" + subId + " chnl=" + channel);
4838 return iccCloseLogicalChannelWithPermission(getPhoneFromSubId(subId), channel);
4839 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07004840
Jordan Liu4c733742019-02-28 12:03:40 -08004841 @Override
4842 public boolean iccCloseLogicalChannelBySlot(int slotIndex, int channel) {
4843 enforceModifyPermission();
4844 if (DBG) log("iccCloseLogicalChannelBySlot: slotIndex=" + slotIndex + " chnl=" + channel);
4845 return iccCloseLogicalChannelWithPermission(getPhoneFromSlotIdOrThrowException(slotIndex),
4846 channel);
4847 }
4848
4849 private boolean iccCloseLogicalChannelWithPermission(Phone phone, int channel) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004850 final long identity = Binder.clearCallingIdentity();
4851 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004852 if (channel < 0) {
4853 return false;
4854 }
Jordan Liu4c733742019-02-28 12:03:40 -08004855 Boolean success = (Boolean) sendRequest(CMD_CLOSE_CHANNEL, channel, phone,
4856 null /* workSource */);
4857 if (DBG) log("iccCloseLogicalChannelWithPermission: " + success);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004858 return success;
4859 } finally {
4860 Binder.restoreCallingIdentity(identity);
Shishir Agrawal566b7612013-10-28 14:41:00 -07004861 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07004862 }
4863
4864 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004865 public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
Shishir Agrawal566b7612013-10-28 14:41:00 -07004866 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004867 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4868 mApp, subId, "iccTransmitApduLogicalChannel");
Jordan Liu4c733742019-02-28 12:03:40 -08004869 if (DBG) {
4870 log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel
4871 + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
4872 + p3 + " data=" + data);
4873 }
4874 return iccTransmitApduLogicalChannelWithPermission(getPhoneFromSubId(subId), channel, cla,
4875 command, p1, p2, p3, data);
4876 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07004877
Jordan Liu4c733742019-02-28 12:03:40 -08004878 @Override
4879 public String iccTransmitApduLogicalChannelBySlot(int slotIndex, int channel, int cla,
4880 int command, int p1, int p2, int p3, String data) {
4881 enforceModifyPermission();
4882 if (DBG) {
4883 log("iccTransmitApduLogicalChannelBySlot: slotIndex=" + slotIndex + " chnl=" + channel
4884 + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
4885 + p3 + " data=" + data);
4886 }
4887 return iccTransmitApduLogicalChannelWithPermission(
4888 getPhoneFromSlotIdOrThrowException(slotIndex), channel, cla, command, p1, p2, p3,
4889 data);
4890 }
4891
4892 private String iccTransmitApduLogicalChannelWithPermission(Phone phone, int channel, int cla,
4893 int command, int p1, int p2, int p3, String data) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004894 final long identity = Binder.clearCallingIdentity();
4895 try {
Hall Liu4fd771b2019-05-02 09:16:29 -07004896 if (channel <= 0) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004897 return "";
4898 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07004899
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004900 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL,
Jordan Liu4c733742019-02-28 12:03:40 -08004901 new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), phone,
4902 null /* workSource */);
4903 if (DBG) log("iccTransmitApduLogicalChannelWithPermission: " + response);
Shishir Agrawal566b7612013-10-28 14:41:00 -07004904
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004905 // Append the returned status code to the end of the response payload.
4906 String s = Integer.toHexString(
4907 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
4908 if (response.payload != null) {
4909 s = IccUtils.bytesToHexString(response.payload) + s;
4910 }
4911 return s;
4912 } finally {
4913 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07004914 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07004915 }
Jake Hambye994d462014-02-03 13:10:13 -08004916
Evan Charltonc66da362014-05-16 14:06:40 -07004917 @Override
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08004918 public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
4919 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004920 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4921 mApp, subId, "iccTransmitApduBasicChannel");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004922 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jordan Liu4c733742019-02-28 12:03:40 -08004923 if (DBG) {
4924 log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd="
4925 + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
4926 }
4927 return iccTransmitApduBasicChannelWithPermission(getPhoneFromSubId(subId), callingPackage,
4928 cla, command, p1, p2, p3, data);
4929 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004930
Jordan Liu4c733742019-02-28 12:03:40 -08004931 @Override
4932 public String iccTransmitApduBasicChannelBySlot(int slotIndex, String callingPackage, int cla,
4933 int command, int p1, int p2, int p3, String data) {
4934 enforceModifyPermission();
4935 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4936 if (DBG) {
4937 log("iccTransmitApduBasicChannelBySlot: slotIndex=" + slotIndex + " cla=" + cla
4938 + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3
4939 + " data=" + data);
4940 }
4941
4942 return iccTransmitApduBasicChannelWithPermission(
4943 getPhoneFromSlotIdOrThrowException(slotIndex), callingPackage, cla, command, p1,
4944 p2, p3, data);
4945 }
4946
4947 // open APDU basic channel assuming the caller has sufficient permissions
4948 private String iccTransmitApduBasicChannelWithPermission(Phone phone, String callingPackage,
4949 int cla, int command, int p1, int p2, int p3, String data) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004950 final long identity = Binder.clearCallingIdentity();
4951 try {
4952 if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
4953 && TextUtils.equals(ISDR_AID, data)) {
4954 // Only allows LPA to select ISD-R.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004955 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
4956 .getContext().getPackageManager());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004957 if (bestComponent == null
4958 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
4959 loge("The calling package is not allowed to select ISD-R.");
4960 throw new SecurityException(
4961 "The calling package is not allowed to select ISD-R.");
4962 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08004963 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08004964
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004965 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL,
Jordan Liu4c733742019-02-28 12:03:40 -08004966 new IccAPDUArgument(0, cla, command, p1, p2, p3, data), phone,
4967 null /* workSource */);
4968 if (DBG) log("iccTransmitApduBasicChannelWithPermission: " + response);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004969
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004970 // Append the returned status code to the end of the response payload.
4971 String s = Integer.toHexString(
4972 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
4973 if (response.payload != null) {
4974 s = IccUtils.bytesToHexString(response.payload) + s;
4975 }
4976 return s;
4977 } finally {
4978 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07004979 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004980 }
4981
4982 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004983 public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004984 String filePath) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004985 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4986 mApp, subId, "iccExchangeSimIO");
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07004987
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004988 final long identity = Binder.clearCallingIdentity();
4989 try {
4990 if (DBG) {
4991 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " "
4992 + p1 + " " + p2 + " " + p3 + ":" + filePath);
4993 }
4994
4995 IccIoResult response =
4996 (IccIoResult) sendRequest(CMD_EXCHANGE_SIM_IO,
4997 new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath),
4998 subId);
4999
5000 if (DBG) {
5001 log("Exchange SIM_IO [R]" + response);
5002 }
5003
5004 byte[] result = null;
5005 int length = 2;
5006 if (response.payload != null) {
5007 length = 2 + response.payload.length;
5008 result = new byte[length];
5009 System.arraycopy(response.payload, 0, result, 0, response.payload.length);
5010 } else {
5011 result = new byte[length];
5012 }
5013
5014 result[length - 1] = (byte) response.sw2;
5015 result[length - 2] = (byte) response.sw1;
5016 return result;
5017 } finally {
5018 Binder.restoreCallingIdentity(identity);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07005019 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07005020 }
5021
Nathan Haroldb3014052017-01-25 15:57:32 -08005022 /**
5023 * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
5024 * on a particular subscription
5025 */
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005026 public String[] getForbiddenPlmns(int subId, int appType, String callingPackage,
5027 String callingFeatureId) {
sqianb6e41952018-03-12 14:54:01 -07005028 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005029 mApp, subId, callingPackage, callingFeatureId, "getForbiddenPlmns")) {
sqianb6e41952018-03-12 14:54:01 -07005030 return null;
5031 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005032
5033 final long identity = Binder.clearCallingIdentity();
5034 try {
5035 if (appType != TelephonyManager.APPTYPE_USIM
5036 && appType != TelephonyManager.APPTYPE_SIM) {
5037 loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
5038 return null;
5039 }
5040 Object response = sendRequest(
5041 CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
5042 if (response instanceof String[]) {
5043 return (String[]) response;
5044 }
yincheng zhao2737e882019-09-06 17:06:54 -07005045 // Response is an Exception of some kind
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005046 // which is signalled to the user as a NULL retval
Nathan Haroldb3014052017-01-25 15:57:32 -08005047 return null;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005048 } finally {
5049 Binder.restoreCallingIdentity(identity);
Nathan Haroldb3014052017-01-25 15:57:32 -08005050 }
Nathan Haroldb3014052017-01-25 15:57:32 -08005051 }
5052
yincheng zhao2737e882019-09-06 17:06:54 -07005053 /**
5054 * Set the forbidden PLMN list from the given app type (ex APPTYPE_USIM) on a particular
5055 * subscription.
5056 *
5057 * @param subId the id of the subscription.
5058 * @param appType the uicc app type, must be USIM or SIM.
5059 * @param fplmns the Forbiden plmns list that needed to be written to the SIM.
5060 * @param callingPackage the op Package name.
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005061 * @param callingFeatureId the feature in the package.
yincheng zhao2737e882019-09-06 17:06:54 -07005062 * @return number of fplmns that is successfully written to the SIM.
5063 */
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005064 public int setForbiddenPlmns(int subId, int appType, List<String> fplmns, String callingPackage,
5065 String callingFeatureId) {
5066 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
5067 callingFeatureId, "setForbiddenPlmns")) {
yincheng zhao2737e882019-09-06 17:06:54 -07005068 if (DBG) logv("no permissions for setForbiddenplmns");
5069 throw new IllegalStateException("No Permissions for setForbiddenPlmns");
5070 }
5071 if (appType != TelephonyManager.APPTYPE_USIM && appType != TelephonyManager.APPTYPE_SIM) {
5072 loge("setForbiddenPlmnList(): App Type must be USIM or SIM");
5073 throw new IllegalArgumentException("Invalid appType: App Type must be USIM or SIM");
5074 }
5075 if (fplmns == null) {
5076 throw new IllegalArgumentException("Fplmn List provided is null");
5077 }
5078 for (String fplmn : fplmns) {
5079 if (!CellIdentity.isValidPlmn(fplmn)) {
5080 throw new IllegalArgumentException("Invalid fplmn provided: " + fplmn);
5081 }
5082 }
5083 final long identity = Binder.clearCallingIdentity();
5084 try {
5085 Object response = sendRequest(
5086 CMD_SET_FORBIDDEN_PLMNS,
5087 new Pair<Integer, List<String>>(new Integer(appType), fplmns),
5088 subId);
5089 return (int) response;
5090 } finally {
5091 Binder.restoreCallingIdentity(identity);
5092 }
5093 }
5094
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07005095 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08005096 public String sendEnvelopeWithStatus(int subId, String content) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005097 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5098 mApp, subId, "sendEnvelopeWithStatus");
Evan Charltonc66da362014-05-16 14:06:40 -07005099
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005100 final long identity = Binder.clearCallingIdentity();
5101 try {
5102 IccIoResult response = (IccIoResult) sendRequest(CMD_SEND_ENVELOPE, content, subId);
5103 if (response.payload == null) {
5104 return "";
5105 }
Evan Charltonc66da362014-05-16 14:06:40 -07005106
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005107 // Append the returned status code to the end of the response payload.
5108 String s = Integer.toHexString(
5109 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
5110 s = IccUtils.bytesToHexString(response.payload) + s;
5111 return s;
5112 } finally {
5113 Binder.restoreCallingIdentity(identity);
5114 }
Evan Charltonc66da362014-05-16 14:06:40 -07005115 }
5116
Jake Hambye994d462014-02-03 13:10:13 -08005117 /**
5118 * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
5119 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
5120 *
5121 * @param itemID the ID of the item to read
5122 * @return the NV item as a String, or null on error.
5123 */
5124 @Override
5125 public String nvReadItem(int itemID) {
vagdeviaf9a5b92018-08-15 16:01:53 -07005126 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08005127 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5128 mApp, getDefaultSubscription(), "nvReadItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005129
5130 final long identity = Binder.clearCallingIdentity();
5131 try {
5132 if (DBG) log("nvReadItem: item " + itemID);
vagdeviaf9a5b92018-08-15 16:01:53 -07005133 String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005134 if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
5135 return value;
5136 } finally {
5137 Binder.restoreCallingIdentity(identity);
5138 }
Jake Hambye994d462014-02-03 13:10:13 -08005139 }
5140
5141 /**
5142 * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
5143 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
5144 *
5145 * @param itemID the ID of the item to read
5146 * @param itemValue the value to write, as a String
5147 * @return true on success; false on any failure
5148 */
5149 @Override
5150 public boolean nvWriteItem(int itemID, String itemValue) {
vagdeviaf9a5b92018-08-15 16:01:53 -07005151 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08005152 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5153 mApp, getDefaultSubscription(), "nvWriteItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005154
5155 final long identity = Binder.clearCallingIdentity();
5156 try {
5157 if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
5158 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
vagdeviaf9a5b92018-08-15 16:01:53 -07005159 new Pair<Integer, String>(itemID, itemValue), workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005160 if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
5161 return success;
5162 } finally {
5163 Binder.restoreCallingIdentity(identity);
5164 }
Jake Hambye994d462014-02-03 13:10:13 -08005165 }
5166
5167 /**
5168 * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
5169 * Used for device configuration by some CDMA operators.
5170 *
5171 * @param preferredRoamingList byte array containing the new PRL
5172 * @return true on success; false on any failure
5173 */
5174 @Override
5175 public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005176 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5177 mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005178
5179 final long identity = Binder.clearCallingIdentity();
5180 try {
5181 if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
5182 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
5183 if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
5184 return success;
5185 } finally {
5186 Binder.restoreCallingIdentity(identity);
5187 }
Jake Hambye994d462014-02-03 13:10:13 -08005188 }
5189
5190 /**
chen xu6dac5ab2018-10-26 17:39:23 -07005191 * Rollback modem configurations to factory default except some config which are in whitelist.
Jake Hambye994d462014-02-03 13:10:13 -08005192 * Used for device configuration by some CDMA operators.
5193 *
chen xu6dac5ab2018-10-26 17:39:23 -07005194 * @param slotIndex - device slot.
5195 *
Jake Hambye994d462014-02-03 13:10:13 -08005196 * @return true on success; false on any failure
5197 */
5198 @Override
chen xu6dac5ab2018-10-26 17:39:23 -07005199 public boolean resetModemConfig(int slotIndex) {
5200 Phone phone = PhoneFactory.getPhone(slotIndex);
5201 if (phone != null) {
5202 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5203 mApp, phone.getSubId(), "resetModemConfig");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005204
chen xu6dac5ab2018-10-26 17:39:23 -07005205 final long identity = Binder.clearCallingIdentity();
5206 try {
5207 Boolean success = (Boolean) sendRequest(CMD_RESET_MODEM_CONFIG, null);
5208 if (DBG) log("resetModemConfig:" + ' ' + (success ? "ok" : "fail"));
5209 return success;
5210 } finally {
5211 Binder.restoreCallingIdentity(identity);
5212 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005213 }
chen xu6dac5ab2018-10-26 17:39:23 -07005214 return false;
5215 }
5216
5217 /**
5218 * Generate a radio modem reset. Used for device configuration by some CDMA operators.
5219 *
5220 * @param slotIndex - device slot.
5221 *
5222 * @return true on success; false on any failure
5223 */
5224 @Override
5225 public boolean rebootModem(int slotIndex) {
5226 Phone phone = PhoneFactory.getPhone(slotIndex);
5227 if (phone != null) {
5228 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5229 mApp, phone.getSubId(), "rebootModem");
5230
5231 final long identity = Binder.clearCallingIdentity();
5232 try {
5233 Boolean success = (Boolean) sendRequest(CMD_MODEM_REBOOT, null);
5234 if (DBG) log("rebootModem:" + ' ' + (success ? "ok" : "fail"));
5235 return success;
5236 } finally {
5237 Binder.restoreCallingIdentity(identity);
5238 }
5239 }
5240 return false;
Jake Hambye994d462014-02-03 13:10:13 -08005241 }
Jake Hamby7c27be32014-03-03 13:25:59 -08005242
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005243 public String[] getPcscfAddress(String apnType, String callingPackage,
5244 String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005245 final Phone defaultPhone = getDefaultPhone();
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005246 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
5247 callingPackage, callingFeatureId, "getPcscfAddress")) {
Svet Ganovb320e182015-04-16 12:30:10 -07005248 return new String[0];
5249 }
5250
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005251 final long identity = Binder.clearCallingIdentity();
5252 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005253 return defaultPhone.getPcscfAddress(apnType);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005254 } finally {
5255 Binder.restoreCallingIdentity(identity);
5256 }
Wink Saville36469e72014-06-11 15:17:00 -07005257 }
5258
Brad Ebinger51f743a2017-01-23 13:50:20 -08005259 /**
Grace Jiaaa2eb6b2020-01-09 16:26:08 -08005260 * Toggle IMS disable and enable for the framework to reset it. See {@link #enableIms(int)} and
5261 * {@link #disableIms(int)}.
5262 * @param slotIndex device slot.
5263 */
5264 public void resetIms(int slotIndex) {
5265 enforceModifyPermission();
5266
5267 final long identity = Binder.clearCallingIdentity();
5268 try {
5269 if (mImsResolver == null) {
5270 // may happen if the does not support IMS.
5271 return;
5272 }
5273 mImsResolver.disableIms(slotIndex);
5274 mImsResolver.enableIms(slotIndex);
5275 } finally {
5276 Binder.restoreCallingIdentity(identity);
5277 }
5278 }
5279
5280 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005281 * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
5282 * status updates, if not already enabled.
Brad Ebinger51f743a2017-01-23 13:50:20 -08005283 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005284 public void enableIms(int slotId) {
Brad Ebinger51f743a2017-01-23 13:50:20 -08005285 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005286
5287 final long identity = Binder.clearCallingIdentity();
5288 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08005289 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005290 // may happen if the device does not support IMS.
5291 return;
5292 }
Brad Ebinger24c29992019-12-05 13:03:21 -08005293 mImsResolver.enableIms(slotId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005294 } finally {
5295 Binder.restoreCallingIdentity(identity);
5296 }
Brad Ebinger34bef922017-11-09 10:27:08 -08005297 }
5298
5299 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005300 * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
5301 * status updates to disabled.
Brad Ebinger34bef922017-11-09 10:27:08 -08005302 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005303 public void disableIms(int slotId) {
5304 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005305
5306 final long identity = Binder.clearCallingIdentity();
5307 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08005308 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005309 // may happen if the device does not support IMS.
5310 return;
5311 }
Brad Ebinger24c29992019-12-05 13:03:21 -08005312 mImsResolver.disableIms(slotId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005313 } finally {
5314 Binder.restoreCallingIdentity(identity);
5315 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005316 }
5317
5318 /**
Brad Ebinger67b3e042020-09-11 12:45:11 -07005319 * Registers for updates to the MmTelFeature connection through the IImsServiceFeatureCallback
5320 * callback.
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005321 */
Brad Ebinger67b3e042020-09-11 12:45:11 -07005322 @Override
Brad Ebingerf6aca002020-10-01 13:51:05 -07005323 public void registerMmTelFeatureCallback(int slotId, IImsServiceFeatureCallback callback) {
Brad Ebinger34bef922017-11-09 10:27:08 -08005324 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005325
5326 final long identity = Binder.clearCallingIdentity();
5327 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08005328 if (mImsResolver == null) {
Brad Ebinger67b3e042020-09-11 12:45:11 -07005329 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
5330 "Device does not support IMS");
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005331 }
Brad Ebingerf6aca002020-10-01 13:51:05 -07005332 mImsResolver.listenForFeature(slotId, ImsFeature.FEATURE_MMTEL, callback);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005333 } finally {
5334 Binder.restoreCallingIdentity(identity);
5335 }
Brad Ebinger34bef922017-11-09 10:27:08 -08005336 }
Brad Ebinger5f64b052017-12-14 14:26:15 -08005337 /**
Brad Ebinger075ff3a2020-05-18 17:52:58 -07005338 * Unregister a previously registered IImsServiceFeatureCallback associated with an ImsFeature.
5339 */
Brad Ebinger67b3e042020-09-11 12:45:11 -07005340 @Override
5341 public void unregisterImsFeatureCallback(IImsServiceFeatureCallback callback) {
Brad Ebinger075ff3a2020-05-18 17:52:58 -07005342 enforceModifyPermission();
5343
5344 final long identity = Binder.clearCallingIdentity();
5345 try {
5346 if (mImsResolver == null) return;
Brad Ebinger67b3e042020-09-11 12:45:11 -07005347 mImsResolver.unregisterImsFeatureCallback(callback);
Brad Ebinger075ff3a2020-05-18 17:52:58 -07005348 } finally {
5349 Binder.restoreCallingIdentity(identity);
5350 }
5351 }
5352
5353 /**
Brad Ebinger5f64b052017-12-14 14:26:15 -08005354 * Returns the {@link IImsRegistration} structure associated with the slotId and feature
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005355 * specified or null if IMS is not supported on the slot specified.
Brad Ebinger5f64b052017-12-14 14:26:15 -08005356 */
5357 public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
5358 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005359
5360 final long identity = Binder.clearCallingIdentity();
5361 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08005362 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005363 // may happen if the device does not support IMS.
5364 return null;
5365 }
Brad Ebinger24c29992019-12-05 13:03:21 -08005366 return mImsResolver.getImsRegistration(slotId, feature);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005367 } finally {
5368 Binder.restoreCallingIdentity(identity);
5369 }
Brad Ebinger5f64b052017-12-14 14:26:15 -08005370 }
5371
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005372 /**
5373 * Returns the {@link IImsConfig} structure associated with the slotId and feature
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005374 * specified or null if IMS is not supported on the slot specified.
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005375 */
5376 public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
5377 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005378
5379 final long identity = Binder.clearCallingIdentity();
5380 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08005381 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005382 // may happen if the device does not support IMS.
5383 return null;
5384 }
Brad Ebinger24c29992019-12-05 13:03:21 -08005385 return mImsResolver.getImsConfig(slotId, feature);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005386 } finally {
5387 Binder.restoreCallingIdentity(identity);
5388 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005389 }
5390
Brad Ebinger884c07b2018-02-15 16:17:40 -08005391 /**
Brad Ebingerdac2f002018-04-03 15:17:52 -07005392 * Sets the ImsService Package Name that Telephony will bind to.
5393 *
Brad Ebinger24c29992019-12-05 13:03:21 -08005394 * @param slotIndex the slot ID that the ImsService should bind for.
5395 * @param isCarrierService true if the ImsService is the carrier override, false if the
Brad Ebingerdac2f002018-04-03 15:17:52 -07005396 * ImsService is the device default ImsService.
Brad Ebinger24c29992019-12-05 13:03:21 -08005397 * @param featureTypes An integer array of feature types associated with a packageName.
5398 * @param packageName The name of the package that the current configuration will be replaced
5399 * with.
Brad Ebingerdac2f002018-04-03 15:17:52 -07005400 * @return true if setting the ImsService to bind to succeeded, false if it did not.
Brad Ebingerdac2f002018-04-03 15:17:52 -07005401 */
Brad Ebinger24c29992019-12-05 13:03:21 -08005402 public boolean setBoundImsServiceOverride(int slotIndex, boolean isCarrierService,
5403 int[] featureTypes, String packageName) {
5404 int[] subIds = SubscriptionManager.getSubId(slotIndex);
5405 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setBoundImsServiceOverride");
Brad Ebingerde696de2018-04-06 09:56:40 -07005406 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
5407 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
Brad Ebinger24c29992019-12-05 13:03:21 -08005408 "setBoundImsServiceOverride");
Brad Ebingerde696de2018-04-06 09:56:40 -07005409
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005410 final long identity = Binder.clearCallingIdentity();
5411 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08005412 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005413 // may happen if the device does not support IMS.
5414 return false;
5415 }
Brad Ebinger24c29992019-12-05 13:03:21 -08005416 Map<Integer, String> featureConfig = new HashMap<>();
5417 for (int featureType : featureTypes) {
5418 featureConfig.put(featureType, packageName);
5419 }
5420 return mImsResolver.overrideImsServiceConfiguration(slotIndex, isCarrierService,
5421 featureConfig);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005422 } finally {
5423 Binder.restoreCallingIdentity(identity);
5424 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07005425 }
5426
5427 /**
Brad Ebinger999d3302020-11-25 14:31:39 -08005428 * Clears any carrier ImsService overrides for the slot index specified that were previously
5429 * set with {@link #setBoundImsServiceOverride(int, boolean, int[], String)}.
5430 *
5431 * This should only be used for testing.
5432 *
5433 * @param slotIndex the slot ID that the ImsService should bind for.
5434 * @return true if clearing the carrier ImsService override succeeded or false if it did not.
5435 */
5436 @Override
5437 public boolean clearCarrierImsServiceOverride(int slotIndex) {
5438 int[] subIds = SubscriptionManager.getSubId(slotIndex);
5439 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
5440 "clearCarrierImsServiceOverride");
5441 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
5442 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
5443 "clearCarrierImsServiceOverride");
5444
5445 final long identity = Binder.clearCallingIdentity();
5446 try {
5447 if (mImsResolver == null) {
5448 // may happen if the device does not support IMS.
5449 return false;
5450 }
5451 return mImsResolver.clearCarrierImsServiceConfiguration(slotIndex);
5452 } finally {
5453 Binder.restoreCallingIdentity(identity);
5454 }
5455 }
5456
5457 /**
Brad Ebinger24c29992019-12-05 13:03:21 -08005458 * Return the package name of the currently bound ImsService.
Brad Ebingerdac2f002018-04-03 15:17:52 -07005459 *
5460 * @param slotId The slot that the ImsService is associated with.
5461 * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
5462 * the device default.
Brad Ebinger24c29992019-12-05 13:03:21 -08005463 * @param featureType The feature associated with the queried configuration.
Brad Ebingerdac2f002018-04-03 15:17:52 -07005464 * @return the package name of the ImsService configuration.
5465 */
Brad Ebinger24c29992019-12-05 13:03:21 -08005466 public String getBoundImsServicePackage(int slotId, boolean isCarrierImsService,
5467 @ImsFeature.FeatureType int featureType) {
Brad Ebingerde696de2018-04-06 09:56:40 -07005468 int[] subIds = SubscriptionManager.getSubId(slotId);
Brad Ebinger24c29992019-12-05 13:03:21 -08005469 TelephonyPermissions
5470 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5471 mApp, (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
5472 "getBoundImsServicePackage");
Brad Ebingerde696de2018-04-06 09:56:40 -07005473
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005474 final long identity = Binder.clearCallingIdentity();
5475 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08005476 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005477 // may happen if the device does not support IMS.
5478 return "";
5479 }
Brad Ebingera80c3312019-12-02 10:59:39 -08005480 // TODO: change API to query RCS separately.
Brad Ebinger24c29992019-12-05 13:03:21 -08005481 return mImsResolver.getImsServiceConfiguration(slotId, isCarrierImsService,
5482 featureType);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005483 } finally {
5484 Binder.restoreCallingIdentity(identity);
5485 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07005486 }
5487
Brad Ebingerbc7dd582019-10-17 17:03:22 -07005488 /**
5489 * Get the MmTelFeature state associated with the requested subscription id.
5490 * @param subId The subscription that the MmTelFeature is associated with.
5491 * @param callback A callback with an integer containing the
5492 * {@link android.telephony.ims.feature.ImsFeature.ImsState} associated with the MmTelFeature.
5493 */
5494 @Override
5495 public void getImsMmTelFeatureState(int subId, IIntegerConsumer callback) {
5496 enforceReadPrivilegedPermission("getImsMmTelFeatureState");
5497 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
5498 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
5499 "IMS not available on device.");
5500 }
5501 final long token = Binder.clearCallingIdentity();
5502 try {
5503 int slotId = getSlotIndex(subId);
5504 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5505 Log.w(LOG_TAG, "getImsMmTelFeatureState: called with an inactive subscription '"
5506 + subId + "'");
5507 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
5508 }
5509 ImsManager.getInstance(mApp, slotId).getImsServiceState(anInteger -> {
5510 try {
5511 callback.accept(anInteger == null ? ImsFeature.STATE_UNAVAILABLE : anInteger);
5512 } catch (RemoteException e) {
5513 Log.w(LOG_TAG, "getImsMmTelFeatureState: remote caller is no longer running. "
5514 + "Ignore");
5515 }
5516 });
5517 } finally {
5518 Binder.restoreCallingIdentity(token);
5519 }
5520 }
5521
Wink Saville36469e72014-06-11 15:17:00 -07005522 public void setImsRegistrationState(boolean registered) {
5523 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005524
5525 final long identity = Binder.clearCallingIdentity();
5526 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005527 getDefaultPhone().setImsRegistrationState(registered);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005528 } finally {
5529 Binder.restoreCallingIdentity(identity);
5530 }
Wink Saville36469e72014-06-11 15:17:00 -07005531 }
5532
5533 /**
Stuart Scott54788802015-03-30 13:18:01 -07005534 * Set the network selection mode to automatic.
5535 *
5536 */
5537 @Override
5538 public void setNetworkSelectionModeAutomatic(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005539 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5540 mApp, subId, "setNetworkSelectionModeAutomatic");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005541
5542 final long identity = Binder.clearCallingIdentity();
5543 try {
shilufc958392020-01-20 11:36:01 -08005544 if (!isActiveSubscription(subId)) {
5545 return;
5546 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005547 if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
5548 sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId);
5549 } finally {
5550 Binder.restoreCallingIdentity(identity);
5551 }
Stuart Scott54788802015-03-30 13:18:01 -07005552 }
5553
Jack Yud10cdd42020-09-28 20:28:01 -07005554 /**
Pengquan Mengea84e042018-09-20 14:57:26 -07005555 * Ask the radio to connect to the input network and change selection mode to manual.
5556 *
5557 * @param subId the id of the subscription.
5558 * @param operatorInfo the operator information, included the PLMN, long name and short name of
5559 * the operator to attach to.
5560 * @param persistSelection whether the selection will persist until reboot. If true, only allows
5561 * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
5562 * normal network selection next time.
5563 * @return {@code true} on success; {@code true} on any failure.
Shishir Agrawal302c8692015-06-19 13:49:39 -07005564 */
5565 @Override
Pengquan Mengea84e042018-09-20 14:57:26 -07005566 public boolean setNetworkSelectionModeManual(
5567 int subId, OperatorInfo operatorInfo, boolean persistSelection) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005568 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5569 mApp, subId, "setNetworkSelectionModeManual");
Pengquan Menge92a50d2018-09-21 15:54:48 -07005570
5571 if (!isActiveSubscription(subId)) {
5572 return false;
5573 }
5574
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005575 final long identity = Binder.clearCallingIdentity();
5576 try {
Pengquan Mengea84e042018-09-20 14:57:26 -07005577 ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operatorInfo,
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005578 persistSelection);
Pengquan Mengea84e042018-09-20 14:57:26 -07005579 if (DBG) {
5580 log("setNetworkSelectionModeManual: subId: " + subId
5581 + " operator: " + operatorInfo);
5582 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005583 return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
5584 } finally {
5585 Binder.restoreCallingIdentity(identity);
5586 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07005587 }
shilu84f6e8b2019-12-19 13:58:01 -08005588 /**
5589 * Get the manual network selection
5590 *
5591 * @param subId the id of the subscription.
5592 *
5593 * @return the previously saved user selected PLMN
5594 */
5595 @Override
5596 public String getManualNetworkSelectionPlmn(int subId) {
5597 TelephonyPermissions
5598 .enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5599 mApp, subId, "getManualNetworkSelectionPlmn");
5600
5601 final long identity = Binder.clearCallingIdentity();
5602 try {
5603 if (!isActiveSubscription(subId)) {
shilufa1c2592020-03-10 10:59:43 -07005604 throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
shilu84f6e8b2019-12-19 13:58:01 -08005605 }
5606
5607 final Phone phone = getPhone(subId);
5608 if (phone == null) {
shilufa1c2592020-03-10 10:59:43 -07005609 throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
shilu84f6e8b2019-12-19 13:58:01 -08005610 }
5611 OperatorInfo networkSelection = phone.getSavedNetworkSelection();
5612 return TextUtils.isEmpty(networkSelection.getOperatorNumeric())
5613 ? phone.getManualNetworkSelectionPlmn() : networkSelection.getOperatorNumeric();
5614 } finally {
5615 Binder.restoreCallingIdentity(identity);
5616 }
5617 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07005618
5619 /**
5620 * Scans for available networks.
5621 */
5622 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07005623 public CellNetworkScanResult getCellNetworkScanResults(int subId, String callingPackage,
5624 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005625 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5626 mApp, subId, "getCellNetworkScanResults");
Hall Liuf19c44f2018-11-27 14:38:17 -08005627 LocationAccessPolicy.LocationPermissionResult locationResult =
5628 LocationAccessPolicy.checkLocationPermission(mApp,
5629 new LocationAccessPolicy.LocationPermissionQuery.Builder()
5630 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07005631 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08005632 .setCallingPid(Binder.getCallingPid())
5633 .setCallingUid(Binder.getCallingUid())
5634 .setMethod("getCellNetworkScanResults")
5635 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
Hall Liuc4a3e422020-05-26 17:18:03 -07005636 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
5637 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
Hall Liuf19c44f2018-11-27 14:38:17 -08005638 .build());
5639 switch (locationResult) {
5640 case DENIED_HARD:
5641 throw new SecurityException("Not allowed to access scan results -- location");
5642 case DENIED_SOFT:
5643 return null;
5644 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005645
Pengquan Menga1bb6272018-09-06 09:59:22 -07005646 long identity = Binder.clearCallingIdentity();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005647 try {
5648 if (DBG) log("getCellNetworkScanResults: subId " + subId);
Pengquan Menga1bb6272018-09-06 09:59:22 -07005649 return (CellNetworkScanResult) sendRequest(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005650 CMD_PERFORM_NETWORK_SCAN, null, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005651 } finally {
5652 Binder.restoreCallingIdentity(identity);
5653 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07005654 }
5655
5656 /**
Shuo Qian4a594052020-01-23 11:59:30 -08005657 * Get the call forwarding info, given the call forwarding reason.
5658 */
5659 @Override
Hall Liu27d24262020-09-18 19:04:59 -07005660 public void getCallForwarding(int subId, int callForwardingReason,
5661 ICallForwardingInfoCallback callback) {
Shuo Qian4a594052020-01-23 11:59:30 -08005662 enforceReadPrivilegedPermission("getCallForwarding");
5663 long identity = Binder.clearCallingIdentity();
5664 try {
5665 if (DBG) {
5666 log("getCallForwarding: subId " + subId
5667 + " callForwardingReason" + callForwardingReason);
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.onError(
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<Integer, TelephonyManager.CallForwardingInfoCallback> argument = Pair.create(
5682 callForwardingReason, new TelephonyManager.CallForwardingInfoCallback() {
5683 @Override
5684 public void onCallForwardingInfoAvailable(CallForwardingInfo info) {
5685 try {
5686 callback.onCallForwardingInfoAvailable(info);
5687 } catch (RemoteException e) {
5688 // ignore
5689 }
5690 }
5691
5692 @Override
5693 public void onError(int error) {
5694 try {
5695 callback.onError(error);
5696 } catch (RemoteException e) {
5697 // ignore
5698 }
5699 }
5700 });
5701 sendRequestAsync(CMD_GET_CALL_FORWARDING, argument, phone, null);
Shuo Qian4a594052020-01-23 11:59:30 -08005702 } finally {
5703 Binder.restoreCallingIdentity(identity);
5704 }
5705 }
5706
5707 /**
5708 * Sets the voice call forwarding info including status (enable/disable), call forwarding
5709 * reason, the number to forward, and the timeout before the forwarding is attempted.
5710 */
5711 @Override
Hall Liu27d24262020-09-18 19:04:59 -07005712 public void setCallForwarding(int subId, CallForwardingInfo callForwardingInfo,
5713 IIntegerConsumer callback) {
Shuo Qian4a594052020-01-23 11:59:30 -08005714 enforceModifyPermission();
5715 long identity = Binder.clearCallingIdentity();
5716 try {
5717 if (DBG) {
5718 log("setCallForwarding: subId " + subId
5719 + " callForwardingInfo" + callForwardingInfo);
5720 }
Hall Liu27d24262020-09-18 19:04:59 -07005721
5722 Phone phone = getPhone(subId);
5723 if (phone == null) {
5724 try {
Hall Liu940c4ca2020-09-29 17:10:18 -07005725 callback.accept(
5726 TelephonyManager.CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN);
Hall Liu27d24262020-09-18 19:04:59 -07005727 } catch (RemoteException e) {
5728 // ignore
5729 }
5730 return;
5731 }
5732
5733 Pair<CallForwardingInfo, Consumer<Integer>> arguments = Pair.create(callForwardingInfo,
5734 FunctionalUtils.ignoreRemoteException(callback::accept));
5735
5736 sendRequestAsync(CMD_SET_CALL_FORWARDING, arguments, phone, null);
Shuo Qian4a594052020-01-23 11:59:30 -08005737 } finally {
5738 Binder.restoreCallingIdentity(identity);
5739 }
5740 }
5741
5742 /**
Hall Liu27d24262020-09-18 19:04:59 -07005743 * Get the call waiting status for a subId.
Shuo Qian4a594052020-01-23 11:59:30 -08005744 */
5745 @Override
Hall Liu27d24262020-09-18 19:04:59 -07005746 public void getCallWaitingStatus(int subId, IIntegerConsumer callback) {
Shuo Qian4a594052020-01-23 11:59:30 -08005747 enforceReadPrivilegedPermission("getCallForwarding");
5748 long identity = Binder.clearCallingIdentity();
5749 try {
Hall Liu27d24262020-09-18 19:04:59 -07005750
5751 Phone phone = getPhone(subId);
5752 if (phone == null) {
5753 try {
5754 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
5755 } catch (RemoteException e) {
5756 // ignore
5757 }
5758 return;
5759 }
5760
5761 Consumer<Integer> argument = FunctionalUtils.ignoreRemoteException(callback::accept);
5762
Shuo Qian4a594052020-01-23 11:59:30 -08005763 if (DBG) log("getCallWaitingStatus: subId " + subId);
Hall Liu27d24262020-09-18 19:04:59 -07005764 sendRequestAsync(CMD_GET_CALL_WAITING, argument, phone, null);
Shuo Qian4a594052020-01-23 11:59:30 -08005765 } finally {
5766 Binder.restoreCallingIdentity(identity);
5767 }
5768 }
5769
5770 /**
Hall Liu27d24262020-09-18 19:04:59 -07005771 * Sets whether call waiting is enabled for a given subId.
Shuo Qian4a594052020-01-23 11:59:30 -08005772 */
5773 @Override
Hall Liu27d24262020-09-18 19:04:59 -07005774 public void setCallWaitingStatus(int subId, boolean enable, IIntegerConsumer callback) {
Shuo Qian4a594052020-01-23 11:59:30 -08005775 enforceModifyPermission();
5776 long identity = Binder.clearCallingIdentity();
5777 try {
Hall Liu27d24262020-09-18 19:04:59 -07005778 if (DBG) log("setCallWaitingStatus: subId " + subId + " enable: " + enable);
5779
5780 Phone phone = getPhone(subId);
5781 if (phone == null) {
5782 try {
5783 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
5784 } catch (RemoteException e) {
5785 // ignore
5786 }
5787 return;
5788 }
5789
5790 Pair<Boolean, Consumer<Integer>> arguments = Pair.create(enable,
5791 FunctionalUtils.ignoreRemoteException(callback::accept));
5792
5793 sendRequestAsync(CMD_SET_CALL_WAITING, arguments, phone, null);
Shuo Qian4a594052020-01-23 11:59:30 -08005794 } finally {
5795 Binder.restoreCallingIdentity(identity);
5796 }
5797 }
5798
5799 /**
yinxub1bed742017-04-17 11:45:04 -07005800 * Starts a new network scan and returns the id of this scan.
yinxu504e1392017-04-12 16:03:22 -07005801 *
yinxub1bed742017-04-17 11:45:04 -07005802 * @param subId id of the subscription
5803 * @param request contains the radio access networks with bands/channels to scan
5804 * @param messenger callback messenger for scan results or errors
5805 * @param binder for the purpose of auto clean when the user thread crashes
yinxu504e1392017-04-12 16:03:22 -07005806 * @return the id of the requested scan which can be used to stop the scan.
5807 */
5808 @Override
5809 public int requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger,
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07005810 IBinder binder, String callingPackage, String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005811 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5812 mApp, subId, "requestNetworkScan");
Hall Liuf19c44f2018-11-27 14:38:17 -08005813 LocationAccessPolicy.LocationPermissionResult locationResult =
5814 LocationAccessPolicy.checkLocationPermission(mApp,
5815 new LocationAccessPolicy.LocationPermissionQuery.Builder()
5816 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07005817 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08005818 .setCallingPid(Binder.getCallingPid())
5819 .setCallingUid(Binder.getCallingUid())
5820 .setMethod("requestNetworkScan")
5821 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
James.cf Lin1d4d7392020-07-03 18:22:53 +08005822 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
5823 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
Hall Liuf19c44f2018-11-27 14:38:17 -08005824 .build());
Hall Liub2ac8ef2019-02-28 15:56:23 -08005825 if (locationResult != LocationAccessPolicy.LocationPermissionResult.ALLOWED) {
Nathan Harold1c11dba2020-09-22 17:54:53 -07005826 SecurityException e = checkNetworkRequestForSanitizedLocationAccess(
5827 request, subId, callingPackage);
Hall Liub2ac8ef2019-02-28 15:56:23 -08005828 if (e != null) {
5829 if (locationResult == LocationAccessPolicy.LocationPermissionResult.DENIED_HARD) {
5830 throw e;
5831 } else {
Hall Liu0e5abaf2019-04-04 01:25:30 -07005832 loge(e.getMessage());
Hall Liub2ac8ef2019-02-28 15:56:23 -08005833 return TelephonyScanManager.INVALID_SCAN_ID;
5834 }
5835 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005836 }
Hall Liu912dfd32019-04-25 14:02:26 -07005837 int callingUid = Binder.getCallingUid();
5838 int callingPid = Binder.getCallingPid();
Ying Xu94a46582019-04-18 17:14:56 -07005839 final long identity = Binder.clearCallingIdentity();
5840 try {
5841 return mNetworkScanRequestTracker.startNetworkScan(
5842 request, messenger, binder, getPhone(subId),
Hall Liu912dfd32019-04-25 14:02:26 -07005843 callingUid, callingPid, callingPackage);
Ying Xu94a46582019-04-18 17:14:56 -07005844 } finally {
5845 Binder.restoreCallingIdentity(identity);
5846 }
yinxu504e1392017-04-12 16:03:22 -07005847 }
5848
Hall Liub2ac8ef2019-02-28 15:56:23 -08005849 private SecurityException checkNetworkRequestForSanitizedLocationAccess(
Nathan Harold1c11dba2020-09-22 17:54:53 -07005850 NetworkScanRequest request, int subId, String callingPackage) {
5851 boolean hasCarrierPriv = checkCarrierPrivilegesForPackage(subId, callingPackage)
Hall Liu558027f2019-05-15 19:14:05 -07005852 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
5853 boolean hasNetworkScanPermission =
5854 mApp.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_SCAN)
5855 == PERMISSION_GRANTED;
5856
5857 if (!hasCarrierPriv && !hasNetworkScanPermission) {
5858 return new SecurityException("permission.NETWORK_SCAN or carrier privileges is needed"
5859 + " for network scans without location access.");
Hall Liub2ac8ef2019-02-28 15:56:23 -08005860 }
5861
5862 if (request.getSpecifiers() != null && request.getSpecifiers().length > 0) {
5863 for (RadioAccessSpecifier ras : request.getSpecifiers()) {
Hall Liub2ac8ef2019-02-28 15:56:23 -08005864 if (ras.getChannels() != null && ras.getChannels().length > 0) {
5865 return new SecurityException("Specific channels must not be"
5866 + " scanned without location access.");
5867 }
5868 }
5869 }
5870
Hall Liub2ac8ef2019-02-28 15:56:23 -08005871 return null;
5872 }
5873
yinxu504e1392017-04-12 16:03:22 -07005874 /**
5875 * Stops an existing network scan with the given scanId.
yinxub1bed742017-04-17 11:45:04 -07005876 *
5877 * @param subId id of the subscription
5878 * @param scanId id of the scan that needs to be stopped
yinxu504e1392017-04-12 16:03:22 -07005879 */
5880 @Override
5881 public void stopNetworkScan(int subId, int scanId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005882 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5883 mApp, subId, "stopNetworkScan");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005884
Hall Liu912dfd32019-04-25 14:02:26 -07005885 int callingUid = Binder.getCallingUid();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005886 final long identity = Binder.clearCallingIdentity();
5887 try {
Hall Liu912dfd32019-04-25 14:02:26 -07005888 mNetworkScanRequestTracker.stopNetworkScan(scanId, callingUid);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005889 } finally {
5890 Binder.restoreCallingIdentity(identity);
5891 }
yinxu504e1392017-04-12 16:03:22 -07005892 }
5893
5894 /**
Junda Liu84d15a22014-07-02 11:21:04 -07005895 * Get the calculated preferred network type.
5896 * Used for debugging incorrect network type.
5897 *
5898 * @return the preferred network type, defined in RILConstants.java.
5899 */
5900 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005901 public int getCalculatedPreferredNetworkType(String callingPackage, String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005902 final Phone defaultPhone = getDefaultPhone();
5903 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005904 callingPackage, callingFeatureId, "getCalculatedPreferredNetworkType")) {
Svet Ganovb320e182015-04-16 12:30:10 -07005905 return RILConstants.PREFERRED_NETWORK_MODE;
5906 }
5907
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005908 final long identity = Binder.clearCallingIdentity();
5909 try {
5910 // FIXME: need to get SubId from somewhere.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005911 return PhoneFactory.calculatePreferredNetworkType(defaultPhone.getContext(), 0);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005912 } finally {
5913 Binder.restoreCallingIdentity(identity);
5914 }
Junda Liu84d15a22014-07-02 11:21:04 -07005915 }
5916
5917 /**
Jake Hamby7c27be32014-03-03 13:25:59 -08005918 * Get the preferred network type.
5919 * Used for device configuration by some CDMA operators.
5920 *
5921 * @return the preferred network type, defined in RILConstants.java.
5922 */
5923 @Override
Stuart Scott54788802015-03-30 13:18:01 -07005924 public int getPreferredNetworkType(int subId) {
Pengquan Menga4009cb2018-12-20 11:00:24 -08005925 TelephonyPermissions
5926 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5927 mApp, subId, "getPreferredNetworkType");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005928
5929 final long identity = Binder.clearCallingIdentity();
5930 try {
5931 if (DBG) log("getPreferredNetworkType");
5932 int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null, subId);
5933 int networkType = (result != null ? result[0] : -1);
5934 if (DBG) log("getPreferredNetworkType: " + networkType);
5935 return networkType;
5936 } finally {
5937 Binder.restoreCallingIdentity(identity);
5938 }
Jake Hamby7c27be32014-03-03 13:25:59 -08005939 }
5940
5941 /**
5942 * Set the preferred network type.
Jake Hamby7c27be32014-03-03 13:25:59 -08005943 *
5944 * @param networkType the preferred network type, defined in RILConstants.java.
5945 * @return true on success; false on any failure.
5946 */
5947 @Override
Stuart Scott54788802015-03-30 13:18:01 -07005948 public boolean setPreferredNetworkType(int subId, int networkType) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005949 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5950 mApp, subId, "setPreferredNetworkType");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005951
5952 final long identity = Binder.clearCallingIdentity();
5953 try {
calvinpan8ed33732020-03-12 14:17:55 +08005954 Boolean success = (Boolean) sendRequest(
5955 CMD_SET_PREFERRED_NETWORK_TYPE, networkType, subId);
calvinpan03641a72020-08-18 16:53:59 +08005956
5957 if (success) {
5958 Settings.Global.putInt(mApp.getContentResolver(),
5959 Settings.Global.PREFERRED_NETWORK_MODE + subId, networkType);
5960 }
calvinpan8ed33732020-03-12 14:17:55 +08005961 if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail"));
5962 return success;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005963 } finally {
5964 Binder.restoreCallingIdentity(identity);
Junda Liu80bc0d12014-07-14 16:36:44 -07005965 }
Jake Hamby7c27be32014-03-03 13:25:59 -08005966 }
Robert Greenwalted86e582014-05-21 20:03:20 -07005967
5968 /**
calvinpan0ac9c1a2020-01-14 20:42:55 +08005969 * Get the allowed network types that store in the telephony provider.
5970 *
5971 * @param subId the id of the subscription.
5972 * @return allowedNetworkTypes the allowed network types.
5973 */
5974 @Override
5975 public long getAllowedNetworkTypes(int subId) {
5976 TelephonyPermissions
5977 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5978 mApp, subId, "getAllowedNetworkTypes");
5979
5980 final long identity = Binder.clearCallingIdentity();
5981 try {
5982 return SubscriptionManager.getLongSubscriptionProperty(
5983 subId, SubscriptionManager.ALLOWED_NETWORK_TYPES, -1, mApp);
5984 } finally {
5985 Binder.restoreCallingIdentity(identity);
5986 }
5987 }
5988
5989 /**
5990 * Set the allowed network types.
5991 *
5992 * @param subId the id of the subscription.
5993 * @param allowedNetworkTypes the allowed network types.
5994 * @return true on success; false on any failure.
5995 */
5996 @Override
5997 public boolean setAllowedNetworkTypes(int subId, long allowedNetworkTypes) {
5998 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5999 mApp, subId, "setAllowedNetworkTypes");
calvinpan0ac9c1a2020-01-14 20:42:55 +08006000
calvinpan8ed33732020-03-12 14:17:55 +08006001 SubscriptionManager.setSubscriptionProperty(subId,
6002 SubscriptionManager.ALLOWED_NETWORK_TYPES,
6003 String.valueOf(allowedNetworkTypes));
calvinpan0ac9c1a2020-01-14 20:42:55 +08006004
calvinpan8ed33732020-03-12 14:17:55 +08006005 int preferredNetworkMode = Settings.Global.getInt(mApp.getContentResolver(),
6006 Settings.Global.PREFERRED_NETWORK_MODE + subId,
6007 RILConstants.PREFERRED_NETWORK_MODE);
6008 return setPreferredNetworkType(subId, preferredNetworkMode);
calvinpan0ac9c1a2020-01-14 20:42:55 +08006009 }
6010
6011 /**
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07006012 * Get the allowed network types for certain reason.
6013 *
6014 * @param subId the id of the subscription.
6015 * @param reason the reason the allowed network type change is taking place
6016 * @return the allowed network types.
6017 */
6018 @Override
6019 public long getAllowedNetworkTypesForReason(int subId,
6020 @TelephonyManager.AllowedNetworkTypesReason int reason) {
6021 TelephonyPermissions
6022 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
6023 mApp, subId, "getAllowedNetworkTypesForReason");
6024 final long identity = Binder.clearCallingIdentity();
6025 try {
6026 return getPhoneFromSubId(subId).getAllowedNetworkTypes(reason);
6027 } finally {
6028 Binder.restoreCallingIdentity(identity);
6029 }
6030 }
6031
6032 /**
Sooraj Sasindran37444802020-08-11 10:40:43 -07006033 * Enable/Disable E-UTRA-NR Dual Connectivity
6034 * @param subId subscription id of the sim card
6035 * @param nrDualConnectivityState expected NR dual connectivity state
6036 * This can be passed following states
6037 * <ol>
6038 * <li>Enable NR dual connectivity {@link TelephonyManager#NR_DUAL_CONNECTIVITY_ENABLE}
6039 * <li>Disable NR dual connectivity {@link TelephonyManager#NR_DUAL_CONNECTIVITY_DISABLE}
6040 * <li>Disable NR dual connectivity and force secondary cell to be released
6041 * {@link TelephonyManager#NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE}
6042 * </ol>
6043 * @return operation result.
6044 */
6045 @Override
6046 public int setNrDualConnectivityState(int subId,
6047 @TelephonyManager.NrDualConnectivityState int nrDualConnectivityState) {
6048 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6049 mApp, subId, "enableNRDualConnectivity");
6050 WorkSource workSource = getWorkSource(Binder.getCallingUid());
6051 final long identity = Binder.clearCallingIdentity();
6052 try {
6053 int result = (int) sendRequest(CMD_ENABLE_NR_DUAL_CONNECTIVITY,
6054 nrDualConnectivityState, subId,
6055 workSource);
6056 if (DBG) log("enableNRDualConnectivity result: " + result);
6057 return result;
6058 } finally {
6059 Binder.restoreCallingIdentity(identity);
6060 }
6061 }
6062
6063 /**
6064 * Is E-UTRA-NR Dual Connectivity enabled
6065 * @return true if dual connectivity is enabled else false
6066 */
6067 @Override
6068 public boolean isNrDualConnectivityEnabled(int subId) {
6069 TelephonyPermissions
6070 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
6071 mApp, subId, "isNRDualConnectivityEnabled");
6072 WorkSource workSource = getWorkSource(Binder.getCallingUid());
6073 final long identity = Binder.clearCallingIdentity();
6074 try {
6075 boolean isEnabled = (boolean) sendRequest(CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED,
6076 null, subId, workSource);
6077 if (DBG) log("isNRDualConnectivityEnabled: " + isEnabled);
6078 return isEnabled;
6079 } finally {
6080 Binder.restoreCallingIdentity(identity);
6081 }
6082 }
6083
6084 /**
Sooraj Sasindran4deb8872020-10-30 13:17:53 -07006085 * get carrier bandwidth per primary and secondary carrier
6086 * @param subId subscription id of the sim card
6087 * @return CarrierBandwidth with bandwidth of both primary and secondary carrier..
6088 */
6089 @Override
6090 public CarrierBandwidth getCarrierBandwidth(int subId) {
6091 TelephonyPermissions
6092 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
6093 mApp, subId, "isNRDualConnectivityEnabled");
6094 WorkSource workSource = getWorkSource(Binder.getCallingUid());
6095 final long identity = Binder.clearCallingIdentity();
6096 try {
6097 CarrierBandwidth carrierBandwidth =
6098 getPhoneFromSubId(subId).getCarrierBandwidth();
6099 if (DBG) log("getCarrierBandwidth: " + carrierBandwidth);
6100 return carrierBandwidth;
6101 } finally {
6102 Binder.restoreCallingIdentity(identity);
6103 }
6104 }
6105
6106 /**
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07006107 * Get the effective allowed network types on the device.
6108 * This API will return an intersection of allowed network types for all reasons,
6109 * including the configuration done through setAllowedNetworkTypes
6110 *
6111 * @param subId the id of the subscription.
6112 * @return the allowed network types
6113 */
6114 @Override
6115 public long getEffectiveAllowedNetworkTypes(int subId) {
6116 TelephonyPermissions
6117 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
6118 mApp, subId, "getEffectiveAllowedNetworkTypes");
6119 final long identity = Binder.clearCallingIdentity();
6120 try {
6121 return getPhoneFromSubId(subId).getEffectiveAllowedNetworkTypes();
6122 } finally {
6123 Binder.restoreCallingIdentity(identity);
6124 }
6125 }
6126
6127 /**
6128 * Set the allowed network types of the device and
6129 * provide the reason triggering the allowed network change.
6130 *
6131 * @param subId the id of the subscription.
6132 * @param reason the reason the allowed network type change is taking place
6133 * @param allowedNetworkTypes the allowed network types.
6134 * @return true on success; false on any failure.
6135 */
6136 @Override
6137 public boolean setAllowedNetworkTypesForReason(int subId,
6138 @TelephonyManager.AllowedNetworkTypesReason int reason, long allowedNetworkTypes) {
6139 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6140 mApp, subId, "setAllowedNetworkTypesForReason");
6141 final long identity = Binder.clearCallingIdentity();
6142 try {
6143 getPhoneFromSubId(subId).setAllowedNetworkTypes(reason, allowedNetworkTypes);
6144 int preferredNetworkMode = Settings.Global.getInt(mApp.getContentResolver(),
6145 Settings.Global.PREFERRED_NETWORK_MODE + subId,
6146 RILConstants.PREFERRED_NETWORK_MODE);
6147 return setPreferredNetworkType(subId, preferredNetworkMode);
6148 } finally {
6149 Binder.restoreCallingIdentity(identity);
6150 }
6151 }
6152
6153 /**
Miaoa84611c2019-03-15 09:21:10 +08006154 * Check whether DUN APN is required for tethering with subId.
Junda Liu475951f2014-11-07 16:45:03 -08006155 *
Miaoa84611c2019-03-15 09:21:10 +08006156 * @param subId the id of the subscription to require tethering.
Amit Mahajanfe58cdf2017-07-11 12:01:53 -07006157 * @return {@code true} if DUN APN is required for tethering.
Junda Liu475951f2014-11-07 16:45:03 -08006158 * @hide
6159 */
6160 @Override
SongFerngWangf08d8122019-11-15 14:58:44 +08006161 public boolean isTetheringApnRequiredForSubscriber(int subId) {
Shishir Agrawalc04d9752016-02-19 10:41:00 -08006162 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006163 final long identity = Binder.clearCallingIdentity();
Miaoa84611c2019-03-15 09:21:10 +08006164 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006165 try {
Miaoa84611c2019-03-15 09:21:10 +08006166 if (phone != null) {
6167 return phone.hasMatchedTetherApnSetting();
6168 } else {
6169 return false;
6170 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006171 } finally {
6172 Binder.restoreCallingIdentity(identity);
Junda Liu475951f2014-11-07 16:45:03 -08006173 }
Junda Liu475951f2014-11-07 16:45:03 -08006174 }
6175
6176 /**
Shuo Qiancd19c462020-01-16 20:51:11 -08006177 * Enable or disable always reporting signal strength changes from radio.
6178 *
6179 * @param isEnable {@code true} for enabling; {@code false} for disabling.
6180 */
6181 @Override
6182 public void setAlwaysReportSignalStrength(int subId, boolean isEnable) {
6183 enforceModifyPermission();
6184 enforceSystemCaller();
6185
6186 final long identity = Binder.clearCallingIdentity();
6187 final Phone phone = getPhone(subId);
6188 try {
6189 if (phone != null) {
6190 if (DBG) {
6191 log("setAlwaysReportSignalStrength: subId=" + subId
6192 + " isEnable=" + isEnable);
6193 }
6194 phone.setAlwaysReportSignalStrength(isEnable);
6195 } else {
6196 loge("setAlwaysReportSignalStrength: no phone found for subId="
6197 + subId);
6198 }
6199 } finally {
6200 Binder.restoreCallingIdentity(identity);
6201 }
6202 }
6203
6204 /**
Malcolm Chen964682d2017-11-28 16:20:07 -08006205 * Get the user enabled state of Mobile Data.
6206 *
6207 * TODO: remove and use isUserDataEnabled.
6208 * This can't be removed now because some vendor codes
6209 * calls through ITelephony directly while they should
6210 * use TelephonyManager.
6211 *
6212 * @return true on enabled
6213 */
6214 @Override
6215 public boolean getDataEnabled(int subId) {
6216 return isUserDataEnabled(subId);
6217 }
6218
6219 /**
6220 * Get whether mobile data is enabled per user setting.
6221 *
6222 * There are other factors deciding whether mobile data is actually enabled, but they are
6223 * not considered here. See {@link #isDataEnabled(int)} for more details.
Robert Greenwalt646120a2014-05-23 11:54:03 -07006224 *
Jeff Davidsona1920712016-11-18 17:05:56 -08006225 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
Robert Greenwalted86e582014-05-21 20:03:20 -07006226 *
6227 * @return {@code true} if data is enabled else {@code false}
6228 */
6229 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08006230 public boolean isUserDataEnabled(int subId) {
Robert Greenwalt646120a2014-05-23 11:54:03 -07006231 try {
6232 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
6233 null);
6234 } catch (Exception e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006235 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6236 mApp, subId, "isUserDataEnabled");
Robert Greenwalt646120a2014-05-23 11:54:03 -07006237 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006238
6239 final long identity = Binder.clearCallingIdentity();
6240 try {
6241 int phoneId = mSubscriptionController.getPhoneId(subId);
6242 if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
6243 Phone phone = PhoneFactory.getPhone(phoneId);
6244 if (phone != null) {
6245 boolean retVal = phone.isUserDataEnabled();
6246 if (DBG) log("isUserDataEnabled: subId=" + subId + " retVal=" + retVal);
6247 return retVal;
6248 } else {
6249 if (DBG) loge("isUserDataEnabled: no phone subId=" + subId + " retVal=false");
6250 return false;
6251 }
6252 } finally {
6253 Binder.restoreCallingIdentity(identity);
Malcolm Chen964682d2017-11-28 16:20:07 -08006254 }
6255 }
6256
6257 /**
Shuo Qian8ee4e882020-01-08 14:30:06 -08006258 * Checks if the device is capable of mobile data by considering whether whether the
6259 * user has enabled mobile data, whether the carrier has enabled mobile data, and
6260 * whether the network policy allows data connections.
Malcolm Chen964682d2017-11-28 16:20:07 -08006261 *
Shuo Qian8ee4e882020-01-08 14:30:06 -08006262 * @return {@code true} if the overall data connection is capable; {@code false} if not.
Malcolm Chen964682d2017-11-28 16:20:07 -08006263 */
6264 @Override
6265 public boolean isDataEnabled(int subId) {
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006266 try {
6267 try {
6268 mApp.enforceCallingOrSelfPermission(
6269 android.Manifest.permission.ACCESS_NETWORK_STATE,
6270 null);
6271 } catch (Exception e) {
6272 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE,
6273 "isDataEnabled");
6274 }
6275 } catch (Exception e) {
6276 enforceReadPrivilegedPermission("isDataEnabled");
6277 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006278
6279 final long identity = Binder.clearCallingIdentity();
6280 try {
6281 int phoneId = mSubscriptionController.getPhoneId(subId);
6282 if (DBG) log("isDataEnabled: subId=" + subId + " phoneId=" + phoneId);
6283 Phone phone = PhoneFactory.getPhone(phoneId);
6284 if (phone != null) {
Jack Yud79fba22018-12-13 11:51:28 -08006285 boolean retVal = phone.getDataEnabledSettings().isDataEnabled();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006286 if (DBG) log("isDataEnabled: subId=" + subId + " retVal=" + retVal);
6287 return retVal;
6288 } else {
6289 if (DBG) loge("isDataEnabled: no phone subId=" + subId + " retVal=false");
6290 return false;
6291 }
6292 } finally {
6293 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08006294 }
Robert Greenwalted86e582014-05-21 20:03:20 -07006295 }
Shishir Agrawal60f9c952014-06-23 12:00:43 -07006296
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006297 /**
6298 * Check if data is enabled for a specific reason
6299 * @param subId Subscription index
6300 * @param reason the reason the data enable change is taking place
6301 * @return {@code true} if the overall data is enabled; {@code false} if not.
6302 */
6303 @Override
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006304 public boolean isDataEnabledForReason(int subId,
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006305 @TelephonyManager.DataEnabledReason int reason) {
6306 try {
6307 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
6308 null);
6309 } catch (Exception e) {
6310 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE,
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006311 "isDataEnabledForReason");
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006312 }
6313
6314
6315 final long identity = Binder.clearCallingIdentity();
6316 try {
6317 int phoneId = mSubscriptionController.getPhoneId(subId);
6318 if (DBG) {
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006319 log("isDataEnabledForReason: subId=" + subId + " phoneId=" + phoneId
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006320 + " reason=" + reason);
6321 }
6322 Phone phone = PhoneFactory.getPhone(phoneId);
6323 if (phone != null) {
6324 boolean retVal;
6325 if (reason == TelephonyManager.DATA_ENABLED_REASON_USER) {
6326 retVal = phone.isUserDataEnabled();
6327 } else {
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006328 retVal = phone.getDataEnabledSettings().isDataEnabledForReason(reason);
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006329 }
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006330 if (DBG) log("isDataEnabledForReason: retVal=" + retVal);
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006331 return retVal;
6332 } else {
6333 if (DBG) {
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006334 loge("isDataEnabledForReason: no phone subId="
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006335 + subId + " retVal=false");
6336 }
6337 return false;
6338 }
6339 } finally {
6340 Binder.restoreCallingIdentity(identity);
6341 }
6342 }
6343
Malcolm Chendf0b4cc2020-02-24 15:12:43 -08006344 private int getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, int uid,
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006345 Phone phone) {
Hall Liu54a2a0c2020-07-13 12:13:03 -07006346 if (uid == Process.SYSTEM_UID || uid == Process.PHONE_UID) {
6347 // Skip the check if it's one of these special uids
6348 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
6349 }
6350
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006351 //load access rules from carrier configs, and check those as well: b/139133814
6352 SubscriptionController subController = SubscriptionController.getInstance();
6353 if (privilegeFromSim == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
6354 || subController == null) return privilegeFromSim;
6355
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006356 PackageManager pkgMgr = phone.getContext().getPackageManager();
6357 String[] packages = pkgMgr.getPackagesForUid(uid);
6358
6359 final long identity = Binder.clearCallingIdentity();
6360 try {
Jeff Davidson8ab02b22020-03-28 12:24:40 -07006361 int subId = phone.getSubId();
6362 if (mCarrierPrivilegeTestOverrideSubIds.contains(subId)) {
6363 // A test override is in place for the privileges for this subId, so don't try to
6364 // read the subscription privileges.
6365 return privilegeFromSim;
6366 }
6367 SubscriptionInfo subInfo = subController.getSubscriptionInfo(subId);
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006368 SubscriptionManager subManager = (SubscriptionManager)
6369 phone.getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
6370 for (String pkg : packages) {
6371 if (subManager.canManageSubscription(subInfo, pkg)) {
6372 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
6373 }
6374 }
6375 return privilegeFromSim;
6376 } finally {
6377 Binder.restoreCallingIdentity(identity);
6378 }
6379 }
6380
6381 private int getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, Phone phone,
6382 String pkgName) {
6383 //load access rules from carrier configs, and check those as well: b/139133814
6384 SubscriptionController subController = SubscriptionController.getInstance();
6385 if (privilegeFromSim == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
6386 || subController == null) return privilegeFromSim;
6387
6388 final long identity = Binder.clearCallingIdentity();
6389 try {
Jeff Davidson8ab02b22020-03-28 12:24:40 -07006390 int subId = phone.getSubId();
6391 if (mCarrierPrivilegeTestOverrideSubIds.contains(subId)) {
6392 // A test override is in place for the privileges for this subId, so don't try to
6393 // read the subscription privileges.
6394 return privilegeFromSim;
6395 }
6396 SubscriptionInfo subInfo = subController.getSubscriptionInfo(subId);
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006397 SubscriptionManager subManager = (SubscriptionManager)
6398 phone.getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
6399 return subManager.canManageSubscription(subInfo, pkgName)
6400 ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS : privilegeFromSim;
6401 } finally {
6402 Binder.restoreCallingIdentity(identity);
6403 }
6404 }
6405
Shishir Agrawal60f9c952014-06-23 12:00:43 -07006406 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08006407 public int getCarrierPrivilegeStatus(int subId) {
6408 final Phone phone = getPhone(subId);
6409 if (phone == null) {
6410 loge("getCarrierPrivilegeStatus: Invalid subId");
6411 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
6412 }
6413 UiccCard card = UiccController.getInstance().getUiccCard(phone.getPhoneId());
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07006414 if (card == null) {
Shishir Agrawal5e5becd2014-11-18 11:38:23 -08006415 loge("getCarrierPrivilegeStatus: No UICC");
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07006416 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
6417 }
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006418
6419 return getCarrierPrivilegeStatusFromCarrierConfigRules(
6420 card.getCarrierPrivilegeStatusForCurrentTransaction(
Malcolm Chendf0b4cc2020-02-24 15:12:43 -08006421 phone.getContext().getPackageManager()), Binder.getCallingUid(), phone);
Shishir Agrawal60f9c952014-06-23 12:00:43 -07006422 }
Junda Liu29340342014-07-10 15:23:27 -07006423
6424 @Override
Jeff Davidson7e17e312018-02-13 18:17:36 -08006425 public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08006426 enforceReadPrivilegedPermission("getCarrierPrivilegeStatusForUid");
Jeff Davidson7e17e312018-02-13 18:17:36 -08006427 final Phone phone = getPhone(subId);
6428 if (phone == null) {
Taesu Leef8fbed92019-10-07 18:47:02 +09006429 loge("getCarrierPrivilegeStatusForUid: Invalid subId");
Jeff Davidson7e17e312018-02-13 18:17:36 -08006430 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
6431 }
6432 UiccProfile profile =
6433 UiccController.getInstance().getUiccProfileForPhone(phone.getPhoneId());
6434 if (profile == null) {
Taesu Leef8fbed92019-10-07 18:47:02 +09006435 loge("getCarrierPrivilegeStatusForUid: No UICC");
Jeff Davidson7e17e312018-02-13 18:17:36 -08006436 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
6437 }
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006438 return getCarrierPrivilegeStatusFromCarrierConfigRules(
Shuo Qian2c0ae432019-12-05 11:40:37 -08006439 profile.getCarrierPrivilegeStatusForUid(
Malcolm Chendf0b4cc2020-02-24 15:12:43 -08006440 phone.getContext().getPackageManager(), uid), uid, phone);
Jeff Davidson7e17e312018-02-13 18:17:36 -08006441 }
6442
6443 @Override
chen xuf7e9fe82019-05-09 19:31:02 -07006444 public int checkCarrierPrivilegesForPackage(int subId, String pkgName) {
6445 if (TextUtils.isEmpty(pkgName)) {
Junda Liu317d70b2016-03-08 09:33:53 -08006446 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
chen xuf7e9fe82019-05-09 19:31:02 -07006447 }
6448
6449 int phoneId = SubscriptionManager.getPhoneId(subId);
6450 UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07006451 if (card == null) {
chen xuf7e9fe82019-05-09 19:31:02 -07006452 loge("checkCarrierPrivilegesForPackage: No UICC on subId " + subId);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07006453 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
6454 }
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006455 return getCarrierPrivilegeStatusFromCarrierConfigRules(
6456 card.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName),
6457 getPhone(phoneId), pkgName);
Zach Johnson50ecba32015-05-19 00:24:21 -07006458 }
6459
6460 @Override
6461 public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
Junda Liu317d70b2016-03-08 09:33:53 -08006462 if (TextUtils.isEmpty(pkgName))
6463 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Zach Johnson50ecba32015-05-19 00:24:21 -07006464 int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
6465 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
6466 UiccCard card = UiccController.getInstance().getUiccCard(i);
6467 if (card == null) {
Jonathan Basseri7d320df2015-06-16 12:17:08 -07006468 // No UICC in that slot.
Zach Johnson50ecba32015-05-19 00:24:21 -07006469 continue;
6470 }
6471
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006472 result = getCarrierPrivilegeStatusFromCarrierConfigRules(
6473 card.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName),
6474 getPhone(i), pkgName);
Zach Johnson50ecba32015-05-19 00:24:21 -07006475 if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
6476 break;
6477 }
6478 }
6479
6480 return result;
Junda Liu29340342014-07-10 15:23:27 -07006481 }
Derek Tan89e89d42014-07-08 17:00:10 -07006482
6483 @Override
Junda Liue64de782015-04-16 17:19:16 -07006484 public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
6485 if (!SubscriptionManager.isValidPhoneId(phoneId)) {
6486 loge("phoneId " + phoneId + " is not valid.");
6487 return null;
6488 }
6489 UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07006490 if (card == null) {
Taesu Leef8fbed92019-10-07 18:47:02 +09006491 loge("getCarrierPackageNamesForIntentAndPhone: No UICC");
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07006492 return null ;
6493 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006494 return card.getCarrierPackageNamesForIntent(mApp.getPackageManager(), intent);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07006495 }
6496
Amith Yamasani6e118872016-02-19 12:53:51 -08006497 @Override
chen xuf7e9fe82019-05-09 19:31:02 -07006498 public List<String> getPackagesWithCarrierPrivileges(int phoneId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006499 PackageManager pm = mApp.getPackageManager();
Amith Yamasani6e118872016-02-19 12:53:51 -08006500 List<String> privilegedPackages = new ArrayList<>();
6501 List<PackageInfo> packages = null;
chen xuf7e9fe82019-05-09 19:31:02 -07006502 UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
6503 // has UICC in that slot.
6504 if (card != null) {
Amith Yamasani6e118872016-02-19 12:53:51 -08006505 if (card.hasCarrierPrivilegeRules()) {
6506 if (packages == null) {
6507 // Only check packages in user 0 for now
6508 packages = pm.getInstalledPackagesAsUser(
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006509 PackageManager.MATCH_DISABLED_COMPONENTS
6510 | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
Cheonho Park17089c62019-08-01 15:23:12 +09006511 | PackageManager.GET_SIGNING_CERTIFICATES,
Amit Mahajanb8f13202020-01-27 18:16:07 -08006512 UserHandle.SYSTEM.getIdentifier());
Amith Yamasani6e118872016-02-19 12:53:51 -08006513 }
6514 for (int p = packages.size() - 1; p >= 0; p--) {
6515 PackageInfo pkgInfo = packages.get(p);
6516 if (pkgInfo != null && pkgInfo.packageName != null
6517 && card.getCarrierPrivilegeStatus(pkgInfo)
chen xuf7e9fe82019-05-09 19:31:02 -07006518 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
Amith Yamasani6e118872016-02-19 12:53:51 -08006519 privilegedPackages.add(pkgInfo.packageName);
6520 }
6521 }
6522 }
6523 }
6524 return privilegedPackages;
6525 }
6526
chen xuf7e9fe82019-05-09 19:31:02 -07006527 @Override
6528 public List<String> getPackagesWithCarrierPrivilegesForAllPhones() {
Shuo Qian067a06d2019-12-03 23:40:18 +00006529 enforceReadPrivilegedPermission("getPackagesWithCarrierPrivilegesForAllPhones");
6530
6531 final long identity = Binder.clearCallingIdentity();
6532
chen xuf7e9fe82019-05-09 19:31:02 -07006533 List<String> privilegedPackages = new ArrayList<>();
Shuo Qian067a06d2019-12-03 23:40:18 +00006534 try {
6535 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
6536 privilegedPackages.addAll(getPackagesWithCarrierPrivileges(i));
6537 }
6538 } finally {
6539 Binder.restoreCallingIdentity(identity);
chen xuf7e9fe82019-05-09 19:31:02 -07006540 }
6541 return privilegedPackages;
6542 }
6543
Wink Savilleb564aae2014-10-23 10:18:09 -07006544 private String getIccId(int subId) {
Sanket Padawe356d7632015-06-22 14:03:32 -07006545 final Phone phone = getPhone(subId);
6546 UiccCard card = phone == null ? null : phone.getUiccCard();
Derek Tan97ebb422014-09-05 16:55:38 -07006547 if (card == null) {
Derek Tan97ebb422014-09-05 16:55:38 -07006548 return null;
6549 }
6550 String iccId = card.getIccId();
6551 if (TextUtils.isEmpty(iccId)) {
Derek Tan97ebb422014-09-05 16:55:38 -07006552 return null;
6553 }
6554 return iccId;
6555 }
6556
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07006557 @Override
Shuo Qiane4e11672020-12-15 22:15:33 -08006558 public void setCallComposerStatus(int subId, int status) {
6559 enforceModifyPermission();
6560
6561 final long identity = Binder.clearCallingIdentity();
6562 try {
6563 Phone phone = getPhone(subId);
6564 if (phone != null) {
6565 Phone defaultPhone = phone.getImsPhone();
6566 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
6567 ImsPhone imsPhone = (ImsPhone) defaultPhone;
6568 imsPhone.setCallComposerStatus(status);
6569 }
6570 }
6571 } finally {
6572 Binder.restoreCallingIdentity(identity);
6573 }
6574 }
6575
6576 @Override
6577 public int getCallComposerStatus(int subId) {
6578 enforceReadPrivilegedPermission("getCallComposerStatus");
6579
6580 final long identity = Binder.clearCallingIdentity();
6581 try {
6582 Phone phone = getPhone(subId);
6583 if (phone != null) {
6584 Phone defaultPhone = phone.getImsPhone();
6585 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
6586 ImsPhone imsPhone = (ImsPhone) defaultPhone;
6587 return imsPhone.getCallComposerStatus();
6588 }
6589 }
6590 } finally {
6591 Binder.restoreCallingIdentity(identity);
6592 }
6593 return TelephonyManager.CALL_COMPOSER_STATUS_OFF;
6594 }
6595
6596 @Override
Jeff Sharkey85190e62014-12-05 09:40:12 -08006597 public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
6598 String number) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08006599 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
Jeff Davidson7e17e312018-02-13 18:17:36 -08006600 subId, "setLine1NumberForDisplayForSubscriber");
Derek Tan97ebb422014-09-05 16:55:38 -07006601
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006602 final long identity = Binder.clearCallingIdentity();
6603 try {
6604 final String iccId = getIccId(subId);
6605 final Phone phone = getPhone(subId);
6606 if (phone == null) {
6607 return false;
6608 }
6609 final String subscriberId = phone.getSubscriberId();
6610
6611 if (DBG_MERGE) {
Amit Mahajanb8f13202020-01-27 18:16:07 -08006612 Rlog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId="
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006613 + subscriberId + " to " + number);
6614 }
6615
6616 if (TextUtils.isEmpty(iccId)) {
6617 return false;
6618 }
6619
6620 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
6621
6622 final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
6623 if (alphaTag == null) {
6624 editor.remove(alphaTagPrefKey);
6625 } else {
6626 editor.putString(alphaTagPrefKey, alphaTag);
6627 }
6628
6629 // Record both the line number and IMSI for this ICCID, since we need to
6630 // track all merged IMSIs based on line number
6631 final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
6632 final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
6633 if (number == null) {
6634 editor.remove(numberPrefKey);
6635 editor.remove(subscriberPrefKey);
6636 } else {
6637 editor.putString(numberPrefKey, number);
6638 editor.putString(subscriberPrefKey, subscriberId);
6639 }
6640
6641 editor.commit();
6642 return true;
6643 } finally {
6644 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07006645 }
Derek Tan7226c842014-07-02 17:42:23 -07006646 }
6647
6648 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006649 public String getLine1NumberForDisplay(int subId, String callingPackage,
6650 String callingFeatureId) {
Makoto Onukifee69342015-06-29 14:44:50 -07006651 // This is open to apps with WRITE_SMS.
Jeff Davidson7e17e312018-02-13 18:17:36 -08006652 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006653 mApp, subId, callingPackage, callingFeatureId, "getLine1NumberForDisplay")) {
Amit Mahajan9cf11512015-11-09 11:40:48 -08006654 if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
Svet Ganovb320e182015-04-16 12:30:10 -07006655 return null;
6656 }
Derek Tan97ebb422014-09-05 16:55:38 -07006657
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006658 final long identity = Binder.clearCallingIdentity();
6659 try {
6660 String iccId = getIccId(subId);
6661 if (iccId != null) {
6662 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
6663 if (DBG_MERGE) {
6664 log("getLine1NumberForDisplay returning "
6665 + mTelephonySharedPreferences.getString(numberPrefKey, null));
6666 }
6667 return mTelephonySharedPreferences.getString(numberPrefKey, null);
Amit Mahajan9cf11512015-11-09 11:40:48 -08006668 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006669 if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null");
6670 return null;
6671 } finally {
6672 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07006673 }
Derek Tan7226c842014-07-02 17:42:23 -07006674 }
6675
6676 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006677 public String getLine1AlphaTagForDisplay(int subId, String callingPackage,
6678 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006679 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006680 mApp, subId, callingPackage, callingFeatureId, "getLine1AlphaTagForDisplay")) {
Svet Ganovb320e182015-04-16 12:30:10 -07006681 return null;
6682 }
Derek Tan97ebb422014-09-05 16:55:38 -07006683
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006684 final long identity = Binder.clearCallingIdentity();
6685 try {
6686 String iccId = getIccId(subId);
6687 if (iccId != null) {
6688 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
6689 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null);
6690 }
6691 return null;
6692 } finally {
6693 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07006694 }
Derek Tan7226c842014-07-02 17:42:23 -07006695 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07006696
6697 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006698 public String[] getMergedSubscriberIds(int subId, String callingPackage,
6699 String callingFeatureId) {
Jeff Davidson913390f2018-02-23 17:11:49 -08006700 // This API isn't public, so no need to provide a valid subscription ID - we're not worried
6701 // about carrier-privileged callers not having access.
Jeff Davidson7e17e312018-02-13 18:17:36 -08006702 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08006703 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006704 callingFeatureId, "getMergedSubscriberIds")) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07006705 return null;
6706 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08006707
Jordan Liub49b04b2019-05-06 14:45:15 -07006708 // Clear calling identity, when calling TelephonyManager, because callerUid must be
6709 // the process, where TelephonyManager was instantiated.
6710 // Otherwise AppOps check will fail.
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07006711 final long identity = Binder.clearCallingIdentity();
6712 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006713 final Context context = mApp;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006714 final TelephonyManager tele = TelephonyManager.from(context);
6715 final SubscriptionManager sub = SubscriptionManager.from(context);
6716
6717 // Figure out what subscribers are currently active
6718 final ArraySet<String> activeSubscriberIds = new ArraySet<>();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006719
Jordan Liub49b04b2019-05-06 14:45:15 -07006720 // Only consider subs which match the current subId
6721 // This logic can be simplified. See b/131189269 for progress.
6722 if (isActiveSubscription(subId)) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07006723 activeSubscriberIds.add(tele.getSubscriberId(subId));
6724 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006725
6726 // First pass, find a number override for an active subscriber
6727 String mergeNumber = null;
6728 final Map<String, ?> prefs = mTelephonySharedPreferences.getAll();
6729 for (String key : prefs.keySet()) {
6730 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) {
6731 final String subscriberId = (String) prefs.get(key);
6732 if (activeSubscriberIds.contains(subscriberId)) {
6733 final String iccId = key.substring(
6734 PREF_CARRIERS_SUBSCRIBER_PREFIX.length());
6735 final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
6736 mergeNumber = (String) prefs.get(numberKey);
6737 if (DBG_MERGE) {
Amit Mahajanb8f13202020-01-27 18:16:07 -08006738 Rlog.d(LOG_TAG, "Found line number " + mergeNumber
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006739 + " for active subscriber " + subscriberId);
6740 }
6741 if (!TextUtils.isEmpty(mergeNumber)) {
6742 break;
6743 }
6744 }
6745 }
6746 }
6747
6748 // Shortcut when no active merged subscribers
6749 if (TextUtils.isEmpty(mergeNumber)) {
6750 return null;
6751 }
6752
6753 // Second pass, find all subscribers under that line override
6754 final ArraySet<String> result = new ArraySet<>();
6755 for (String key : prefs.keySet()) {
6756 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) {
6757 final String number = (String) prefs.get(key);
6758 if (mergeNumber.equals(number)) {
6759 final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length());
6760 final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
6761 final String subscriberId = (String) prefs.get(subscriberKey);
6762 if (!TextUtils.isEmpty(subscriberId)) {
6763 result.add(subscriberId);
6764 }
6765 }
6766 }
6767 }
6768
6769 final String[] resultArray = result.toArray(new String[result.size()]);
6770 Arrays.sort(resultArray);
6771 if (DBG_MERGE) {
Amit Mahajanb8f13202020-01-27 18:16:07 -08006772 Rlog.d(LOG_TAG,
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006773 "Found subscribers " + Arrays.toString(resultArray) + " after merge");
6774 }
6775 return resultArray;
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07006776 } finally {
6777 Binder.restoreCallingIdentity(identity);
Jeff Sharkey85190e62014-12-05 09:40:12 -08006778 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08006779 }
6780
6781 @Override
zoey chen38003472019-12-13 17:16:31 +08006782 public String[] getMergedImsisFromGroup(int subId, String callingPackage) {
6783 enforceReadPrivilegedPermission("getMergedImsisFromGroup");
Malcolm Chen6ca97372019-07-01 16:28:21 -07006784
6785 final long identity = Binder.clearCallingIdentity();
6786 try {
6787 final TelephonyManager telephonyManager = mApp.getSystemService(
6788 TelephonyManager.class);
6789 String subscriberId = telephonyManager.getSubscriberId(subId);
6790 if (subscriberId == null) {
6791 if (DBG) {
zoey chen38003472019-12-13 17:16:31 +08006792 log("getMergedImsisFromGroup can't find subscriberId for subId "
Malcolm Chen6ca97372019-07-01 16:28:21 -07006793 + subId);
6794 }
6795 return null;
6796 }
6797
6798 final SubscriptionInfo info = SubscriptionController.getInstance()
6799 .getSubscriptionInfo(subId);
6800 final ParcelUuid groupUuid = info.getGroupUuid();
6801 // If it doesn't belong to any group, return just subscriberId of itself.
6802 if (groupUuid == null) {
6803 return new String[]{subscriberId};
6804 }
6805
6806 // Get all subscriberIds from the group.
6807 final List<String> mergedSubscriberIds = new ArrayList<>();
6808 final List<SubscriptionInfo> groupInfos = SubscriptionController.getInstance()
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006809 .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName(),
Philip P. Moltmann8d34f0c2020-03-05 16:24:02 -08006810 mApp.getAttributionTag());
Malcolm Chen6ca97372019-07-01 16:28:21 -07006811 for (SubscriptionInfo subInfo : groupInfos) {
6812 subscriberId = telephonyManager.getSubscriberId(subInfo.getSubscriptionId());
6813 if (subscriberId != null) {
6814 mergedSubscriberIds.add(subscriberId);
6815 }
6816 }
6817
6818 return mergedSubscriberIds.toArray(new String[mergedSubscriberIds.size()]);
6819 } finally {
6820 Binder.restoreCallingIdentity(identity);
6821
6822 }
6823 }
6824
6825 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08006826 public boolean setOperatorBrandOverride(int subId, String brand) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08006827 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
Jeff Davidson7e17e312018-02-13 18:17:36 -08006828 subId, "setOperatorBrandOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006829
6830 final long identity = Binder.clearCallingIdentity();
6831 try {
6832 final Phone phone = getPhone(subId);
6833 return phone == null ? false : phone.setOperatorBrandOverride(brand);
6834 } finally {
6835 Binder.restoreCallingIdentity(identity);
6836 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07006837 }
Steven Liu4bf01bc2014-07-17 11:05:29 -05006838
6839 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08006840 public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
Shishir Agrawal621a47c2014-12-01 10:25:09 -08006841 List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
6842 List<String> cdmaNonRoamingList) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08006843 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
6844 mApp, subId, "setRoamingOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006845
6846 final long identity = Binder.clearCallingIdentity();
6847 try {
6848 final Phone phone = getPhone(subId);
6849 if (phone == null) {
6850 return false;
6851 }
6852 return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList,
6853 cdmaNonRoamingList);
6854 } finally {
6855 Binder.restoreCallingIdentity(identity);
Shishir Agrawalc04d9752016-02-19 10:41:00 -08006856 }
Shishir Agrawal621a47c2014-12-01 10:25:09 -08006857 }
6858
6859 @Override
Shuo Qian850e4d6a2018-04-25 21:02:08 +00006860 @Deprecated
6861 public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
6862 enforceModifyPermission();
6863
6864 int returnValue = 0;
6865 try {
vagdeviaf9a5b92018-08-15 16:01:53 -07006866 AsyncResult result = (AsyncResult) sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
Shuo Qian850e4d6a2018-04-25 21:02:08 +00006867 if(result.exception == null) {
6868 if (result.result != null) {
6869 byte[] responseData = (byte[])(result.result);
6870 if(responseData.length > oemResp.length) {
6871 Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +
6872 responseData.length + "bytes. Buffer Size is " +
6873 oemResp.length + "bytes.");
6874 }
6875 System.arraycopy(responseData, 0, oemResp, 0, responseData.length);
6876 returnValue = responseData.length;
6877 }
6878 } else {
6879 CommandException ex = (CommandException) result.exception;
6880 returnValue = ex.getCommandError().ordinal();
6881 if(returnValue > 0) returnValue *= -1;
6882 }
6883 } catch (RuntimeException e) {
6884 Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");
6885 returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());
6886 if(returnValue > 0) returnValue *= -1;
6887 }
6888
6889 return returnValue;
6890 }
6891
6892 @Override
Wink Saville5d475dd2014-10-17 15:00:58 -07006893 public void setRadioCapability(RadioAccessFamily[] rafs) {
6894 try {
6895 ProxyController.getInstance().setRadioCapability(rafs);
6896 } catch (RuntimeException e) {
6897 Log.w(LOG_TAG, "setRadioCapability: Runtime Exception");
6898 }
6899 }
6900
6901 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07006902 public int getRadioAccessFamily(int phoneId, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08006903 Phone phone = PhoneFactory.getPhone(phoneId);
Shuo Qiandee53402020-05-29 14:08:15 -07006904 try {
6905 TelephonyPermissions
6906 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
6907 mApp, phone.getSubId(), "getRadioAccessFamily");
6908 } catch (SecurityException e) {
6909 EventLog.writeEvent(0x534e4554, "150857259", -1, "Missing Permission");
6910 throw e;
6911 }
chen xub97461a2018-10-26 14:17:57 -07006912 int raf = RadioAccessFamily.RAF_UNKNOWN;
Jeff Davidson913390f2018-02-23 17:11:49 -08006913 if (phone == null) {
chen xub97461a2018-10-26 14:17:57 -07006914 return raf;
Jeff Davidson913390f2018-02-23 17:11:49 -08006915 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006916 final long identity = Binder.clearCallingIdentity();
6917 try {
chen xub97461a2018-10-26 14:17:57 -07006918 TelephonyPermissions
6919 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
6920 mApp, phone.getSubId(), "getRadioAccessFamily");
6921 raf = ProxyController.getInstance().getRadioAccessFamily(phoneId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006922 } finally {
6923 Binder.restoreCallingIdentity(identity);
6924 }
chen xub97461a2018-10-26 14:17:57 -07006925 return raf;
Wink Saville5d475dd2014-10-17 15:00:58 -07006926 }
Andrew Leedf14ead2014-10-17 14:22:52 -07006927
6928 @Override
6929 public void enableVideoCalling(boolean enable) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006930 final Phone defaultPhone = getDefaultPhone();
Andrew Leedf14ead2014-10-17 14:22:52 -07006931 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006932
6933 final long identity = Binder.clearCallingIdentity();
6934 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006935 ImsManager.getInstance(defaultPhone.getContext(),
6936 defaultPhone.getPhoneId()).setVtSetting(enable);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006937 } finally {
6938 Binder.restoreCallingIdentity(identity);
6939 }
Andrew Leedf14ead2014-10-17 14:22:52 -07006940 }
6941
6942 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006943 public boolean isVideoCallingEnabled(String callingPackage, String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006944 final Phone defaultPhone = getDefaultPhone();
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006945 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
6946 callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
Amit Mahajan578e53d2018-03-20 16:18:38 +00006947 return false;
6948 }
Svet Ganovb320e182015-04-16 12:30:10 -07006949
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006950 final long identity = Binder.clearCallingIdentity();
6951 try {
6952 // Check the user preference and the system-level IMS setting. Even if the user has
6953 // enabled video calling, if IMS is disabled we aren't able to support video calling.
6954 // In the long run, we may instead need to check if there exists a connection service
6955 // which can support video calling.
6956 ImsManager imsManager =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006957 ImsManager.getInstance(defaultPhone.getContext(), defaultPhone.getPhoneId());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006958 return imsManager.isVtEnabledByPlatform()
6959 && imsManager.isEnhanced4gLteModeSettingEnabledByUser()
6960 && imsManager.isVtEnabledByUser();
6961 } finally {
6962 Binder.restoreCallingIdentity(identity);
6963 }
Andrew Leedf14ead2014-10-17 14:22:52 -07006964 }
Libin.Tang@motorola.comafe82642014-12-18 13:27:53 -06006965
Andrew Leea1239f22015-03-02 17:44:07 -08006966 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006967 public boolean canChangeDtmfToneLength(int subId, String callingPackage,
6968 String callingFeatureId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006969 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006970 mApp, subId, callingPackage, callingFeatureId,
6971 "isVideoCallingEnabled")) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006972 return false;
6973 }
6974
6975 final long identity = Binder.clearCallingIdentity();
6976 try {
6977 CarrierConfigManager configManager =
6978 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006979 return configManager.getConfigForSubId(subId)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006980 .getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL);
6981 } finally {
6982 Binder.restoreCallingIdentity(identity);
6983 }
Andrew Leea1239f22015-03-02 17:44:07 -08006984 }
6985
6986 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006987 public boolean isWorldPhone(int subId, String callingPackage, String callingFeatureId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006988 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006989 mApp, subId, callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006990 return false;
6991 }
6992
6993 final long identity = Binder.clearCallingIdentity();
6994 try {
6995 CarrierConfigManager configManager =
6996 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006997 return configManager.getConfigForSubId(subId)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006998 .getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL);
6999 } finally {
7000 Binder.restoreCallingIdentity(identity);
7001 }
Andrew Leea1239f22015-03-02 17:44:07 -08007002 }
7003
Andrew Lee9431b832015-03-09 18:46:45 -07007004 @Override
7005 public boolean isTtyModeSupported() {
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07007006 TelecomManager telecomManager = mApp.getSystemService(TelecomManager.class);
Wooki Wu1f82f7a2016-02-15 15:59:58 +08007007 return telecomManager.isTtySupported();
Andrew Lee9431b832015-03-09 18:46:45 -07007008 }
7009
7010 @Override
7011 public boolean isHearingAidCompatibilitySupported() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007012 final long identity = Binder.clearCallingIdentity();
7013 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007014 return mApp.getResources().getBoolean(R.bool.hac_enabled);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007015 } finally {
7016 Binder.restoreCallingIdentity(identity);
7017 }
Andrew Lee9431b832015-03-09 18:46:45 -07007018 }
7019
Hall Liuf6668912018-10-31 17:05:23 -07007020 /**
7021 * Determines whether the device currently supports RTT (Real-time text). Based both on carrier
7022 * support for the feature and device firmware support.
7023 *
7024 * @return {@code true} if the device and carrier both support RTT, {@code false} otherwise.
7025 */
7026 @Override
7027 public boolean isRttSupported(int subscriptionId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007028 final long identity = Binder.clearCallingIdentity();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007029 final Phone phone = getPhone(subscriptionId);
7030 if (phone == null) {
7031 loge("isRttSupported: no Phone found. Invalid subId:" + subscriptionId);
7032 return false;
7033 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007034 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007035 boolean isCarrierSupported = mApp.getCarrierConfigForSubId(subscriptionId).getBoolean(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007036 CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
7037 boolean isDeviceSupported =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007038 phone.getContext().getResources().getBoolean(R.bool.config_support_rtt);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007039 return isCarrierSupported && isDeviceSupported;
7040 } finally {
7041 Binder.restoreCallingIdentity(identity);
7042 }
Hall Liu98187582018-01-22 19:15:32 -08007043 }
7044
Hall Liuf6668912018-10-31 17:05:23 -07007045 /**
Hall Liuf2daa022019-07-23 18:39:00 -07007046 * Determines whether the user has turned on RTT. If the carrier wants to ignore the user-set
7047 * RTT setting, will return true if the device and carrier both support RTT.
7048 * Otherwise. only returns true if the device and carrier both also support RTT.
Hall Liuf6668912018-10-31 17:05:23 -07007049 */
7050 public boolean isRttEnabled(int subscriptionId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007051 final long identity = Binder.clearCallingIdentity();
7052 try {
Hall Liu5bab75c2019-12-11 23:58:20 +00007053 boolean isRttSupported = isRttSupported(subscriptionId);
7054 boolean isUserRttSettingOn = Settings.Secure.getInt(
7055 mApp.getContentResolver(), Settings.Secure.RTT_CALLING_MODE, 0) != 0;
7056 boolean shouldIgnoreUserRttSetting = mApp.getCarrierConfigForSubId(subscriptionId)
7057 .getBoolean(CarrierConfigManager.KEY_IGNORE_RTT_MODE_SETTING_BOOL);
7058 return isRttSupported && (isUserRttSettingOn || shouldIgnoreUserRttSetting);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007059 } finally {
7060 Binder.restoreCallingIdentity(identity);
7061 }
Hall Liu3ad5f012018-04-06 16:23:39 -07007062 }
7063
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007064 @Deprecated
7065 @Override
7066 public String getDeviceId(String callingPackage) {
7067 return getDeviceIdWithFeature(callingPackage, null);
7068 }
7069
Sanket Padawe7310cc72015-01-14 09:53:20 -08007070 /**
7071 * Returns the unique device ID of phone, for example, the IMEI for
7072 * GSM and the MEID for CDMA phones. Return null if device ID is not available.
7073 *
7074 * <p>Requires Permission:
7075 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
7076 */
7077 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007078 public String getDeviceIdWithFeature(String callingPackage, String callingFeatureId) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08007079 final Phone phone = PhoneFactory.getPhone(0);
Jeff Davidson913390f2018-02-23 17:11:49 -08007080 if (phone == null) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08007081 return null;
7082 }
Jeff Davidson913390f2018-02-23 17:11:49 -08007083 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07007084 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007085 callingPackage, callingFeatureId, "getDeviceId")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08007086 return null;
7087 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007088
7089 final long identity = Binder.clearCallingIdentity();
7090 try {
7091 return phone.getDeviceId();
7092 } finally {
7093 Binder.restoreCallingIdentity(identity);
7094 }
Sanket Padawe7310cc72015-01-14 09:53:20 -08007095 }
7096
Ping Sunc67b7c22016-03-02 19:16:45 +08007097 /**
7098 * {@hide}
7099 * Returns the IMS Registration Status on a particular subid
7100 *
7101 * @param subId
7102 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007103 public boolean isImsRegistered(int subId) {
Ping Sunc67b7c22016-03-02 19:16:45 +08007104 Phone phone = getPhone(subId);
7105 if (phone != null) {
7106 return phone.isImsRegistered();
7107 } else {
7108 return false;
7109 }
7110 }
7111
Santos Cordon7a1885b2015-02-03 11:15:19 -08007112 @Override
7113 public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007114 final long identity = Binder.clearCallingIdentity();
7115 try {
7116 return PhoneUtils.getSubIdForPhoneAccount(phoneAccount);
7117 } finally {
7118 Binder.restoreCallingIdentity(identity);
7119 }
Santos Cordon7a1885b2015-02-03 11:15:19 -08007120 }
Nathan Harolddcfc7932015-03-18 10:01:20 -07007121
Tyler Gunnf70ed162019-04-03 15:28:53 -07007122 @Override
Shuo Qian6e6137d2019-10-30 16:33:31 -07007123 public int getSubIdForPhoneAccountHandle(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007124 PhoneAccountHandle phoneAccountHandle, String callingPackage, String callingFeatureId) {
Shuo Qian6e6137d2019-10-30 16:33:31 -07007125 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, getDefaultSubscription(),
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007126 callingPackage, callingFeatureId, "getSubIdForPhoneAccountHandle")) {
Shuo Qian6e6137d2019-10-30 16:33:31 -07007127 throw new SecurityException("Requires READ_PHONE_STATE permission.");
7128 }
7129 final long identity = Binder.clearCallingIdentity();
7130 try {
7131 return PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle);
7132 } finally {
7133 Binder.restoreCallingIdentity(identity);
7134 }
7135 }
7136
7137 @Override
Tyler Gunnf70ed162019-04-03 15:28:53 -07007138 public @Nullable PhoneAccountHandle getPhoneAccountHandleForSubscriptionId(int subscriptionId) {
duki.hongfd96bde2020-07-22 17:32:19 +09007139 enforceReadPrivilegedPermission("getPhoneAccountHandleForSubscriptionId, "
7140 + "subscriptionId: " + subscriptionId);
Tyler Gunnf70ed162019-04-03 15:28:53 -07007141 final long identity = Binder.clearCallingIdentity();
7142 try {
7143 Phone phone = getPhone(subscriptionId);
7144 if (phone == null) {
7145 return null;
7146 }
7147 return PhoneUtils.makePstnPhoneAccountHandle(phone);
7148 } finally {
7149 Binder.restoreCallingIdentity(identity);
7150 }
7151 }
7152
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007153 /**
7154 * @return the VoWiFi calling availability.
Nathan Haroldc55097a2015-03-11 18:14:50 -07007155 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007156 public boolean isWifiCallingAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007157 final long identity = Binder.clearCallingIdentity();
7158 try {
7159 Phone phone = getPhone(subId);
7160 if (phone != null) {
7161 return phone.isWifiCallingEnabled();
7162 } else {
7163 return false;
7164 }
7165 } finally {
7166 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007167 }
Nathan Haroldc55097a2015-03-11 18:14:50 -07007168 }
7169
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007170 /**
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007171 * @return the VT calling availability.
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07007172 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007173 public boolean isVideoTelephonyAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007174 final long identity = Binder.clearCallingIdentity();
7175 try {
7176 Phone phone = getPhone(subId);
7177 if (phone != null) {
7178 return phone.isVideoEnabled();
7179 } else {
7180 return false;
7181 }
7182 } finally {
7183 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007184 }
7185 }
7186
7187 /**
7188 * @return the IMS registration technology for the MMTEL feature. Valid return values are
7189 * defined in {@link ImsRegistrationImplBase}.
7190 */
7191 public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007192 final long identity = Binder.clearCallingIdentity();
7193 try {
7194 Phone phone = getPhone(subId);
7195 if (phone != null) {
7196 return phone.getImsRegistrationTech();
7197 } else {
7198 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
7199 }
7200 } finally {
7201 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007202 }
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07007203 }
7204
Stuart Scott8eef64f2015-04-08 15:13:54 -07007205 @Override
7206 public void factoryReset(int subId) {
paulhu5a773602019-08-23 19:17:33 +08007207 enforceSettingsPermission();
Stuart Scott981d8582015-04-21 14:09:50 -07007208 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
7209 return;
7210 }
7211
Svet Ganovcc087f82015-05-12 20:35:54 -07007212 final long identity = Binder.clearCallingIdentity();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007213
Svet Ganovcc087f82015-05-12 20:35:54 -07007214 try {
Stuart Scott981d8582015-04-21 14:09:50 -07007215 if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
7216 UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07007217 setDataEnabledForReason(subId, TelephonyManager.DATA_ENABLED_REASON_USER,
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007218 getDefaultDataEnabled());
Svet Ganovcc087f82015-05-12 20:35:54 -07007219 setNetworkSelectionModeAutomatic(subId);
Pengquan Meng85728fb2018-03-12 16:31:21 -07007220 setPreferredNetworkType(subId, getDefaultNetworkType(subId));
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007221 setDataRoamingEnabled(subId, getDefaultDataRoamingEnabled(subId));
7222 CarrierInfoManager.deleteAllCarrierKeysForImsiEncryption(mApp);
Svet Ganovcc087f82015-05-12 20:35:54 -07007223 }
Amit Mahajan7dbbd822019-03-13 17:33:47 -07007224 // There has been issues when Sms raw table somehow stores orphan
7225 // fragments. They lead to garbled message when new fragments come
7226 // in and combined with those stale ones. In case this happens again,
7227 // user can reset all network settings which will clean up this table.
7228 cleanUpSmsRawTable(getDefaultPhone().getContext());
Brad Ebingerbc7dd582019-10-17 17:03:22 -07007229 // Clean up IMS settings as well here.
7230 int slotId = getSlotIndex(subId);
7231 if (slotId > SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
7232 ImsManager.getInstance(mApp, slotId).factoryReset();
7233 }
Naina Nallurid63128d2019-09-17 14:10:30 -07007234
7235 // Erase modem config if erase modem on network setting is enabled.
7236 String configValue = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_TELEPHONY,
7237 RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED);
7238 if (configValue != null && Boolean.parseBoolean(configValue)) {
7239 sendEraseModemConfig(getDefaultPhone());
7240 }
Svet Ganovcc087f82015-05-12 20:35:54 -07007241 } finally {
7242 Binder.restoreCallingIdentity(identity);
Stuart Scott8eef64f2015-04-08 15:13:54 -07007243 }
7244 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01007245
Amit Mahajan7dbbd822019-03-13 17:33:47 -07007246 private void cleanUpSmsRawTable(Context context) {
7247 ContentResolver resolver = context.getContentResolver();
7248 Uri uri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete");
7249 resolver.delete(uri, null, null);
7250 }
7251
Narayan Kamath1c496c22015-04-16 14:40:19 +01007252 @Override
chen xu5d3637b2019-01-21 23:31:38 -08007253 public String getSimLocaleForSubscriber(int subId) {
7254 enforceReadPrivilegedPermission("getSimLocaleForSubscriber, subId: " + subId);
7255 final Phone phone = getPhone(subId);
7256 if (phone == null) {
7257 log("getSimLocaleForSubscriber, invalid subId");
chen xu2bb91e42019-01-24 14:35:54 -08007258 return null;
chen xu5d3637b2019-01-21 23:31:38 -08007259 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007260 final long identity = Binder.clearCallingIdentity();
7261 try {
chen xu5d3637b2019-01-21 23:31:38 -08007262 final SubscriptionInfo info = mSubscriptionController.getActiveSubscriptionInfo(subId,
Philip P. Moltmann8d34f0c2020-03-05 16:24:02 -08007263 phone.getContext().getOpPackageName(), phone.getContext().getAttributionTag());
chen xu6291c472019-02-04 12:55:53 -08007264 if (info == null) {
7265 log("getSimLocaleForSubscriber, inactive subId: " + subId);
7266 return null;
7267 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007268 // Try and fetch the locale from the carrier properties or from the SIM language
7269 // preferences (EF-PL and EF-LI)...
7270 final int mcc = info.getMcc();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007271 String simLanguage = null;
chen xu5d3637b2019-01-21 23:31:38 -08007272 final Locale localeFromDefaultSim = phone.getLocaleFromSimAndCarrierPrefs();
7273 if (localeFromDefaultSim != null) {
7274 if (!localeFromDefaultSim.getCountry().isEmpty()) {
7275 if (DBG) log("Using locale from subId: " + subId + " locale: "
7276 + localeFromDefaultSim);
7277 return localeFromDefaultSim.toLanguageTag();
7278 } else {
7279 simLanguage = localeFromDefaultSim.getLanguage();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007280 }
7281 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01007282
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007283 // The SIM language preferences only store a language (e.g. fr = French), not an
7284 // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
7285 // the SIM and carrier preferences does not include a country we add the country
7286 // determined from the SIM MCC to provide an exact locale.
zoey chenc730df82019-12-18 17:07:20 +08007287 final Locale mccLocale = LocaleUtils.getLocaleFromMcc(mApp, mcc, simLanguage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007288 if (mccLocale != null) {
chen xu5d3637b2019-01-21 23:31:38 -08007289 if (DBG) log("No locale from SIM, using mcc locale:" + mccLocale);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007290 return mccLocale.toLanguageTag();
7291 }
7292
7293 if (DBG) log("No locale found - returning null");
7294 return null;
7295 } finally {
7296 Binder.restoreCallingIdentity(identity);
7297 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01007298 }
7299
7300 private List<SubscriptionInfo> getAllSubscriptionInfoList() {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007301 return mSubscriptionController.getAllSubInfoList(mApp.getOpPackageName(),
Philip P. Moltmann8d34f0c2020-03-05 16:24:02 -08007302 mApp.getAttributionTag());
Narayan Kamath1c496c22015-04-16 14:40:19 +01007303 }
7304
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007305 /**
7306 * NOTE: this method assumes permission checks are done and caller identity has been cleared.
7307 */
7308 private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007309 return mSubscriptionController.getActiveSubscriptionInfoList(mApp.getOpPackageName(),
Philip P. Moltmann8d34f0c2020-03-05 16:24:02 -08007310 mApp.getAttributionTag());
Narayan Kamath1c496c22015-04-16 14:40:19 +01007311 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07007312
Chenjie Yu1ba97252018-01-11 18:16:20 -08007313 private final ModemActivityInfo mLastModemActivityInfo =
Hall Liu49656c02020-10-09 19:00:11 -07007314 new ModemActivityInfo(0, 0, 0, new int[ModemActivityInfo.getNumTxPowerLevels()], 0);
Chenjie Yu1ba97252018-01-11 18:16:20 -08007315
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07007316 /**
Adam Lesinski903a54c2016-04-11 14:49:52 -07007317 * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
7318 * representing the state of the modem.
7319 *
Chenjie Yu1ba97252018-01-11 18:16:20 -08007320 * NOTE: The underlying implementation clears the modem state, so there should only ever be one
7321 * caller to it. Everyone should call this class to get cumulative data.
Adam Lesinski903a54c2016-04-11 14:49:52 -07007322 * @hide
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07007323 */
7324 @Override
Adam Lesinski903a54c2016-04-11 14:49:52 -07007325 public void requestModemActivityInfo(ResultReceiver result) {
7326 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07007327 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007328
7329 final long identity = Binder.clearCallingIdentity();
7330 try {
Shuo Qian8f4750a2020-02-20 17:12:10 -08007331 sendRequestAsync(CMD_GET_MODEM_ACTIVITY_INFO, result, null, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007332 } finally {
7333 Binder.restoreCallingIdentity(identity);
Chenjie Yu1ba97252018-01-11 18:16:20 -08007334 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07007335 }
Jack Yu85bd38a2015-11-09 11:34:32 -08007336
Siddharth Rayb8114062018-06-17 15:02:38 -07007337 // Checks that ModemActivityInfo is valid. Sleep time, Idle time, Rx time and Tx time should be
7338 // less than total activity duration.
7339 private boolean isModemActivityInfoValid(ModemActivityInfo info) {
7340 if (info == null) {
7341 return false;
7342 }
7343 int activityDurationMs =
Hall Liu49656c02020-10-09 19:00:11 -07007344 (int) (info.getTimestampMillis() - mLastModemActivityInfo.getTimestampMillis());
7345 int totalTxTimeMs = Arrays.stream(info.getTransmitTimeMillis()).sum();
7346
Siddharth Rayb8114062018-06-17 15:02:38 -07007347 return (info.isValid()
7348 && (info.getSleepTimeMillis() <= activityDurationMs)
7349 && (info.getIdleTimeMillis() <= activityDurationMs)
Chen Xud78231e2019-09-10 18:49:52 -07007350 && (info.getReceiveTimeMillis() <= activityDurationMs)
Siddharth Rayb8114062018-06-17 15:02:38 -07007351 && (totalTxTimeMs <= activityDurationMs));
7352 }
7353
Jack Yu85bd38a2015-11-09 11:34:32 -08007354 /**
7355 * {@hide}
7356 * Returns the service state information on specified subscription.
7357 */
7358 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07007359 public ServiceState getServiceStateForSubscriber(int subId, String callingPackage,
7360 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08007361 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007362 mApp, subId, callingPackage, callingFeatureId, "getServiceStateForSubscriber")) {
Jack Yu85bd38a2015-11-09 11:34:32 -08007363 return null;
7364 }
7365
Hall Liuf19c44f2018-11-27 14:38:17 -08007366 LocationAccessPolicy.LocationPermissionResult fineLocationResult =
7367 LocationAccessPolicy.checkLocationPermission(mApp,
7368 new LocationAccessPolicy.LocationPermissionQuery.Builder()
7369 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07007370 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08007371 .setCallingPid(Binder.getCallingPid())
7372 .setCallingUid(Binder.getCallingUid())
7373 .setMethod("getServiceStateForSubscriber")
Hall Liuf18a0cf2019-04-17 13:37:11 -07007374 .setLogAsInfo(true)
Hall Liuf19c44f2018-11-27 14:38:17 -08007375 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
Hall Liuc4a3e422020-05-26 17:18:03 -07007376 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
7377 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
Hall Liuf19c44f2018-11-27 14:38:17 -08007378 .build());
7379
7380 LocationAccessPolicy.LocationPermissionResult coarseLocationResult =
7381 LocationAccessPolicy.checkLocationPermission(mApp,
7382 new LocationAccessPolicy.LocationPermissionQuery.Builder()
7383 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07007384 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08007385 .setCallingPid(Binder.getCallingPid())
7386 .setCallingUid(Binder.getCallingUid())
7387 .setMethod("getServiceStateForSubscriber")
Hall Liuf18a0cf2019-04-17 13:37:11 -07007388 .setLogAsInfo(true)
Hall Liuf19c44f2018-11-27 14:38:17 -08007389 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
Hall Liuc4a3e422020-05-26 17:18:03 -07007390 .setMinSdkVersionForFine(Integer.MAX_VALUE)
7391 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
Hall Liuf19c44f2018-11-27 14:38:17 -08007392 .build());
7393 // We don't care about hard or soft here -- all we need to know is how much info to scrub.
7394 boolean hasFinePermission =
7395 fineLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
7396 boolean hasCoarsePermission =
7397 coarseLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
7398
Jack Yu479f40e2020-10-27 21:29:25 -07007399 final Phone phone = getPhone(subId);
7400 if (phone == null) {
7401 return null;
7402 }
7403
Jordan Liu0f2bc442020-11-18 16:47:37 -08007404 final long identity = Binder.clearCallingIdentity();
7405
Jack Yu479f40e2020-10-27 21:29:25 -07007406 boolean isCallingPackageDataService = phone.getDataServicePackages()
7407 .contains(callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007408 try {
Jordan Liuc437b192020-08-17 10:59:12 -07007409 // isActiveSubId requires READ_PHONE_STATE, which we already check for above
7410 if (!mSubscriptionController.isActiveSubId(subId, callingPackage, callingFeatureId)) {
7411 Rlog.d(LOG_TAG,
7412 "getServiceStateForSubscriber returning null for inactive subId=" + subId);
7413 return null;
7414 }
7415
Hall Liuf19c44f2018-11-27 14:38:17 -08007416 ServiceState ss = phone.getServiceState();
7417
7418 // Scrub out the location info in ServiceState depending on what level of access
7419 // the caller has.
Jack Yu479f40e2020-10-27 21:29:25 -07007420 if (hasFinePermission || isCallingPackageDataService) return ss;
Malcolm Chen5052de62019-12-30 13:56:38 -08007421 if (hasCoarsePermission) return ss.createLocationInfoSanitizedCopy(false);
7422 return ss.createLocationInfoSanitizedCopy(true);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007423 } finally {
7424 Binder.restoreCallingIdentity(identity);
7425 }
Jack Yu85bd38a2015-11-09 11:34:32 -08007426 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08007427
7428 /**
7429 * Returns the URI for the per-account voicemail ringtone set in Phone settings.
7430 *
7431 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
7432 * voicemail ringtone.
7433 * @return The URI for the ringtone to play when receiving a voicemail from a specific
7434 * PhoneAccount.
7435 */
7436 @Override
7437 public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007438 final long identity = Binder.clearCallingIdentity();
7439 try {
7440 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
7441 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007442 phone = getDefaultPhone();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007443 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08007444
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007445 return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext());
7446 } finally {
7447 Binder.restoreCallingIdentity(identity);
7448 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08007449 }
7450
7451 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08007452 * Sets the per-account voicemail ringtone.
7453 *
7454 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
7455 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
7456 *
7457 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
7458 * voicemail ringtone.
7459 * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
7460 * PhoneAccount.
7461 */
7462 @Override
7463 public void setVoicemailRingtoneUri(String callingPackage,
7464 PhoneAccountHandle phoneAccountHandle, Uri uri) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007465 final Phone defaultPhone = getDefaultPhone();
Ta-wei Yenc33877d2017-01-23 18:11:21 -08007466 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07007467 TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
7468 if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08007469 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7470 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
7471 "setVoicemailRingtoneUri");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08007472 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007473
7474 final long identity = Binder.clearCallingIdentity();
7475 try {
7476 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
7477 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007478 phone = defaultPhone;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007479 }
7480 VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri);
7481 } finally {
7482 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08007483 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08007484 }
7485
7486 /**
Nancy Chen31f9ba12016-01-06 11:42:12 -08007487 * Returns whether vibration is set for voicemail notification in Phone settings.
7488 *
7489 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
7490 * voicemail vibration setting.
7491 * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
7492 */
7493 @Override
7494 public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007495 final long identity = Binder.clearCallingIdentity();
7496 try {
7497 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
7498 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007499 phone = getDefaultPhone();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007500 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08007501
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007502 return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext());
7503 } finally {
7504 Binder.restoreCallingIdentity(identity);
7505 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08007506 }
7507
Youhan Wange64578a2016-05-02 15:32:42 -07007508 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08007509 * Sets the per-account voicemail vibration.
7510 *
7511 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
7512 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
7513 *
7514 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
7515 * voicemail vibration setting.
7516 * @param enabled Whether to enable or disable vibration for voicemail notifications from a
7517 * specific PhoneAccount.
7518 */
7519 @Override
7520 public void setVoicemailVibrationEnabled(String callingPackage,
7521 PhoneAccountHandle phoneAccountHandle, boolean enabled) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007522 final Phone defaultPhone = getDefaultPhone();
Ta-wei Yenc33877d2017-01-23 18:11:21 -08007523 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07007524 TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
7525 if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08007526 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7527 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
7528 "setVoicemailVibrationEnabled");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08007529 }
7530
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007531 final long identity = Binder.clearCallingIdentity();
7532 try {
7533 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
7534 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007535 phone = defaultPhone;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007536 }
7537 VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled);
7538 } finally {
7539 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08007540 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08007541 }
7542
7543 /**
Youhan Wange64578a2016-05-02 15:32:42 -07007544 * Make sure either called from same process as self (phone) or IPC caller has read privilege.
7545 *
7546 * @throws SecurityException if the caller does not have the required permission
7547 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07007548 private void enforceReadPrivilegedPermission(String message) {
Youhan Wange64578a2016-05-02 15:32:42 -07007549 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
Brad Ebinger35c841c2018-10-01 10:40:55 -07007550 message);
Youhan Wange64578a2016-05-02 15:32:42 -07007551 }
7552
7553 /**
Ta-wei Yen30a69c82016-12-27 14:52:32 -08007554 * Make sure either called from same process as self (phone) or IPC caller has send SMS
7555 * permission.
7556 *
7557 * @throws SecurityException if the caller does not have the required permission
7558 */
7559 private void enforceSendSmsPermission() {
7560 mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null);
7561 }
7562
7563 /**
Ta-wei Yen527a9c02017-01-06 15:29:25 -08007564 * Make sure called from the package in charge of visual voicemail.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08007565 *
Ta-wei Yen527a9c02017-01-06 15:29:25 -08007566 * @throws SecurityException if the caller is not the visual voicemail package.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08007567 */
Ta-wei Yen527a9c02017-01-06 15:29:25 -08007568 private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007569 final long identity = Binder.clearCallingIdentity();
7570 try {
7571 ComponentName componentName =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007572 RemoteVvmTaskManager.getRemotePackage(mApp, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007573 if (componentName == null) {
7574 throw new SecurityException(
7575 "Caller not current active visual voicemail package[null]");
7576 }
7577 String vvmPackage = componentName.getPackageName();
7578 if (!callingPackage.equals(vvmPackage)) {
7579 throw new SecurityException("Caller not current active visual voicemail package["
7580 + vvmPackage + "]");
7581 }
7582 } finally {
7583 Binder.restoreCallingIdentity(identity);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08007584 }
7585 }
7586
7587 /**
Youhan Wange64578a2016-05-02 15:32:42 -07007588 * Return the application ID for the app type.
7589 *
7590 * @param subId the subscription ID that this request applies to.
7591 * @param appType the uicc app type.
7592 * @return Application ID for specificied app type, or null if no uicc.
7593 */
7594 @Override
7595 public String getAidForAppType(int subId, int appType) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07007596 enforceReadPrivilegedPermission("getAidForAppType");
Youhan Wange64578a2016-05-02 15:32:42 -07007597 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007598
7599 final long identity = Binder.clearCallingIdentity();
Youhan Wange64578a2016-05-02 15:32:42 -07007600 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007601 if (phone == null) {
7602 return null;
7603 }
7604 String aid = null;
7605 try {
7606 aid = UiccController.getInstance().getUiccCard(phone.getPhoneId())
7607 .getApplicationByType(appType).getAid();
7608 } catch (Exception e) {
7609 Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e);
7610 }
7611 return aid;
7612 } finally {
7613 Binder.restoreCallingIdentity(identity);
Youhan Wange64578a2016-05-02 15:32:42 -07007614 }
Youhan Wange64578a2016-05-02 15:32:42 -07007615 }
7616
Youhan Wang4001d252016-05-11 10:29:41 -07007617 /**
7618 * Return the Electronic Serial Number.
7619 *
7620 * @param subId the subscription ID that this request applies to.
7621 * @return ESN or null if error.
7622 */
7623 @Override
7624 public String getEsn(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07007625 enforceReadPrivilegedPermission("getEsn");
Youhan Wang4001d252016-05-11 10:29:41 -07007626 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007627
7628 final long identity = Binder.clearCallingIdentity();
Youhan Wang4001d252016-05-11 10:29:41 -07007629 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007630 if (phone == null) {
7631 return null;
7632 }
7633 String esn = null;
7634 try {
7635 esn = phone.getEsn();
7636 } catch (Exception e) {
7637 Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e);
7638 }
7639 return esn;
7640 } finally {
7641 Binder.restoreCallingIdentity(identity);
Youhan Wang4001d252016-05-11 10:29:41 -07007642 }
Youhan Wang4001d252016-05-11 10:29:41 -07007643 }
7644
Sanket Padawe99ef1e32016-05-18 16:12:33 -07007645 /**
Youhan Wang66ad5d72016-07-18 17:56:58 -07007646 * Return the Preferred Roaming List Version.
7647 *
7648 * @param subId the subscription ID that this request applies to.
7649 * @return PRLVersion or null if error.
7650 */
7651 @Override
7652 public String getCdmaPrlVersion(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07007653 enforceReadPrivilegedPermission("getCdmaPrlVersion");
Youhan Wang66ad5d72016-07-18 17:56:58 -07007654 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007655
7656 final long identity = Binder.clearCallingIdentity();
Youhan Wang66ad5d72016-07-18 17:56:58 -07007657 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007658 if (phone == null) {
7659 return null;
7660 }
7661 String cdmaPrlVersion = null;
7662 try {
7663 cdmaPrlVersion = phone.getCdmaPrlVersion();
7664 } catch (Exception e) {
7665 Log.e(LOG_TAG, "Not getting PRLVersion", e);
7666 }
7667 return cdmaPrlVersion;
7668 } finally {
7669 Binder.restoreCallingIdentity(identity);
Youhan Wang66ad5d72016-07-18 17:56:58 -07007670 }
Youhan Wang66ad5d72016-07-18 17:56:58 -07007671 }
7672
7673 /**
Sanket Padawe99ef1e32016-05-18 16:12:33 -07007674 * Get snapshot of Telephony histograms
7675 * @return List of Telephony histograms
7676 * @hide
7677 */
7678 @Override
7679 public List<TelephonyHistogram> getTelephonyHistograms() {
Jeff Davidson7e17e312018-02-13 18:17:36 -08007680 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7681 mApp, getDefaultSubscription(), "getTelephonyHistograms");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007682
7683 final long identity = Binder.clearCallingIdentity();
7684 try {
7685 return RIL.getTelephonyRILTimingHistograms();
7686 } finally {
7687 Binder.restoreCallingIdentity(identity);
7688 }
Sanket Padawe99ef1e32016-05-18 16:12:33 -07007689 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07007690
7691 /**
7692 * {@hide}
Michele Berionne482f8202018-11-27 18:57:59 -08007693 * Set the allowed carrier list and the excluded carrier list, indicating the priority between
7694 * the two lists.
Meng Wang1a7c35a2016-05-05 20:56:15 -07007695 * Require system privileges. In the future we may add this to carrier APIs.
7696 *
Michele Berionne482f8202018-11-27 18:57:59 -08007697 * @return Integer with the result of the operation, as defined in {@link TelephonyManager}.
Meng Wang1a7c35a2016-05-05 20:56:15 -07007698 */
7699 @Override
Michele Berionne482f8202018-11-27 18:57:59 -08007700 @TelephonyManager.SetCarrierRestrictionResult
7701 public int setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules) {
Meng Wang1a7c35a2016-05-05 20:56:15 -07007702 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07007703 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Sanket Padawe13bac7b2017-03-20 15:04:47 -07007704
Michele Berionne482f8202018-11-27 18:57:59 -08007705 if (carrierRestrictionRules == null) {
7706 throw new NullPointerException("carrier restriction cannot be null");
Meng Wang9b7c4e92017-02-17 11:41:27 -08007707 }
Sanket Padawe13bac7b2017-03-20 15:04:47 -07007708
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007709 final long identity = Binder.clearCallingIdentity();
7710 try {
Michele Berionne482f8202018-11-27 18:57:59 -08007711 return (int) sendRequest(CMD_SET_ALLOWED_CARRIERS, carrierRestrictionRules,
vagdeviaf9a5b92018-08-15 16:01:53 -07007712 workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007713 } finally {
7714 Binder.restoreCallingIdentity(identity);
7715 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07007716 }
7717
7718 /**
7719 * {@hide}
Michele Berionne482f8202018-11-27 18:57:59 -08007720 * Get the allowed carrier list and the excluded carrier list, including the priority between
7721 * the two lists.
Meng Wang1a7c35a2016-05-05 20:56:15 -07007722 * Require system privileges. In the future we may add this to carrier APIs.
7723 *
Michele Berionne482f8202018-11-27 18:57:59 -08007724 * @return {@link android.telephony.CarrierRestrictionRules}
Meng Wang1a7c35a2016-05-05 20:56:15 -07007725 */
7726 @Override
Michele Berionne482f8202018-11-27 18:57:59 -08007727 public CarrierRestrictionRules getAllowedCarriers() {
Brad Ebinger35c841c2018-10-01 10:40:55 -07007728 enforceReadPrivilegedPermission("getAllowedCarriers");
vagdeviaf9a5b92018-08-15 16:01:53 -07007729 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007730
7731 final long identity = Binder.clearCallingIdentity();
7732 try {
Michele Berionne482f8202018-11-27 18:57:59 -08007733 Object response = sendRequest(CMD_GET_ALLOWED_CARRIERS, null, workSource);
7734 if (response instanceof CarrierRestrictionRules) {
7735 return (CarrierRestrictionRules) response;
7736 }
7737 // Response is an Exception of some kind,
7738 // which is signalled to the user as a NULL retval
7739 return null;
7740 } catch (Exception e) {
7741 Log.e(LOG_TAG, "getAllowedCarriers. Exception ex=" + e);
7742 return null;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007743 } finally {
7744 Binder.restoreCallingIdentity(identity);
7745 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07007746 }
7747
fionaxu59545b42016-05-25 15:53:37 -07007748 /**
fionaxu59545b42016-05-25 15:53:37 -07007749 * Action set from carrier signalling broadcast receivers to enable/disable radio
7750 * @param subId the subscription ID that this action applies to.
7751 * @param enabled control enable or disable radio.
7752 * {@hide}
7753 */
7754 @Override
7755 public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
7756 enforceModifyPermission();
7757 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007758
7759 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07007760 if (phone == null) {
7761 loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
7762 return;
7763 }
7764 try {
7765 phone.carrierActionSetRadioEnabled(enabled);
7766 } catch (Exception e) {
7767 Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007768 } finally {
7769 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07007770 }
7771 }
7772
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07007773 /**
fionaxu8da9cb12017-05-23 15:02:46 -07007774 * Action set from carrier signalling broadcast receivers to start/stop reporting the default
7775 * network status based on which carrier apps could apply actions accordingly,
7776 * enable/disable default url handler for example.
7777 *
7778 * @param subId the subscription ID that this action applies to.
7779 * @param report control start/stop reporting the default network status.
7780 * {@hide}
7781 */
7782 @Override
7783 public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
7784 enforceModifyPermission();
7785 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007786
7787 final long identity = Binder.clearCallingIdentity();
fionaxu8da9cb12017-05-23 15:02:46 -07007788 if (phone == null) {
7789 loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId);
7790 return;
7791 }
7792 try {
7793 phone.carrierActionReportDefaultNetworkStatus(report);
7794 } catch (Exception e) {
7795 Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007796 } finally {
7797 Binder.restoreCallingIdentity(identity);
fionaxu8da9cb12017-05-23 15:02:46 -07007798 }
7799 }
7800
7801 /**
fionaxud9622282017-07-17 17:51:30 -07007802 * Action set from carrier signalling broadcast receivers to reset all carrier actions
7803 * @param subId the subscription ID that this action applies to.
7804 * {@hide}
7805 */
7806 @Override
7807 public void carrierActionResetAll(int subId) {
7808 enforceModifyPermission();
7809 final Phone phone = getPhone(subId);
7810 if (phone == null) {
7811 loge("carrierAction: ResetAll fails with invalid sibId: " + subId);
7812 return;
7813 }
7814 try {
7815 phone.carrierActionResetAll();
7816 } catch (Exception e) {
7817 Log.e(LOG_TAG, "carrierAction: ResetAll fails. Exception ex=" + e);
7818 }
7819 }
7820
7821 /**
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07007822 * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a
7823 * bug report is being generated.
7824 */
7825 @Override
Ta-wei Yen99282e02016-06-21 18:19:35 -07007826 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007827 if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
7828 != PackageManager.PERMISSION_GRANTED) {
dcashman22b950d2016-06-27 11:39:02 -07007829 writer.println("Permission Denial: can't dump Phone from pid="
7830 + Binder.getCallingPid()
7831 + ", uid=" + Binder.getCallingUid()
7832 + "without permission "
7833 + android.Manifest.permission.DUMP);
7834 return;
7835 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007836 DumpsysHandler.dump(mApp, fd, writer, args);
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07007837 }
Jack Yueb89b242016-06-22 13:27:47 -07007838
Brad Ebingerdac2f002018-04-03 15:17:52 -07007839 @Override
Hall Liua1548bd2019-12-24 14:14:12 -08007840 public int handleShellCommand(@NonNull ParcelFileDescriptor in,
7841 @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
7842 @NonNull String[] args) {
7843 return new TelephonyShellCommand(this, getDefaultPhone().getContext()).exec(
7844 this, in.getFileDescriptor(), out.getFileDescriptor(),
7845 err.getFileDescriptor(), args);
Brad Ebingerdac2f002018-04-03 15:17:52 -07007846 }
7847
Jack Yueb89b242016-06-22 13:27:47 -07007848 /**
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007849 * Policy control of data connection with reason {@@TelephonyManager.DataEnabledReason}
Greg Kaiser17f41752020-05-05 16:47:47 +00007850 * @param subId Subscription index
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007851 * @param reason the reason the data enable change is taking place
7852 * @param enabled True if enabling the data, otherwise disabling.
7853 * @hide
Jack Yu75ab2952016-07-08 14:29:33 -07007854 */
7855 @Override
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07007856 public void setDataEnabledForReason(int subId, @TelephonyManager.DataEnabledReason int reason,
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007857 boolean enabled) {
7858 if (reason == TelephonyManager.DATA_ENABLED_REASON_USER
7859 || reason == TelephonyManager.DATA_ENABLED_REASON_CARRIER) {
7860 try {
7861 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07007862 mApp, subId, "setDataEnabledForReason");
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007863 } catch (SecurityException se) {
7864 enforceModifyPermission();
7865 }
7866 } else {
7867 enforceModifyPermission();
7868 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007869
7870 final long identity = Binder.clearCallingIdentity();
7871 try {
7872 Phone phone = getPhone(subId);
7873 if (phone != null) {
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007874 if (reason == TelephonyManager.DATA_ENABLED_REASON_CARRIER) {
7875 phone.carrierActionSetMeteredApnsEnabled(enabled);
7876 } else {
7877 phone.getDataEnabledSettings().setDataEnabled(reason, enabled);
7878 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007879 }
7880 } finally {
7881 Binder.restoreCallingIdentity(identity);
Jack Yu75ab2952016-07-08 14:29:33 -07007882 }
7883 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07007884
7885 /**
7886 * Get Client request stats
7887 * @return List of Client Request Stats
7888 * @hide
7889 */
7890 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007891 public List<ClientRequestStats> getClientRequestStats(String callingPackage,
7892 String callingFeatureId, int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08007893 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007894 mApp, subId, callingPackage, callingFeatureId, "getClientRequestStats")) {
Sooraj Sasindran9a909312016-07-18 11:57:25 -07007895 return null;
7896 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07007897 Phone phone = getPhone(subId);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07007898
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007899 final long identity = Binder.clearCallingIdentity();
7900 try {
7901 if (phone != null) {
7902 return phone.getClientRequestStats();
7903 }
7904
7905 return null;
7906 } finally {
7907 Binder.restoreCallingIdentity(identity);
7908 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07007909 }
7910
Narayan Kamathf04b5a12018-01-09 11:47:15 +00007911 private WorkSource getWorkSource(int uid) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007912 String packageName = mApp.getPackageManager().getNameForUid(uid);
Narayan Kamathf04b5a12018-01-09 11:47:15 +00007913 return new WorkSource(uid, packageName);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07007914 }
Jack Yueb4124c2017-02-16 15:32:43 -08007915
7916 /**
Grace Chen70990072017-03-24 17:21:30 -07007917 * Set SIM card power state.
Jack Yueb4124c2017-02-16 15:32:43 -08007918 *
Sanket Padawe13bac7b2017-03-20 15:04:47 -07007919 * @param slotIndex SIM slot id.
Grace Chen70990072017-03-24 17:21:30 -07007920 * @param state State of SIM (power down, power up, pass through)
7921 * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
7922 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
7923 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
Jack Yueb4124c2017-02-16 15:32:43 -08007924 *
7925 **/
7926 @Override
Grace Chen70990072017-03-24 17:21:30 -07007927 public void setSimPowerStateForSlot(int slotIndex, int state) {
Jack Yueb4124c2017-02-16 15:32:43 -08007928 enforceModifyPermission();
Sanket Padawe13bac7b2017-03-20 15:04:47 -07007929 Phone phone = PhoneFactory.getPhone(slotIndex);
7930
vagdeviaf9a5b92018-08-15 16:01:53 -07007931 WorkSource workSource = getWorkSource(Binder.getCallingUid());
7932
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007933 final long identity = Binder.clearCallingIdentity();
7934 try {
7935 if (phone != null) {
Jordan Liu109698e2020-11-24 14:50:34 -08007936 phone.setSimPowerState(state, null, workSource);
7937 }
7938 } finally {
7939 Binder.restoreCallingIdentity(identity);
7940 }
7941 }
7942
7943 /**
7944 * Set SIM card power state.
7945 *
7946 * @param slotIndex SIM slot id.
7947 * @param state State of SIM (power down, power up, pass through)
7948 * @param callback callback to trigger after success or failure
7949 * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
7950 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
7951 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
7952 *
7953 **/
7954 @Override
7955 public void setSimPowerStateForSlotWithCallback(int slotIndex, int state,
7956 IIntegerConsumer callback) {
7957 enforceModifyPermission();
7958 Phone phone = PhoneFactory.getPhone(slotIndex);
7959
7960 WorkSource workSource = getWorkSource(Binder.getCallingUid());
7961
7962 final long identity = Binder.clearCallingIdentity();
7963 try {
7964 if (phone != null) {
7965 Pair<Integer, IIntegerConsumer> arguments = Pair.create(state, callback);
7966 sendRequestAsync(CMD_SET_SIM_POWER, arguments, phone, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007967 }
7968 } finally {
7969 Binder.restoreCallingIdentity(identity);
Jack Yueb4124c2017-02-16 15:32:43 -08007970 }
7971 }
Shuo Qiandd210312017-04-12 22:11:33 +00007972
Tyler Gunn65d45c22017-06-05 11:22:26 -07007973 private boolean isUssdApiAllowed(int subId) {
7974 CarrierConfigManager configManager =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007975 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Tyler Gunn65d45c22017-06-05 11:22:26 -07007976 if (configManager == null) {
7977 return false;
7978 }
7979 PersistableBundle pb = configManager.getConfigForSubId(subId);
7980 if (pb == null) {
7981 return false;
7982 }
7983 return pb.getBoolean(
7984 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL);
7985 }
7986
Shuo Qiandd210312017-04-12 22:11:33 +00007987 /**
7988 * Check if phone is in emergency callback mode
7989 * @return true if phone is in emergency callback mode
7990 * @param subId sub id
7991 */
goneil9c5f4872017-12-05 14:07:56 -08007992 @Override
Shuo Qiandd210312017-04-12 22:11:33 +00007993 public boolean getEmergencyCallbackMode(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07007994 enforceReadPrivilegedPermission("getEmergencyCallbackMode");
Shuo Qiandd210312017-04-12 22:11:33 +00007995 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007996
7997 final long identity = Binder.clearCallingIdentity();
7998 try {
7999 if (phone != null) {
8000 return phone.isInEcm();
8001 } else {
8002 return false;
8003 }
8004 } finally {
8005 Binder.restoreCallingIdentity(identity);
Shuo Qiandd210312017-04-12 22:11:33 +00008006 }
8007 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08008008
8009 /**
8010 * Get the current signal strength information for the given subscription.
8011 * Because this information is not updated when the device is in a low power state
8012 * it should not be relied-upon to be current.
8013 * @param subId Subscription index
8014 * @return the most recent cached signal strength info from the modem
8015 */
8016 @Override
8017 public SignalStrength getSignalStrength(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008018 final long identity = Binder.clearCallingIdentity();
8019 try {
8020 Phone p = getPhone(subId);
8021 if (p == null) {
8022 return null;
8023 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08008024
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008025 return p.getSignalStrength();
8026 } finally {
8027 Binder.restoreCallingIdentity(identity);
8028 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08008029 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00008030
Pengquan Meng77b7f132018-08-22 14:49:57 -07008031 /**
Chen Xuf792fd62018-10-17 17:54:36 +00008032 * Get the current modem radio state for the given slot.
8033 * @param slotIndex slot index.
8034 * @param callingPackage the name of the package making the call.
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008035 * @param callingFeatureId The feature in the package.
Chen Xuf792fd62018-10-17 17:54:36 +00008036 * @return the current radio power state from the modem
8037 */
8038 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008039 public int getRadioPowerState(int slotIndex, String callingPackage, String callingFeatureId) {
Chen Xuf792fd62018-10-17 17:54:36 +00008040 Phone phone = PhoneFactory.getPhone(slotIndex);
8041 if (phone != null) {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008042 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, phone.getSubId(),
8043 callingPackage, callingFeatureId, "getRadioPowerState")) {
Chen Xuf792fd62018-10-17 17:54:36 +00008044 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
8045 }
8046
8047 final long identity = Binder.clearCallingIdentity();
8048 try {
8049 return phone.getRadioPowerState();
8050 } finally {
8051 Binder.restoreCallingIdentity(identity);
8052 }
8053 }
8054 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
8055 }
8056
8057 /**
Pengquan Meng77b7f132018-08-22 14:49:57 -07008058 * Checks if data roaming is enabled on the subscription with id {@code subId}.
8059 *
8060 * <p>Requires one of the following permissions:
8061 * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
8062 * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
8063 * privileges.
8064 *
8065 * @param subId subscription id
8066 * @return {@code true} if data roaming is enabled on this subscription, otherwise return
8067 * {@code false}.
8068 */
8069 @Override
8070 public boolean isDataRoamingEnabled(int subId) {
Shuo Qian093013d2020-08-13 15:42:55 -07008071 try {
8072 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
8073 null);
8074 } catch (Exception e) {
8075 TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
8076 mApp, subId, "isDataRoamingEnabled");
8077 }
Pengquan Meng44e66f12019-04-01 10:48:20 -07008078
Pengquan Menga1bb6272018-09-06 09:59:22 -07008079 boolean isEnabled = false;
8080 final long identity = Binder.clearCallingIdentity();
Pengquan Meng77b7f132018-08-22 14:49:57 -07008081 try {
Pengquan Menga1bb6272018-09-06 09:59:22 -07008082 Phone phone = getPhone(subId);
8083 isEnabled = phone != null ? phone.getDataRoamingEnabled() : false;
Pengquan Menga1bb6272018-09-06 09:59:22 -07008084 } finally {
8085 Binder.restoreCallingIdentity(identity);
Pengquan Meng77b7f132018-08-22 14:49:57 -07008086 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07008087 return isEnabled;
Pengquan Meng77b7f132018-08-22 14:49:57 -07008088 }
8089
8090
8091 /**
8092 * Enables/Disables the data roaming on the subscription with id {@code subId}.
8093 *
8094 * <p> Requires permission:
8095 * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier
8096 * privileges.
8097 *
8098 * @param subId subscription id
8099 * @param isEnabled {@code true} means enable, {@code false} means disable.
8100 */
8101 @Override
8102 public void setDataRoamingEnabled(int subId, boolean isEnabled) {
Pengquan Meng44e66f12019-04-01 10:48:20 -07008103 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8104 mApp, subId, "setDataRoamingEnabled");
8105
Pengquan Menga1bb6272018-09-06 09:59:22 -07008106 final long identity = Binder.clearCallingIdentity();
8107 try {
Pengquan Menga1bb6272018-09-06 09:59:22 -07008108 Phone phone = getPhone(subId);
8109 if (phone != null) {
8110 phone.setDataRoamingEnabled(isEnabled);
8111 }
8112 } finally {
8113 Binder.restoreCallingIdentity(identity);
Pengquan Meng77b7f132018-08-22 14:49:57 -07008114 }
8115 }
8116
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00008117 @Override
Pengquan Meng6884a2c2018-10-03 12:19:13 -07008118 public boolean isManualNetworkSelectionAllowed(int subId) {
tom hsuc91afc72020-01-06 23:46:07 +08008119 TelephonyPermissions
8120 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Pengquan Meng44e66f12019-04-01 10:48:20 -07008121 mApp, subId, "isManualNetworkSelectionAllowed");
8122
Pengquan Meng6884a2c2018-10-03 12:19:13 -07008123 boolean isAllowed = true;
8124 final long identity = Binder.clearCallingIdentity();
8125 try {
Pengquan Meng6884a2c2018-10-03 12:19:13 -07008126 Phone phone = getPhone(subId);
8127 if (phone != null) {
8128 isAllowed = phone.isCspPlmnEnabled();
8129 }
8130 } finally {
8131 Binder.restoreCallingIdentity(identity);
8132 }
8133 return isAllowed;
8134 }
8135
8136 @Override
Jordan Liu75f43ea2019-01-17 16:56:37 -08008137 public List<UiccCardInfo> getUiccCardsInfo(String callingPackage) {
Jordan Liu4cda4552020-03-23 11:55:07 -07008138 // Verify that tha callingPackage belongs to the calling UID
8139 mApp.getSystemService(AppOpsManager.class)
8140 .checkPackage(Binder.getCallingUid(), callingPackage);
8141
Jordan Liu1e142fc2019-04-22 15:10:43 -07008142 boolean hasReadPermission = false;
Jordan Liuc65bc952019-02-12 17:54:02 -08008143 try {
8144 enforceReadPrivilegedPermission("getUiccCardsInfo");
Jordan Liu1e142fc2019-04-22 15:10:43 -07008145 hasReadPermission = true;
Jordan Liuc65bc952019-02-12 17:54:02 -08008146 } catch (SecurityException e) {
8147 // even without READ_PRIVILEGED_PHONE_STATE, we allow the call to continue if the caller
8148 // has carrier privileges on an active UICC
8149 if (checkCarrierPrivilegesForPackageAnyPhone(callingPackage)
8150 != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
Jordan Liu1e142fc2019-04-22 15:10:43 -07008151 throw new SecurityException("Caller does not have permission.");
Jordan Liuc65bc952019-02-12 17:54:02 -08008152 }
Jordan Liu75f43ea2019-01-17 16:56:37 -08008153 }
Jordan Liu5aa07002018-12-18 15:44:48 -08008154
8155 final long identity = Binder.clearCallingIdentity();
8156 try {
Jordan Liu75f43ea2019-01-17 16:56:37 -08008157 UiccController uiccController = UiccController.getInstance();
8158 ArrayList<UiccCardInfo> cardInfos = uiccController.getAllUiccCardInfos();
Jordan Liu1e142fc2019-04-22 15:10:43 -07008159 if (hasReadPermission) {
8160 return cardInfos;
Jordan Liu75f43ea2019-01-17 16:56:37 -08008161 }
Jordan Liu1e142fc2019-04-22 15:10:43 -07008162
8163 // Remove private info if the caller doesn't have access
8164 ArrayList<UiccCardInfo> filteredInfos = new ArrayList<>();
8165 for (UiccCardInfo cardInfo : cardInfos) {
8166 // For an inactive eUICC, the UiccCard will be null even though the UiccCardInfo
8167 // is available
8168 UiccCard card = uiccController.getUiccCardForSlot(cardInfo.getSlotIndex());
8169 if (card == null || card.getUiccProfile() == null) {
8170 // assume no access if the card or profile is unavailable
8171 filteredInfos.add(cardInfo.getUnprivileged());
8172 continue;
8173 }
8174 UiccProfile profile = card.getUiccProfile();
8175 if (profile.getCarrierPrivilegeStatus(mApp.getPackageManager(), callingPackage)
8176 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
8177 filteredInfos.add(cardInfo);
8178 } else {
8179 filteredInfos.add(cardInfo.getUnprivileged());
8180 }
8181 }
8182 return filteredInfos;
Jordan Liu5aa07002018-12-18 15:44:48 -08008183 } finally {
8184 Binder.restoreCallingIdentity(identity);
8185 }
8186 }
8187
8188 @Override
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00008189 public UiccSlotInfo[] getUiccSlotsInfo() {
Brad Ebinger35c841c2018-10-01 10:40:55 -07008190 enforceReadPrivilegedPermission("getUiccSlotsInfo");
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00008191
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008192 final long identity = Binder.clearCallingIdentity();
8193 try {
8194 UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
8195 if (slots == null) {
8196 Rlog.i(LOG_TAG, "slots is null.");
8197 return null;
8198 }
8199
8200 UiccSlotInfo[] infos = new UiccSlotInfo[slots.length];
8201 for (int i = 0; i < slots.length; i++) {
8202 UiccSlot slot = slots[i];
8203 if (slot == null) {
8204 continue;
8205 }
8206
Jordan Liu7be7e652019-05-06 18:55:02 +00008207 String cardId;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008208 UiccCard card = slot.getUiccCard();
8209 if (card != null) {
8210 cardId = card.getCardId();
Jordan Liu7be7e652019-05-06 18:55:02 +00008211 } else {
Jordan Liu01bd00d2019-09-12 16:19:43 -07008212 cardId = slot.getEid();
8213 if (TextUtils.isEmpty(cardId)) {
8214 cardId = slot.getIccId();
8215 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008216 }
8217
Jordan Liu857451f2019-05-09 16:35:35 -07008218 if (cardId != null) {
8219 // if cardId is an ICCID, strip off trailing Fs before exposing to user
8220 // if cardId is an EID, it's all digits so this is fine
8221 cardId = IccUtils.stripTrailingFs(cardId);
8222 }
8223
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008224 int cardState = 0;
8225 switch (slot.getCardState()) {
8226 case CARDSTATE_ABSENT:
8227 cardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
8228 break;
8229 case CARDSTATE_PRESENT:
8230 cardState = UiccSlotInfo.CARD_STATE_INFO_PRESENT;
8231 break;
8232 case CARDSTATE_ERROR:
8233 cardState = UiccSlotInfo.CARD_STATE_INFO_ERROR;
8234 break;
8235 case CARDSTATE_RESTRICTED:
8236 cardState = UiccSlotInfo.CARD_STATE_INFO_RESTRICTED;
8237 break;
8238 default:
8239 break;
8240
8241 }
8242
8243 infos[i] = new UiccSlotInfo(
8244 slot.isActive(),
8245 slot.isEuicc(),
8246 cardId,
8247 cardState,
8248 slot.getPhoneId(),
Jordan Liua2619582019-02-14 12:56:40 -08008249 slot.isExtendedApduSupported(),
8250 slot.isRemovable());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008251 }
8252 return infos;
8253 } finally {
8254 Binder.restoreCallingIdentity(identity);
Holly Jiuyu Sun1d957c52018-04-04 13:52:42 -07008255 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00008256 }
8257
8258 @Override
8259 public boolean switchSlots(int[] physicalSlots) {
8260 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008261
8262 final long identity = Binder.clearCallingIdentity();
8263 try {
8264 return (Boolean) sendRequest(CMD_SWITCH_SLOTS, physicalSlots);
8265 } finally {
8266 Binder.restoreCallingIdentity(identity);
8267 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00008268 }
Jack Yu4c988042018-02-27 15:30:01 -08008269
8270 @Override
Jordan Liu7de49fa2018-12-06 14:48:49 -08008271 public int getCardIdForDefaultEuicc(int subId, String callingPackage) {
Jordan Liu7de49fa2018-12-06 14:48:49 -08008272 final long identity = Binder.clearCallingIdentity();
8273 try {
8274 return UiccController.getInstance().getCardIdForDefaultEuicc();
8275 } finally {
8276 Binder.restoreCallingIdentity(identity);
8277 }
8278 }
8279
Pengquan Meng85728fb2018-03-12 16:31:21 -07008280 /**
goneil47ffb6e2018-04-06 15:40:58 -07008281 * A test API to reload the UICC profile.
8282 *
8283 * <p>Requires that the calling app has permission
8284 * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
8285 * @hide
8286 */
8287 @Override
8288 public void refreshUiccProfile(int subId) {
8289 enforceModifyPermission();
8290
8291 final long identity = Binder.clearCallingIdentity();
8292 try {
8293 Phone phone = getPhone(subId);
8294 if (phone == null) {
8295 return;
8296 }
8297 UiccCard uiccCard = phone.getUiccCard();
8298 if (uiccCard == null) {
8299 return;
8300 }
8301 UiccProfile uiccProfile = uiccCard.getUiccProfile();
8302 if (uiccProfile == null) {
8303 return;
8304 }
8305 uiccProfile.refresh();
8306 } finally {
8307 Binder.restoreCallingIdentity(identity);
8308 }
8309 }
8310
8311 /**
Pengquan Meng85728fb2018-03-12 16:31:21 -07008312 * Returns false if the mobile data is disabled by default, otherwise return true.
8313 */
8314 private boolean getDefaultDataEnabled() {
Inseob Kim14bb3d02018-12-13 17:11:34 +09008315 return TelephonyProperties.mobile_data().orElse(true);
Pengquan Meng85728fb2018-03-12 16:31:21 -07008316 }
8317
8318 /**
8319 * Returns true if the data roaming is enabled by default, i.e the system property
8320 * of {@link #DEFAULT_DATA_ROAMING_PROPERTY_NAME} is true or the config of
8321 * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} is true.
8322 */
8323 private boolean getDefaultDataRoamingEnabled(int subId) {
8324 final CarrierConfigManager configMgr = (CarrierConfigManager)
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008325 mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Shuo Qian1d84a0e2020-07-15 12:36:44 -07008326 boolean isDataRoamingEnabled = TelephonyProperties.data_roaming().orElse(false);
Pengquan Meng85728fb2018-03-12 16:31:21 -07008327 isDataRoamingEnabled |= configMgr.getConfigForSubId(subId).getBoolean(
8328 CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
8329 return isDataRoamingEnabled;
8330 }
8331
8332 /**
8333 * Returns the default network type for the given {@code subId}, if the default network type is
8334 * not set, return {@link Phone#PREFERRED_NT_MODE}.
8335 */
8336 private int getDefaultNetworkType(int subId) {
Inseob Kim14bb3d02018-12-13 17:11:34 +09008337 List<Integer> list = TelephonyProperties.default_network();
8338 int phoneId = mSubscriptionController.getPhoneId(subId);
8339 if (phoneId >= 0 && phoneId < list.size() && list.get(phoneId) != null) {
8340 return list.get(phoneId);
8341 }
8342 return Phone.PREFERRED_NT_MODE;
Pengquan Meng85728fb2018-03-12 16:31:21 -07008343 }
fionaxua13278b2018-03-21 00:08:13 -07008344
8345 @Override
8346 public void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String
chen xueaba88a2019-03-15 13:15:10 -07008347 gid1, String gid2, String plmn, String spn, String carrierPrivilegeRules, String apn) {
fionaxua13278b2018-03-21 00:08:13 -07008348 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008349
8350 final long identity = Binder.clearCallingIdentity();
8351 try {
8352 final Phone phone = getPhone(subId);
8353 if (phone == null) {
8354 loge("setCarrierTestOverride fails with invalid subId: " + subId);
8355 return;
8356 }
chen xueaba88a2019-03-15 13:15:10 -07008357 phone.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, plmn, spn,
8358 carrierPrivilegeRules, apn);
Jeff Davidson8ab02b22020-03-28 12:24:40 -07008359 if (carrierPrivilegeRules == null) {
8360 mCarrierPrivilegeTestOverrideSubIds.remove(subId);
8361 } else {
8362 mCarrierPrivilegeTestOverrideSubIds.add(subId);
8363 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008364 } finally {
8365 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07008366 }
fionaxua13278b2018-03-21 00:08:13 -07008367 }
8368
8369 @Override
8370 public int getCarrierIdListVersion(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07008371 enforceReadPrivilegedPermission("getCarrierIdListVersion");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008372
8373 final long identity = Binder.clearCallingIdentity();
8374 try {
8375 final Phone phone = getPhone(subId);
8376 if (phone == null) {
8377 loge("getCarrierIdListVersion fails with invalid subId: " + subId);
8378 return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
8379 }
8380 return phone.getCarrierIdListVersion();
8381 } finally {
8382 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07008383 }
fionaxua13278b2018-03-21 00:08:13 -07008384 }
Malcolm Chen2c63d402018-08-14 16:00:53 -07008385
8386 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008387 public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage,
8388 String callingFeatureId) {
Malcolm Chen2c63d402018-08-14 16:00:53 -07008389 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008390 mApp, subId, callingPackage, callingFeatureId,
8391 "getNumberOfModemsWithSimultaneousDataConnections")) {
Malcolm Chen2c63d402018-08-14 16:00:53 -07008392 return -1;
8393 }
8394
8395 final long identity = Binder.clearCallingIdentity();
8396 try {
8397 return mPhoneConfigurationManager.getNumberOfModemsWithSimultaneousDataConnections();
8398 } finally {
8399 Binder.restoreCallingIdentity(identity);
8400 }
8401 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07008402
8403 @Override
8404 public int getCdmaRoamingMode(int subId) {
zoey chen7e6d4e52019-12-17 18:18:59 +08008405 TelephonyPermissions
8406 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Pengquan Menga1bb6272018-09-06 09:59:22 -07008407 mApp, subId, "getCdmaRoamingMode");
8408
8409 final long identity = Binder.clearCallingIdentity();
8410 try {
8411 return (int) sendRequest(CMD_GET_CDMA_ROAMING_MODE, null /* argument */, subId);
8412 } finally {
8413 Binder.restoreCallingIdentity(identity);
8414 }
8415 }
8416
8417 @Override
8418 public boolean setCdmaRoamingMode(int subId, int mode) {
8419 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8420 mApp, subId, "setCdmaRoamingMode");
8421
8422 final long identity = Binder.clearCallingIdentity();
8423 try {
8424 return (boolean) sendRequest(CMD_SET_CDMA_ROAMING_MODE, mode, subId);
8425 } finally {
8426 Binder.restoreCallingIdentity(identity);
8427 }
8428 }
8429
8430 @Override
Sarah Chinbaab1432020-10-28 13:46:24 -07008431 public int getCdmaSubscriptionMode(int subId) {
8432 TelephonyPermissions
8433 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
8434 mApp, subId, "getCdmaSubscriptionMode");
8435
8436 final long identity = Binder.clearCallingIdentity();
8437 try {
8438 return (int) sendRequest(CMD_GET_CDMA_SUBSCRIPTION_MODE, null /* argument */, subId);
8439 } finally {
8440 Binder.restoreCallingIdentity(identity);
8441 }
8442 }
8443
8444 @Override
Pengquan Menga1bb6272018-09-06 09:59:22 -07008445 public boolean setCdmaSubscriptionMode(int subId, int mode) {
8446 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8447 mApp, subId, "setCdmaSubscriptionMode");
8448
8449 final long identity = Binder.clearCallingIdentity();
8450 try {
8451 return (boolean) sendRequest(CMD_SET_CDMA_SUBSCRIPTION_MODE, mode, subId);
8452 } finally {
8453 Binder.restoreCallingIdentity(identity);
8454 }
8455 }
Makoto Onukida3bf792018-09-18 16:06:29 -07008456
sqianc5eccab2018-10-19 18:46:41 -07008457 @Override
sqian8c685422019-02-22 15:55:18 -08008458 public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008459 String callingPackage, String callingFeatureId) {
sqian11b7a0e2018-12-05 18:48:28 -08008460 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008461 mApp, getDefaultSubscription(), callingPackage, callingFeatureId,
8462 "getEmergencyNumberList")) {
sqian11b7a0e2018-12-05 18:48:28 -08008463 throw new SecurityException("Requires READ_PHONE_STATE permission.");
8464 }
8465 final long identity = Binder.clearCallingIdentity();
8466 try {
sqian854d44b2018-12-12 16:48:18 -08008467 Map<Integer, List<EmergencyNumber>> emergencyNumberListInternal = new HashMap<>();
8468 for (Phone phone: PhoneFactory.getPhones()) {
8469 if (phone.getEmergencyNumberTracker() != null
8470 && phone.getEmergencyNumberTracker().getEmergencyNumberList() != null) {
8471 emergencyNumberListInternal.put(
8472 phone.getSubId(),
8473 phone.getEmergencyNumberTracker().getEmergencyNumberList());
8474 }
sqian11b7a0e2018-12-05 18:48:28 -08008475 }
sqian854d44b2018-12-12 16:48:18 -08008476 return emergencyNumberListInternal;
sqian11b7a0e2018-12-05 18:48:28 -08008477 } finally {
8478 Binder.restoreCallingIdentity(identity);
8479 }
sqianc5eccab2018-10-19 18:46:41 -07008480 }
8481
8482 @Override
sqian8c685422019-02-22 15:55:18 -08008483 public boolean isEmergencyNumber(String number, boolean exactMatch) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008484 final Phone defaultPhone = getDefaultPhone();
sqian11b7a0e2018-12-05 18:48:28 -08008485 if (!exactMatch) {
8486 TelephonyPermissions
8487 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
sqian8c685422019-02-22 15:55:18 -08008488 mApp, defaultPhone.getSubId(), "isEmergencyNumber(Potential)");
sqian11b7a0e2018-12-05 18:48:28 -08008489 }
8490 final long identity = Binder.clearCallingIdentity();
8491 try {
sqian854d44b2018-12-12 16:48:18 -08008492 for (Phone phone: PhoneFactory.getPhones()) {
8493 if (phone.getEmergencyNumberTracker() != null
Taesu Leee050c002020-10-13 17:19:35 +09008494 && phone.getEmergencyNumberTracker()
8495 .isEmergencyNumber(number, exactMatch)) {
8496 return true;
sqian11b7a0e2018-12-05 18:48:28 -08008497 }
sqian11b7a0e2018-12-05 18:48:28 -08008498 }
8499 return false;
8500 } finally {
8501 Binder.restoreCallingIdentity(identity);
8502 }
8503 }
8504
sqianf4ca7ed2019-01-15 18:32:07 -08008505 /**
8506 * Update emergency number list for test mode.
8507 */
8508 @Override
8509 public void updateEmergencyNumberListTestMode(int action, EmergencyNumber num) {
8510 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
8511 "updateEmergencyNumberListTestMode");
8512
8513 final long identity = Binder.clearCallingIdentity();
8514 try {
8515 for (Phone phone: PhoneFactory.getPhones()) {
8516 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
8517 if (tracker != null) {
8518 tracker.executeEmergencyNumberTestModeCommand(action, num);
8519 }
8520 }
8521 } finally {
8522 Binder.restoreCallingIdentity(identity);
8523 }
8524 }
8525
8526 /**
8527 * Get the full emergency number list for test mode.
8528 */
8529 @Override
8530 public List<String> getEmergencyNumberListTestMode() {
8531 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
8532 "getEmergencyNumberListTestMode");
8533
8534 final long identity = Binder.clearCallingIdentity();
8535 try {
8536 Set<String> emergencyNumbers = new HashSet<>();
8537 for (Phone phone: PhoneFactory.getPhones()) {
8538 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
8539 if (tracker != null) {
8540 for (EmergencyNumber num : tracker.getEmergencyNumberList()) {
8541 emergencyNumbers.add(num.getNumber());
8542 }
8543 }
8544 }
8545 return new ArrayList<>(emergencyNumbers);
8546 } finally {
8547 Binder.restoreCallingIdentity(identity);
8548 }
8549 }
8550
chen xud6b45bd2018-10-30 22:27:10 -07008551 @Override
Shuo Qian3b6ee772019-11-13 17:43:31 -08008552 public int getEmergencyNumberDbVersion(int subId) {
8553 enforceReadPrivilegedPermission("getEmergencyNumberDbVersion");
8554
8555 final long identity = Binder.clearCallingIdentity();
8556 try {
8557 final Phone phone = getPhone(subId);
8558 if (phone == null) {
8559 loge("getEmergencyNumberDbVersion fails with invalid subId: " + subId);
8560 return TelephonyManager.INVALID_EMERGENCY_NUMBER_DB_VERSION;
8561 }
8562 return phone.getEmergencyNumberDbVersion();
8563 } finally {
8564 Binder.restoreCallingIdentity(identity);
8565 }
8566 }
8567
8568 @Override
8569 public void notifyOtaEmergencyNumberDbInstalled() {
8570 enforceModifyPermission();
8571
8572 final long identity = Binder.clearCallingIdentity();
8573 try {
8574 for (Phone phone: PhoneFactory.getPhones()) {
8575 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
8576 if (tracker != null) {
8577 tracker.updateOtaEmergencyNumberDatabase();
8578 }
8579 }
8580 } finally {
8581 Binder.restoreCallingIdentity(identity);
8582 }
8583 }
8584
8585 @Override
Shuo Qianc373f112020-03-05 17:55:34 -08008586 public void updateOtaEmergencyNumberDbFilePath(ParcelFileDescriptor otaParcelFileDescriptor) {
Shuo Qian3b6ee772019-11-13 17:43:31 -08008587 enforceActiveEmergencySessionPermission();
8588
8589 final long identity = Binder.clearCallingIdentity();
8590 try {
8591 for (Phone phone: PhoneFactory.getPhones()) {
8592 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
8593 if (tracker != null) {
Shuo Qianc373f112020-03-05 17:55:34 -08008594 tracker.updateOtaEmergencyNumberDbFilePath(otaParcelFileDescriptor);
8595 }
8596 }
8597 } finally {
8598 Binder.restoreCallingIdentity(identity);
8599 }
8600 }
8601
8602 @Override
8603 public void resetOtaEmergencyNumberDbFilePath() {
8604 enforceActiveEmergencySessionPermission();
8605
8606 final long identity = Binder.clearCallingIdentity();
8607 try {
8608 for (Phone phone: PhoneFactory.getPhones()) {
8609 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
8610 if (tracker != null) {
8611 tracker.resetOtaEmergencyNumberDbFilePath();
Shuo Qian3b6ee772019-11-13 17:43:31 -08008612 }
8613 }
8614 } finally {
8615 Binder.restoreCallingIdentity(identity);
8616 }
8617 }
8618
8619 @Override
chen xud6b45bd2018-10-30 22:27:10 -07008620 public List<String> getCertsFromCarrierPrivilegeAccessRules(int subId) {
8621 enforceReadPrivilegedPermission("getCertsFromCarrierPrivilegeAccessRules");
8622 Phone phone = getPhone(subId);
8623 if (phone == null) {
8624 return null;
8625 }
8626 final long identity = Binder.clearCallingIdentity();
8627 try {
8628 UiccProfile profile = UiccController.getInstance()
8629 .getUiccProfileForPhone(phone.getPhoneId());
8630 if (profile != null) {
8631 return profile.getCertsFromCarrierPrivilegeAccessRules();
8632 }
8633 } finally {
8634 Binder.restoreCallingIdentity(identity);
8635 }
8636 return null;
8637 }
Malcolm Chen8e4ed912019-01-15 20:22:16 -08008638
8639 /**
8640 * Enable or disable a modem stack.
8641 */
8642 @Override
8643 public boolean enableModemForSlot(int slotIndex, boolean enable) {
8644 enforceModifyPermission();
8645
8646 final long identity = Binder.clearCallingIdentity();
8647 try {
8648 Phone phone = PhoneFactory.getPhone(slotIndex);
8649 if (phone == null) {
8650 return false;
8651 } else {
8652 return (Boolean) sendRequest(CMD_REQUEST_ENABLE_MODEM, enable, phone, null);
8653 }
8654 } finally {
8655 Binder.restoreCallingIdentity(identity);
8656 }
8657 }
Michelecea4cf22018-12-21 15:00:11 -08008658
Malcolm Chen4bcd9822019-03-27 18:34:05 -07008659 /**
8660 * Whether a modem stack is enabled or not.
8661 */
8662 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008663 public boolean isModemEnabledForSlot(int slotIndex, String callingPackage,
8664 String callingFeatureId) {
Malcolm Chen4bcd9822019-03-27 18:34:05 -07008665 Phone phone = PhoneFactory.getPhone(slotIndex);
8666 if (phone == null) return false;
8667
8668 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008669 mApp, phone.getSubId(), callingPackage, callingFeatureId,
8670 "isModemEnabledForSlot")) {
Malcolm Chen4bcd9822019-03-27 18:34:05 -07008671 throw new SecurityException("Requires READ_PHONE_STATE permission.");
8672 }
8673
8674 final long identity = Binder.clearCallingIdentity();
8675 try {
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07008676 try {
8677 return mPhoneConfigurationManager.getPhoneStatusFromCache(phone.getPhoneId());
8678 } catch (NoSuchElementException ex) {
8679 return (Boolean) sendRequest(CMD_GET_MODEM_STATUS, null, phone, null);
8680 }
Malcolm Chen4bcd9822019-03-27 18:34:05 -07008681 } finally {
8682 Binder.restoreCallingIdentity(identity);
8683 }
8684 }
8685
Michelecea4cf22018-12-21 15:00:11 -08008686 @Override
Michele0ea7d782019-03-19 14:58:42 -07008687 public void setMultiSimCarrierRestriction(boolean isMultiSimCarrierRestricted) {
Michelecea4cf22018-12-21 15:00:11 -08008688 enforceModifyPermission();
8689
8690 final long identity = Binder.clearCallingIdentity();
8691 try {
8692 mTelephonySharedPreferences.edit()
Michele0ea7d782019-03-19 14:58:42 -07008693 .putBoolean(PREF_MULTI_SIM_RESTRICTED, isMultiSimCarrierRestricted)
Michelecea4cf22018-12-21 15:00:11 -08008694 .commit();
8695 } finally {
8696 Binder.restoreCallingIdentity(identity);
8697 }
8698 }
8699
8700 @Override
Michele0ea7d782019-03-19 14:58:42 -07008701 @TelephonyManager.IsMultiSimSupportedResult
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008702 public int isMultiSimSupported(String callingPackage, String callingFeatureId) {
Michele4245e952019-02-04 11:36:23 -08008703 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008704 getDefaultPhone().getSubId(), callingPackage, callingFeatureId,
8705 "isMultiSimSupported")) {
Michele0ea7d782019-03-19 14:58:42 -07008706 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele4245e952019-02-04 11:36:23 -08008707 }
Michelecea4cf22018-12-21 15:00:11 -08008708
8709 final long identity = Binder.clearCallingIdentity();
8710 try {
Michele0ea7d782019-03-19 14:58:42 -07008711 return isMultiSimSupportedInternal();
Michelecea4cf22018-12-21 15:00:11 -08008712 } finally {
8713 Binder.restoreCallingIdentity(identity);
8714 }
8715 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08008716
Michele0ea7d782019-03-19 14:58:42 -07008717 @TelephonyManager.IsMultiSimSupportedResult
8718 private int isMultiSimSupportedInternal() {
Michele30b57b22019-03-01 12:01:14 -08008719 // If the device has less than 2 SIM cards, indicate that multisim is restricted.
8720 int numPhysicalSlots = UiccController.getInstance().getUiccSlots().length;
8721 if (numPhysicalSlots < 2) {
Michele0ea7d782019-03-19 14:58:42 -07008722 loge("isMultiSimSupportedInternal: requires at least 2 cards");
8723 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -08008724 }
8725 // Check if the hardware supports multisim functionality. If usage of multisim is not
8726 // supported by the modem, indicate that it is restricted.
8727 PhoneCapability staticCapability =
8728 mPhoneConfigurationManager.getStaticPhoneCapability();
8729 if (staticCapability == null) {
Michele0ea7d782019-03-19 14:58:42 -07008730 loge("isMultiSimSupportedInternal: no static configuration available");
8731 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -08008732 }
Sarah Chin7caee492020-02-18 20:49:02 +00008733 if (staticCapability.logicalModemList.size() < 2) {
Michele0ea7d782019-03-19 14:58:42 -07008734 loge("isMultiSimSupportedInternal: maximum number of modem is < 2");
8735 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -08008736 }
8737 // Check if support of multiple SIMs is restricted by carrier
8738 if (mTelephonySharedPreferences.getBoolean(PREF_MULTI_SIM_RESTRICTED, false)) {
Michele0ea7d782019-03-19 14:58:42 -07008739 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_CARRIER;
Michele30b57b22019-03-01 12:01:14 -08008740 }
8741
Michele0ea7d782019-03-19 14:58:42 -07008742 return TelephonyManager.MULTISIM_ALLOWED;
Michele30b57b22019-03-01 12:01:14 -08008743 }
8744
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08008745 /**
8746 * Switch configs to enable multi-sim or switch back to single-sim
Nazanin Bakhshi17318782019-03-01 11:56:08 -08008747 * Note: Switch from multi-sim to single-sim is only possible with MODIFY_PHONE_STATE
8748 * permission, but the other way around is possible with either MODIFY_PHONE_STATE
8749 * or carrier privileges
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08008750 * @param numOfSims number of active sims we want to switch to
8751 */
8752 @Override
8753 public void switchMultiSimConfig(int numOfSims) {
Nazanin Bakhshi17318782019-03-01 11:56:08 -08008754 if (numOfSims == 1) {
8755 enforceModifyPermission();
8756 } else {
8757 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8758 mApp, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, "switchMultiSimConfig");
8759 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08008760 final long identity = Binder.clearCallingIdentity();
Michele30b57b22019-03-01 12:01:14 -08008761
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08008762 try {
Michele30b57b22019-03-01 12:01:14 -08008763 //only proceed if multi-sim is not restricted
Michele0ea7d782019-03-19 14:58:42 -07008764 if (isMultiSimSupportedInternal() != TelephonyManager.MULTISIM_ALLOWED) {
Michele30b57b22019-03-01 12:01:14 -08008765 loge("switchMultiSimConfig not possible. It is restricted or not supported.");
8766 return;
8767 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08008768 mPhoneConfigurationManager.switchMultiSimConfig(numOfSims);
8769 } finally {
8770 Binder.restoreCallingIdentity(identity);
8771 }
8772 }
8773
Hyungjun Parkbb07fde2019-01-10 15:28:51 +09008774 @Override
8775 public boolean isApplicationOnUicc(int subId, int appType) {
8776 enforceReadPrivilegedPermission("isApplicationOnUicc");
8777 Phone phone = getPhone(subId);
8778 if (phone == null) {
8779 return false;
8780 }
8781 final long identity = Binder.clearCallingIdentity();
8782 try {
8783 UiccCard uiccCard = phone.getUiccCard();
8784 if (uiccCard == null) {
8785 return false;
8786 }
8787 UiccProfile uiccProfile = uiccCard.getUiccProfile();
8788 if (uiccProfile == null) {
8789 return false;
8790 }
8791 if (TelephonyManager.APPTYPE_SIM <= appType
8792 && appType <= TelephonyManager.APPTYPE_ISIM) {
8793 return uiccProfile.isApplicationOnIcc(AppType.values()[appType]);
8794 }
8795 return false;
8796 } finally {
8797 Binder.restoreCallingIdentity(identity);
8798 }
8799 }
8800
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08008801 /**
chen xub4baa772019-04-03 10:23:41 -07008802 * Get whether making changes to modem configurations will trigger reboot.
8803 * Return value defaults to true.
Nazanin Bakhshi5fe5ef22019-01-30 10:52:09 -08008804 */
8805 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008806 public boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage,
8807 String callingFeatureId) {
chen xub4baa772019-04-03 10:23:41 -07008808 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008809 mApp, subId, callingPackage, callingFeatureId,
8810 "doesSwitchMultiSimConfigTriggerReboot")) {
chen xub4baa772019-04-03 10:23:41 -07008811 return false;
8812 }
Nazanin Bakhshi5fe5ef22019-01-30 10:52:09 -08008813 final long identity = Binder.clearCallingIdentity();
8814 try {
8815 return mPhoneConfigurationManager.isRebootRequiredForModemConfigChange();
8816 } finally {
8817 Binder.restoreCallingIdentity(identity);
8818 }
8819 }
8820
Nathan Harold29f5f052019-02-15 13:41:57 -08008821 private void updateModemStateMetrics() {
8822 TelephonyMetrics metrics = TelephonyMetrics.getInstance();
8823 // TODO: check the state for each modem if the api is ready.
8824 metrics.updateEnabledModemBitmap((1 << TelephonyManager.from(mApp).getPhoneCount()) - 1);
8825 }
8826
Pengquan Meng3889a572019-01-23 11:16:29 -08008827 @Override
8828 public int[] getSlotsMapping() {
8829 enforceReadPrivilegedPermission("getSlotsMapping");
8830
8831 final long identity = Binder.clearCallingIdentity();
8832 try {
8833 int phoneCount = TelephonyManager.getDefault().getPhoneCount();
8834 // All logical slots should have a mapping to a physical slot.
8835 int[] logicalSlotsMapping = new int[phoneCount];
8836 UiccSlotInfo[] slotInfos = getUiccSlotsInfo();
8837 for (int i = 0; i < slotInfos.length; i++) {
8838 if (SubscriptionManager.isValidPhoneId(slotInfos[i].getLogicalSlotIdx())) {
8839 logicalSlotsMapping[slotInfos[i].getLogicalSlotIdx()] = i;
8840 }
8841 }
8842 return logicalSlotsMapping;
8843 } finally {
8844 Binder.restoreCallingIdentity(identity);
8845 }
8846 }
Nathan Harold48d6fd52019-02-06 19:01:40 -08008847
8848 /**
8849 * Get the IRadio HAL Version
8850 */
8851 @Override
8852 public int getRadioHalVersion() {
8853 Phone phone = getDefaultPhone();
8854 if (phone == null) return -1;
8855 HalVersion hv = phone.getHalVersion();
8856 if (hv.equals(HalVersion.UNKNOWN)) return -1;
8857 return hv.major * 100 + hv.minor;
8858 }
Malcolm Chendc8c10e2019-04-10 18:25:07 -07008859
8860 /**
Shuo Qianda2d6ec2020-01-14 15:18:28 -08008861 * Get the current calling package name.
8862 * @return the current calling package name
8863 */
8864 @Override
8865 public String getCurrentPackageName() {
8866 return mApp.getPackageManager().getPackagesForUid(Binder.getCallingUid())[0];
8867 }
8868
8869 /**
Malcolm Chene5ad5792019-04-18 13:51:02 -07008870 * Return whether data is enabled for certain APN type. This will tell if framework will accept
8871 * corresponding network requests on a subId.
8872 *
8873 * Data is enabled if:
Malcolm Chendc8c10e2019-04-10 18:25:07 -07008874 * 1) user data is turned on, or
Malcolm Chene5ad5792019-04-18 13:51:02 -07008875 * 2) APN is un-metered for this subscription, or
8876 * 3) APN type is whitelisted. E.g. MMS is whitelisted if
Hall Liu746e03c2020-09-25 11:13:49 -07008877 * {@link TelephonyManager#MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED} is enabled.
Malcolm Chene5ad5792019-04-18 13:51:02 -07008878 *
8879 * @return whether data is allowed for a apn type.
8880 *
8881 * @hide
Malcolm Chendc8c10e2019-04-10 18:25:07 -07008882 */
8883 @Override
Malcolm Chene5ad5792019-04-18 13:51:02 -07008884 public boolean isDataEnabledForApn(int apnType, int subId, String callingPackage) {
Amit Mahajan5d4e1922019-10-07 16:20:43 -07008885 enforceReadPrivilegedPermission("Needs READ_PRIVILEGED_PHONE_STATE for "
8886 + "isDataEnabledForApn");
Malcolm Chendc8c10e2019-04-10 18:25:07 -07008887
8888 // Now that all security checks passes, perform the operation as ourselves.
8889 final long identity = Binder.clearCallingIdentity();
8890 try {
8891 Phone phone = getPhone(subId);
8892 if (phone == null) return false;
8893
Jack Yu41407ee2019-05-13 16:54:09 -07008894 boolean isMetered = ApnSettingUtils.isMeteredApnType(apnType, phone);
Malcolm Chene5ad5792019-04-18 13:51:02 -07008895 return !isMetered || phone.getDataEnabledSettings().isDataEnabled(apnType);
8896 } finally {
8897 Binder.restoreCallingIdentity(identity);
8898 }
8899 }
8900
8901 @Override
Jack Yu41407ee2019-05-13 16:54:09 -07008902 public boolean isApnMetered(@ApnType int apnType, int subId) {
Malcolm Chene5ad5792019-04-18 13:51:02 -07008903 enforceReadPrivilegedPermission("isApnMetered");
8904
8905 // Now that all security checks passes, perform the operation as ourselves.
8906 final long identity = Binder.clearCallingIdentity();
8907 try {
8908 Phone phone = getPhone(subId);
8909 if (phone == null) return true; // By default return true.
8910
Jack Yu41407ee2019-05-13 16:54:09 -07008911 return ApnSettingUtils.isMeteredApnType(apnType, phone);
Malcolm Chendc8c10e2019-04-10 18:25:07 -07008912 } finally {
8913 Binder.restoreCallingIdentity(identity);
8914 }
8915 }
Brad Ebingera63db5f2019-04-23 16:31:13 -07008916
8917 @Override
Hall Liu73f5d362020-01-20 13:42:00 -08008918 public void setSystemSelectionChannels(List<RadioAccessSpecifier> specifiers,
8919 int subscriptionId, IBooleanConsumer resultCallback) {
8920 enforceModifyPermission();
8921 long token = Binder.clearCallingIdentity();
8922 try {
8923 Phone phone = getPhone(subscriptionId);
8924 if (phone == null) {
8925 try {
8926 if (resultCallback != null) {
8927 resultCallback.accept(false);
8928 }
8929 } catch (RemoteException e) {
8930 // ignore
8931 }
8932 return;
8933 }
8934 Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> argument =
8935 Pair.create(specifiers, (x) -> {
8936 try {
8937 if (resultCallback != null) {
8938 resultCallback.accept(x);
8939 }
8940 } catch (RemoteException e) {
8941 // ignore
8942 }
8943 });
8944 sendRequestAsync(CMD_SET_SYSTEM_SELECTION_CHANNELS, argument, phone, null);
8945 } finally {
8946 Binder.restoreCallingIdentity(token);
8947 }
8948 }
8949
8950 @Override
Sarah Chin679c08a2020-11-18 13:39:35 -08008951 public List<RadioAccessSpecifier> getSystemSelectionChannels(int subId) {
8952 TelephonyPermissions
8953 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
8954 mApp, subId, "getSystemSelectionChannels");
8955 WorkSource workSource = getWorkSource(Binder.getCallingUid());
8956 final long identity = Binder.clearCallingIdentity();
8957 try {
8958 List<RadioAccessSpecifier> specifiers =
8959 (List<RadioAccessSpecifier>) sendRequest(CMD_GET_SYSTEM_SELECTION_CHANNELS,
8960 null, subId, workSource);
8961 if (DBG) log("getSystemSelectionChannels: " + specifiers);
8962 return specifiers;
8963 } finally {
8964 Binder.restoreCallingIdentity(identity);
8965 }
8966 }
8967
8968 @Override
changbetty7157e9e2019-12-06 18:16:37 +08008969 public boolean isMvnoMatched(int subId, int mvnoType, @NonNull String mvnoMatchData) {
changbettyca3d40d2020-03-03 16:27:31 +08008970 enforceReadPrivilegedPermission("isMvnoMatched");
changbetty7157e9e2019-12-06 18:16:37 +08008971 IccRecords iccRecords = UiccController.getInstance().getIccRecords(
8972 SubscriptionManager.getPhoneId(subId), UiccController.APP_FAM_3GPP);
8973 if (iccRecords == null) {
8974 Log.d(LOG_TAG, "isMvnoMatched# IccRecords is null");
8975 return false;
8976 }
8977 return ApnSettingUtils.mvnoMatches(iccRecords, mvnoType, mvnoMatchData);
8978 }
8979
8980 @Override
Philip P. Moltmannd02b7372020-03-18 17:06:12 -07008981 public void enqueueSmsPickResult(String callingPackage, String callingAttributionTag,
8982 IIntegerConsumer pendingSubIdResult) {
Shuo Qianda2d6ec2020-01-14 15:18:28 -08008983 if (callingPackage == null) {
8984 callingPackage = getCurrentPackageName();
8985 }
Brad Ebingera63db5f2019-04-23 16:31:13 -07008986 SmsPermissions permissions = new SmsPermissions(getDefaultPhone(), mApp,
8987 (AppOpsManager) mApp.getSystemService(Context.APP_OPS_SERVICE));
Philip P. Moltmannd02b7372020-03-18 17:06:12 -07008988 if (!permissions.checkCallingCanSendSms(callingPackage, callingAttributionTag,
8989 "Sending message")) {
Brad Ebingera63db5f2019-04-23 16:31:13 -07008990 throw new SecurityException("Requires SEND_SMS permission to perform this operation");
8991 }
8992 PickSmsSubscriptionActivity.addPendingResult(pendingSubIdResult);
8993 Intent intent = new Intent();
8994 intent.setClass(mApp, PickSmsSubscriptionActivity.class);
8995 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8996 // Bring up choose default SMS subscription dialog right now
8997 intent.putExtra(PickSmsSubscriptionActivity.DIALOG_TYPE_KEY,
8998 PickSmsSubscriptionActivity.SMS_PICK_FOR_MESSAGE);
8999 mApp.startActivity(intent);
9000 }
chen xud5ca2d52019-05-28 15:20:57 -07009001
9002 @Override
9003 public String getMmsUAProfUrl(int subId) {
9004 //TODO investigate if this API should require proper permission check in R b/133791609
9005 final long identity = Binder.clearCallingIdentity();
9006 try {
Guoqiang.Qiu171383d2020-07-13 09:38:32 +08009007 String carrierUAProfUrl = mApp.getCarrierConfigForSubId(subId).getString(
9008 CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING);
9009 if (!TextUtils.isEmpty(carrierUAProfUrl)) {
9010 return carrierUAProfUrl;
9011 }
Daniel Brightebb4eb72020-02-18 15:16:33 -08009012 return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
9013 .getString(com.android.internal.R.string.config_mms_user_agent_profile_url);
chen xud5ca2d52019-05-28 15:20:57 -07009014 } finally {
9015 Binder.restoreCallingIdentity(identity);
9016 }
9017 }
9018
9019 @Override
9020 public String getMmsUserAgent(int subId) {
9021 //TODO investigate if this API should require proper permission check in R b/133791609
9022 final long identity = Binder.clearCallingIdentity();
9023 try {
Guoqiang.Qiu171383d2020-07-13 09:38:32 +08009024 String carrierUserAgent = mApp.getCarrierConfigForSubId(subId).getString(
9025 CarrierConfigManager.KEY_MMS_USER_AGENT_STRING);
9026 if (!TextUtils.isEmpty(carrierUserAgent)) {
9027 return carrierUserAgent;
9028 }
Daniel Brightebb4eb72020-02-18 15:16:33 -08009029 return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
9030 .getString(com.android.internal.R.string.config_mms_user_agent);
chen xud5ca2d52019-05-28 15:20:57 -07009031 } finally {
9032 Binder.restoreCallingIdentity(identity);
9033 }
9034 }
Jack Yub07d4972019-05-28 16:12:25 -07009035
9036 @Override
Hall Liua62f5da2020-09-25 10:42:19 -07009037 public boolean isMobileDataPolicyEnabled(int subscriptionId, int policy) {
9038 enforceReadPrivilegedPermission("isMobileDataPolicyEnabled");
Jack Yub07d4972019-05-28 16:12:25 -07009039
Jack Yub07d4972019-05-28 16:12:25 -07009040 final long identity = Binder.clearCallingIdentity();
9041 try {
Hall Liua62f5da2020-09-25 10:42:19 -07009042 Phone phone = getPhone(subscriptionId);
Jack Yub07d4972019-05-28 16:12:25 -07009043 if (phone == null) return false;
9044
Hall Liua62f5da2020-09-25 10:42:19 -07009045 switch (policy) {
9046 case TelephonyManager.MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL:
9047 return phone.getDataEnabledSettings().isDataAllowedInVoiceCall();
9048 case TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED:
9049 return phone.getDataEnabledSettings().isMmsAlwaysAllowed();
9050 default:
9051 throw new IllegalArgumentException(policy + " is not a valid policy");
9052 }
Jack Yub07d4972019-05-28 16:12:25 -07009053 } finally {
9054 Binder.restoreCallingIdentity(identity);
9055 }
9056 }
9057
9058 @Override
Hall Liua62f5da2020-09-25 10:42:19 -07009059 public void setMobileDataPolicyEnabledStatus(int subscriptionId, int policy,
9060 boolean enabled) {
changbettyd5c246e2019-12-24 15:40:37 +08009061 enforceModifyPermission();
9062
changbettyd5c246e2019-12-24 15:40:37 +08009063 final long identity = Binder.clearCallingIdentity();
9064 try {
Hall Liua62f5da2020-09-25 10:42:19 -07009065 Phone phone = getPhone(subscriptionId);
9066 if (phone == null) return;
changbettyd5c246e2019-12-24 15:40:37 +08009067
Hall Liua62f5da2020-09-25 10:42:19 -07009068 switch (policy) {
9069 case TelephonyManager.MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL:
9070 phone.getDataEnabledSettings().setAllowDataDuringVoiceCall(enabled);
9071 break;
9072 case TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED:
9073 phone.getDataEnabledSettings().setAlwaysAllowMmsData(enabled);
9074 break;
9075 default:
9076 throw new IllegalArgumentException(policy + " is not a valid policy");
9077 }
changbettyd5c246e2019-12-24 15:40:37 +08009078 } finally {
9079 Binder.restoreCallingIdentity(identity);
9080 }
9081 }
9082
Tyler Gunn7bcdc742019-10-04 15:56:59 -07009083 /**
Hall Liu746e03c2020-09-25 11:13:49 -07009084 * Updates whether conference event package handling is enabled.
Tyler Gunn7bcdc742019-10-04 15:56:59 -07009085 * @param isCepEnabled {@code true} if CEP handling is enabled (default), or {@code false}
9086 * otherwise.
9087 */
9088 @Override
9089 public void setCepEnabled(boolean isCepEnabled) {
9090 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setCepEnabled");
9091
9092 final long identity = Binder.clearCallingIdentity();
9093 try {
9094 Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled);
9095 for (Phone phone : PhoneFactory.getPhones()) {
9096 Phone defaultPhone = phone.getImsPhone();
9097 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
9098 ImsPhone imsPhone = (ImsPhone) defaultPhone;
9099 ImsPhoneCallTracker imsPhoneCallTracker =
9100 (ImsPhoneCallTracker) imsPhone.getCallTracker();
9101 imsPhoneCallTracker.setConferenceEventPackageEnabled(isCepEnabled);
9102 Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled + ", for imsPhone "
9103 + imsPhone.getMsisdn());
9104 }
9105 }
9106 } finally {
9107 Binder.restoreCallingIdentity(identity);
9108 }
9109 }
allenwtsu46dcc572020-01-08 18:24:03 +08009110
9111 /**
9112 * Notify that an RCS autoconfiguration XML file has been received for provisioning.
9113 *
9114 * @param config The XML file to be read. ASCII/UTF8 encoded text if not compressed.
9115 * @param isCompressed The XML file is compressed in gzip format and must be decompressed
9116 * before being read.
9117 */
9118 @Override
9119 public void notifyRcsAutoConfigurationReceived(int subId, @NonNull byte[] config, boolean
9120 isCompressed) {
9121 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
9122 mApp, subId, "notifyRcsAutoConfigurationReceived");
9123 try {
9124 IImsConfig configBinder = getImsConfig(getSlotIndex(subId), ImsFeature.FEATURE_RCS);
9125 if (configBinder == null) {
9126 Rlog.e(LOG_TAG, "null result for getImsConfig");
9127 } else {
9128 configBinder.notifyRcsAutoConfigurationReceived(config, isCompressed);
9129 }
9130 } catch (RemoteException e) {
9131 Rlog.e(LOG_TAG, "fail to getImsConfig " + e.getMessage());
9132 }
9133 }
zoey chene02881a2019-12-30 16:11:23 +08009134
9135 @Override
9136 public boolean isIccLockEnabled(int subId) {
9137 enforceReadPrivilegedPermission("isIccLockEnabled");
9138
9139 // Now that all security checks passes, perform the operation as ourselves.
9140 final long identity = Binder.clearCallingIdentity();
9141 try {
9142 Phone phone = getPhone(subId);
9143 if (phone != null && phone.getIccCard() != null) {
9144 return phone.getIccCard().getIccLockEnabled();
9145 } else {
9146 return false;
9147 }
9148 } finally {
9149 Binder.restoreCallingIdentity(identity);
9150 }
9151 }
9152
9153 /**
9154 * Set the ICC pin lock enabled or disabled.
9155 *
9156 * @return an integer representing the status of IccLock enabled or disabled in the following
9157 * three cases:
9158 * - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if enabled or disabled IccLock
9159 * successfully.
9160 * - Positive number and zero for remaining password attempts.
9161 * - Negative number for other failure cases (such like enabling/disabling PIN failed).
9162 *
9163 */
9164 @Override
9165 public int setIccLockEnabled(int subId, boolean enabled, String password) {
9166 enforceModifyPermission();
9167
9168 Phone phone = getPhone(subId);
9169 if (phone == null) {
9170 return 0;
9171 }
9172 // Now that all security checks passes, perform the operation as ourselves.
9173 final long identity = Binder.clearCallingIdentity();
9174 try {
9175 int attemptsRemaining = (int) sendRequest(CMD_SET_ICC_LOCK_ENABLED,
9176 new Pair<Boolean, String>(enabled, password), phone, null);
9177 return attemptsRemaining;
9178
9179 } catch (Exception e) {
9180 Log.e(LOG_TAG, "setIccLockEnabled. Exception e =" + e);
9181 } finally {
9182 Binder.restoreCallingIdentity(identity);
9183 }
9184 return 0;
9185 }
9186
9187 /**
9188 * Change the ICC password used in ICC pin lock.
9189 *
9190 * @return an integer representing the status of IccLock changed in the following three cases:
9191 * - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if changed IccLock successfully.
9192 * - Positive number and zero for remaining password attempts.
9193 * - Negative number for other failure cases (such like enabling/disabling PIN failed).
9194 *
9195 */
9196 @Override
9197 public int changeIccLockPassword(int subId, String oldPassword, String newPassword) {
9198 enforceModifyPermission();
9199
9200 Phone phone = getPhone(subId);
9201 if (phone == null) {
9202 return 0;
9203 }
9204 // Now that all security checks passes, perform the operation as ourselves.
9205 final long identity = Binder.clearCallingIdentity();
9206 try {
9207 int attemptsRemaining = (int) sendRequest(CMD_CHANGE_ICC_LOCK_PASSWORD,
9208 new Pair<String, String>(oldPassword, newPassword), phone, null);
9209 return attemptsRemaining;
9210
9211 } catch (Exception e) {
9212 Log.e(LOG_TAG, "changeIccLockPassword. Exception e =" + e);
9213 } finally {
9214 Binder.restoreCallingIdentity(identity);
9215 }
9216 return 0;
9217 }
Peter Wangdafb9ac2020-01-15 14:13:38 -08009218
9219 /**
9220 * Request for receiving user activity notification
9221 */
9222 @Override
9223 public void requestUserActivityNotification() {
9224 if (!mNotifyUserActivity.get()
9225 && !mMainThreadHandler.hasMessages(MSG_NOTIFY_USER_ACTIVITY)) {
9226 mNotifyUserActivity.set(true);
9227 }
9228 }
9229
9230 /**
9231 * Called when userActivity is signalled in the power manager.
9232 * This is safe to call from any thread, with any window manager locks held or not.
9233 */
9234 @Override
9235 public void userActivity() {
9236 // ***************************************
9237 // * Inherited from PhoneWindowManager *
9238 // ***************************************
9239 // THIS IS CALLED FROM DEEP IN THE POWER MANAGER
9240 // WITH ITS LOCKS HELD.
9241 //
9242 // This code must be VERY careful about the locks
9243 // it acquires.
9244 // In fact, the current code acquires way too many,
9245 // and probably has lurking deadlocks.
9246
9247 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9248 throw new SecurityException("Only the OS may call notifyUserActivity()");
9249 }
9250
9251 if (mNotifyUserActivity.getAndSet(false)) {
9252 mMainThreadHandler.sendEmptyMessageDelayed(MSG_NOTIFY_USER_ACTIVITY,
9253 USER_ACTIVITY_NOTIFICATION_DELAY);
9254 }
9255 }
Malcolm Chen4639c562020-04-13 11:59:40 -07009256
9257 @Override
9258 public boolean canConnectTo5GInDsdsMode() {
9259 return mApp.getResources().getBoolean(R.bool.config_5g_connection_in_dsds_mode);
9260 }
Jack Yud10cdd42020-09-28 20:28:01 -07009261
9262 @Override
9263 public @NonNull List<String> getEquivalentHomePlmns(int subId, String callingPackage,
9264 String callingFeatureId) {
9265 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
9266 mApp, subId, callingPackage, callingFeatureId, "getEquivalentHomePlmns")) {
9267 throw new SecurityException("Requires READ_PHONE_STATE permission.");
9268 }
9269
9270 Phone phone = getPhone(subId);
9271 if (phone == null) {
9272 throw new RuntimeException("phone is not available");
9273 }
9274 // Now that all security checks passes, perform the operation as ourselves.
9275 final long identity = Binder.clearCallingIdentity();
9276 try {
9277 return phone.getEquivalentHomePlmns();
9278 } finally {
9279 Binder.restoreCallingIdentity(identity);
9280 }
9281 }
Daniel Bright59e67312020-11-13 11:49:37 -08009282
9283 @Override
9284 public boolean isRadioInterfaceCapabilitySupported(
9285 @NonNull @TelephonyManager.RadioInterfaceCapability String capability) {
9286 RadioInterfaceCapabilities radioInterfaceCapabilities =
9287 mPhoneConfigurationManager.getRadioInterfaceCapabilities();
9288 if (radioInterfaceCapabilities == null) {
9289 throw new RuntimeException("radio interface capabilities are not available");
9290 } else {
9291 return radioInterfaceCapabilities.isSupported(capability);
9292 }
9293 }
Jack Nudelmanb0b87642020-11-12 15:04:39 -08009294
9295 /**
9296 * Attempts to set the radio power state for thermal reason. This does not guarantee that the
9297 * requested radio power state will actually be set. See {@link
9298 * PhoneInternalInterface#setRadioPowerForReason} for more details.
9299 *
9300 * @param subId the subscription ID of the phone requesting to set the radio power state.
9301 * @param enable {@code true} if trying to turn radio on.
9302 * @return {@code true} if phone setRadioPowerForReason was called. Otherwise, returns {@code
9303 * false}.
9304 */
9305 private boolean setRadioPowerForThermal(int subId, boolean enable) {
9306 Phone phone = getPhone(subId);
9307 if (phone != null) {
9308 phone.setRadioPowerForReason(enable, Phone.RADIO_POWER_REASON_THERMAL);
9309 return true;
9310 }
9311 return false;
9312 }
9313
9314 private int handleDataThrottlingRequest(int subId,
9315 DataThrottlingRequest dataThrottlingRequest) {
9316 // Ensure that radio is on. If not able to power on due to phone being unavailable, return
9317 // THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
9318 if (!setRadioPowerForThermal(subId, true)) {
9319 return TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
9320 }
9321
9322 setDataEnabledForReason(subId, TelephonyManager.DATA_ENABLED_REASON_THERMAL, true);
9323
9324 int thermalMitigationResult =
9325 (int) sendRequest(CMD_SET_DATA_THROTTLING, dataThrottlingRequest, subId);
9326 if (thermalMitigationResult == SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS) {
9327 throw new IllegalArgumentException("modem returned INVALID_ARGUMENTS");
9328 }
9329 return thermalMitigationResult;
9330 }
9331
9332 /**
9333 * Thermal mitigation request to control functionalities at modem.
9334 *
9335 * @param subId the id of the subscription.
9336 * @param thermalMitigationRequest holds all necessary information to be passed down to modem.
9337 *
9338 * @return thermalMitigationResult enum as defined in android.telephony.Annotation.
9339 */
9340 @Override
9341 @ThermalMitigationResult
9342 public int sendThermalMitigationRequest(
9343 int subId,
9344 ThermalMitigationRequest thermalMitigationRequest) throws IllegalArgumentException {
9345 enforceModifyPermission();
9346
9347 WorkSource workSource = getWorkSource(Binder.getCallingUid());
9348 final long identity = Binder.clearCallingIdentity();
9349
9350 int thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_UNKNOWN_ERROR;
9351 try {
9352 int thermalMitigationAction = thermalMitigationRequest.getThermalMitigationAction();
9353 switch (thermalMitigationAction) {
9354 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_DATA_THROTTLING:
9355 thermalMitigationResult =
9356 handleDataThrottlingRequest(subId,
9357 thermalMitigationRequest.getDataThrottlingRequest());
9358 break;
9359 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_VOICE_ONLY:
9360 if (thermalMitigationRequest.getDataThrottlingRequest() != null) {
9361 throw new IllegalArgumentException("dataThrottlingRequest must be null for "
9362 + "ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_VOICE_ONLY");
9363 }
9364
9365 // Ensure that radio is on. If not able to power on due to phone being
9366 // unavailable, return THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
9367 if (!setRadioPowerForThermal(subId, true)) {
9368 thermalMitigationResult =
9369 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
9370 break;
9371 }
9372
9373 setDataEnabledForReason(subId, TelephonyManager.DATA_ENABLED_REASON_THERMAL,
9374 false);
9375 thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
9376 break;
9377 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_RADIO_OFF:
9378 if (thermalMitigationRequest.getDataThrottlingRequest() != null) {
9379 throw new IllegalArgumentException("dataThrottlingRequest must be null for"
9380 + " ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_RADIO_OFF");
9381 }
9382
9383 TelecomAccountRegistry registry = TelecomAccountRegistry.getInstance(null);
9384 if (registry != null) {
9385 TelephonyConnectionService service =
9386 registry.getTelephonyConnectionService();
9387 Phone phone = getPhone(subId);
9388 if (phone == null) {
9389 thermalMitigationResult =
9390 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
9391 break;
9392 }
9393
9394 if (PhoneConstantConversions.convertCallState(phone.getState())
9395 != TelephonyManager.CALL_STATE_IDLE
9396 || phone.isInEmergencySmsMode() || phone.isInEcm()
9397 || (service != null && service.isEmergencyCallPending())) {
9398 String errorMessage = "Phone state is not valid. call state = "
9399 + PhoneConstantConversions.convertCallState(phone.getState())
9400 + " isInEmergencySmsMode = " + phone.isInEmergencySmsMode()
9401 + " isInEmergencyCallbackMode = " + phone.isInEcm();
9402 errorMessage += service == null
9403 ? " TelephonyConnectionService is null"
9404 : " isEmergencyCallPending = "
9405 + service.isEmergencyCallPending();
9406 Log.e(LOG_TAG, errorMessage);
9407 thermalMitigationResult =
9408 TelephonyManager.THERMAL_MITIGATION_RESULT_INVALID_STATE;
9409 break;
9410 }
9411 } else {
9412 thermalMitigationResult =
9413 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
9414 break;
9415 }
9416
9417 // Turn radio off. If not able to power off due to phone being unavailable,
9418 // return THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
9419 if (!setRadioPowerForThermal(subId, false)) {
9420 thermalMitigationResult =
9421 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
9422 break;
9423 }
9424 thermalMitigationResult =
9425 TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
9426 break;
9427 default:
9428 throw new IllegalArgumentException("the requested thermalMitigationAction does "
9429 + "not exist. Requested action: " + thermalMitigationAction);
9430 }
9431 } catch (IllegalArgumentException e) {
9432 throw e;
9433 } catch (Exception e) {
9434 Log.e(LOG_TAG, "thermalMitigationRequest. Exception e =" + e);
9435 thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
9436 } finally {
9437 Binder.restoreCallingIdentity(identity);
9438 }
9439
9440 if (DBG) {
9441 log("thermalMitigationRequest returning with thermalMitigationResult: "
9442 + thermalMitigationResult);
9443 }
9444
9445 return thermalMitigationResult;
9446 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07009447}