blob: e90f37c6db98529e4a9dab1ddf038140208fa257 [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;
Gil Cukierman1c0eb932022-12-06 22:28:24 +000020import static android.telephony.TelephonyManager.HAL_SERVICE_NETWORK;
jimsunf9ec1622022-09-13 21:18:43 +080021import static android.telephony.TelephonyManager.HAL_SERVICE_RADIO;
Hall Liud892bec2018-11-30 14:51:45 -080022
Shuo Qianccbaf742021-02-22 18:32:21 -080023import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_CDMA;
24import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_GSM;
Tyler Gunn7bcdc742019-10-04 15:56:59 -070025import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_IMS;
Ta-wei Yen87c49842016-05-13 21:19:52 -070026import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
joonhunshin3e154242021-09-17 06:33:39 +000027import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__CLIENT_PARAMS_SENT;
Ta-wei Yen87c49842016-05-13 21:19:52 -070028
Brad Ebinger34c09a52021-02-17 23:23:21 +000029import android.Manifest;
Ta-wei Yen30a69c82016-12-27 14:52:32 -080030import android.Manifest.permission;
Hall Liua1548bd2019-12-24 14:14:12 -080031import android.annotation.NonNull;
Tyler Gunnf70ed162019-04-03 15:28:53 -070032import android.annotation.Nullable;
sandeepjsb6c87872021-09-27 15:34:44 +000033import android.annotation.RequiresPermission;
Sarah Chin532d6bb2022-12-28 22:50:43 -080034import android.app.ActivityManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070035import android.app.AppOpsManager;
Ta-wei Yen30a69c82016-12-27 14:52:32 -080036import android.app.PendingIntent;
Tyler Gunn64144d92022-03-17 14:16:41 -070037import android.app.PropertyInvalidatedCache;
Brad Ebinger4f6208e2021-03-23 21:04:45 +000038import android.app.compat.CompatChanges;
Hall Liu82694d52020-12-11 18:22:04 -080039import android.app.role.RoleManager;
sandeepjsb6c87872021-09-27 15:34:44 +000040import android.compat.annotation.ChangeId;
41import android.compat.annotation.EnabledSince;
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -070042import android.content.ComponentName;
Amit Mahajan7dbbd822019-03-13 17:33:47 -070043import android.content.ContentResolver;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070044import android.content.Context;
45import android.content.Intent;
Derek Tan97ebb422014-09-05 16:55:38 -070046import android.content.SharedPreferences;
Derek Tan740e1672017-06-27 14:56:27 -070047import android.content.pm.ComponentInfo;
Shishir Agrawal60f9c952014-06-23 12:00:43 -070048import android.content.pm.PackageManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070049import android.net.Uri;
50import android.os.AsyncResult;
51import android.os.Binder;
Hall Liuf19c44f2018-11-27 14:38:17 -080052import android.os.Build;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070053import android.os.Bundle;
54import android.os.Handler;
yinxu504e1392017-04-12 16:03:22 -070055import android.os.IBinder;
tom hsu0b59d292022-09-29 23:49:21 +080056import android.os.LocaleList;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070057import android.os.Looper;
58import android.os.Message;
yinxu504e1392017-04-12 16:03:22 -070059import android.os.Messenger;
Hall Liua1548bd2019-12-24 14:14:12 -080060import android.os.ParcelFileDescriptor;
Malcolm Chen6ca97372019-07-01 16:28:21 -070061import android.os.ParcelUuid;
Tyler Gunn65d45c22017-06-05 11:22:26 -070062import android.os.PersistableBundle;
Shuo Qiancd19c462020-01-16 20:51:11 -080063import android.os.Process;
Brad Ebinger5f64b052017-12-14 14:26:15 -080064import android.os.RemoteException;
Adam Lesinski903a54c2016-04-11 14:49:52 -070065import android.os.ResultReceiver;
Brad Ebinger1ce9c432019-07-16 13:19:44 -070066import android.os.ServiceSpecificException;
Rambo Wang0f050d82021-02-12 11:43:36 -080067import android.os.SystemClock;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070068import android.os.UserHandle;
Stuart Scott981d8582015-04-21 14:09:50 -070069import android.os.UserManager;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070070import android.os.WorkSource;
Derek Tan97ebb422014-09-05 16:55:38 -070071import android.preference.PreferenceManager;
Naina Nallurid63128d2019-09-17 14:10:30 -070072import android.provider.DeviceConfig;
Ihab Awadf2177b72013-11-25 13:33:23 -080073import android.provider.Settings;
Amit Mahajan7dbbd822019-03-13 17:33:47 -070074import android.provider.Telephony;
arunvoddud7401012022-12-15 16:08:12 +000075import android.service.carrier.CarrierIdentifier;
Inseob Kim14bb3d02018-12-13 17:11:34 +090076import android.sysprop.TelephonyProperties;
Santos Cordon7a1885b2015-02-03 11:15:19 -080077import android.telecom.PhoneAccount;
Nancy Chen31f9ba12016-01-06 11:42:12 -080078import android.telecom.PhoneAccountHandle;
Andrew Lee9431b832015-03-09 18:46:45 -070079import android.telecom.TelecomManager;
Gary Jian3aa9a762022-01-24 16:41:19 +080080import android.telephony.AccessNetworkConstants;
81import android.telephony.ActivityStatsTechSpecificInfo;
Chen Xu227e06f2019-09-26 22:48:11 -070082import android.telephony.Annotation.ApnType;
Jack Yu0eda6842022-04-18 00:34:46 -070083import android.telephony.Annotation.DataActivityType;
Jack Nudelmanb0b87642020-11-12 15:04:39 -080084import android.telephony.Annotation.ThermalMitigationResult;
Sarah Chin2ec39f62022-08-31 17:03:26 -070085import android.telephony.AnomalyReporter;
Shuo Qian4a594052020-01-23 11:59:30 -080086import android.telephony.CallForwardingInfo;
Junda Liu12f7d802015-05-01 12:06:44 -070087import android.telephony.CarrierConfigManager;
Michele Berionne482f8202018-11-27 18:57:59 -080088import android.telephony.CarrierRestrictionRules;
Hui Wang9b5793a2022-12-05 14:38:06 -060089import android.telephony.CellBroadcastIdRange;
yincheng zhao2737e882019-09-06 17:06:54 -070090import android.telephony.CellIdentity;
Meng Wanga10e89e2019-12-09 13:13:01 -080091import android.telephony.CellIdentityCdma;
92import android.telephony.CellIdentityGsm;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070093import android.telephony.CellInfo;
Nathan Haroldf180aac2018-06-01 18:43:55 -070094import android.telephony.CellInfoGsm;
95import android.telephony.CellInfoWcdma;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070096import android.telephony.ClientRequestStats;
Jack Nudelmanb0b87642020-11-12 15:04:39 -080097import android.telephony.DataThrottlingRequest;
Hui Wang641e81c2020-10-12 12:14:23 -070098import android.telephony.IBootstrapAuthenticationCallback;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -070099import android.telephony.ICellInfoCallback;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700100import android.telephony.IccOpenLogicalChannelResponse;
Hall Liu1aa510f2017-11-22 17:40:08 -0800101import android.telephony.LocationAccessPolicy;
Ta-wei Yen87c49842016-05-13 21:19:52 -0700102import android.telephony.ModemActivityInfo;
Jake Hambye994d462014-02-03 13:10:13 -0800103import android.telephony.NeighboringCellInfo;
yinxu504e1392017-04-12 16:03:22 -0700104import android.telephony.NetworkScanRequest;
Michele4245e952019-02-04 11:36:23 -0800105import android.telephony.PhoneCapability;
Hall Liud892bec2018-11-30 14:51:45 -0800106import android.telephony.PhoneNumberRange;
Wink Saville5d475dd2014-10-17 15:00:58 -0700107import android.telephony.RadioAccessFamily;
Hall Liub2ac8ef2019-02-28 15:56:23 -0800108import android.telephony.RadioAccessSpecifier;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700109import android.telephony.ServiceState;
Nathan Harold46b42aa2017-03-10 19:38:22 -0800110import android.telephony.SignalStrength;
Rambo Wanga5cc9b72021-01-07 10:51:54 -0800111import android.telephony.SignalStrengthUpdateRequest;
112import android.telephony.SignalThresholdInfo;
Wink Saville0f3b5fc2014-11-11 08:40:49 -0800113import android.telephony.SubscriptionInfo;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800114import android.telephony.SubscriptionManager;
Peter Wangc035ce42020-01-08 21:00:22 -0800115import android.telephony.TelephonyFrameworkInitializer;
Sanket Padawe99ef1e32016-05-18 16:12:33 -0700116import android.telephony.TelephonyHistogram;
Ta-wei Yenb6929602016-05-24 15:48:27 -0700117import android.telephony.TelephonyManager;
Jack Yuf5badd92022-12-08 00:50:53 -0800118import android.telephony.TelephonyManager.SimState;
Hall Liub2ac8ef2019-02-28 15:56:23 -0800119import android.telephony.TelephonyScanManager;
Jack Nudelmanb0b87642020-11-12 15:04:39 -0800120import android.telephony.ThermalMitigationRequest;
Jordan Liu5aa07002018-12-18 15:44:48 -0800121import android.telephony.UiccCardInfo;
sandeepjsb6c87872021-09-27 15:34:44 +0000122import android.telephony.UiccPortInfo;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000123import android.telephony.UiccSlotInfo;
sandeepjsb6c87872021-09-27 15:34:44 +0000124import android.telephony.UiccSlotMapping;
Tyler Gunn65d45c22017-06-05 11:22:26 -0700125import android.telephony.UssdResponse;
Ta-wei Yenb6929602016-05-24 15:48:27 -0700126import android.telephony.VisualVoicemailSmsFilterSettings;
Hongbo Zeng0e18b162021-04-07 16:52:18 +0800127import android.telephony.data.NetworkSlicingConfig;
Jack Yub5d8f642018-11-26 11:20:48 -0800128import android.telephony.emergency.EmergencyNumber;
Hui Wang641e81c2020-10-12 12:14:23 -0700129import android.telephony.gba.GbaAuthRequest;
130import android.telephony.gba.UaSecurityProtocolIdentifier;
Brad Ebinger1ce9c432019-07-16 13:19:44 -0700131import android.telephony.ims.ImsException;
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800132import android.telephony.ims.ProvisioningManager;
Hui Wang761a6682020-10-31 05:12:53 +0000133import android.telephony.ims.RcsClientConfiguration;
Brad Ebinger14d467f2021-02-12 06:18:28 +0000134import android.telephony.ims.RcsContactUceCapability;
Brad Ebingera34a6c22019-10-22 17:36:18 -0700135import android.telephony.ims.RegistrationManager;
joonhunshincffb7fc2021-11-28 07:32:01 +0000136import android.telephony.ims.aidl.IFeatureProvisioningCallback;
Brad Ebinger35c841c2018-10-01 10:40:55 -0700137import android.telephony.ims.aidl.IImsCapabilityCallback;
Brad Ebinger22bc3e42018-01-16 09:39:35 -0800138import android.telephony.ims.aidl.IImsConfig;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -0700139import android.telephony.ims.aidl.IImsConfigCallback;
Brad Ebinger22bc3e42018-01-16 09:39:35 -0800140import android.telephony.ims.aidl.IImsRegistration;
Brad Ebinger35c841c2018-10-01 10:40:55 -0700141import android.telephony.ims.aidl.IImsRegistrationCallback;
Hui Wang761a6682020-10-31 05:12:53 +0000142import android.telephony.ims.aidl.IRcsConfigCallback;
Brad Ebingerbc7dd582019-10-17 17:03:22 -0700143import android.telephony.ims.feature.ImsFeature;
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800144import android.telephony.ims.stub.ImsConfigImplBase;
Brad Ebinger1f2b5082018-02-08 16:11:32 -0800145import android.telephony.ims.stub.ImsRegistrationImplBase;
Sarah Chineccfbd12023-01-20 19:00:35 -0800146import android.telephony.satellite.ISatellitePositionUpdateCallback;
147import android.telephony.satellite.PointingInfo;
148import android.telephony.satellite.SatelliteManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700149import android.text.TextUtils;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800150import android.util.ArraySet;
Hall Liud60acc92020-05-21 17:09:35 -0700151import android.util.EventLog;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700152import android.util.Log;
Jake Hambye994d462014-02-03 13:10:13 -0800153import android.util.Pair;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800154
Andrew Lee312e8172014-10-23 17:01:36 -0700155import com.android.ims.ImsManager;
Brad Ebinger34bef922017-11-09 10:27:08 -0800156import com.android.ims.internal.IImsServiceFeatureCallback;
James.cf Linbcdf8b32021-01-14 16:44:13 +0800157import com.android.ims.rcs.uce.eab.EabUtil;
SongFerngWangfd89b102021-05-27 22:44:54 +0800158import com.android.internal.annotations.VisibleForTesting;
Shuo Qian4a594052020-01-23 11:59:30 -0800159import com.android.internal.telephony.CallForwardInfo;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700160import com.android.internal.telephony.CallManager;
Tyler Gunn52dcf772017-04-26 11:30:31 -0700161import com.android.internal.telephony.CallStateException;
Tyler Gunnd4339262021-05-03 14:46:49 -0700162import com.android.internal.telephony.CallTracker;
Rambo Wang9c9ffdd2022-01-13 21:51:44 -0800163import com.android.internal.telephony.CarrierPrivilegesTracker;
chen xu651eec72018-11-11 19:03:44 -0800164import com.android.internal.telephony.CarrierResolver;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700165import com.android.internal.telephony.CellNetworkScanResult;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700166import com.android.internal.telephony.CommandException;
Shuo Qian4a594052020-01-23 11:59:30 -0800167import com.android.internal.telephony.CommandsInterface;
Hui Wang641e81c2020-10-12 12:14:23 -0700168import com.android.internal.telephony.GbaManager;
Shuo Qianccbaf742021-02-22 18:32:21 -0800169import com.android.internal.telephony.GsmCdmaPhone;
Nathan Harold48d6fd52019-02-06 19:01:40 -0800170import com.android.internal.telephony.HalVersion;
Hall Liu73f5d362020-01-20 13:42:00 -0800171import com.android.internal.telephony.IBooleanConsumer;
Hall Liu27d24262020-09-18 19:04:59 -0700172import com.android.internal.telephony.ICallForwardingInfoCallback;
Hunsuk Choi3b742d62021-10-25 19:48:34 +0000173import com.android.internal.telephony.IImsStateCallback;
Brad Ebingera63db5f2019-04-23 16:31:13 -0700174import com.android.internal.telephony.IIntegerConsumer;
Hall Liud892bec2018-11-30 14:51:45 -0800175import com.android.internal.telephony.INumberVerificationCallback;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700176import com.android.internal.telephony.ITelephony;
Jake Hambye994d462014-02-03 13:10:13 -0800177import com.android.internal.telephony.IccCard;
Jack Yuf5badd92022-12-08 00:50:53 -0800178import com.android.internal.telephony.IccCardConstants;
Rambo Wanga1782702021-11-10 20:15:19 -0800179import com.android.internal.telephony.IccLogicalChannelRequest;
Jack Yu5f7092c2018-04-13 14:05:37 -0700180import com.android.internal.telephony.LocaleTracker;
yinxub1bed742017-04-17 11:45:04 -0700181import com.android.internal.telephony.NetworkScanRequestTracker;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700182import com.android.internal.telephony.OperatorInfo;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700183import com.android.internal.telephony.Phone;
Malcolm Chen2c63d402018-08-14 16:00:53 -0700184import com.android.internal.telephony.PhoneConfigurationManager;
Nathan Harolda667c152016-12-14 11:27:20 -0800185import com.android.internal.telephony.PhoneConstantConversions;
Ta-wei Yen87c49842016-05-13 21:19:52 -0700186import com.android.internal.telephony.PhoneConstants;
Wink Saville36469e72014-06-11 15:17:00 -0700187import com.android.internal.telephony.PhoneFactory;
Wink Saville5d475dd2014-10-17 15:00:58 -0700188import com.android.internal.telephony.ProxyController;
Sanket Padawe99ef1e32016-05-18 16:12:33 -0700189import com.android.internal.telephony.RIL;
SongFerngWang8c6e82e2021-03-02 22:09:29 +0800190import com.android.internal.telephony.RILConstants;
Sarah Chineccfbd12023-01-20 19:00:35 -0800191import com.android.internal.telephony.RILUtils;
Daniel Bright94f43662021-03-01 14:43:40 -0800192import com.android.internal.telephony.RadioInterfaceCapabilityController;
Jack Yu5f7092c2018-04-13 14:05:37 -0700193import com.android.internal.telephony.ServiceStateTracker;
Aishwarya Mallampatifbc70d32022-11-10 20:33:02 +0000194import com.android.internal.telephony.SmsApplication;
Amit Mahajandccb3f12019-05-13 13:48:32 -0700195import com.android.internal.telephony.SmsController;
Brad Ebingera63db5f2019-04-23 16:31:13 -0700196import com.android.internal.telephony.SmsPermissions;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800197import com.android.internal.telephony.SubscriptionController;
Peter Wang59571be2020-01-27 12:35:15 +0800198import com.android.internal.telephony.TelephonyIntents;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800199import com.android.internal.telephony.TelephonyPermissions;
Jack Yu27422a52022-03-21 10:38:05 -0700200import com.android.internal.telephony.data.DataUtils;
Hunsuk Choi42cc62a2022-10-16 06:03:40 +0000201import com.android.internal.telephony.domainselection.DomainSelectionResolver;
sqianf4ca7ed2019-01-15 18:32:07 -0800202import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Derek Tan740e1672017-06-27 14:56:27 -0700203import com.android.internal.telephony.euicc.EuiccConnector;
Brad Ebinger9c0eb502019-01-23 15:06:19 -0800204import com.android.internal.telephony.ims.ImsResolver;
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700205import com.android.internal.telephony.imsphone.ImsPhone;
206import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
joonhunshin3e154242021-09-17 06:33:39 +0000207import com.android.internal.telephony.metrics.RcsStats;
Pengquan Meng6c2dc9f2019-02-06 11:12:53 -0800208import com.android.internal.telephony.metrics.TelephonyMetrics;
Jack Yu285100e2022-12-02 22:48:35 -0800209import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
210import com.android.internal.telephony.subscription.SubscriptionManagerService;
Meng Wangafbc5852019-09-19 17:37:13 -0700211import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700212import com.android.internal.telephony.uicc.IccIoResult;
213import com.android.internal.telephony.uicc.IccUtils;
Nathan Haroldb3014052017-01-25 15:57:32 -0800214import com.android.internal.telephony.uicc.SIMRecords;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700215import com.android.internal.telephony.uicc.UiccCard;
Nathan Haroldb3014052017-01-25 15:57:32 -0800216import com.android.internal.telephony.uicc.UiccCardApplication;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700217import com.android.internal.telephony.uicc.UiccController;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000218import com.android.internal.telephony.uicc.UiccPort;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800219import com.android.internal.telephony.uicc.UiccProfile;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000220import com.android.internal.telephony.uicc.UiccSlot;
zoey chenc730df82019-12-18 17:07:20 +0800221import com.android.internal.telephony.util.LocaleUtils;
Aishwarya Mallampatifbc70d32022-11-10 20:33:02 +0000222import com.android.internal.telephony.util.TelephonyUtils;
fionaxu7ed723d2017-05-30 18:58:54 -0700223import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
Hall Liu27d24262020-09-18 19:04:59 -0700224import com.android.internal.util.FunctionalUtils;
Jake Hambye994d462014-02-03 13:10:13 -0800225import com.android.internal.util.HexDump;
Hall Liuaa4211e2021-01-20 15:43:39 -0800226import com.android.phone.callcomposer.CallComposerPictureManager;
227import com.android.phone.callcomposer.CallComposerPictureTransfer;
228import com.android.phone.callcomposer.ImageData;
Brad Ebingera63db5f2019-04-23 16:31:13 -0700229import com.android.phone.settings.PickSmsSubscriptionActivity;
Sarah Chin46355ba2022-11-01 23:51:16 -0700230import com.android.phone.slice.SlicePurchaseController;
arunvoddud7401012022-12-15 16:08:12 +0000231import com.android.phone.utils.CarrierAllowListInfo;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700232import com.android.phone.vvm.PhoneAccountHandleConverter;
Ta-wei Yen527a9c02017-01-06 15:29:25 -0800233import com.android.phone.vvm.RemoteVvmTaskManager;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700234import com.android.phone.vvm.VisualVoicemailSettingsUtil;
Ta-wei Yenc8905312017-03-28 11:14:45 -0700235import com.android.phone.vvm.VisualVoicemailSmsFilterConfig;
Jack Nudelmanb0b87642020-11-12 15:04:39 -0800236import com.android.services.telephony.TelecomAccountRegistry;
237import com.android.services.telephony.TelephonyConnectionService;
Peter Wang44b186e2020-01-13 23:33:09 -0800238import com.android.telephony.Rlog;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800239
Hall Liu82694d52020-12-11 18:22:04 -0800240import java.io.ByteArrayOutputStream;
Ta-wei Yenc236d6b2016-06-21 13:33:12 -0700241import java.io.FileDescriptor;
Hall Liu82694d52020-12-11 18:22:04 -0800242import java.io.IOException;
243import java.io.InputStream;
Ta-wei Yenc236d6b2016-06-21 13:33:12 -0700244import java.io.PrintWriter;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700245import java.util.ArrayList;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800246import java.util.Arrays;
Muralidhar Reddyeb809e32021-11-19 03:07:54 +0000247import java.util.Collection;
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -0800248import java.util.Collections;
sqian11b7a0e2018-12-05 18:48:28 -0800249import java.util.HashMap;
sqianf4ca7ed2019-01-15 18:32:07 -0800250import java.util.HashSet;
Jake Hambye994d462014-02-03 13:10:13 -0800251import java.util.List;
Narayan Kamath1c496c22015-04-16 14:40:19 +0100252import java.util.Locale;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800253import java.util.Map;
Nazanin Bakhshif71371d2019-04-29 17:29:44 -0700254import java.util.NoSuchElementException;
Hall Liu82694d52020-12-11 18:22:04 -0800255import java.util.Objects;
sqianf4ca7ed2019-01-15 18:32:07 -0800256import java.util.Set;
Sarah Chin2ec39f62022-08-31 17:03:26 -0700257import java.util.UUID;
Sarah Chineccfbd12023-01-20 19:00:35 -0800258import java.util.concurrent.ConcurrentHashMap;
Hall Liu82694d52020-12-11 18:22:04 -0800259import java.util.concurrent.Executors;
Peter Wangdafb9ac2020-01-15 14:13:38 -0800260import java.util.concurrent.atomic.AtomicBoolean;
Hall Liu73f5d362020-01-20 13:42:00 -0800261import java.util.function.Consumer;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700262
263/**
264 * Implementation of the ITelephony interface.
265 */
Santos Cordon117fee72014-05-16 17:56:12 -0700266public class PhoneInterfaceManager extends ITelephony.Stub {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700267 private static final String LOG_TAG = "PhoneInterfaceManager";
268 private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
269 private static final boolean DBG_LOC = false;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800270 private static final boolean DBG_MERGE = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700271
272 // Message codes used with mMainThreadHandler
273 private static final int CMD_HANDLE_PIN_MMI = 1;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700274 private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7;
275 private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700276 private static final int CMD_OPEN_CHANNEL = 9;
277 private static final int EVENT_OPEN_CHANNEL_DONE = 10;
278 private static final int CMD_CLOSE_CHANNEL = 11;
279 private static final int EVENT_CLOSE_CHANNEL_DONE = 12;
Jake Hambye994d462014-02-03 13:10:13 -0800280 private static final int CMD_NV_READ_ITEM = 13;
281 private static final int EVENT_NV_READ_ITEM_DONE = 14;
282 private static final int CMD_NV_WRITE_ITEM = 15;
283 private static final int EVENT_NV_WRITE_ITEM_DONE = 16;
284 private static final int CMD_NV_WRITE_CDMA_PRL = 17;
285 private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18;
chen xu6dac5ab2018-10-26 17:39:23 -0700286 private static final int CMD_RESET_MODEM_CONFIG = 19;
287 private static final int EVENT_RESET_MODEM_CONFIG_DONE = 20;
SongFerngWang3ef3e072020-12-21 16:41:52 +0800288 private static final int CMD_GET_ALLOWED_NETWORK_TYPES_BITMASK = 21;
289 private static final int EVENT_GET_ALLOWED_NETWORK_TYPES_BITMASK_DONE = 22;
Sailesh Nepal35b59452014-03-06 09:26:56 -0800290 private static final int CMD_SEND_ENVELOPE = 25;
291 private static final int EVENT_SEND_ENVELOPE_DONE = 26;
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000292 private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27;
293 private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28;
Derek Tan6b088ee2014-09-05 14:15:18 -0700294 private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29;
295 private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30;
296 private static final int CMD_EXCHANGE_SIM_IO = 31;
297 private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800298 private static final int CMD_SET_VOICEMAIL_NUMBER = 33;
299 private static final int EVENT_SET_VOICEMAIL_NUMBER_DONE = 34;
Stuart Scott54788802015-03-30 13:18:01 -0700300 private static final int CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC = 35;
301 private static final int EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE = 36;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700302 private static final int CMD_GET_MODEM_ACTIVITY_INFO = 37;
303 private static final int EVENT_GET_MODEM_ACTIVITY_INFO_DONE = 38;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700304 private static final int CMD_PERFORM_NETWORK_SCAN = 39;
305 private static final int EVENT_PERFORM_NETWORK_SCAN_DONE = 40;
306 private static final int CMD_SET_NETWORK_SELECTION_MODE_MANUAL = 41;
307 private static final int EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE = 42;
Meng Wang1a7c35a2016-05-05 20:56:15 -0700308 private static final int CMD_SET_ALLOWED_CARRIERS = 43;
309 private static final int EVENT_SET_ALLOWED_CARRIERS_DONE = 44;
310 private static final int CMD_GET_ALLOWED_CARRIERS = 45;
311 private static final int EVENT_GET_ALLOWED_CARRIERS_DONE = 46;
pkanwar32d516d2016-10-14 19:37:38 -0700312 private static final int CMD_HANDLE_USSD_REQUEST = 47;
Nathan Haroldb3014052017-01-25 15:57:32 -0800313 private static final int CMD_GET_FORBIDDEN_PLMNS = 48;
314 private static final int EVENT_GET_FORBIDDEN_PLMNS_DONE = 49;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000315 private static final int CMD_SWITCH_SLOTS = 50;
316 private static final int EVENT_SWITCH_SLOTS_DONE = 51;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700317 private static final int CMD_GET_NETWORK_SELECTION_MODE = 52;
318 private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 53;
319 private static final int CMD_GET_CDMA_ROAMING_MODE = 54;
320 private static final int EVENT_GET_CDMA_ROAMING_MODE_DONE = 55;
321 private static final int CMD_SET_CDMA_ROAMING_MODE = 56;
322 private static final int EVENT_SET_CDMA_ROAMING_MODE_DONE = 57;
323 private static final int CMD_SET_CDMA_SUBSCRIPTION_MODE = 58;
324 private static final int EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE = 59;
Nathan Harold3ff88932018-08-14 10:19:49 -0700325 private static final int CMD_GET_ALL_CELL_INFO = 60;
326 private static final int EVENT_GET_ALL_CELL_INFO_DONE = 61;
327 private static final int CMD_GET_CELL_LOCATION = 62;
328 private static final int EVENT_GET_CELL_LOCATION_DONE = 63;
chen xu6dac5ab2018-10-26 17:39:23 -0700329 private static final int CMD_MODEM_REBOOT = 64;
330 private static final int EVENT_CMD_MODEM_REBOOT_DONE = 65;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -0700331 private static final int CMD_REQUEST_CELL_INFO_UPDATE = 66;
332 private static final int EVENT_REQUEST_CELL_INFO_UPDATE_DONE = 67;
Malcolm Chen8e4ed912019-01-15 20:22:16 -0800333 private static final int CMD_REQUEST_ENABLE_MODEM = 68;
334 private static final int EVENT_ENABLE_MODEM_DONE = 69;
Nazanin Bakhshif71371d2019-04-29 17:29:44 -0700335 private static final int CMD_GET_MODEM_STATUS = 70;
336 private static final int EVENT_GET_MODEM_STATUS_DONE = 71;
yincheng zhao2737e882019-09-06 17:06:54 -0700337 private static final int CMD_SET_FORBIDDEN_PLMNS = 72;
338 private static final int EVENT_SET_FORBIDDEN_PLMNS_DONE = 73;
Naina Nallurid63128d2019-09-17 14:10:30 -0700339 private static final int CMD_ERASE_MODEM_CONFIG = 74;
340 private static final int EVENT_ERASE_MODEM_CONFIG_DONE = 75;
zoey chene02881a2019-12-30 16:11:23 +0800341 private static final int CMD_CHANGE_ICC_LOCK_PASSWORD = 76;
342 private static final int EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE = 77;
343 private static final int CMD_SET_ICC_LOCK_ENABLED = 78;
344 private static final int EVENT_SET_ICC_LOCK_ENABLED_DONE = 79;
Hall Liu73f5d362020-01-20 13:42:00 -0800345 private static final int CMD_SET_SYSTEM_SELECTION_CHANNELS = 80;
346 private static final int EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE = 81;
Peter Wangdafb9ac2020-01-15 14:13:38 -0800347 private static final int MSG_NOTIFY_USER_ACTIVITY = 82;
Shuo Qian4a594052020-01-23 11:59:30 -0800348 private static final int CMD_GET_CALL_FORWARDING = 83;
349 private static final int EVENT_GET_CALL_FORWARDING_DONE = 84;
350 private static final int CMD_SET_CALL_FORWARDING = 85;
351 private static final int EVENT_SET_CALL_FORWARDING_DONE = 86;
352 private static final int CMD_GET_CALL_WAITING = 87;
353 private static final int EVENT_GET_CALL_WAITING_DONE = 88;
354 private static final int CMD_SET_CALL_WAITING = 89;
355 private static final int EVENT_SET_CALL_WAITING_DONE = 90;
Sooraj Sasindran37444802020-08-11 10:40:43 -0700356 private static final int CMD_ENABLE_NR_DUAL_CONNECTIVITY = 91;
357 private static final int EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE = 92;
358 private static final int CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED = 93;
359 private static final int EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE = 94;
Sarah Chinbaab1432020-10-28 13:46:24 -0700360 private static final int CMD_GET_CDMA_SUBSCRIPTION_MODE = 95;
361 private static final int EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE = 96;
Sarah Chin679c08a2020-11-18 13:39:35 -0800362 private static final int CMD_GET_SYSTEM_SELECTION_CHANNELS = 97;
363 private static final int EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE = 98;
Jack Nudelmanb0b87642020-11-12 15:04:39 -0800364 private static final int CMD_SET_DATA_THROTTLING = 99;
365 private static final int EVENT_SET_DATA_THROTTLING_DONE = 100;
Jordan Liu109698e2020-11-24 14:50:34 -0800366 private static final int CMD_SET_SIM_POWER = 101;
367 private static final int EVENT_SET_SIM_POWER_DONE = 102;
Rambo Wanga5cc9b72021-01-07 10:51:54 -0800368 private static final int CMD_SET_SIGNAL_STRENGTH_UPDATE_REQUEST = 103;
369 private static final int EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE = 104;
370 private static final int CMD_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST = 105;
371 private static final int EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE = 106;
SongFerngWang3ef3e072020-12-21 16:41:52 +0800372 private static final int CMD_SET_ALLOWED_NETWORK_TYPES_FOR_REASON = 107;
373 private static final int EVENT_SET_ALLOWED_NETWORK_TYPES_FOR_REASON_DONE = 108;
Michele Berionne5e411512020-11-13 02:36:59 +0000374 private static final int CMD_PREPARE_UNATTENDED_REBOOT = 109;
Hongbo Zeng156aa4a2021-02-08 21:50:28 +0800375 private static final int CMD_GET_SLICING_CONFIG = 110;
376 private static final int EVENT_GET_SLICING_CONFIG_DONE = 111;
Kai Shif70f46f2021-03-03 13:59:46 -0800377 private static final int CMD_ERASE_DATA_SHARED_PREFERENCES = 112;
Sooraj Sasindrandaf060f2021-06-15 14:52:55 -0700378 private static final int CMD_ENABLE_VONR = 113;
379 private static final int EVENT_ENABLE_VONR_DONE = 114;
380 private static final int CMD_IS_VONR_ENABLED = 115;
381 private static final int EVENT_IS_VONR_ENABLED_DONE = 116;
Sarah Chin2ec39f62022-08-31 17:03:26 -0700382 private static final int CMD_PURCHASE_PREMIUM_CAPABILITY = 117;
383 private static final int EVENT_PURCHASE_PREMIUM_CAPABILITY_DONE = 118;
Sarah Chineccfbd12023-01-20 19:00:35 -0800384 private static final int CMD_START_SATELLITE_POSITION_UPDATES = 119;
385 private static final int EVENT_START_SATELLITE_POSITION_UPDATES_DONE = 120;
386 private static final int CMD_STOP_SATELLITE_POSITION_UPDATES = 121;
387 private static final int EVENT_STOP_SATELLITE_POSITION_UPDATES_DONE = 122;
Aishwarya Mallampati60fe1132023-01-24 19:07:21 +0000388 private static final int CMD_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG = 123;
389 private static final int EVENT_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG_DONE = 124;
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -0800390 // Parameters of select command.
391 private static final int SELECT_COMMAND = 0xA4;
392 private static final int SELECT_P1 = 0x04;
393 private static final int SELECT_P2 = 0;
394 private static final int SELECT_P3 = 0x10;
395
Gil Cukierman1c0eb932022-12-06 22:28:24 +0000396 // Toggling null cipher and integrity support was added in IRadioNetwork 2.1
397 private static final int MIN_NULL_CIPHER_AND_INTEGRITY_VERSION = 201;
398
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700399 /** The singleton instance. */
400 private static PhoneInterfaceManager sInstance;
Jack Nudelman644b91a2021-03-12 14:09:48 -0800401 private static List<String> sThermalMitigationAllowlistedPackages = new ArrayList<>();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700402
Wink Saville3ab207e2014-11-20 13:07:20 -0800403 private PhoneGlobals mApp;
Wink Saville3ab207e2014-11-20 13:07:20 -0800404 private CallManager mCM;
Brad Ebinger24c29992019-12-05 13:03:21 -0800405 private ImsResolver mImsResolver;
Stuart Scott981d8582015-04-21 14:09:50 -0700406 private UserManager mUserManager;
Wink Saville3ab207e2014-11-20 13:07:20 -0800407 private AppOpsManager mAppOps;
Grace Jia0ddb3612021-04-22 13:35:26 -0700408 private PackageManager mPm;
Wink Saville3ab207e2014-11-20 13:07:20 -0800409 private MainThreadHandler mMainThreadHandler;
Jack Yue37dd262022-12-16 11:53:37 -0800410 private final SubscriptionController mSubscriptionController;
Wink Saville3ab207e2014-11-20 13:07:20 -0800411 private SharedPreferences mTelephonySharedPreferences;
Malcolm Chen2c63d402018-08-14 16:00:53 -0700412 private PhoneConfigurationManager mPhoneConfigurationManager;
Daniel Bright94f43662021-03-01 14:43:40 -0800413 private final RadioInterfaceCapabilityController mRadioInterfaceCapabilities;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700414
Peter Wangdafb9ac2020-01-15 14:13:38 -0800415 /** User Activity */
416 private AtomicBoolean mNotifyUserActivity;
Peter Wangdafb9ac2020-01-15 14:13:38 -0800417 private static final int USER_ACTIVITY_NOTIFICATION_DELAY = 200;
418
Jeff Davidson8ab02b22020-03-28 12:24:40 -0700419 private Set<Integer> mCarrierPrivilegeTestOverrideSubIds = new ArraySet<>();
Sarah Chineccfbd12023-01-20 19:00:35 -0800420 private Map<Integer, SatellitePositionUpdateHandler> mSatellitePositionUpdateHandlers =
421 new ConcurrentHashMap<>();
Jeff Davidson8ab02b22020-03-28 12:24:40 -0700422
Derek Tan97ebb422014-09-05 16:55:38 -0700423 private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
424 private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
Jeff Sharkey85190e62014-12-05 09:40:12 -0800425 private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800426 private static final String PREF_PROVISION_IMS_MMTEL_PREFIX = "provision_ims_mmtel_";
Derek Tan89e89d42014-07-08 17:00:10 -0700427
Michelecea4cf22018-12-21 15:00:11 -0800428 // String to store multi SIM allowed
429 private static final String PREF_MULTI_SIM_RESTRICTED = "multisim_restricted";
430
Derek Tan740e1672017-06-27 14:56:27 -0700431 // The AID of ISD-R.
432 private static final String ISDR_AID = "A0000005591010FFFFFFFF8900000100";
433
yinxub1bed742017-04-17 11:45:04 -0700434 private NetworkScanRequestTracker mNetworkScanRequestTracker;
435
David Kelly5e06a7f2018-03-12 14:10:59 +0000436 private static final int TYPE_ALLOCATION_CODE_LENGTH = 8;
437 private static final int MANUFACTURER_CODE_LENGTH = 8;
438
Jack Nudelmanb0b87642020-11-12 15:04:39 -0800439 private static final int SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS = -1;
Jack Nudelman5d6a98b2021-03-04 14:26:25 -0800440 private static final int MODEM_DOES_NOT_SUPPORT_DATA_THROTTLING_ERROR_CODE = -2;
Jack Nudelmanb0b87642020-11-12 15:04:39 -0800441
Sarah Chin2ec39f62022-08-31 17:03:26 -0700442 private static final String PURCHASE_PREMIUM_CAPABILITY_ERROR_UUID =
443 "24bf97a6-e8a6-44d8-a6a4-255d7548733c";
444
Derek Tan89e89d42014-07-08 17:00:10 -0700445 /**
Naina Nallurid63128d2019-09-17 14:10:30 -0700446 * Experiment flag to enable erase modem config on reset network, default value is false
447 */
448 public static final String RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED =
449 "reset_network_erase_modem_config_enabled";
450
Rambo Wang0f050d82021-02-12 11:43:36 -0800451 private static final int SET_NETWORK_SELECTION_MODE_AUTOMATIC_TIMEOUT_MS = 2000; // 2 seconds
Chen Xu540470b2021-12-14 17:15:47 -0800452
Gary Jian76280a42022-12-07 16:18:33 +0800453 private static final int MODEM_ACTIVITY_TIME_OFFSET_CORRECTION_MS = 50;
454
sandeepjsb6c87872021-09-27 15:34:44 +0000455 /**
456 * With support for MEP(multiple enabled profile) in Android T, a SIM card can have more than
457 * one ICCID active at the same time.
458 * Apps should use below API signatures if targeting SDK is T and beyond.
459 *
460 * @hide
461 */
462 @ChangeId
463 @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
464 public static final long GET_API_SIGNATURES_FROM_UICC_PORT_INFO = 202110963L;
Rambo Wang0f050d82021-02-12 11:43:36 -0800465
Naina Nallurid63128d2019-09-17 14:10:30 -0700466 /**
Chen Xu540470b2021-12-14 17:15:47 -0800467 * Apps targeting on Android T and beyond will get exception whenever icc close channel
468 * operation fails.
469 */
470 @ChangeId
471 @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
472 public static final long ICC_CLOSE_CHANNEL_EXCEPTION_ON_FAILURE = 208739934L;
473
474 /**
Shishir Agrawal566b7612013-10-28 14:41:00 -0700475 * A request object to use for transmitting data to an ICC.
476 */
477 private static final class IccAPDUArgument {
478 public int channel, cla, command, p1, p2, p3;
479 public String data;
480
481 public IccAPDUArgument(int channel, int cla, int command,
482 int p1, int p2, int p3, String data) {
483 this.channel = channel;
484 this.cla = cla;
485 this.command = command;
486 this.p1 = p1;
487 this.p2 = p2;
488 this.p3 = p3;
489 this.data = data;
490 }
491 }
492
493 /**
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700494 * A request object to use for transmitting data to an ICC.
495 */
496 private static final class ManualNetworkSelectionArgument {
497 public OperatorInfo operatorInfo;
498 public boolean persistSelection;
499
500 public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) {
501 this.operatorInfo = operatorInfo;
502 this.persistSelection = persistSelection;
503 }
504 }
505
Sarah Chin71b3a852022-09-28 15:54:19 -0700506 private static final class PurchasePremiumCapabilityArgument {
507 public @TelephonyManager.PremiumCapability int capability;
Sarah Chin71b3a852022-09-28 15:54:19 -0700508 public @NonNull IIntegerConsumer callback;
509
510 PurchasePremiumCapabilityArgument(@TelephonyManager.PremiumCapability int capability,
Sarah Chinb8218c22023-01-04 13:35:29 -0800511 @NonNull IIntegerConsumer callback) {
Sarah Chin71b3a852022-09-28 15:54:19 -0700512 this.capability = capability;
Sarah Chin71b3a852022-09-28 15:54:19 -0700513 this.callback = callback;
514 }
515 }
516
Sarah Chineccfbd12023-01-20 19:00:35 -0800517 private static final class SatellitePositionUpdateHandler extends Handler {
518 public static final int EVENT_POSITION_UPDATE = 1;
519 public static final int EVENT_MESSAGE_TRANSFER_STATE_UPDATE = 2;
520
521 private final ISatellitePositionUpdateCallback mCallback;
522
523 SatellitePositionUpdateHandler(ISatellitePositionUpdateCallback callback, Looper looper) {
524 super(looper);
525 mCallback = callback;
526 }
527
528 @Override
529 public void handleMessage(@NonNull Message msg) {
530 switch (msg.what) {
531 case EVENT_POSITION_UPDATE: {
532 AsyncResult ar = (AsyncResult) msg.obj;
533 PointingInfo pointingInfo = (PointingInfo) ar.result;
534 try {
535 mCallback.onSatellitePositionUpdate(pointingInfo);
536 } catch (RemoteException e) {
537 loge("EVENT_POSITION_UPDATE RemoteException: " + e);
538 }
539 break;
540 }
541 case EVENT_MESSAGE_TRANSFER_STATE_UPDATE: {
542 AsyncResult ar = (AsyncResult) msg.obj;
543 int state = (int) ar.result;
544 try {
545 mCallback.onMessageTransferStateUpdate(state);
546 } catch (RemoteException e) {
547 loge("EVENT_MESSAGE_TRANSFER_STATE_UPDATE RemoteException: " + e);
548 }
549 break;
550 }
551 default:
552 loge("SatellitePositionUpdateHandler unknown event: " + msg.what);
553 }
554 }
555 }
556
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700557 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700558 * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
559 * request after sending. The main thread will notify the request when it is complete.
560 */
561 private static final class MainThreadRequest {
562 /** The argument to use for the request */
563 public Object argument;
564 /** The result of the request that is run on the main thread */
565 public Object result;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800566 // The subscriber id that this request applies to. Defaults to
567 // SubscriptionManager.INVALID_SUBSCRIPTION_ID
568 public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700569
Nathan Harold92bed182018-10-12 18:16:49 -0700570 // In cases where subId is unavailable, the caller needs to specify the phone.
571 public Phone phone;
572
vagdeviaf9a5b92018-08-15 16:01:53 -0700573 public WorkSource workSource;
574
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700575 public MainThreadRequest(Object argument) {
576 this.argument = argument;
577 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800578
Nathan Harold92bed182018-10-12 18:16:49 -0700579 MainThreadRequest(Object argument, Phone phone, WorkSource workSource) {
580 this.argument = argument;
581 if (phone != null) {
582 this.phone = phone;
583 }
584 this.workSource = workSource;
585 }
586
vagdeviaf9a5b92018-08-15 16:01:53 -0700587 MainThreadRequest(Object argument, Integer subId, WorkSource workSource) {
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800588 this.argument = argument;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800589 if (subId != null) {
590 this.subId = subId;
591 }
vagdeviaf9a5b92018-08-15 16:01:53 -0700592 this.workSource = workSource;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800593 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700594 }
595
Sailesh Nepalcc0375f2013-11-13 09:15:18 -0800596 private static final class IncomingThirdPartyCallArgs {
597 public final ComponentName component;
598 public final String callId;
599 public final String callerDisplayName;
600
601 public IncomingThirdPartyCallArgs(ComponentName component, String callId,
602 String callerDisplayName) {
603 this.component = component;
604 this.callId = callId;
605 this.callerDisplayName = callerDisplayName;
606 }
607 }
608
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700609 /**
610 * A handler that processes messages on the main thread in the phone process. Since many
611 * of the Phone calls are not thread safe this is needed to shuttle the requests from the
612 * inbound binder threads to the main thread in the phone process. The Binder thread
613 * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
614 * on, which will be notified when the operation completes and will contain the result of the
615 * request.
616 *
617 * <p>If a MainThreadRequest object is provided in the msg.obj field,
618 * note that request.result must be set to something non-null for the calling thread to
619 * unblock.
620 */
621 private final class MainThreadHandler extends Handler {
622 @Override
623 public void handleMessage(Message msg) {
624 MainThreadRequest request;
625 Message onCompleted;
626 AsyncResult ar;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000627 UiccPort uiccPort;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700628 IccAPDUArgument iccArgument;
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800629 final Phone defaultPhone = getDefaultPhone();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700630
631 switch (msg.what) {
Pengquan Menga1bb6272018-09-06 09:59:22 -0700632 case CMD_HANDLE_USSD_REQUEST: {
633 request = (MainThreadRequest) msg.obj;
634 final Phone phone = getPhoneFromRequest(request);
635 Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
Chen Xue9d737e2022-01-01 23:41:31 -0800636 String ussdRequest = ussdObject.first;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700637 ResultReceiver wrappedCallback = ussdObject.second;
Tyler Gunn65d45c22017-06-05 11:22:26 -0700638
Pengquan Menga1bb6272018-09-06 09:59:22 -0700639 if (!isUssdApiAllowed(request.subId)) {
640 // Carrier does not support use of this API, return failure.
641 Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
642 UssdResponse response = new UssdResponse(ussdRequest, null);
643 Bundle returnData = new Bundle();
644 returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
645 wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
Tyler Gunn65d45c22017-06-05 11:22:26 -0700646
Pengquan Menga1bb6272018-09-06 09:59:22 -0700647 request.result = true;
648 notifyRequester(request);
649 return;
650 }
Tyler Gunn65d45c22017-06-05 11:22:26 -0700651
Pengquan Menga1bb6272018-09-06 09:59:22 -0700652 try {
653 request.result = phone != null
654 ? phone.handleUssdRequest(ussdRequest, wrappedCallback) : false;
655 } catch (CallStateException cse) {
656 request.result = false;
657 }
658 // Wake up the requesting thread
659 notifyRequester(request);
660 break;
pkanwar32d516d2016-10-14 19:37:38 -0700661 }
662
Yorke Lee716f67e2015-06-17 15:39:16 -0700663 case CMD_HANDLE_PIN_MMI: {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700664 request = (MainThreadRequest) msg.obj;
Yorke Lee716f67e2015-06-17 15:39:16 -0700665 final Phone phone = getPhoneFromRequest(request);
666 request.result = phone != null ?
667 getPhoneFromRequest(request).handlePinMmi((String) request.argument)
668 : false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700669 // Wake up the requesting thread
Pengquan Menga1bb6272018-09-06 09:59:22 -0700670 notifyRequester(request);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700671 break;
Yorke Lee716f67e2015-06-17 15:39:16 -0700672 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700673
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700674 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700675 request = (MainThreadRequest) msg.obj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700676 iccArgument = (IccAPDUArgument) request.argument;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000677 uiccPort = getUiccPortFromRequest(request);
678 if (uiccPort == null) {
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700679 loge("iccTransmitApduLogicalChannel: No UICC");
Chen Xue9d737e2022-01-01 23:41:31 -0800680 request.result = new IccIoResult(0x6F, 0, (byte[]) null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700681 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700682 } else {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700683 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
Chen Xue9d737e2022-01-01 23:41:31 -0800684 request);
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000685 uiccPort.iccTransmitApduLogicalChannel(
Chen Xue9d737e2022-01-01 23:41:31 -0800686 iccArgument.channel, iccArgument.cla, iccArgument.command,
687 iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data,
688 onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700689 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700690 break;
691
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700692 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700693 ar = (AsyncResult) msg.obj;
694 request = (MainThreadRequest) ar.userObj;
695 if (ar.exception == null && ar.result != null) {
696 request.result = ar.result;
697 } else {
Chen Xue9d737e2022-01-01 23:41:31 -0800698 request.result = new IccIoResult(0x6F, 0, (byte[]) null);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700699 if (ar.result == null) {
700 loge("iccTransmitApduLogicalChannel: Empty response");
Jake Hambye994d462014-02-03 13:10:13 -0800701 } else if (ar.exception instanceof CommandException) {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700702 loge("iccTransmitApduLogicalChannel: CommandException: " +
Jake Hambye994d462014-02-03 13:10:13 -0800703 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700704 } else {
705 loge("iccTransmitApduLogicalChannel: Unknown exception");
706 }
707 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700708 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700709 break;
710
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700711 case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
712 request = (MainThreadRequest) msg.obj;
713 iccArgument = (IccAPDUArgument) request.argument;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000714 uiccPort = getUiccPortFromRequest(request);
715 if (uiccPort == null) {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700716 loge("iccTransmitApduBasicChannel: No UICC");
Chen Xue9d737e2022-01-01 23:41:31 -0800717 request.result = new IccIoResult(0x6F, 0, (byte[]) null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700718 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700719 } else {
720 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
Chen Xue9d737e2022-01-01 23:41:31 -0800721 request);
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000722 uiccPort.iccTransmitApduBasicChannel(
Chen Xue9d737e2022-01-01 23:41:31 -0800723 iccArgument.cla, iccArgument.command, iccArgument.p1,
724 iccArgument.p2,
725 iccArgument.p3, iccArgument.data, onCompleted);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700726 }
727 break;
728
729 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
730 ar = (AsyncResult) msg.obj;
731 request = (MainThreadRequest) ar.userObj;
732 if (ar.exception == null && ar.result != null) {
733 request.result = ar.result;
734 } else {
Chen Xue9d737e2022-01-01 23:41:31 -0800735 request.result = new IccIoResult(0x6F, 0, (byte[]) null);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700736 if (ar.result == null) {
737 loge("iccTransmitApduBasicChannel: Empty response");
738 } else if (ar.exception instanceof CommandException) {
739 loge("iccTransmitApduBasicChannel: CommandException: " +
740 ar.exception);
741 } else {
742 loge("iccTransmitApduBasicChannel: Unknown exception");
743 }
744 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700745 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700746 break;
747
748 case CMD_EXCHANGE_SIM_IO:
749 request = (MainThreadRequest) msg.obj;
750 iccArgument = (IccAPDUArgument) request.argument;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000751 uiccPort = getUiccPortFromRequest(request);
752 if (uiccPort == null) {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700753 loge("iccExchangeSimIO: No UICC");
Chen Xue9d737e2022-01-01 23:41:31 -0800754 request.result = new IccIoResult(0x6F, 0, (byte[]) null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700755 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700756 } else {
757 onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
758 request);
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000759 uiccPort.iccExchangeSimIO(iccArgument.cla, /* fileID */
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700760 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3,
761 iccArgument.data, onCompleted);
762 }
763 break;
764
765 case EVENT_EXCHANGE_SIM_IO_DONE:
766 ar = (AsyncResult) msg.obj;
767 request = (MainThreadRequest) ar.userObj;
768 if (ar.exception == null && ar.result != null) {
769 request.result = ar.result;
770 } else {
Chen Xue9d737e2022-01-01 23:41:31 -0800771 request.result = new IccIoResult(0x6f, 0, (byte[]) null);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700772 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700773 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700774 break;
775
Derek Tan4d5e5c12014-02-04 11:54:58 -0800776 case CMD_SEND_ENVELOPE:
777 request = (MainThreadRequest) msg.obj;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000778 uiccPort = getUiccPortFromRequest(request);
779 if (uiccPort == null) {
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700780 loge("sendEnvelopeWithStatus: No UICC");
Chen Xue9d737e2022-01-01 23:41:31 -0800781 request.result = new IccIoResult(0x6F, 0, (byte[]) null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700782 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700783 } else {
784 onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
Chen Xue9d737e2022-01-01 23:41:31 -0800785 uiccPort.sendEnvelopeWithStatus((String) request.argument, onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700786 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800787 break;
788
789 case EVENT_SEND_ENVELOPE_DONE:
790 ar = (AsyncResult) msg.obj;
791 request = (MainThreadRequest) ar.userObj;
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700792 if (ar.exception == null && ar.result != null) {
793 request.result = ar.result;
Derek Tan4d5e5c12014-02-04 11:54:58 -0800794 } else {
Chen Xue9d737e2022-01-01 23:41:31 -0800795 request.result = new IccIoResult(0x6F, 0, (byte[]) null);
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700796 if (ar.result == null) {
797 loge("sendEnvelopeWithStatus: Empty response");
798 } else if (ar.exception instanceof CommandException) {
799 loge("sendEnvelopeWithStatus: CommandException: " +
800 ar.exception);
801 } else {
802 loge("sendEnvelopeWithStatus: exception:" + ar.exception);
803 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800804 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700805 notifyRequester(request);
Derek Tan4d5e5c12014-02-04 11:54:58 -0800806 break;
807
Shishir Agrawal566b7612013-10-28 14:41:00 -0700808 case CMD_OPEN_CHANNEL:
809 request = (MainThreadRequest) msg.obj;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000810 uiccPort = getUiccPortFromRequest(request);
Rambo Wanga1782702021-11-10 20:15:19 -0800811 IccLogicalChannelRequest openChannelRequest =
812 (IccLogicalChannelRequest) request.argument;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000813 if (uiccPort == null) {
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700814 loge("iccOpenLogicalChannel: No UICC");
Shishir Agrawalfc0492a2016-02-17 11:15:33 -0800815 request.result = new IccOpenLogicalChannelResponse(-1,
Chen Xue9d737e2022-01-01 23:41:31 -0800816 IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700817 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700818 } else {
819 onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
Rambo Wanga1782702021-11-10 20:15:19 -0800820 uiccPort.iccOpenLogicalChannel(openChannelRequest.aid,
821 openChannelRequest.p2, onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700822 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700823 break;
824
825 case EVENT_OPEN_CHANNEL_DONE:
826 ar = (AsyncResult) msg.obj;
827 request = (MainThreadRequest) ar.userObj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700828 IccOpenLogicalChannelResponse openChannelResp;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700829 if (ar.exception == null && ar.result != null) {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700830 int[] result = (int[]) ar.result;
831 int channelId = result[0];
832 byte[] selectResponse = null;
833 if (result.length > 1) {
834 selectResponse = new byte[result.length - 1];
835 for (int i = 1; i < result.length; ++i) {
836 selectResponse[i - 1] = (byte) result[i];
837 }
838 }
839 openChannelResp = new IccOpenLogicalChannelResponse(channelId,
Chen Xue9d737e2022-01-01 23:41:31 -0800840 IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse);
Rambo Wang3b77c4c2021-11-10 20:15:19 -0800841
842 uiccPort = getUiccPortFromRequest(request);
Rambo Wange53e07d2022-05-10 13:01:13 -0700843 if (uiccPort == null) {
844 loge("EVENT_OPEN_CHANNEL_DONE: UiccPort is null");
845 } else {
846 IccLogicalChannelRequest channelRequest =
847 (IccLogicalChannelRequest) request.argument;
848 channelRequest.channel = channelId;
849 uiccPort.onLogicalChannelOpened(channelRequest);
850 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700851 } else {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700852 if (ar.result == null) {
853 loge("iccOpenLogicalChannel: Empty response");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700854 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700855 if (ar.exception != null) {
856 loge("iccOpenLogicalChannel: Exception: " + ar.exception);
857 }
858
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700859 int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR;
Junda Liua754ba12015-05-20 01:17:52 -0700860 if (ar.exception instanceof CommandException) {
861 CommandException.Error error =
Chen Xue9d737e2022-01-01 23:41:31 -0800862 ((CommandException) (ar.exception)).getCommandError();
Junda Liua754ba12015-05-20 01:17:52 -0700863 if (error == CommandException.Error.MISSING_RESOURCE) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700864 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE;
Junda Liua754ba12015-05-20 01:17:52 -0700865 } else if (error == CommandException.Error.NO_SUCH_ELEMENT) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700866 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700867 }
868 }
869 openChannelResp = new IccOpenLogicalChannelResponse(
Chen Xue9d737e2022-01-01 23:41:31 -0800870 IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700871 }
Shishir Agrawal82c8a462014-07-31 18:13:17 -0700872 request.result = openChannelResp;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700873 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700874 break;
875
876 case CMD_CLOSE_CHANNEL:
877 request = (MainThreadRequest) msg.obj;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000878 uiccPort = getUiccPortFromRequest(request);
879 if (uiccPort == null) {
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700880 loge("iccCloseLogicalChannel: No UICC");
Chen Xua8f0dff2022-02-12 00:34:15 -0800881 request.result = new IllegalArgumentException(
Chen Xue9d737e2022-01-01 23:41:31 -0800882 "iccCloseLogicalChannel: No UICC");
Chen Xue9d737e2022-01-01 23:41:31 -0800883 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700884 } else {
885 onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000886 uiccPort.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700887 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700888 break;
889
890 case EVENT_CLOSE_CHANNEL_DONE:
Chen Xu540470b2021-12-14 17:15:47 -0800891 ar = (AsyncResult) msg.obj;
892 request = (MainThreadRequest) ar.userObj;
893 if (ar.exception == null) {
894 request.result = true;
Rambo Wang3b77c4c2021-11-10 20:15:19 -0800895 uiccPort = getUiccPortFromRequest(request);
Rambo Wange53e07d2022-05-10 13:01:13 -0700896 if (uiccPort == null) {
897 loge("EVENT_CLOSE_CHANNEL_DONE: UiccPort is null");
898 } else {
899 final int channelId = (Integer) request.argument;
900 uiccPort.onLogicalChannelClosed(channelId);
901 }
Chen Xu540470b2021-12-14 17:15:47 -0800902 } else {
903 request.result = false;
Chen Xue9d737e2022-01-01 23:41:31 -0800904 Exception exception = null;
Chen Xu540470b2021-12-14 17:15:47 -0800905 if (ar.exception instanceof CommandException) {
906 loge("iccCloseLogicalChannel: CommandException: " + ar.exception);
907 CommandException.Error error =
908 ((CommandException) (ar.exception)).getCommandError();
Chen Xue9d737e2022-01-01 23:41:31 -0800909 if (error == CommandException.Error.INVALID_ARGUMENTS) {
910 // should only throw exceptions from the binder threads.
911 exception = new IllegalArgumentException(
Chen Xu540470b2021-12-14 17:15:47 -0800912 "iccCloseLogicalChannel: invalid argument ");
913 }
914 } else {
915 loge("iccCloseLogicalChannel: Unknown exception");
916 }
Chen Xua8f0dff2022-02-12 00:34:15 -0800917 request.result = (exception != null) ? exception :
918 new IllegalStateException(
919 "exception from modem to close iccLogical Channel");
Chen Xu540470b2021-12-14 17:15:47 -0800920 }
921 notifyRequester(request);
Jake Hambye994d462014-02-03 13:10:13 -0800922 break;
923
924 case CMD_NV_READ_ITEM:
925 request = (MainThreadRequest) msg.obj;
926 onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800927 defaultPhone.nvReadItem((Integer) request.argument, onCompleted,
928 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800929 break;
930
931 case EVENT_NV_READ_ITEM_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700932 ar = (AsyncResult) msg.obj;
933 request = (MainThreadRequest) ar.userObj;
Jake Hambye994d462014-02-03 13:10:13 -0800934 if (ar.exception == null && ar.result != null) {
935 request.result = ar.result; // String
Shishir Agrawal566b7612013-10-28 14:41:00 -0700936 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800937 request.result = "";
938 if (ar.result == null) {
939 loge("nvReadItem: Empty response");
940 } else if (ar.exception instanceof CommandException) {
941 loge("nvReadItem: CommandException: " +
942 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700943 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800944 loge("nvReadItem: Unknown exception");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700945 }
946 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700947 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700948 break;
949
Jake Hambye994d462014-02-03 13:10:13 -0800950 case CMD_NV_WRITE_ITEM:
951 request = (MainThreadRequest) msg.obj;
952 onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
953 Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800954 defaultPhone.nvWriteItem(idValue.first, idValue.second, onCompleted,
vagdeviaf9a5b92018-08-15 16:01:53 -0700955 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800956 break;
957
958 case EVENT_NV_WRITE_ITEM_DONE:
959 handleNullReturnEvent(msg, "nvWriteItem");
960 break;
961
962 case CMD_NV_WRITE_CDMA_PRL:
963 request = (MainThreadRequest) msg.obj;
964 onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800965 defaultPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
Jake Hambye994d462014-02-03 13:10:13 -0800966 break;
967
968 case EVENT_NV_WRITE_CDMA_PRL_DONE:
969 handleNullReturnEvent(msg, "nvWriteCdmaPrl");
970 break;
971
chen xu6dac5ab2018-10-26 17:39:23 -0700972 case CMD_RESET_MODEM_CONFIG:
Jake Hambye994d462014-02-03 13:10:13 -0800973 request = (MainThreadRequest) msg.obj;
chen xu6dac5ab2018-10-26 17:39:23 -0700974 onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800975 defaultPhone.resetModemConfig(onCompleted);
Jake Hambye994d462014-02-03 13:10:13 -0800976 break;
977
chen xu6dac5ab2018-10-26 17:39:23 -0700978 case EVENT_RESET_MODEM_CONFIG_DONE:
979 handleNullReturnEvent(msg, "resetModemConfig");
Jake Hambye994d462014-02-03 13:10:13 -0800980 break;
981
Sooraj Sasindran37444802020-08-11 10:40:43 -0700982 case CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED: {
983 request = (MainThreadRequest) msg.obj;
984 onCompleted = obtainMessage(EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE,
985 request);
986 Phone phone = getPhoneFromRequest(request);
987 if (phone != null) {
988 phone.isNrDualConnectivityEnabled(onCompleted, request.workSource);
989 } else {
990 loge("isNRDualConnectivityEnabled: No phone object");
991 request.result = false;
992 notifyRequester(request);
993 }
994 break;
995 }
996
997 case EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE:
998 ar = (AsyncResult) msg.obj;
999 request = (MainThreadRequest) ar.userObj;
1000 if (ar.exception == null && ar.result != null) {
1001 request.result = ar.result;
1002 } else {
1003 // request.result must be set to something non-null
1004 // for the calling thread to unblock
Sooraj Sasindrandaf060f2021-06-15 14:52:55 -07001005 if (ar.result != null) {
Sooraj Sasindran37444802020-08-11 10:40:43 -07001006 request.result = ar.result;
1007 } else {
1008 request.result = false;
1009 }
1010 if (ar.result == null) {
1011 loge("isNRDualConnectivityEnabled: Empty response");
1012 } else if (ar.exception instanceof CommandException) {
1013 loge("isNRDualConnectivityEnabled: CommandException: "
1014 + ar.exception);
1015 } else {
1016 loge("isNRDualConnectivityEnabled: Unknown exception");
1017 }
1018 }
1019 notifyRequester(request);
1020 break;
1021
Sooraj Sasindrandaf060f2021-06-15 14:52:55 -07001022 case CMD_IS_VONR_ENABLED: {
1023 request = (MainThreadRequest) msg.obj;
1024 onCompleted = obtainMessage(EVENT_IS_VONR_ENABLED_DONE,
1025 request);
1026 Phone phone = getPhoneFromRequest(request);
1027 if (phone != null) {
1028 phone.isVoNrEnabled(onCompleted, request.workSource);
1029 } else {
1030 loge("isVoNrEnabled: No phone object");
1031 request.result = false;
1032 notifyRequester(request);
1033 }
1034 break;
1035 }
1036
1037 case EVENT_IS_VONR_ENABLED_DONE:
1038 ar = (AsyncResult) msg.obj;
1039 request = (MainThreadRequest) ar.userObj;
1040 if (ar.exception == null && ar.result != null) {
1041 request.result = ar.result;
1042 } else {
1043 // request.result must be set to something non-null
1044 // for the calling thread to unblock
1045 if (ar.result != null) {
1046 request.result = ar.result;
1047 } else {
1048 request.result = false;
1049 }
1050 if (ar.result == null) {
1051 loge("isVoNrEnabled: Empty response");
1052 } else if (ar.exception instanceof CommandException) {
1053 loge("isVoNrEnabled: CommandException: "
1054 + ar.exception);
1055 } else {
1056 loge("isVoNrEnabled: Unknown exception");
1057 }
1058 }
1059 notifyRequester(request);
1060 break;
1061
Sooraj Sasindran37444802020-08-11 10:40:43 -07001062 case CMD_ENABLE_NR_DUAL_CONNECTIVITY: {
1063 request = (MainThreadRequest) msg.obj;
1064 onCompleted = obtainMessage(EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE, request);
1065 Phone phone = getPhoneFromRequest(request);
1066 if (phone != null) {
1067 phone.setNrDualConnectivityState((int) request.argument, onCompleted,
1068 request.workSource);
1069 } else {
1070 loge("enableNrDualConnectivity: No phone object");
1071 request.result =
1072 TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE;
1073 notifyRequester(request);
1074 }
1075 break;
1076 }
1077
1078 case EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE: {
1079 ar = (AsyncResult) msg.obj;
1080 request = (MainThreadRequest) ar.userObj;
1081 if (ar.exception == null) {
1082 request.result =
1083 TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_SUCCESS;
1084 } else {
1085 request.result =
1086 TelephonyManager
1087 .ENABLE_NR_DUAL_CONNECTIVITY_RADIO_ERROR;
1088 if (ar.exception instanceof CommandException) {
1089 CommandException.Error error =
1090 ((CommandException) (ar.exception)).getCommandError();
1091 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1092 request.result =
1093 TelephonyManager
1094 .ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE;
Sooraj Sasindran29654162021-03-03 23:00:01 +00001095 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1096 request.result =
1097 TelephonyManager
1098 .ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED;
Sooraj Sasindran37444802020-08-11 10:40:43 -07001099 }
1100 loge("enableNrDualConnectivity" + ": CommandException: "
1101 + ar.exception);
1102 } else {
1103 loge("enableNrDualConnectivity" + ": Unknown exception");
1104 }
1105 }
1106 notifyRequester(request);
1107 break;
1108 }
1109
Sooraj Sasindrandaf060f2021-06-15 14:52:55 -07001110 case CMD_ENABLE_VONR: {
1111 request = (MainThreadRequest) msg.obj;
1112 onCompleted = obtainMessage(EVENT_ENABLE_VONR_DONE, request);
1113 Phone phone = getPhoneFromRequest(request);
1114 if (phone != null) {
1115 phone.setVoNrEnabled((boolean) request.argument, onCompleted,
1116 request.workSource);
1117 } else {
1118 loge("setVoNrEnabled: No phone object");
1119 request.result =
1120 TelephonyManager.ENABLE_VONR_RADIO_NOT_AVAILABLE;
1121 notifyRequester(request);
1122 }
1123 break;
1124 }
1125
1126 case EVENT_ENABLE_VONR_DONE: {
1127 ar = (AsyncResult) msg.obj;
1128 request = (MainThreadRequest) ar.userObj;
1129 if (ar.exception == null) {
1130 request.result = TelephonyManager.ENABLE_VONR_SUCCESS;
1131 } else {
1132 request.result = TelephonyManager.ENABLE_VONR_RADIO_ERROR;
1133 if (ar.exception instanceof CommandException) {
1134 CommandException.Error error =
1135 ((CommandException) (ar.exception)).getCommandError();
1136 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1137 request.result = TelephonyManager.ENABLE_VONR_RADIO_NOT_AVAILABLE;
1138 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1139 request.result = TelephonyManager.ENABLE_VONR_REQUEST_NOT_SUPPORTED;
1140 } else {
1141 request.result = TelephonyManager.ENABLE_VONR_RADIO_ERROR;
1142 }
1143 loge("setVoNrEnabled" + ": CommandException: "
1144 + ar.exception);
1145 } else {
1146 loge("setVoNrEnabled" + ": Unknown exception");
1147 }
1148 }
1149 notifyRequester(request);
1150 break;
1151 }
1152
SongFerngWang3ef3e072020-12-21 16:41:52 +08001153 case CMD_GET_ALLOWED_NETWORK_TYPES_BITMASK:
Jake Hamby7c27be32014-03-03 13:25:59 -08001154 request = (MainThreadRequest) msg.obj;
SongFerngWang3ef3e072020-12-21 16:41:52 +08001155 onCompleted = obtainMessage(EVENT_GET_ALLOWED_NETWORK_TYPES_BITMASK_DONE,
1156 request);
1157 getPhoneFromRequest(request).getAllowedNetworkTypesBitmask(onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -08001158 break;
1159
SongFerngWang3ef3e072020-12-21 16:41:52 +08001160 case EVENT_GET_ALLOWED_NETWORK_TYPES_BITMASK_DONE:
Jake Hamby7c27be32014-03-03 13:25:59 -08001161 ar = (AsyncResult) msg.obj;
1162 request = (MainThreadRequest) ar.userObj;
1163 if (ar.exception == null && ar.result != null) {
1164 request.result = ar.result; // Integer
1165 } else {
Nazish Tabassume8ba43a2020-07-28 14:49:25 +05301166 // request.result must be set to something non-null
1167 // for the calling thread to unblock
1168 request.result = new int[]{-1};
Jake Hamby7c27be32014-03-03 13:25:59 -08001169 if (ar.result == null) {
SongFerngWang3ef3e072020-12-21 16:41:52 +08001170 loge("getAllowedNetworkTypesBitmask: Empty response");
Jake Hamby7c27be32014-03-03 13:25:59 -08001171 } else if (ar.exception instanceof CommandException) {
SongFerngWang3ef3e072020-12-21 16:41:52 +08001172 loge("getAllowedNetworkTypesBitmask: CommandException: "
1173 + ar.exception);
Jake Hamby7c27be32014-03-03 13:25:59 -08001174 } else {
SongFerngWang3ef3e072020-12-21 16:41:52 +08001175 loge("getAllowedNetworkTypesBitmask: Unknown exception");
Jake Hamby7c27be32014-03-03 13:25:59 -08001176 }
1177 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001178 notifyRequester(request);
Jake Hamby7c27be32014-03-03 13:25:59 -08001179 break;
1180
SongFerngWang3ef3e072020-12-21 16:41:52 +08001181 case CMD_SET_ALLOWED_NETWORK_TYPES_FOR_REASON:
Jake Hamby7c27be32014-03-03 13:25:59 -08001182 request = (MainThreadRequest) msg.obj;
SongFerngWang3ef3e072020-12-21 16:41:52 +08001183 onCompleted = obtainMessage(EVENT_SET_ALLOWED_NETWORK_TYPES_FOR_REASON_DONE,
1184 request);
1185 Pair<Integer, Long> reasonWithNetworkTypes =
1186 (Pair<Integer, Long>) request.argument;
1187 getPhoneFromRequest(request).setAllowedNetworkTypes(
1188 reasonWithNetworkTypes.first,
1189 reasonWithNetworkTypes.second,
1190 onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -08001191 break;
1192
SongFerngWang3ef3e072020-12-21 16:41:52 +08001193 case EVENT_SET_ALLOWED_NETWORK_TYPES_FOR_REASON_DONE:
1194 handleNullReturnEvent(msg, "setAllowedNetworkTypesForReason");
Jake Hamby7c27be32014-03-03 13:25:59 -08001195 break;
1196
Shuo Qian850e4d6a2018-04-25 21:02:08 +00001197 case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
1198 request = (MainThreadRequest)msg.obj;
1199 onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001200 defaultPhone.invokeOemRilRequestRaw((byte[]) request.argument, onCompleted);
Shuo Qian850e4d6a2018-04-25 21:02:08 +00001201 break;
1202
1203 case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
1204 ar = (AsyncResult)msg.obj;
1205 request = (MainThreadRequest)ar.userObj;
1206 request.result = ar;
Pengquan Menga1bb6272018-09-06 09:59:22 -07001207 notifyRequester(request);
Shuo Qian850e4d6a2018-04-25 21:02:08 +00001208 break;
1209
Shishir Agrawal76d5da92014-11-09 16:17:25 -08001210 case CMD_SET_VOICEMAIL_NUMBER:
1211 request = (MainThreadRequest) msg.obj;
1212 onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
1213 Pair<String, String> tagNum = (Pair<String, String>) request.argument;
Stuart Scott584921c2015-01-15 17:10:34 -08001214 getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
1215 onCompleted);
Shishir Agrawal76d5da92014-11-09 16:17:25 -08001216 break;
1217
1218 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
1219 handleNullReturnEvent(msg, "setVoicemailNumber");
1220 break;
1221
Stuart Scott54788802015-03-30 13:18:01 -07001222 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC:
1223 request = (MainThreadRequest) msg.obj;
1224 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE,
1225 request);
1226 getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted);
1227 break;
1228
1229 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE:
1230 handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic");
1231 break;
1232
Shishir Agrawal302c8692015-06-19 13:49:39 -07001233 case CMD_PERFORM_NETWORK_SCAN:
1234 request = (MainThreadRequest) msg.obj;
1235 onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request);
1236 getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
1237 break;
1238
Hall Liu27d24262020-09-18 19:04:59 -07001239 case CMD_GET_CALL_FORWARDING: {
Shuo Qian4a594052020-01-23 11:59:30 -08001240 request = (MainThreadRequest) msg.obj;
1241 onCompleted = obtainMessage(EVENT_GET_CALL_FORWARDING_DONE, request);
Hall Liu27d24262020-09-18 19:04:59 -07001242 Pair<Integer, TelephonyManager.CallForwardingInfoCallback> args =
1243 (Pair<Integer, TelephonyManager.CallForwardingInfoCallback>)
1244 request.argument;
1245 int callForwardingReason = args.first;
1246 request.phone.getCallForwardingOption(callForwardingReason, onCompleted);
Shuo Qian4a594052020-01-23 11:59:30 -08001247 break;
Hall Liu27d24262020-09-18 19:04:59 -07001248 }
1249 case EVENT_GET_CALL_FORWARDING_DONE: {
Shuo Qian4a594052020-01-23 11:59:30 -08001250 ar = (AsyncResult) msg.obj;
1251 request = (MainThreadRequest) ar.userObj;
Hall Liu27d24262020-09-18 19:04:59 -07001252 TelephonyManager.CallForwardingInfoCallback callback =
1253 ((Pair<Integer, TelephonyManager.CallForwardingInfoCallback>)
1254 request.argument).second;
Shuo Qian4a594052020-01-23 11:59:30 -08001255 if (ar.exception == null && ar.result != null) {
Hall Liu27d24262020-09-18 19:04:59 -07001256 CallForwardingInfo callForwardingInfo = null;
Shuo Qian4a594052020-01-23 11:59:30 -08001257 CallForwardInfo[] callForwardInfos = (CallForwardInfo[]) ar.result;
1258 for (CallForwardInfo callForwardInfo : callForwardInfos) {
1259 // Service Class is a bit mask per 3gpp 27.007. Search for
1260 // any service for voice call.
1261 if ((callForwardInfo.serviceClass
1262 & CommandsInterface.SERVICE_CLASS_VOICE) > 0) {
Yuchen Dong69cc1412021-09-27 20:27:01 +08001263 callForwardingInfo = new CallForwardingInfo(
1264 callForwardInfo.status
1265 == CommandsInterface.CF_ACTION_ENABLE,
Hall Liu27d24262020-09-18 19:04:59 -07001266 callForwardInfo.reason,
1267 callForwardInfo.number,
1268 callForwardInfo.timeSeconds);
Shuo Qian4a594052020-01-23 11:59:30 -08001269 break;
1270 }
1271 }
1272 // Didn't find a call forward info for voice call.
1273 if (callForwardingInfo == null) {
Hall Liu27d24262020-09-18 19:04:59 -07001274 callForwardingInfo = new CallForwardingInfo(false /* enabled */,
1275 0 /* reason */, null /* number */, 0 /* timeout */);
Shuo Qian4a594052020-01-23 11:59:30 -08001276 }
Hall Liu27d24262020-09-18 19:04:59 -07001277 callback.onCallForwardingInfoAvailable(callForwardingInfo);
Shuo Qian4a594052020-01-23 11:59:30 -08001278 } else {
1279 if (ar.result == null) {
1280 loge("EVENT_GET_CALL_FORWARDING_DONE: Empty response");
1281 }
1282 if (ar.exception != null) {
1283 loge("EVENT_GET_CALL_FORWARDING_DONE: Exception: " + ar.exception);
1284 }
Hall Liu940c4ca2020-09-29 17:10:18 -07001285 int errorCode = TelephonyManager
1286 .CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN;
Shuo Qian4a594052020-01-23 11:59:30 -08001287 if (ar.exception instanceof CommandException) {
1288 CommandException.Error error =
1289 ((CommandException) (ar.exception)).getCommandError();
1290 if (error == CommandException.Error.FDN_CHECK_FAILURE) {
Hall Liu940c4ca2020-09-29 17:10:18 -07001291 errorCode = TelephonyManager
1292 .CallForwardingInfoCallback.RESULT_ERROR_FDN_CHECK_FAILURE;
Shuo Qian4a594052020-01-23 11:59:30 -08001293 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
Hall Liu940c4ca2020-09-29 17:10:18 -07001294 errorCode = TelephonyManager
1295 .CallForwardingInfoCallback.RESULT_ERROR_NOT_SUPPORTED;
Shuo Qian4a594052020-01-23 11:59:30 -08001296 }
1297 }
Hall Liu27d24262020-09-18 19:04:59 -07001298 callback.onError(errorCode);
Shuo Qian4a594052020-01-23 11:59:30 -08001299 }
Shuo Qian4a594052020-01-23 11:59:30 -08001300 break;
Hall Liu27d24262020-09-18 19:04:59 -07001301 }
Shuo Qian4a594052020-01-23 11:59:30 -08001302
Hall Liu27d24262020-09-18 19:04:59 -07001303 case CMD_SET_CALL_FORWARDING: {
Shuo Qian4a594052020-01-23 11:59:30 -08001304 request = (MainThreadRequest) msg.obj;
1305 onCompleted = obtainMessage(EVENT_SET_CALL_FORWARDING_DONE, request);
Hall Liu27d24262020-09-18 19:04:59 -07001306 request = (MainThreadRequest) msg.obj;
Shuo Qian4a594052020-01-23 11:59:30 -08001307 CallForwardingInfo callForwardingInfoToSet =
Hall Liu27d24262020-09-18 19:04:59 -07001308 ((Pair<CallForwardingInfo, Consumer<Integer>>)
1309 request.argument).first;
1310 request.phone.setCallForwardingOption(
1311 callForwardingInfoToSet.isEnabled()
Calvin Pan258f1f72021-07-28 21:46:56 +08001312 ? CommandsInterface.CF_ACTION_REGISTRATION
Hall Liu27d24262020-09-18 19:04:59 -07001313 : CommandsInterface.CF_ACTION_DISABLE,
Shuo Qian4a594052020-01-23 11:59:30 -08001314 callForwardingInfoToSet.getReason(),
1315 callForwardingInfoToSet.getNumber(),
1316 callForwardingInfoToSet.getTimeoutSeconds(), onCompleted);
1317 break;
Hall Liu27d24262020-09-18 19:04:59 -07001318 }
Shuo Qian4a594052020-01-23 11:59:30 -08001319
Hall Liu27d24262020-09-18 19:04:59 -07001320 case EVENT_SET_CALL_FORWARDING_DONE: {
Shuo Qian4a594052020-01-23 11:59:30 -08001321 ar = (AsyncResult) msg.obj;
1322 request = (MainThreadRequest) ar.userObj;
Hall Liu27d24262020-09-18 19:04:59 -07001323 Consumer<Integer> callback =
1324 ((Pair<CallForwardingInfo, Consumer<Integer>>)
1325 request.argument).second;
1326 if (ar.exception != null) {
Shuo Qian4a594052020-01-23 11:59:30 -08001327 loge("setCallForwarding exception: " + ar.exception);
Hall Liu940c4ca2020-09-29 17:10:18 -07001328 int errorCode = TelephonyManager.CallForwardingInfoCallback
1329 .RESULT_ERROR_UNKNOWN;
Hall Liu27d24262020-09-18 19:04:59 -07001330 if (ar.exception instanceof CommandException) {
1331 CommandException.Error error =
1332 ((CommandException) (ar.exception)).getCommandError();
1333 if (error == CommandException.Error.FDN_CHECK_FAILURE) {
Hall Liu940c4ca2020-09-29 17:10:18 -07001334 errorCode = TelephonyManager.CallForwardingInfoCallback
1335 .RESULT_ERROR_FDN_CHECK_FAILURE;
Hall Liu27d24262020-09-18 19:04:59 -07001336 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
Hall Liu940c4ca2020-09-29 17:10:18 -07001337 errorCode = TelephonyManager.CallForwardingInfoCallback
1338 .RESULT_ERROR_NOT_SUPPORTED;
Hall Liu27d24262020-09-18 19:04:59 -07001339 }
1340 }
1341 callback.accept(errorCode);
1342 } else {
Hall Liu940c4ca2020-09-29 17:10:18 -07001343 callback.accept(TelephonyManager.CallForwardingInfoCallback.RESULT_SUCCESS);
Shuo Qian4a594052020-01-23 11:59:30 -08001344 }
Shuo Qian4a594052020-01-23 11:59:30 -08001345 break;
Hall Liu27d24262020-09-18 19:04:59 -07001346 }
Shuo Qian4a594052020-01-23 11:59:30 -08001347
Hall Liu27d24262020-09-18 19:04:59 -07001348 case CMD_GET_CALL_WAITING: {
Shuo Qian4a594052020-01-23 11:59:30 -08001349 request = (MainThreadRequest) msg.obj;
1350 onCompleted = obtainMessage(EVENT_GET_CALL_WAITING_DONE, request);
1351 getPhoneFromRequest(request).getCallWaiting(onCompleted);
1352 break;
Hall Liu27d24262020-09-18 19:04:59 -07001353 }
Shuo Qian4a594052020-01-23 11:59:30 -08001354
Hall Liu27d24262020-09-18 19:04:59 -07001355 case EVENT_GET_CALL_WAITING_DONE: {
Shuo Qian4a594052020-01-23 11:59:30 -08001356 ar = (AsyncResult) msg.obj;
1357 request = (MainThreadRequest) ar.userObj;
Hall Liu27d24262020-09-18 19:04:59 -07001358 Consumer<Integer> callback = (Consumer<Integer>) request.argument;
SongFerngWangebda2c52022-01-11 15:28:38 +08001359 int callWaitingStatus = TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR;
Shuo Qian4a594052020-01-23 11:59:30 -08001360 if (ar.exception == null && ar.result != null) {
Shuo Qiand6a0dba2020-02-18 18:13:49 -08001361 int[] callForwardResults = (int[]) ar.result;
Shuo Qian4a594052020-01-23 11:59:30 -08001362 // Service Class is a bit mask per 3gpp 27.007.
1363 // Search for any service for voice call.
Shuo Qiand6a0dba2020-02-18 18:13:49 -08001364 if (callForwardResults.length > 1
1365 && ((callForwardResults[1]
Hall Liu27d24262020-09-18 19:04:59 -07001366 & CommandsInterface.SERVICE_CLASS_VOICE) > 0)) {
SongFerngWangebda2c52022-01-11 15:28:38 +08001367 callWaitingStatus = callForwardResults[0] == 0
Hall Liu27d24262020-09-18 19:04:59 -07001368 ? TelephonyManager.CALL_WAITING_STATUS_DISABLED
1369 : TelephonyManager.CALL_WAITING_STATUS_ENABLED;
Shuo Qian4a594052020-01-23 11:59:30 -08001370 } else {
SongFerngWangebda2c52022-01-11 15:28:38 +08001371 callWaitingStatus = TelephonyManager.CALL_WAITING_STATUS_DISABLED;
Shuo Qian4a594052020-01-23 11:59:30 -08001372 }
1373 } else {
1374 if (ar.result == null) {
1375 loge("EVENT_GET_CALL_WAITING_DONE: Empty response");
1376 }
1377 if (ar.exception != null) {
1378 loge("EVENT_GET_CALL_WAITING_DONE: Exception: " + ar.exception);
1379 }
1380 if (ar.exception instanceof CommandException) {
1381 CommandException.Error error =
1382 ((CommandException) (ar.exception)).getCommandError();
1383 if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
SongFerngWangebda2c52022-01-11 15:28:38 +08001384 callWaitingStatus =
Shuo Qian4a594052020-01-23 11:59:30 -08001385 TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED;
SongFerngWangebda2c52022-01-11 15:28:38 +08001386 } else if (error == CommandException.Error.FDN_CHECK_FAILURE) {
1387 callWaitingStatus =
1388 TelephonyManager.CALL_WAITING_STATUS_FDN_CHECK_FAILURE;
Shuo Qian4a594052020-01-23 11:59:30 -08001389 }
1390 }
1391 }
SongFerngWangebda2c52022-01-11 15:28:38 +08001392 callback.accept(callWaitingStatus);
Shuo Qian4a594052020-01-23 11:59:30 -08001393 break;
Hall Liu27d24262020-09-18 19:04:59 -07001394 }
Shuo Qian4a594052020-01-23 11:59:30 -08001395
Hall Liu27d24262020-09-18 19:04:59 -07001396 case CMD_SET_CALL_WAITING: {
Shuo Qian4a594052020-01-23 11:59:30 -08001397 request = (MainThreadRequest) msg.obj;
1398 onCompleted = obtainMessage(EVENT_SET_CALL_WAITING_DONE, request);
Hall Liu27d24262020-09-18 19:04:59 -07001399 boolean enable = ((Pair<Boolean, Consumer<Integer>>) request.argument).first;
1400 getPhoneFromRequest(request).setCallWaiting(enable, onCompleted);
Shuo Qian4a594052020-01-23 11:59:30 -08001401 break;
Hall Liu27d24262020-09-18 19:04:59 -07001402 }
Shuo Qian4a594052020-01-23 11:59:30 -08001403
Hall Liu27d24262020-09-18 19:04:59 -07001404 case EVENT_SET_CALL_WAITING_DONE: {
Shuo Qian4a594052020-01-23 11:59:30 -08001405 ar = (AsyncResult) msg.obj;
1406 request = (MainThreadRequest) ar.userObj;
Hall Liu27d24262020-09-18 19:04:59 -07001407 boolean enable = ((Pair<Boolean, Consumer<Integer>>) request.argument).first;
1408 Consumer<Integer> callback =
1409 ((Pair<Boolean, Consumer<Integer>>) request.argument).second;
1410 if (ar.exception != null) {
Shuo Qian4a594052020-01-23 11:59:30 -08001411 loge("setCallWaiting exception: " + ar.exception);
Hall Liu27d24262020-09-18 19:04:59 -07001412 if (ar.exception instanceof CommandException) {
1413 CommandException.Error error =
1414 ((CommandException) (ar.exception)).getCommandError();
1415 if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1416 callback.accept(TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED);
SongFerngWangebda2c52022-01-11 15:28:38 +08001417 } else if (error == CommandException.Error.FDN_CHECK_FAILURE) {
1418 callback.accept(
1419 TelephonyManager.CALL_WAITING_STATUS_FDN_CHECK_FAILURE);
Hall Liu27d24262020-09-18 19:04:59 -07001420 } else {
1421 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
1422 }
1423 } else {
1424 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
1425 }
1426 } else {
1427 callback.accept(enable ? TelephonyManager.CALL_WAITING_STATUS_ENABLED
1428 : TelephonyManager.CALL_WAITING_STATUS_DISABLED);
Shuo Qian4a594052020-01-23 11:59:30 -08001429 }
Shuo Qian4a594052020-01-23 11:59:30 -08001430 break;
Hall Liu27d24262020-09-18 19:04:59 -07001431 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07001432 case EVENT_PERFORM_NETWORK_SCAN_DONE:
1433 ar = (AsyncResult) msg.obj;
1434 request = (MainThreadRequest) ar.userObj;
1435 CellNetworkScanResult cellScanResult;
1436 if (ar.exception == null && ar.result != null) {
1437 cellScanResult = new CellNetworkScanResult(
1438 CellNetworkScanResult.STATUS_SUCCESS,
1439 (List<OperatorInfo>) ar.result);
1440 } else {
1441 if (ar.result == null) {
1442 loge("getCellNetworkScanResults: Empty response");
1443 }
1444 if (ar.exception != null) {
1445 loge("getCellNetworkScanResults: Exception: " + ar.exception);
1446 }
1447 int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR;
1448 if (ar.exception instanceof CommandException) {
1449 CommandException.Error error =
1450 ((CommandException) (ar.exception)).getCommandError();
1451 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1452 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE;
1453 } else if (error == CommandException.Error.GENERIC_FAILURE) {
1454 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE;
1455 }
1456 }
1457 cellScanResult = new CellNetworkScanResult(errorCode, null);
1458 }
1459 request.result = cellScanResult;
Pengquan Menga1bb6272018-09-06 09:59:22 -07001460 notifyRequester(request);
Shishir Agrawal302c8692015-06-19 13:49:39 -07001461 break;
1462
1463 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
1464 request = (MainThreadRequest) msg.obj;
Shishir Agrawal77ba3172015-09-10 14:50:19 -07001465 ManualNetworkSelectionArgument selArg =
1466 (ManualNetworkSelectionArgument) request.argument;
Shishir Agrawal302c8692015-06-19 13:49:39 -07001467 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE,
1468 request);
Shishir Agrawal77ba3172015-09-10 14:50:19 -07001469 getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo,
1470 selArg.persistSelection, onCompleted);
Shishir Agrawal302c8692015-06-19 13:49:39 -07001471 break;
1472
1473 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
Pengquan Menge3d01e22018-09-20 15:25:35 -07001474 ar = (AsyncResult) msg.obj;
1475 request = (MainThreadRequest) ar.userObj;
1476 if (ar.exception == null) {
1477 request.result = true;
1478 } else {
1479 request.result = false;
1480 loge("setNetworkSelectionModeManual " + ar.exception);
1481 }
1482 notifyRequester(request);
1483 mApp.onNetworkSelectionChanged(request.subId);
Shishir Agrawal302c8692015-06-19 13:49:39 -07001484 break;
1485
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001486 case CMD_GET_MODEM_ACTIVITY_INFO:
1487 request = (MainThreadRequest) msg.obj;
1488 onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
James Mattisab947702019-04-03 14:18:34 -07001489 if (defaultPhone != null) {
1490 defaultPhone.getModemActivityInfo(onCompleted, request.workSource);
Shuo Qian8f4750a2020-02-20 17:12:10 -08001491 } else {
1492 ResultReceiver result = (ResultReceiver) request.argument;
1493 Bundle bundle = new Bundle();
1494 bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY,
Hall Liu49656c02020-10-09 19:00:11 -07001495 new ModemActivityInfo(0, 0, 0,
1496 new int[ModemActivityInfo.getNumTxPowerLevels()], 0));
Shuo Qian8f4750a2020-02-20 17:12:10 -08001497 result.send(0, bundle);
James Mattisab947702019-04-03 14:18:34 -07001498 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001499 break;
1500
Hall Liud0f208c2020-10-14 16:54:44 -07001501 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE: {
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001502 ar = (AsyncResult) msg.obj;
1503 request = (MainThreadRequest) ar.userObj;
Shuo Qian8f4750a2020-02-20 17:12:10 -08001504 ResultReceiver result = (ResultReceiver) request.argument;
Hall Liud0f208c2020-10-14 16:54:44 -07001505 int error = 0;
Kai Shi917fdc62022-11-28 14:01:02 -08001506 ModemActivityInfo ret = null;
Gary Jian3aa9a762022-01-24 16:41:19 +08001507 if (mLastModemActivityInfo == null) {
1508 mLastModemActivitySpecificInfo = new ActivityStatsTechSpecificInfo[1];
1509 mLastModemActivitySpecificInfo[0] =
1510 new ActivityStatsTechSpecificInfo(
1511 0,
1512 0,
1513 new int[ModemActivityInfo.getNumTxPowerLevels()],
1514 0);
1515 mLastModemActivityInfo =
1516 new ModemActivityInfo(0, 0, 0, mLastModemActivitySpecificInfo);
1517 }
1518
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001519 if (ar.exception == null && ar.result != null) {
Shuo Qian8f4750a2020-02-20 17:12:10 -08001520 // Update the last modem activity info and the result of the request.
1521 ModemActivityInfo info = (ModemActivityInfo) ar.result;
1522 if (isModemActivityInfoValid(info)) {
Gary Jian3aa9a762022-01-24 16:41:19 +08001523 mergeModemActivityInfo(info);
Gary Jian76280a42022-12-07 16:18:33 +08001524 } else {
1525 loge("queryModemActivityInfo: invalid response");
Shuo Qian8f4750a2020-02-20 17:12:10 -08001526 }
Kai Shi917fdc62022-11-28 14:01:02 -08001527 // This is needed to decouple ret from mLastModemActivityInfo
1528 // We don't want to return mLastModemActivityInfo which is updated
1529 // inside mergeModemActivityInfo()
1530 ret = new ModemActivityInfo(
1531 mLastModemActivityInfo.getTimestampMillis(),
1532 mLastModemActivityInfo.getSleepTimeMillis(),
1533 mLastModemActivityInfo.getIdleTimeMillis(),
1534 deepCopyModemActivitySpecificInfo(mLastModemActivitySpecificInfo));
Gary Jian3aa9a762022-01-24 16:41:19 +08001535
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001536 } else {
1537 if (ar.result == null) {
1538 loge("queryModemActivityInfo: Empty response");
Hall Liud0f208c2020-10-14 16:54:44 -07001539 error = TelephonyManager.ModemActivityInfoException
1540 .ERROR_INVALID_INFO_RECEIVED;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001541 } else if (ar.exception instanceof CommandException) {
Gary Jian3aa9a762022-01-24 16:41:19 +08001542 loge("queryModemActivityInfo: CommandException: " + ar.exception);
Hall Liud0f208c2020-10-14 16:54:44 -07001543 error = TelephonyManager.ModemActivityInfoException
1544 .ERROR_MODEM_RESPONSE_ERROR;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001545 } else {
1546 loge("queryModemActivityInfo: Unknown exception");
Hall Liud0f208c2020-10-14 16:54:44 -07001547 error = TelephonyManager.ModemActivityInfoException
1548 .ERROR_UNKNOWN;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001549 }
1550 }
Shuo Qian8f4750a2020-02-20 17:12:10 -08001551 Bundle bundle = new Bundle();
Kai Shi917fdc62022-11-28 14:01:02 -08001552 if (ret != null) {
Gary Jian3aa9a762022-01-24 16:41:19 +08001553 bundle.putParcelable(
1554 TelephonyManager.MODEM_ACTIVITY_RESULT_KEY,
Kai Shi917fdc62022-11-28 14:01:02 -08001555 ret);
Hall Liud0f208c2020-10-14 16:54:44 -07001556 } else {
1557 bundle.putInt(TelephonyManager.EXCEPTION_RESULT_KEY, error);
1558 }
Shuo Qian8f4750a2020-02-20 17:12:10 -08001559 result.send(0, bundle);
Pengquan Menga1bb6272018-09-06 09:59:22 -07001560 notifyRequester(request);
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001561 break;
Hall Liud0f208c2020-10-14 16:54:44 -07001562 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001563
Meng Wang1a7c35a2016-05-05 20:56:15 -07001564 case CMD_SET_ALLOWED_CARRIERS:
1565 request = (MainThreadRequest) msg.obj;
Michele Berionne482f8202018-11-27 18:57:59 -08001566 CarrierRestrictionRules argument =
1567 (CarrierRestrictionRules) request.argument;
Meng Wang1a7c35a2016-05-05 20:56:15 -07001568 onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
Michele Berionne482f8202018-11-27 18:57:59 -08001569 defaultPhone.setAllowedCarriers(argument, onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -07001570 break;
1571
1572 case EVENT_SET_ALLOWED_CARRIERS_DONE:
1573 ar = (AsyncResult) msg.obj;
1574 request = (MainThreadRequest) ar.userObj;
1575 if (ar.exception == null && ar.result != null) {
1576 request.result = ar.result;
1577 } else {
Michele Berionne482f8202018-11-27 18:57:59 -08001578 request.result = TelephonyManager.SET_CARRIER_RESTRICTION_ERROR;
1579 if (ar.exception instanceof CommandException) {
1580 loge("setAllowedCarriers: CommandException: " + ar.exception);
1581 CommandException.Error error =
1582 ((CommandException) (ar.exception)).getCommandError();
1583 if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1584 request.result =
1585 TelephonyManager.SET_CARRIER_RESTRICTION_NOT_SUPPORTED;
1586 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07001587 } else {
1588 loge("setAllowedCarriers: Unknown exception");
1589 }
1590 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001591 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -07001592 break;
1593
1594 case CMD_GET_ALLOWED_CARRIERS:
1595 request = (MainThreadRequest) msg.obj;
1596 onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001597 defaultPhone.getAllowedCarriers(onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -07001598 break;
1599
1600 case EVENT_GET_ALLOWED_CARRIERS_DONE:
1601 ar = (AsyncResult) msg.obj;
1602 request = (MainThreadRequest) ar.userObj;
1603 if (ar.exception == null && ar.result != null) {
1604 request.result = ar.result;
1605 } else {
Michele Berionne482f8202018-11-27 18:57:59 -08001606 request.result = new IllegalStateException(
1607 "Failed to get carrier restrictions");
Meng Wang1a7c35a2016-05-05 20:56:15 -07001608 if (ar.result == null) {
1609 loge("getAllowedCarriers: Empty response");
1610 } else if (ar.exception instanceof CommandException) {
1611 loge("getAllowedCarriers: CommandException: " +
1612 ar.exception);
1613 } else {
1614 loge("getAllowedCarriers: Unknown exception");
1615 }
1616 }
arunvoddud7401012022-12-15 16:08:12 +00001617 if (request.argument != null) {
1618 // This is for the implementation of carrierRestrictionStatus.
1619 CallerCallbackInfo callbackInfo = (CallerCallbackInfo) request.argument;
1620 Consumer<Integer> callback = callbackInfo.getConsumer();
1621 int callerCarrierId = callbackInfo.getCarrierId();
1622 int lockStatus = TelephonyManager.CARRIER_RESTRICTION_STATUS_UNKNOWN;
1623 if (ar.exception == null && ar.result instanceof CarrierRestrictionRules) {
1624 CarrierRestrictionRules carrierRestrictionRules =
1625 (CarrierRestrictionRules) ar.result;
1626 int carrierId = -1;
1627 try {
1628 CarrierIdentifier carrierIdentifier =
1629 carrierRestrictionRules.getAllowedCarriers().get(0);
1630 carrierId = CarrierResolver.getCarrierIdFromIdentifier(mApp,
1631 carrierIdentifier);
1632 } catch (NullPointerException | IndexOutOfBoundsException ex) {
1633 Rlog.e(LOG_TAG, "CarrierIdentifier exception = " + ex);
1634 }
1635 lockStatus = carrierRestrictionRules.getCarrierRestrictionStatus();
1636 if (carrierId != -1 && callerCarrierId == carrierId && lockStatus
1637 == TelephonyManager.CARRIER_RESTRICTION_STATUS_RESTRICTED) {
1638 lockStatus =
1639 TelephonyManager.CARRIER_RESTRICTION_STATUS_RESTRICTED_TO_CALLER;
1640 }
1641 } else {
1642 Rlog.e(LOG_TAG,
1643 "getCarrierRestrictionStatus: exception ex = " + ar.exception);
1644 }
1645 callback.accept(lockStatus);
1646 } else {
1647 // This is for the implementation of getAllowedCarriers.
1648 notifyRequester(request);
1649 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07001650 break;
1651
Nathan Haroldb3014052017-01-25 15:57:32 -08001652 case EVENT_GET_FORBIDDEN_PLMNS_DONE:
1653 ar = (AsyncResult) msg.obj;
1654 request = (MainThreadRequest) ar.userObj;
1655 if (ar.exception == null && ar.result != null) {
1656 request.result = ar.result;
1657 } else {
1658 request.result = new IllegalArgumentException(
1659 "Failed to retrieve Forbidden Plmns");
1660 if (ar.result == null) {
1661 loge("getForbiddenPlmns: Empty response");
1662 } else {
1663 loge("getForbiddenPlmns: Unknown exception");
1664 }
1665 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001666 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -08001667 break;
1668
1669 case CMD_GET_FORBIDDEN_PLMNS:
1670 request = (MainThreadRequest) msg.obj;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00001671 uiccPort = getUiccPortFromRequest(request);
1672 if (uiccPort == null) {
1673 loge("getForbiddenPlmns() UiccPort is null");
Nathan Haroldb3014052017-01-25 15:57:32 -08001674 request.result = new IllegalArgumentException(
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00001675 "getForbiddenPlmns() UiccPort is null");
Pengquan Menga1bb6272018-09-06 09:59:22 -07001676 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -08001677 break;
1678 }
1679 Integer appType = (Integer) request.argument;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00001680 UiccCardApplication uiccApp = uiccPort.getApplicationByType(appType);
Nathan Haroldb3014052017-01-25 15:57:32 -08001681 if (uiccApp == null) {
1682 loge("getForbiddenPlmns() no app with specified type -- "
1683 + appType);
1684 request.result = new IllegalArgumentException("Failed to get UICC App");
Pengquan Menga1bb6272018-09-06 09:59:22 -07001685 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -08001686 break;
1687 } else {
1688 if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
1689 + " specified type -- " + appType);
1690 }
1691 onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
1692 ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
1693 onCompleted);
1694 break;
1695
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001696 case CMD_SWITCH_SLOTS:
1697 request = (MainThreadRequest) msg.obj;
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00001698 List<UiccSlotMapping> slotMapping = (List<UiccSlotMapping>) request.argument;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001699 onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00001700 UiccController.getInstance().switchSlots(slotMapping, onCompleted);
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001701 break;
1702
1703 case EVENT_SWITCH_SLOTS_DONE:
1704 ar = (AsyncResult) msg.obj;
1705 request = (MainThreadRequest) ar.userObj;
1706 request.result = (ar.exception == null);
Pengquan Menga1bb6272018-09-06 09:59:22 -07001707 notifyRequester(request);
1708 break;
1709 case CMD_GET_NETWORK_SELECTION_MODE:
1710 request = (MainThreadRequest) msg.obj;
1711 onCompleted = obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE, request);
1712 getPhoneFromRequest(request).getNetworkSelectionMode(onCompleted);
1713 break;
1714
1715 case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
1716 ar = (AsyncResult) msg.obj;
1717 request = (MainThreadRequest) ar.userObj;
1718 if (ar.exception != null) {
1719 request.result = TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
1720 } else {
1721 int mode = ((int[]) ar.result)[0];
1722 if (mode == 0) {
1723 request.result = TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
1724 } else {
1725 request.result = TelephonyManager.NETWORK_SELECTION_MODE_MANUAL;
1726 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001727 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001728 notifyRequester(request);
1729 break;
1730 case CMD_GET_CDMA_ROAMING_MODE:
1731 request = (MainThreadRequest) msg.obj;
1732 onCompleted = obtainMessage(EVENT_GET_CDMA_ROAMING_MODE_DONE, request);
1733 getPhoneFromRequest(request).queryCdmaRoamingPreference(onCompleted);
1734 break;
1735 case EVENT_GET_CDMA_ROAMING_MODE_DONE:
1736 ar = (AsyncResult) msg.obj;
1737 request = (MainThreadRequest) ar.userObj;
1738 if (ar.exception != null) {
1739 request.result = TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT;
1740 } else {
1741 request.result = ((int[]) ar.result)[0];
1742 }
1743 notifyRequester(request);
1744 break;
1745 case CMD_SET_CDMA_ROAMING_MODE:
1746 request = (MainThreadRequest) msg.obj;
1747 onCompleted = obtainMessage(EVENT_SET_CDMA_ROAMING_MODE_DONE, request);
1748 int mode = (int) request.argument;
1749 getPhoneFromRequest(request).setCdmaRoamingPreference(mode, onCompleted);
1750 break;
1751 case EVENT_SET_CDMA_ROAMING_MODE_DONE:
1752 ar = (AsyncResult) msg.obj;
1753 request = (MainThreadRequest) ar.userObj;
1754 request.result = ar.exception == null;
1755 notifyRequester(request);
1756 break;
Sarah Chinbaab1432020-10-28 13:46:24 -07001757 case CMD_GET_CDMA_SUBSCRIPTION_MODE:
1758 request = (MainThreadRequest) msg.obj;
1759 onCompleted = obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1760 getPhoneFromRequest(request).queryCdmaSubscriptionMode(onCompleted);
1761 break;
1762 case EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE:
1763 ar = (AsyncResult) msg.obj;
1764 request = (MainThreadRequest) ar.userObj;
1765 if (ar.exception != null) {
1766 request.result = TelephonyManager.CDMA_SUBSCRIPTION_RUIM_SIM;
1767 } else {
1768 request.result = ((int[]) ar.result)[0];
1769 }
1770 notifyRequester(request);
1771 break;
Pengquan Menga1bb6272018-09-06 09:59:22 -07001772 case CMD_SET_CDMA_SUBSCRIPTION_MODE:
1773 request = (MainThreadRequest) msg.obj;
1774 onCompleted = obtainMessage(EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1775 int subscriptionMode = (int) request.argument;
Sarah Chinbaab1432020-10-28 13:46:24 -07001776 getPhoneFromRequest(request).setCdmaSubscriptionMode(
1777 subscriptionMode, onCompleted);
Pengquan Menga1bb6272018-09-06 09:59:22 -07001778 break;
1779 case EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE:
1780 ar = (AsyncResult) msg.obj;
1781 request = (MainThreadRequest) ar.userObj;
1782 request.result = ar.exception == null;
1783 notifyRequester(request);
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001784 break;
Nathan Harold3ff88932018-08-14 10:19:49 -07001785 case CMD_GET_ALL_CELL_INFO:
1786 request = (MainThreadRequest) msg.obj;
Nathan Harold3ff88932018-08-14 10:19:49 -07001787 onCompleted = obtainMessage(EVENT_GET_ALL_CELL_INFO_DONE, request);
Nathan Harold92bed182018-10-12 18:16:49 -07001788 request.phone.requestCellInfoUpdate(request.workSource, onCompleted);
Nathan Harold3ff88932018-08-14 10:19:49 -07001789 break;
Nathan Harold3ff88932018-08-14 10:19:49 -07001790 case EVENT_GET_ALL_CELL_INFO_DONE:
1791 ar = (AsyncResult) msg.obj;
1792 request = (MainThreadRequest) ar.userObj;
Nathan Harold8d0f1742018-10-02 12:14:47 -07001793 // If a timeout occurs, the response will be null
1794 request.result = (ar.exception == null && ar.result != null)
1795 ? ar.result : new ArrayList<CellInfo>();
Nathan Harold3ff88932018-08-14 10:19:49 -07001796 synchronized (request) {
1797 request.notifyAll();
1798 }
1799 break;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001800 case CMD_REQUEST_CELL_INFO_UPDATE:
1801 request = (MainThreadRequest) msg.obj;
1802 request.phone.requestCellInfoUpdate(request.workSource,
1803 obtainMessage(EVENT_REQUEST_CELL_INFO_UPDATE_DONE, request));
1804 break;
1805 case EVENT_REQUEST_CELL_INFO_UPDATE_DONE:
1806 ar = (AsyncResult) msg.obj;
1807 request = (MainThreadRequest) ar.userObj;
1808 ICellInfoCallback cb = (ICellInfoCallback) request.argument;
1809 try {
1810 if (ar.exception != null) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001811 Log.e(LOG_TAG, "Exception retrieving CellInfo=" + ar.exception);
Meng Wangd8921f42019-09-30 17:13:54 -07001812 cb.onError(
1813 TelephonyManager.CellInfoCallback.ERROR_MODEM_ERROR,
1814 ar.exception.getClass().getName(),
1815 ar.exception.toString());
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001816 } else if (ar.result == null) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001817 Log.w(LOG_TAG, "Timeout Waiting for CellInfo!");
Meng Wangd8921f42019-09-30 17:13:54 -07001818 cb.onError(TelephonyManager.CellInfoCallback.ERROR_TIMEOUT, null, null);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001819 } else {
1820 // use the result as returned
1821 cb.onCellInfo((List<CellInfo>) ar.result);
1822 }
1823 } catch (RemoteException re) {
1824 Log.w(LOG_TAG, "Discarded CellInfo due to Callback RemoteException");
1825 }
1826 break;
Sarah Chin679c08a2020-11-18 13:39:35 -08001827 case CMD_GET_CELL_LOCATION: {
Nathan Harold3ff88932018-08-14 10:19:49 -07001828 request = (MainThreadRequest) msg.obj;
1829 WorkSource ws = (WorkSource) request.argument;
1830 Phone phone = getPhoneFromRequest(request);
Meng Wanga10e89e2019-12-09 13:13:01 -08001831 phone.getCellIdentity(ws, obtainMessage(EVENT_GET_CELL_LOCATION_DONE, request));
Nathan Harold3ff88932018-08-14 10:19:49 -07001832 break;
Sarah Chin679c08a2020-11-18 13:39:35 -08001833 }
1834 case EVENT_GET_CELL_LOCATION_DONE: {
Nathan Harold3ff88932018-08-14 10:19:49 -07001835 ar = (AsyncResult) msg.obj;
1836 request = (MainThreadRequest) ar.userObj;
1837 if (ar.exception == null) {
1838 request.result = ar.result;
1839 } else {
Sarah Chin679c08a2020-11-18 13:39:35 -08001840 Phone phone = getPhoneFromRequest(request);
Nathan Harold3ff88932018-08-14 10:19:49 -07001841 request.result = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
Meng Wanga10e89e2019-12-09 13:13:01 -08001842 ? new CellIdentityCdma() : new CellIdentityGsm();
Nathan Harold3ff88932018-08-14 10:19:49 -07001843 }
1844
1845 synchronized (request) {
1846 request.notifyAll();
1847 }
1848 break;
Sarah Chin679c08a2020-11-18 13:39:35 -08001849 }
chen xu6dac5ab2018-10-26 17:39:23 -07001850 case CMD_MODEM_REBOOT:
1851 request = (MainThreadRequest) msg.obj;
1852 onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001853 defaultPhone.rebootModem(onCompleted);
chen xu6dac5ab2018-10-26 17:39:23 -07001854 break;
chen xu6dac5ab2018-10-26 17:39:23 -07001855 case EVENT_CMD_MODEM_REBOOT_DONE:
1856 handleNullReturnEvent(msg, "rebootModem");
1857 break;
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001858 case CMD_REQUEST_ENABLE_MODEM:
1859 request = (MainThreadRequest) msg.obj;
1860 boolean enable = (boolean) request.argument;
1861 onCompleted = obtainMessage(EVENT_ENABLE_MODEM_DONE, request);
Nazanin Bakhshi33d584b2019-02-27 10:44:32 -08001862 onCompleted.arg1 = enable ? 1 : 0;
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001863 PhoneConfigurationManager.getInstance()
1864 .enablePhone(request.phone, enable, onCompleted);
1865 break;
Michele Berionne5e411512020-11-13 02:36:59 +00001866 case EVENT_ENABLE_MODEM_DONE: {
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001867 ar = (AsyncResult) msg.obj;
1868 request = (MainThreadRequest) ar.userObj;
1869 request.result = (ar.exception == null);
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07001870 int phoneId = request.phone.getPhoneId();
Nazanin Bakhshi33d584b2019-02-27 10:44:32 -08001871 //update the cache as modem status has changed
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07001872 if ((boolean) request.result) {
1873 mPhoneConfigurationManager.addToPhoneStatusCache(phoneId, msg.arg1 == 1);
1874 updateModemStateMetrics();
1875 } else {
1876 Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1877 + ar.exception);
1878 }
1879 notifyRequester(request);
1880 break;
Michele Berionne5e411512020-11-13 02:36:59 +00001881 }
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07001882 case CMD_GET_MODEM_STATUS:
1883 request = (MainThreadRequest) msg.obj;
1884 onCompleted = obtainMessage(EVENT_GET_MODEM_STATUS_DONE, request);
1885 PhoneConfigurationManager.getInstance()
1886 .getPhoneStatusFromModem(request.phone, onCompleted);
1887 break;
1888 case EVENT_GET_MODEM_STATUS_DONE:
1889 ar = (AsyncResult) msg.obj;
1890 request = (MainThreadRequest) ar.userObj;
1891 int id = request.phone.getPhoneId();
1892 if (ar.exception == null && ar.result != null) {
1893 request.result = ar.result;
1894 //update the cache as modem status has changed
1895 mPhoneConfigurationManager.addToPhoneStatusCache(id,
1896 (boolean) request.result);
1897 } else {
1898 // Return true if modem status cannot be retrieved. For most cases,
1899 // modem status is on. And for older version modems, GET_MODEM_STATUS
1900 // and disable modem are not supported. Modem is always on.
1901 // TODO: this should be fixed in R to support a third
1902 // status UNKNOWN b/131631629
1903 request.result = true;
1904 Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1905 + ar.exception);
1906 }
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001907 notifyRequester(request);
1908 break;
Hall Liu73f5d362020-01-20 13:42:00 -08001909 case CMD_SET_SYSTEM_SELECTION_CHANNELS: {
1910 request = (MainThreadRequest) msg.obj;
1911 onCompleted = obtainMessage(EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE, request);
1912 Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> args =
1913 (Pair<List<RadioAccessSpecifier>, Consumer<Boolean>>) request.argument;
1914 request.phone.setSystemSelectionChannels(args.first, onCompleted);
1915 break;
1916 }
1917 case EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE: {
1918 ar = (AsyncResult) msg.obj;
1919 request = (MainThreadRequest) ar.userObj;
1920 Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> args =
1921 (Pair<List<RadioAccessSpecifier>, Consumer<Boolean>>) request.argument;
1922 args.second.accept(ar.exception == null);
1923 notifyRequester(request);
1924 break;
1925 }
Sarah Chin679c08a2020-11-18 13:39:35 -08001926 case CMD_GET_SYSTEM_SELECTION_CHANNELS: {
1927 request = (MainThreadRequest) msg.obj;
1928 onCompleted = obtainMessage(EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE, request);
1929 Phone phone = getPhoneFromRequest(request);
1930 if (phone != null) {
1931 phone.getSystemSelectionChannels(onCompleted);
1932 } else {
1933 loge("getSystemSelectionChannels: No phone object");
1934 request.result = new ArrayList<RadioAccessSpecifier>();
1935 notifyRequester(request);
1936 }
1937 break;
1938 }
1939 case EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE:
1940 ar = (AsyncResult) msg.obj;
1941 request = (MainThreadRequest) ar.userObj;
1942 if (ar.exception == null && ar.result != null) {
1943 request.result = ar.result;
1944 } else {
Sarah Chin428d1d62021-03-13 03:17:40 -08001945 request.result = new IllegalStateException(
1946 "Failed to retrieve system selecton channels");
Sarah Chin679c08a2020-11-18 13:39:35 -08001947 if (ar.result == null) {
1948 loge("getSystemSelectionChannels: Empty response");
1949 } else {
1950 loge("getSystemSelectionChannels: Unknown exception");
1951 }
1952 }
1953 notifyRequester(request);
1954 break;
yincheng zhao2737e882019-09-06 17:06:54 -07001955 case EVENT_SET_FORBIDDEN_PLMNS_DONE:
1956 ar = (AsyncResult) msg.obj;
1957 request = (MainThreadRequest) ar.userObj;
1958 if (ar.exception == null && ar.result != null) {
1959 request.result = ar.result;
1960 } else {
1961 request.result = -1;
1962 loge("Failed to set Forbidden Plmns");
1963 if (ar.result == null) {
1964 loge("setForbidenPlmns: Empty response");
1965 } else if (ar.exception != null) {
1966 loge("setForbiddenPlmns: Exception: " + ar.exception);
1967 request.result = -1;
1968 } else {
1969 loge("setForbiddenPlmns: Unknown exception");
1970 }
1971 }
1972 notifyRequester(request);
1973 break;
1974 case CMD_SET_FORBIDDEN_PLMNS:
1975 request = (MainThreadRequest) msg.obj;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00001976 uiccPort = getUiccPortFromRequest(request);
1977 if (uiccPort == null) {
1978 loge("setForbiddenPlmns: UiccPort is null");
yincheng zhao2737e882019-09-06 17:06:54 -07001979 request.result = -1;
1980 notifyRequester(request);
1981 break;
1982 }
1983 Pair<Integer, List<String>> setFplmnsArgs =
1984 (Pair<Integer, List<String>>) request.argument;
1985 appType = setFplmnsArgs.first;
1986 List<String> fplmns = setFplmnsArgs.second;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00001987 uiccApp = uiccPort.getApplicationByType(appType);
yincheng zhao2737e882019-09-06 17:06:54 -07001988 if (uiccApp == null) {
1989 loge("setForbiddenPlmns: no app with specified type -- " + appType);
1990 request.result = -1;
1991 loge("Failed to get UICC App");
1992 notifyRequester(request);
1993 } else {
1994 onCompleted = obtainMessage(EVENT_SET_FORBIDDEN_PLMNS_DONE, request);
1995 ((SIMRecords) uiccApp.getIccRecords())
1996 .setForbiddenPlmns(onCompleted, fplmns);
1997 }
yinchengzhao4d163c02019-12-12 15:21:47 -08001998 break;
Naina Nallurid63128d2019-09-17 14:10:30 -07001999 case CMD_ERASE_MODEM_CONFIG:
2000 request = (MainThreadRequest) msg.obj;
2001 onCompleted = obtainMessage(EVENT_ERASE_MODEM_CONFIG_DONE, request);
2002 defaultPhone.eraseModemConfig(onCompleted);
2003 break;
2004 case EVENT_ERASE_MODEM_CONFIG_DONE:
2005 handleNullReturnEvent(msg, "eraseModemConfig");
yincheng zhao2737e882019-09-06 17:06:54 -07002006 break;
zoey chene02881a2019-12-30 16:11:23 +08002007
Kai Shif70f46f2021-03-03 13:59:46 -08002008 case CMD_ERASE_DATA_SHARED_PREFERENCES:
2009 request = (MainThreadRequest) msg.obj;
2010 request.result = defaultPhone.eraseDataInSharedPreferences();
2011 notifyRequester(request);
2012 break;
2013
zoey chene02881a2019-12-30 16:11:23 +08002014 case CMD_CHANGE_ICC_LOCK_PASSWORD:
2015 request = (MainThreadRequest) msg.obj;
2016 onCompleted = obtainMessage(EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE, request);
2017 Pair<String, String> changed = (Pair<String, String>) request.argument;
2018 getPhoneFromRequest(request).getIccCard().changeIccLockPassword(
2019 changed.first, changed.second, onCompleted);
2020 break;
2021 case EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE:
2022 ar = (AsyncResult) msg.obj;
2023 request = (MainThreadRequest) ar.userObj;
2024 if (ar.exception == null) {
2025 request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
Michele Berionne5e411512020-11-13 02:36:59 +00002026 // If the operation is successful, update the PIN storage
2027 Pair<String, String> passwords = (Pair<String, String>) request.argument;
2028 int phoneId = getPhoneFromRequest(request).getPhoneId();
Jon Spivack9c3bc762021-10-06 20:53:09 +00002029 UiccController.getInstance().getPinStorage()
2030 .storePin(passwords.second, phoneId);
zoey chene02881a2019-12-30 16:11:23 +08002031 } else {
2032 request.result = msg.arg1;
2033 }
2034 notifyRequester(request);
2035 break;
2036
Michele Berionne5e411512020-11-13 02:36:59 +00002037 case CMD_SET_ICC_LOCK_ENABLED: {
zoey chene02881a2019-12-30 16:11:23 +08002038 request = (MainThreadRequest) msg.obj;
2039 onCompleted = obtainMessage(EVENT_SET_ICC_LOCK_ENABLED_DONE, request);
2040 Pair<Boolean, String> enabled = (Pair<Boolean, String>) request.argument;
2041 getPhoneFromRequest(request).getIccCard().setIccLockEnabled(
2042 enabled.first, enabled.second, onCompleted);
2043 break;
Michele Berionne5e411512020-11-13 02:36:59 +00002044 }
zoey chene02881a2019-12-30 16:11:23 +08002045 case EVENT_SET_ICC_LOCK_ENABLED_DONE:
2046 ar = (AsyncResult) msg.obj;
2047 request = (MainThreadRequest) ar.userObj;
2048 if (ar.exception == null) {
2049 request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
Michele Berionne5e411512020-11-13 02:36:59 +00002050 // If the operation is successful, update the PIN storage
2051 Pair<Boolean, String> enabled = (Pair<Boolean, String>) request.argument;
2052 int phoneId = getPhoneFromRequest(request).getPhoneId();
2053 if (enabled.first) {
Jon Spivack9c3bc762021-10-06 20:53:09 +00002054 UiccController.getInstance().getPinStorage()
2055 .storePin(enabled.second, phoneId);
Michele Berionne5e411512020-11-13 02:36:59 +00002056 } else {
2057 UiccController.getInstance().getPinStorage().clearPin(phoneId);
2058 }
zoey chene02881a2019-12-30 16:11:23 +08002059 } else {
2060 request.result = msg.arg1;
2061 }
Michele Berionne5e411512020-11-13 02:36:59 +00002062
2063
zoey chene02881a2019-12-30 16:11:23 +08002064 notifyRequester(request);
2065 break;
2066
Peter Wangdafb9ac2020-01-15 14:13:38 -08002067 case MSG_NOTIFY_USER_ACTIVITY:
2068 removeMessages(MSG_NOTIFY_USER_ACTIVITY);
Peter Wang59571be2020-01-27 12:35:15 +08002069 Intent intent = new Intent(TelephonyIntents.ACTION_USER_ACTIVITY_NOTIFICATION);
Peter Wangdafb9ac2020-01-15 14:13:38 -08002070 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
2071 getDefaultPhone().getContext().sendBroadcastAsUser(
2072 intent, UserHandle.ALL, permission.USER_ACTIVITY);
2073 break;
Jack Nudelmanb0b87642020-11-12 15:04:39 -08002074
2075 case CMD_SET_DATA_THROTTLING: {
2076 request = (MainThreadRequest) msg.obj;
2077 onCompleted = obtainMessage(EVENT_SET_DATA_THROTTLING_DONE, request);
2078 DataThrottlingRequest dataThrottlingRequest =
2079 (DataThrottlingRequest) request.argument;
2080 Phone phone = getPhoneFromRequest(request);
2081 if (phone != null) {
2082 phone.setDataThrottling(onCompleted,
2083 request.workSource, dataThrottlingRequest.getDataThrottlingAction(),
2084 dataThrottlingRequest.getCompletionDurationMillis());
2085 } else {
2086 loge("setDataThrottling: No phone object");
2087 request.result =
2088 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
2089 notifyRequester(request);
2090 }
2091
2092 break;
2093 }
2094 case EVENT_SET_DATA_THROTTLING_DONE:
2095 ar = (AsyncResult) msg.obj;
2096 request = (MainThreadRequest) ar.userObj;
2097
2098 if (ar.exception == null) {
2099 request.result = TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
2100 } else if (ar.exception instanceof CommandException) {
2101 loge("setDataThrottling: CommandException: " + ar.exception);
2102 CommandException.Error error =
2103 ((CommandException) (ar.exception)).getCommandError();
2104
2105 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
2106 request.result = TelephonyManager
2107 .THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
2108 } else if (error == CommandException.Error.INVALID_ARGUMENTS) {
2109 request.result = SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS;
Jack Nudelman5d6a98b2021-03-04 14:26:25 -08002110 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
2111 request.result = MODEM_DOES_NOT_SUPPORT_DATA_THROTTLING_ERROR_CODE;
Jack Nudelmanb0b87642020-11-12 15:04:39 -08002112 } else {
2113 request.result =
2114 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
2115 }
2116 } else {
2117 request.result = TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
2118 }
2119 Log.w(LOG_TAG, "DataThrottlingResult = " + request.result);
2120 notifyRequester(request);
2121 break;
Jordan Liu109698e2020-11-24 14:50:34 -08002122
2123 case CMD_SET_SIM_POWER: {
2124 request = (MainThreadRequest) msg.obj;
2125 onCompleted = obtainMessage(EVENT_SET_SIM_POWER_DONE, request);
2126 request = (MainThreadRequest) msg.obj;
2127 int stateToSet =
2128 ((Pair<Integer, IIntegerConsumer>)
2129 request.argument).first;
2130 request.phone.setSimPowerState(stateToSet, onCompleted, request.workSource);
2131 break;
2132 }
2133 case EVENT_SET_SIM_POWER_DONE: {
2134 ar = (AsyncResult) msg.obj;
2135 request = (MainThreadRequest) ar.userObj;
2136 IIntegerConsumer callback =
2137 ((Pair<Integer, IIntegerConsumer>) request.argument).second;
2138 if (ar.exception != null) {
2139 loge("setSimPower exception: " + ar.exception);
2140 int errorCode = TelephonyManager.CallForwardingInfoCallback
2141 .RESULT_ERROR_UNKNOWN;
2142 if (ar.exception instanceof CommandException) {
2143 CommandException.Error error =
2144 ((CommandException) (ar.exception)).getCommandError();
2145 if (error == CommandException.Error.SIM_ERR) {
2146 errorCode = TelephonyManager.SET_SIM_POWER_STATE_SIM_ERROR;
2147 } else if (error == CommandException.Error.INVALID_ARGUMENTS) {
2148 errorCode = TelephonyManager.SET_SIM_POWER_STATE_ALREADY_IN_STATE;
2149 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
2150 errorCode = TelephonyManager.SET_SIM_POWER_STATE_NOT_SUPPORTED;
2151 } else {
2152 errorCode = TelephonyManager.SET_SIM_POWER_STATE_MODEM_ERROR;
2153 }
2154 }
2155 try {
2156 callback.accept(errorCode);
2157 } catch (RemoteException e) {
2158 // Ignore if the remote process is no longer available to call back.
2159 Log.w(LOG_TAG, "setSimPower: callback not available.");
2160 }
2161 } else {
2162 try {
2163 callback.accept(TelephonyManager.SET_SIM_POWER_STATE_SUCCESS);
2164 } catch (RemoteException e) {
2165 // Ignore if the remote process is no longer available to call back.
2166 Log.w(LOG_TAG, "setSimPower: callback not available.");
2167 }
2168 }
2169 break;
2170 }
Rambo Wanga5cc9b72021-01-07 10:51:54 -08002171 case CMD_SET_SIGNAL_STRENGTH_UPDATE_REQUEST: {
2172 request = (MainThreadRequest) msg.obj;
2173
2174 final Phone phone = getPhoneFromRequest(request);
2175 if (phone == null || phone.getServiceStateTracker() == null) {
2176 request.result = new IllegalStateException("Phone or SST is null");
2177 notifyRequester(request);
2178 break;
2179 }
2180
2181 Pair<Integer, SignalStrengthUpdateRequest> pair =
2182 (Pair<Integer, SignalStrengthUpdateRequest>) request.argument;
2183 onCompleted = obtainMessage(EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE,
2184 request);
Rambo Wang6568f172021-02-03 16:56:47 -08002185 phone.getSignalStrengthController().setSignalStrengthUpdateRequest(
Rambo Wanga5cc9b72021-01-07 10:51:54 -08002186 request.subId, pair.first /*callingUid*/,
2187 pair.second /*request*/, onCompleted);
2188 break;
2189 }
2190 case EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE: {
2191 ar = (AsyncResult) msg.obj;
2192 request = (MainThreadRequest) ar.userObj;
2193 // request.result will be the exception of ar if present, true otherwise.
2194 // Be cautious not to leave result null which will wait() forever
2195 request.result = ar.exception != null ? ar.exception : true;
2196 notifyRequester(request);
2197 break;
2198 }
2199 case CMD_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST: {
2200 request = (MainThreadRequest) msg.obj;
2201
2202 Phone phone = getPhoneFromRequest(request);
2203 if (phone == null || phone.getServiceStateTracker() == null) {
2204 request.result = new IllegalStateException("Phone or SST is null");
2205 notifyRequester(request);
2206 break;
2207 }
2208
2209 Pair<Integer, SignalStrengthUpdateRequest> pair =
2210 (Pair<Integer, SignalStrengthUpdateRequest>) request.argument;
2211 onCompleted = obtainMessage(EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE,
2212 request);
Rambo Wang6568f172021-02-03 16:56:47 -08002213 phone.getSignalStrengthController().clearSignalStrengthUpdateRequest(
Rambo Wanga5cc9b72021-01-07 10:51:54 -08002214 request.subId, pair.first /*callingUid*/,
2215 pair.second /*request*/, onCompleted);
2216 break;
2217 }
2218 case EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE: {
2219 ar = (AsyncResult) msg.obj;
2220 request = (MainThreadRequest) ar.userObj;
2221 request.result = ar.exception != null ? ar.exception : true;
2222 notifyRequester(request);
2223 break;
2224 }
Jordan Liu109698e2020-11-24 14:50:34 -08002225
Hongbo Zeng156aa4a2021-02-08 21:50:28 +08002226 case CMD_GET_SLICING_CONFIG: {
2227 request = (MainThreadRequest) msg.obj;
2228 onCompleted = obtainMessage(EVENT_GET_SLICING_CONFIG_DONE, request);
2229 request.phone.getSlicingConfig(onCompleted);
2230 break;
2231 }
2232 case EVENT_GET_SLICING_CONFIG_DONE: {
2233 ar = (AsyncResult) msg.obj;
2234 request = (MainThreadRequest) ar.userObj;
2235 ResultReceiver result = (ResultReceiver) request.argument;
2236
Hongbo Zeng0e18b162021-04-07 16:52:18 +08002237 NetworkSlicingConfig slicingConfig = null;
Hongbo Zeng156aa4a2021-02-08 21:50:28 +08002238 Bundle bundle = new Bundle();
2239 int resultCode = 0;
2240 if (ar.exception != null) {
2241 Log.e(LOG_TAG, "Exception retrieving slicing configuration="
2242 + ar.exception);
Hongbo Zeng0e18b162021-04-07 16:52:18 +08002243 resultCode = TelephonyManager.NetworkSlicingException.ERROR_MODEM_ERROR;
Hongbo Zeng156aa4a2021-02-08 21:50:28 +08002244 } else if (ar.result == null) {
2245 Log.w(LOG_TAG, "Timeout Waiting for slicing configuration!");
Hongbo Zeng0e18b162021-04-07 16:52:18 +08002246 resultCode = TelephonyManager.NetworkSlicingException.ERROR_TIMEOUT;
Hongbo Zeng156aa4a2021-02-08 21:50:28 +08002247 } else {
2248 // use the result as returned
Hongbo Zeng0e18b162021-04-07 16:52:18 +08002249 resultCode = TelephonyManager.NetworkSlicingException.SUCCESS;
2250 slicingConfig = (NetworkSlicingConfig) ar.result;
Hongbo Zeng156aa4a2021-02-08 21:50:28 +08002251 }
2252
2253 if (slicingConfig == null) {
Hongbo Zeng0e18b162021-04-07 16:52:18 +08002254 slicingConfig = new NetworkSlicingConfig();
Hongbo Zeng156aa4a2021-02-08 21:50:28 +08002255 }
2256 bundle.putParcelable(TelephonyManager.KEY_SLICING_CONFIG_HANDLE, slicingConfig);
2257 result.send(resultCode, bundle);
2258 notifyRequester(request);
2259 break;
2260 }
2261
Sarah Chin71b3a852022-09-28 15:54:19 -07002262 case CMD_PURCHASE_PREMIUM_CAPABILITY: {
Sarah Chin2ec39f62022-08-31 17:03:26 -07002263 request = (MainThreadRequest) msg.obj;
2264 onCompleted = obtainMessage(EVENT_PURCHASE_PREMIUM_CAPABILITY_DONE, request);
Sarah Chin71b3a852022-09-28 15:54:19 -07002265 PurchasePremiumCapabilityArgument arg =
2266 (PurchasePremiumCapabilityArgument) request.argument;
Sarah Chin46355ba2022-11-01 23:51:16 -07002267 SlicePurchaseController.getInstance(request.phone).purchasePremiumCapability(
Sarah Chinb8218c22023-01-04 13:35:29 -08002268 arg.capability, onCompleted);
Sarah Chin2ec39f62022-08-31 17:03:26 -07002269 break;
Sarah Chin71b3a852022-09-28 15:54:19 -07002270 }
Sarah Chin2ec39f62022-08-31 17:03:26 -07002271
Sarah Chin71b3a852022-09-28 15:54:19 -07002272 case EVENT_PURCHASE_PREMIUM_CAPABILITY_DONE: {
Sarah Chin2ec39f62022-08-31 17:03:26 -07002273 ar = (AsyncResult) msg.obj;
2274 request = (MainThreadRequest) ar.userObj;
Sarah Chin71b3a852022-09-28 15:54:19 -07002275 PurchasePremiumCapabilityArgument arg =
2276 (PurchasePremiumCapabilityArgument) request.argument;
Sarah Chin2ec39f62022-08-31 17:03:26 -07002277 try {
2278 int result = (int) ar.result;
Sarah Chin71b3a852022-09-28 15:54:19 -07002279 arg.callback.accept(result);
Sarah Chin2ec39f62022-08-31 17:03:26 -07002280 log("purchasePremiumCapability: capability="
Sarah Chin71b3a852022-09-28 15:54:19 -07002281 + TelephonyManager.convertPremiumCapabilityToString(arg.capability)
Sarah Chin2ec39f62022-08-31 17:03:26 -07002282 + ", result= "
2283 + TelephonyManager.convertPurchaseResultToString(result));
2284 } catch (RemoteException e) {
2285 String logStr = "Purchase premium capability "
Sarah Chin71b3a852022-09-28 15:54:19 -07002286 + TelephonyManager.convertPremiumCapabilityToString(arg.capability)
Sarah Chin2ec39f62022-08-31 17:03:26 -07002287 + " failed: " + e;
2288 if (DBG) log(logStr);
2289 AnomalyReporter.reportAnomaly(
2290 UUID.fromString(PURCHASE_PREMIUM_CAPABILITY_ERROR_UUID), logStr);
2291 }
2292 break;
Sarah Chin71b3a852022-09-28 15:54:19 -07002293 }
Sarah Chin2ec39f62022-08-31 17:03:26 -07002294
Michele Berionne5e411512020-11-13 02:36:59 +00002295 case CMD_PREPARE_UNATTENDED_REBOOT:
2296 request = (MainThreadRequest) msg.obj;
2297 request.result =
Rafael Higuera Silvad9630642021-09-20 15:32:01 +00002298 UiccController.getInstance().getPinStorage()
2299 .prepareUnattendedReboot(request.workSource);
Michele Berionne5e411512020-11-13 02:36:59 +00002300 notifyRequester(request);
2301 break;
2302
Sarah Chineccfbd12023-01-20 19:00:35 -08002303 case CMD_START_SATELLITE_POSITION_UPDATES: {
2304 request = (MainThreadRequest) msg.obj;
2305 onCompleted =
2306 obtainMessage(EVENT_START_SATELLITE_POSITION_UPDATES_DONE, request);
2307 Phone phone = getPhoneFromRequest(request);
2308 if (phone != null) {
2309 phone.startSatellitePositionUpdates(onCompleted);
2310 } else {
2311 loge("startSatellitePositionUpdates: No phone object");
2312 request.result = SatelliteManager.SATELLITE_SERVICE_REQUEST_FAILED;
2313 notifyRequester(request);
2314 }
2315 break;
2316 }
2317
2318 case EVENT_START_SATELLITE_POSITION_UPDATES_DONE: {
2319 ar = (AsyncResult) msg.obj;
2320 request = (MainThreadRequest) ar.userObj;
2321 if (ar.exception == null) {
2322 request.result = SatelliteManager.SATELLITE_SERVICE_SUCCESS;
2323 } else {
2324 request.result = SatelliteManager.SATELLITE_SERVICE_ERROR;
2325 if (ar.exception instanceof CommandException) {
2326 CommandException.Error error =
2327 ((CommandException) (ar.exception)).getCommandError();
2328 request.result = RILUtils.convertToSatelliteError(error);
2329 loge("startSatellitePositionUpdates CommandException: " + ar.exception);
2330 } else {
2331 loge("startSatellitePositionUpdates unknown exception:" + ar.exception);
2332 }
2333 }
2334 notifyRequester(request);
2335 break;
2336 }
2337
2338 case CMD_STOP_SATELLITE_POSITION_UPDATES: {
2339 request = (MainThreadRequest) msg.obj;
2340 onCompleted =
2341 obtainMessage(EVENT_STOP_SATELLITE_POSITION_UPDATES_DONE, request);
2342 Phone phone = getPhoneFromRequest(request);
2343 if (phone != null) {
2344 phone.stopSatellitePositionUpdates(onCompleted);
2345 } else {
2346 loge("stopSatellitePositionUpdates: No phone object");
2347 request.result = SatelliteManager.SATELLITE_SERVICE_REQUEST_FAILED;
2348 notifyRequester(request);
2349 }
2350 break;
2351 }
2352
2353 case EVENT_STOP_SATELLITE_POSITION_UPDATES_DONE: {
2354 ar = (AsyncResult) msg.obj;
2355 request = (MainThreadRequest) ar.userObj;
2356 if (ar.exception == null) {
2357 request.result = SatelliteManager.SATELLITE_SERVICE_SUCCESS;
2358 } else {
2359 request.result = SatelliteManager.SATELLITE_SERVICE_ERROR;
2360 if (ar.exception instanceof CommandException) {
2361 CommandException.Error error =
2362 ((CommandException) (ar.exception)).getCommandError();
2363 request.result = RILUtils.convertToSatelliteError(error);
2364 loge("stopSatellitePositionUpdates CommandException: " + ar.exception);
2365 } else {
2366 loge("stopSatellitePositionUpdates unknown exception:" + ar.exception);
2367 }
2368 }
2369 notifyRequester(request);
2370 break;
2371 }
2372
Aishwarya Mallampati60fe1132023-01-24 19:07:21 +00002373 case CMD_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG: {
2374 request = (MainThreadRequest) msg.obj;
2375 onCompleted = obtainMessage(EVENT_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG_DONE,
2376 request);
2377 Phone phone = getPhoneFromRequest(request);
2378 if (phone != null) {
2379 phone.getMaxCharactersPerSatelliteTextMessage(onCompleted);
2380 } else {
2381 loge("getMaxCharactersPerSatelliteTextMessage: No phone object");
2382 request.result = SatelliteManager
2383 .SATELLITE_SERVICE_TELEPHONY_INTERNAL_ERROR;
2384 notifyRequester(request);
2385 }
2386 break;
2387 }
2388
2389 case EVENT_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG_DONE: {
2390 ar = (AsyncResult) msg.obj;
2391 request = (MainThreadRequest) ar.userObj;
2392 Consumer<Integer> callback = (Consumer<Integer>) request.argument;
2393 if (ar.exception != null) {
2394 request.result = SatelliteManager.SATELLITE_SERVICE_ERROR;
2395 if (ar.exception instanceof CommandException) {
2396 CommandException.Error error =
2397 ((CommandException) (ar.exception)).getCommandError();
2398 request.result = RILUtils.convertToSatelliteError(error);
2399 loge("getMaxCharactersPerSatelliteTextMessage: "
2400 + "CommandException: " + ar.exception);
2401 } else {
2402 loge("getMaxCharactersPerSatelliteTextMessage: "
2403 + "unknown exception:" + ar.exception);
2404 }
2405 } else if (ar.result == null) {
2406 request.result = SatelliteManager
2407 .SATELLITE_SERVICE_TELEPHONY_INTERNAL_ERROR;
2408 loge("getMaxCharactersPerSatelliteTextMessage: result is null");
2409 } else {
2410 request.result = SatelliteManager.SATELLITE_SERVICE_SUCCESS;
2411 int maxCharLimit = ((int[]) ar.result)[0];
2412 if(DBG) log("getMaxCharactersPerSatelliteTextMessage "
2413 + "maxCharLimit:" + maxCharLimit);
2414 callback.accept(maxCharLimit);
2415 }
2416 notifyRequester(request);
2417 break;
2418 }
2419
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002420 default:
2421 Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
2422 break;
2423 }
2424 }
Jake Hambye994d462014-02-03 13:10:13 -08002425
Pengquan Menga1bb6272018-09-06 09:59:22 -07002426 private void notifyRequester(MainThreadRequest request) {
2427 synchronized (request) {
2428 request.notifyAll();
2429 }
2430 }
2431
Jake Hambye994d462014-02-03 13:10:13 -08002432 private void handleNullReturnEvent(Message msg, String command) {
2433 AsyncResult ar = (AsyncResult) msg.obj;
2434 MainThreadRequest request = (MainThreadRequest) ar.userObj;
2435 if (ar.exception == null) {
2436 request.result = true;
2437 } else {
2438 request.result = false;
2439 if (ar.exception instanceof CommandException) {
2440 loge(command + ": CommandException: " + ar.exception);
2441 } else {
2442 loge(command + ": Unknown exception");
2443 }
2444 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07002445 notifyRequester(request);
Jake Hambye994d462014-02-03 13:10:13 -08002446 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002447 }
2448
2449 /**
2450 * Posts the specified command to be executed on the main thread,
2451 * waits for the request to complete, and returns the result.
2452 * @see #sendRequestAsync
2453 */
2454 private Object sendRequest(int command, Object argument) {
Rambo Wang0f050d82021-02-12 11:43:36 -08002455 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, null,
2456 null, -1 /*timeoutInMs*/);
vagdeviaf9a5b92018-08-15 16:01:53 -07002457 }
2458
2459 /**
2460 * Posts the specified command to be executed on the main thread,
2461 * waits for the request to complete, and returns the result.
2462 * @see #sendRequestAsync
2463 */
2464 private Object sendRequest(int command, Object argument, WorkSource workSource) {
2465 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
Rambo Wang0f050d82021-02-12 11:43:36 -08002466 null, workSource, -1 /*timeoutInMs*/);
Wink Saville36469e72014-06-11 15:17:00 -07002467 }
2468
2469 /**
2470 * Posts the specified command to be executed on the main thread,
2471 * waits for the request to complete, and returns the result.
2472 * @see #sendRequestAsync
2473 */
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002474 private Object sendRequest(int command, Object argument, Integer subId) {
Rambo Wang0f050d82021-02-12 11:43:36 -08002475 return sendRequest(command, argument, subId, null, null, -1 /*timeoutInMs*/);
2476 }
2477
2478 /**
2479 * Posts the specified command to be executed on the main thread,
2480 * waits for the request to complete for at most {@code timeoutInMs}, and returns the result
2481 * if not timeout or null otherwise.
2482 * @see #sendRequestAsync
2483 */
2484 private @Nullable Object sendRequest(int command, Object argument, Integer subId,
2485 long timeoutInMs) {
2486 return sendRequest(command, argument, subId, null, null, timeoutInMs);
vagdeviaf9a5b92018-08-15 16:01:53 -07002487 }
2488
2489 /**
2490 * Posts the specified command to be executed on the main thread,
2491 * waits for the request to complete, and returns the result.
2492 * @see #sendRequestAsync
2493 */
Nathan Harold92bed182018-10-12 18:16:49 -07002494 private Object sendRequest(int command, Object argument, int subId, WorkSource workSource) {
Rambo Wang0f050d82021-02-12 11:43:36 -08002495 return sendRequest(command, argument, subId, null, workSource, -1 /*timeoutInMs*/);
Nathan Harold92bed182018-10-12 18:16:49 -07002496 }
2497
2498 /**
2499 * Posts the specified command to be executed on the main thread,
2500 * waits for the request to complete, and returns the result.
2501 * @see #sendRequestAsync
2502 */
2503 private Object sendRequest(int command, Object argument, Phone phone, WorkSource workSource) {
Rambo Wang0f050d82021-02-12 11:43:36 -08002504 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phone,
2505 workSource, -1 /*timeoutInMs*/);
Nathan Harold92bed182018-10-12 18:16:49 -07002506 }
2507
2508 /**
Rambo Wang0f050d82021-02-12 11:43:36 -08002509 * Posts the specified command to be executed on the main thread. If {@code timeoutInMs} is
2510 * negative, waits for the request to complete, and returns the result. Otherwise, wait for
2511 * maximum of {@code timeoutInMs} milliseconds, interrupt and return null.
Nathan Harold92bed182018-10-12 18:16:49 -07002512 * @see #sendRequestAsync
2513 */
Rambo Wang0f050d82021-02-12 11:43:36 -08002514 private @Nullable Object sendRequest(int command, Object argument, Integer subId, Phone phone,
2515 WorkSource workSource, long timeoutInMs) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002516 if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
2517 throw new RuntimeException("This method will deadlock if called from the main thread.");
2518 }
2519
Nathan Harold92bed182018-10-12 18:16:49 -07002520 MainThreadRequest request = null;
2521 if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && phone != null) {
2522 throw new IllegalArgumentException("subId and phone cannot both be specified!");
2523 } else if (phone != null) {
2524 request = new MainThreadRequest(argument, phone, workSource);
2525 } else {
2526 request = new MainThreadRequest(argument, subId, workSource);
2527 }
2528
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002529 Message msg = mMainThreadHandler.obtainMessage(command, request);
2530 msg.sendToTarget();
2531
Rambo Wang0f050d82021-02-12 11:43:36 -08002532
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002533 synchronized (request) {
Rambo Wang0f050d82021-02-12 11:43:36 -08002534 if (timeoutInMs >= 0) {
2535 // Wait for at least timeoutInMs before returning null request result
2536 long now = SystemClock.elapsedRealtime();
2537 long deadline = now + timeoutInMs;
Grace Jia8a0a1e82021-05-23 22:59:52 -07002538 while (request.result == null && now < deadline) {
Rambo Wang0f050d82021-02-12 11:43:36 -08002539 try {
2540 request.wait(deadline - now);
2541 } catch (InterruptedException e) {
2542 // Do nothing, go back and check if request is completed or timeout
2543 } finally {
2544 now = SystemClock.elapsedRealtime();
2545 }
2546 }
2547 } else {
2548 // Wait for the request to complete
2549 while (request.result == null) {
2550 try {
2551 request.wait();
2552 } catch (InterruptedException e) {
2553 // Do nothing, go back and wait until the request is complete
2554 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002555 }
2556 }
2557 }
Rambo Wang0f050d82021-02-12 11:43:36 -08002558 if (request.result == null) {
2559 Log.wtf(LOG_TAG,
2560 "sendRequest: Blocking command timed out. Something has gone terribly wrong.");
2561 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002562 return request.result;
2563 }
2564
2565 /**
2566 * Asynchronous ("fire and forget") version of sendRequest():
2567 * Posts the specified command to be executed on the main thread, and
2568 * returns immediately.
2569 * @see #sendRequest
2570 */
2571 private void sendRequestAsync(int command) {
2572 mMainThreadHandler.sendEmptyMessage(command);
2573 }
2574
2575 /**
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07002576 * Same as {@link #sendRequestAsync(int)} except it takes an argument.
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002577 * @see {@link #sendRequest(int)}
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07002578 */
2579 private void sendRequestAsync(int command, Object argument) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002580 sendRequestAsync(command, argument, null, null);
2581 }
2582
2583 /**
2584 * Same as {@link #sendRequestAsync(int,Object)} except it takes a Phone and WorkSource.
2585 * @see {@link #sendRequest(int,Object)}
2586 */
2587 private void sendRequestAsync(
2588 int command, Object argument, Phone phone, WorkSource workSource) {
2589 MainThreadRequest request = new MainThreadRequest(argument, phone, workSource);
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07002590 Message msg = mMainThreadHandler.obtainMessage(command, request);
2591 msg.sendToTarget();
2592 }
2593
2594 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002595 * Initialize the singleton PhoneInterfaceManager instance.
2596 * This is only done once, at startup, from PhoneApp.onCreate().
2597 */
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002598 /* package */ static PhoneInterfaceManager init(PhoneGlobals app) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002599 synchronized (PhoneInterfaceManager.class) {
2600 if (sInstance == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002601 sInstance = new PhoneInterfaceManager(app);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002602 } else {
2603 Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
2604 }
2605 return sInstance;
2606 }
2607 }
2608
2609 /** Private constructor; @see init() */
Jordan Liu1979a042020-03-20 21:39:35 +00002610 private PhoneInterfaceManager(PhoneGlobals app) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002611 mApp = app;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002612 mCM = PhoneGlobals.getInstance().mCM;
Brad Ebingerd1947d82021-05-17 20:54:49 +00002613 mImsResolver = ImsResolver.getInstance();
Stuart Scott981d8582015-04-21 14:09:50 -07002614 mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002615 mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
Grace Jia0ddb3612021-04-22 13:35:26 -07002616 mPm = app.getSystemService(PackageManager.class);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002617 mMainThreadHandler = new MainThreadHandler();
Jack Yue37dd262022-12-16 11:53:37 -08002618 if (!PhoneFactory.isSubscriptionManagerServiceEnabled()) {
2619 mSubscriptionController = SubscriptionController.getInstance();
2620 } else {
2621 mSubscriptionController = null;
2622 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002623 mTelephonySharedPreferences =
2624 PreferenceManager.getDefaultSharedPreferences(mApp);
yinxub1bed742017-04-17 11:45:04 -07002625 mNetworkScanRequestTracker = new NetworkScanRequestTracker();
Malcolm Chen2c63d402018-08-14 16:00:53 -07002626 mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
Daniel Bright94f43662021-03-01 14:43:40 -08002627 mRadioInterfaceCapabilities = RadioInterfaceCapabilityController.getInstance();
Peter Wanga3cf4ac2020-01-27 09:39:46 +08002628 mNotifyUserActivity = new AtomicBoolean(false);
Tyler Gunn64144d92022-03-17 14:16:41 -07002629 PropertyInvalidatedCache.invalidateCache(TelephonyManager.CACHE_KEY_PHONE_ACCOUNT_TO_SUBID);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002630 publish();
arunvoddud7401012022-12-15 16:08:12 +00002631 CarrierAllowListInfo.loadInstance(mApp);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002632 }
2633
Gil Cukierman1c0eb932022-12-06 22:28:24 +00002634 @VisibleForTesting
2635 public SharedPreferences getSharedPreferences() {
2636 return mTelephonySharedPreferences;
2637 }
2638
Gil Cukierman92cc7db2023-01-06 19:25:53 +00002639 /**
2640 * Get the default phone for this device.
2641 */
2642 @VisibleForTesting
2643 public Phone getDefaultPhone() {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002644 Phone thePhone = getPhone(getDefaultSubscription());
2645 return (thePhone != null) ? thePhone : PhoneFactory.getDefaultPhone();
2646 }
2647
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002648 private void publish() {
2649 if (DBG) log("publish: " + this);
2650
Peter Wangc035ce42020-01-08 21:00:22 -08002651 TelephonyFrameworkInitializer
2652 .getTelephonyServiceManager()
2653 .getTelephonyServiceRegisterer()
2654 .register(this);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002655 }
2656
Stuart Scott584921c2015-01-15 17:10:34 -08002657 private Phone getPhoneFromRequest(MainThreadRequest request) {
Jordan Liu4c733742019-02-28 12:03:40 -08002658 if (request.phone != null) {
2659 return request.phone;
2660 } else {
2661 return getPhoneFromSubId(request.subId);
2662 }
2663 }
2664
2665 private Phone getPhoneFromSubId(int subId) {
2666 return (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
2667 ? getDefaultPhone() : getPhone(subId);
Stuart Scott584921c2015-01-15 17:10:34 -08002668 }
2669
Aishwarya Mallampati5e581e12023-01-17 21:57:06 +00002670 /**
2671 * Get phone object associated with a subscription.
2672 * Return default phone if phone object associated with subscription is null
2673 * @param subId - subscriptionId
2674 * @return phone object associated with a subscription or default phone if null.
2675 */
2676 private Phone getPhoneFromSubIdOrDefault(int subId) {
2677 Phone phone = getPhoneFromSubId(subId);
2678 if (phone == null) {
2679 phone = getDefaultPhone();
2680 }
2681 return phone;
2682 }
2683
Rambo Wange53e07d2022-05-10 13:01:13 -07002684 @Nullable
2685 private UiccPort getUiccPortFromRequest(@NonNull MainThreadRequest request) {
Shishir Agrawalc04d9752016-02-19 10:41:00 -08002686 Phone phone = getPhoneFromRequest(request);
2687 return phone == null ? null :
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00002688 UiccController.getInstance().getUiccPort(phone.getPhoneId());
Shishir Agrawalc04d9752016-02-19 10:41:00 -08002689 }
2690
Wink Saville36469e72014-06-11 15:17:00 -07002691 // returns phone associated with the subId.
Wink Savilleb564aae2014-10-23 10:18:09 -07002692 private Phone getPhone(int subId) {
Jack Yu285100e2022-12-02 22:48:35 -08002693 return PhoneFactory.getPhone(SubscriptionManager.getPhoneId(subId));
Wink Saville36469e72014-06-11 15:17:00 -07002694 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002695
Kai Shif70f46f2021-03-03 13:59:46 -08002696 private void sendEraseModemConfig(@NonNull Phone phone) {
2697 Boolean success = (Boolean) sendRequest(CMD_ERASE_MODEM_CONFIG, null);
2698 if (DBG) log("eraseModemConfig:" + ' ' + (success ? "ok" : "fail"));
2699 }
2700
2701 private void sendEraseDataInSharedPreferences(@NonNull Phone phone) {
2702 Boolean success = (Boolean) sendRequest(CMD_ERASE_DATA_SHARED_PREFERENCES, null);
2703 if (DBG) log("eraseDataInSharedPreferences:" + ' ' + (success ? "ok" : "fail"));
Naina Nallurid63128d2019-09-17 14:10:30 -07002704 }
2705
Peter Wang44b186e2020-01-13 23:33:09 -08002706 private boolean isImsAvailableOnDevice() {
2707 PackageManager pm = getDefaultPhone().getContext().getPackageManager();
2708 if (pm == null) {
2709 // For some reason package manger is not available.. This will fail internally anyway,
2710 // so do not throw error and allow.
2711 return true;
2712 }
2713 return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS, 0);
2714 }
2715
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002716 public void dial(String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002717 dialForSubscriber(getPreferredVoiceSubscription(), number);
Wink Saville36469e72014-06-11 15:17:00 -07002718 }
2719
Wink Savilleb564aae2014-10-23 10:18:09 -07002720 public void dialForSubscriber(int subId, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002721 if (DBG) log("dial: " + number);
2722 // No permission check needed here: This is just a wrapper around the
2723 // ACTION_DIAL intent, which is available to any app since it puts up
2724 // the UI before it does anything.
2725
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002726 final long identity = Binder.clearCallingIdentity();
2727 try {
2728 String url = createTelUrl(number);
2729 if (url == null) {
2730 return;
2731 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002732
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002733 // PENDING: should we just silently fail if phone is offhook or ringing?
2734 PhoneConstants.State state = mCM.getState(subId);
2735 if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
2736 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
2737 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2738 mApp.startActivity(intent);
2739 }
2740 } finally {
2741 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002742 }
2743 }
2744
2745 public void call(String callingPackage, String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002746 callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number);
Wink Saville36469e72014-06-11 15:17:00 -07002747 }
2748
Wink Savilleb564aae2014-10-23 10:18:09 -07002749 public void callForSubscriber(int subId, String callingPackage, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002750 if (DBG) log("call: " + number);
2751
2752 // This is just a wrapper around the ACTION_CALL intent, but we still
2753 // need to do a permission check since we're calling startActivity()
2754 // from the context of the phone app.
2755 enforceCallPermission();
2756
Jordan Liu1617b712019-07-10 15:06:26 -07002757 if (mAppOps.noteOp(AppOpsManager.OPSTR_CALL_PHONE, Binder.getCallingUid(), callingPackage)
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002758 != AppOpsManager.MODE_ALLOWED) {
2759 return;
2760 }
2761
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002762 final long identity = Binder.clearCallingIdentity();
2763 try {
2764 String url = createTelUrl(number);
2765 if (url == null) {
2766 return;
2767 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002768
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002769 boolean isValid = false;
2770 final List<SubscriptionInfo> slist = getActiveSubscriptionInfoListPrivileged();
2771 if (slist != null) {
2772 for (SubscriptionInfo subInfoRecord : slist) {
2773 if (subInfoRecord.getSubscriptionId() == subId) {
2774 isValid = true;
2775 break;
2776 }
Wink Saville3ab207e2014-11-20 13:07:20 -08002777 }
Wink Saville08874612014-08-31 19:19:58 -07002778 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002779 if (!isValid) {
2780 return;
2781 }
Wink Saville08874612014-08-31 19:19:58 -07002782
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002783 Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
2784 intent.putExtra(SUBSCRIPTION_KEY, subId);
2785 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2786 mApp.startActivity(intent);
2787 } finally {
2788 Binder.restoreCallingIdentity(identity);
2789 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002790 }
2791
Wink Savilleb564aae2014-10-23 10:18:09 -07002792 public boolean supplyPinForSubscriber(int subId, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002793 int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07002794 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
2795 }
2796
Wink Savilleb564aae2014-10-23 10:18:09 -07002797 public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002798 int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07002799 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
2800 }
2801
Wink Savilleb564aae2014-10-23 10:18:09 -07002802 public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002803 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002804
2805 final long identity = Binder.clearCallingIdentity();
2806 try {
Michele Berionne5e411512020-11-13 02:36:59 +00002807 Phone phone = getPhone(subId);
2808 final UnlockSim checkSimPin = new UnlockSim(phone.getPhoneId(), phone.getIccCard());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002809 checkSimPin.start();
2810 return checkSimPin.unlockSim(null, pin);
2811 } finally {
2812 Binder.restoreCallingIdentity(identity);
2813 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002814 }
2815
Wink Savilleb564aae2014-10-23 10:18:09 -07002816 public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002817 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002818
2819 final long identity = Binder.clearCallingIdentity();
2820 try {
Michele Berionne5e411512020-11-13 02:36:59 +00002821 Phone phone = getPhone(subId);
2822 final UnlockSim checkSimPuk = new UnlockSim(phone.getPhoneId(), phone.getIccCard());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002823 checkSimPuk.start();
2824 return checkSimPuk.unlockSim(puk, pin);
2825 } finally {
2826 Binder.restoreCallingIdentity(identity);
2827 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002828 }
2829
2830 /**
Wink Saville9de0f752013-10-22 19:04:03 -07002831 * Helper thread to turn async call to SimCard#supplyPin into
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002832 * a synchronous one.
2833 */
2834 private static class UnlockSim extends Thread {
2835
2836 private final IccCard mSimCard;
Michele Berionne5e411512020-11-13 02:36:59 +00002837 private final int mPhoneId;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002838
2839 private boolean mDone = false;
Wink Saville9de0f752013-10-22 19:04:03 -07002840 private int mResult = PhoneConstants.PIN_GENERAL_FAILURE;
2841 private int mRetryCount = -1;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002842
2843 // For replies from SimCard interface
2844 private Handler mHandler;
2845
2846 // For async handler to identify request type
2847 private static final int SUPPLY_PIN_COMPLETE = 100;
2848
Michele Berionne5e411512020-11-13 02:36:59 +00002849 UnlockSim(int phoneId, IccCard simCard) {
2850 mPhoneId = phoneId;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002851 mSimCard = simCard;
2852 }
2853
2854 @Override
2855 public void run() {
2856 Looper.prepare();
2857 synchronized (UnlockSim.this) {
2858 mHandler = new Handler() {
2859 @Override
2860 public void handleMessage(Message msg) {
2861 AsyncResult ar = (AsyncResult) msg.obj;
2862 switch (msg.what) {
2863 case SUPPLY_PIN_COMPLETE:
2864 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
2865 synchronized (UnlockSim.this) {
Wink Saville9de0f752013-10-22 19:04:03 -07002866 mRetryCount = msg.arg1;
2867 if (ar.exception != null) {
2868 if (ar.exception instanceof CommandException &&
2869 ((CommandException)(ar.exception)).getCommandError()
2870 == CommandException.Error.PASSWORD_INCORRECT) {
2871 mResult = PhoneConstants.PIN_PASSWORD_INCORRECT;
vivi.lib5e9ada2019-09-12 16:04:24 +08002872 } //When UiccCardApp dispose,handle message and return exception
2873 else if (ar.exception instanceof CommandException &&
2874 ((CommandException) (ar.exception)).getCommandError()
2875 == CommandException.Error.ABORTED) {
2876 mResult = PhoneConstants.PIN_OPERATION_ABORTED;
Wink Saville9de0f752013-10-22 19:04:03 -07002877 } else {
2878 mResult = PhoneConstants.PIN_GENERAL_FAILURE;
2879 }
2880 } else {
2881 mResult = PhoneConstants.PIN_RESULT_SUCCESS;
2882 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002883 mDone = true;
2884 UnlockSim.this.notifyAll();
2885 }
2886 break;
2887 }
2888 }
2889 };
2890 UnlockSim.this.notifyAll();
2891 }
2892 Looper.loop();
2893 }
2894
2895 /*
2896 * Use PIN or PUK to unlock SIM card
2897 *
2898 * If PUK is null, unlock SIM card with PIN
2899 *
2900 * If PUK is not null, unlock SIM card with PUK and set PIN code
2901 */
Wink Saville9de0f752013-10-22 19:04:03 -07002902 synchronized int[] unlockSim(String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002903
2904 while (mHandler == null) {
2905 try {
2906 wait();
2907 } catch (InterruptedException e) {
2908 Thread.currentThread().interrupt();
2909 }
2910 }
2911 Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
2912
2913 if (puk == null) {
2914 mSimCard.supplyPin(pin, callback);
2915 } else {
2916 mSimCard.supplyPuk(puk, pin, callback);
2917 }
2918
2919 while (!mDone) {
2920 try {
2921 Log.d(LOG_TAG, "wait for done");
2922 wait();
2923 } catch (InterruptedException e) {
2924 // Restore the interrupted status
2925 Thread.currentThread().interrupt();
2926 }
2927 }
2928 Log.d(LOG_TAG, "done");
Wink Saville9de0f752013-10-22 19:04:03 -07002929 int[] resultArray = new int[2];
2930 resultArray[0] = mResult;
2931 resultArray[1] = mRetryCount;
Michele Berionne5e411512020-11-13 02:36:59 +00002932
2933 if (mResult == PhoneConstants.PIN_RESULT_SUCCESS && pin.length() > 0) {
Jon Spivack9c3bc762021-10-06 20:53:09 +00002934 UiccController.getInstance().getPinStorage().storePin(pin, mPhoneId);
Michele Berionne5e411512020-11-13 02:36:59 +00002935 }
2936
Wink Saville9de0f752013-10-22 19:04:03 -07002937 return resultArray;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002938 }
2939 }
2940
Nathan Harold7c8d0f12020-05-28 20:40:31 -07002941 /**
2942 * This method has been removed due to privacy and stability concerns.
2943 */
2944 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002945 public void updateServiceLocation() {
Nathan Harold7c8d0f12020-05-28 20:40:31 -07002946 Log.e(LOG_TAG, "Call to unsupported method updateServiceLocation()");
2947 return;
Wink Saville36469e72014-06-11 15:17:00 -07002948 }
2949
Nathan Harold1f889d82020-06-04 17:05:26 -07002950 @Override
2951 public void updateServiceLocationWithPackageName(String callingPackage) {
2952 mApp.getSystemService(AppOpsManager.class)
2953 .checkPackage(Binder.getCallingUid(), callingPackage);
2954
Nathan Haroldf096d982020-11-18 17:18:06 -08002955 final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
Nathan Harold1f889d82020-06-04 17:05:26 -07002956 if (targetSdk > android.os.Build.VERSION_CODES.R) {
2957 // Callers targeting S have no business invoking this method.
2958 return;
2959 }
2960
2961 LocationAccessPolicy.LocationPermissionResult locationResult =
2962 LocationAccessPolicy.checkLocationPermission(mApp,
2963 new LocationAccessPolicy.LocationPermissionQuery.Builder()
2964 .setCallingPackage(callingPackage)
2965 .setCallingFeatureId(null)
2966 .setCallingPid(Binder.getCallingPid())
2967 .setCallingUid(Binder.getCallingUid())
2968 .setMethod("updateServiceLocation")
2969 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
2970 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2971 .build());
2972 // Apps that lack location permission have no business calling this method;
2973 // however, because no permission was declared in the public API, denials must
2974 // all be "soft".
2975 switch (locationResult) {
2976 case DENIED_HARD: /* fall through */
2977 case DENIED_SOFT:
2978 return;
2979 }
2980
2981 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002982 final long identity = Binder.clearCallingIdentity();
2983 try {
Nathan Harold1f889d82020-06-04 17:05:26 -07002984 final Phone phone = getPhone(getDefaultSubscription());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002985 if (phone != null) {
Nathan Harold1f889d82020-06-04 17:05:26 -07002986 phone.updateServiceLocation(workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002987 }
2988 } finally {
2989 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002990 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002991 }
2992
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002993 @Deprecated
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002994 @Override
2995 public boolean isRadioOn(String callingPackage) {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002996 return isRadioOnWithFeature(callingPackage, null);
2997 }
2998
2999
3000 @Override
3001 public boolean isRadioOnWithFeature(String callingPackage, String callingFeatureId) {
3002 return isRadioOnForSubscriberWithFeature(getDefaultSubscription(), callingPackage,
3003 callingFeatureId);
3004 }
3005
3006 @Deprecated
3007 @Override
3008 public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
3009 return isRadioOnForSubscriberWithFeature(subId, callingPackage, null);
Wink Saville36469e72014-06-11 15:17:00 -07003010 }
3011
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003012 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003013 public boolean isRadioOnForSubscriberWithFeature(int subId, String callingPackage,
3014 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003015 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003016 mApp, subId, callingPackage, callingFeatureId, "isRadioOnForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003017 return false;
3018 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003019
3020 final long identity = Binder.clearCallingIdentity();
3021 try {
3022 return isRadioOnForSubscriber(subId);
3023 } finally {
3024 Binder.restoreCallingIdentity(identity);
3025 }
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003026 }
3027
3028 private boolean isRadioOnForSubscriber(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003029 final long identity = Binder.clearCallingIdentity();
3030 try {
3031 final Phone phone = getPhone(subId);
3032 if (phone != null) {
3033 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
3034 } else {
3035 return false;
3036 }
3037 } finally {
3038 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003039 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003040 }
3041
3042 public void toggleRadioOnOff() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07003043 toggleRadioOnOffForSubscriber(getDefaultSubscription());
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003044 }
Wink Saville36469e72014-06-11 15:17:00 -07003045
Wink Savilleb564aae2014-10-23 10:18:09 -07003046 public void toggleRadioOnOffForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003047 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003048
3049 final long identity = Binder.clearCallingIdentity();
3050 try {
3051 final Phone phone = getPhone(subId);
3052 if (phone != null) {
3053 phone.setRadioPower(!isRadioOnForSubscriber(subId));
3054 }
3055 } finally {
3056 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003057 }
Wink Saville36469e72014-06-11 15:17:00 -07003058 }
3059
3060 public boolean setRadio(boolean turnOn) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07003061 return setRadioForSubscriber(getDefaultSubscription(), turnOn);
Wink Saville36469e72014-06-11 15:17:00 -07003062 }
3063
Wink Savilleb564aae2014-10-23 10:18:09 -07003064 public boolean setRadioForSubscriber(int subId, boolean turnOn) {
Wink Saville36469e72014-06-11 15:17:00 -07003065 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003066
3067 final long identity = Binder.clearCallingIdentity();
3068 try {
3069 final Phone phone = getPhone(subId);
3070 if (phone == null) {
3071 return false;
3072 }
3073 if ((phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF) != turnOn) {
3074 toggleRadioOnOffForSubscriber(subId);
3075 }
3076 return true;
3077 } finally {
3078 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003079 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003080 }
Wink Saville36469e72014-06-11 15:17:00 -07003081
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07003082 public boolean needMobileRadioShutdown() {
Shuo Qianfa7b6b32019-12-10 10:40:38 -08003083 enforceReadPrivilegedPermission("needMobileRadioShutdown");
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07003084 /*
3085 * If any of the Radios are available, it will need to be
3086 * shutdown. So return true if any Radio is available.
3087 */
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003088 final long identity = Binder.clearCallingIdentity();
3089 try {
3090 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
3091 Phone phone = PhoneFactory.getPhone(i);
3092 if (phone != null && phone.isRadioAvailable()) return true;
3093 }
3094 logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown.");
3095 return false;
3096 } finally {
3097 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07003098 }
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07003099 }
3100
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003101 @Override
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07003102 public void shutdownMobileRadios() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003103 enforceModifyPermission();
3104
3105 final long identity = Binder.clearCallingIdentity();
3106 try {
3107 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
3108 logv("Shutting down Phone " + i);
3109 shutdownRadioUsingPhoneId(i);
3110 }
3111 } finally {
3112 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07003113 }
3114 }
3115
3116 private void shutdownRadioUsingPhoneId(int phoneId) {
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07003117 Phone phone = PhoneFactory.getPhone(phoneId);
3118 if (phone != null && phone.isRadioAvailable()) {
3119 phone.shutdownRadio();
3120 }
3121 }
3122
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003123 public boolean setRadioPower(boolean turnOn) {
Jack Yub4e16162017-05-15 12:48:40 -07003124 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003125
Ling Ma83dc5ea2023-01-12 15:06:04 -08003126 if (!turnOn) {
3127 log("setRadioPower off: callingPackage=" + getCurrentPackageName());
3128 }
3129
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003130 final long identity = Binder.clearCallingIdentity();
3131 try {
3132 final Phone defaultPhone = PhoneFactory.getDefaultPhone();
3133 if (defaultPhone != null) {
3134 defaultPhone.setRadioPower(turnOn);
3135 return true;
3136 } else {
3137 loge("There's no default phone.");
3138 return false;
3139 }
3140 } finally {
3141 Binder.restoreCallingIdentity(identity);
Wei Liu9ae2a062016-08-08 11:09:34 -07003142 }
Wink Saville36469e72014-06-11 15:17:00 -07003143 }
3144
Wink Savilleb564aae2014-10-23 10:18:09 -07003145 public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003146 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003147
Ling Ma83dc5ea2023-01-12 15:06:04 -08003148 if (!turnOn) {
3149 log("setRadioPowerForSubscriber off: subId=" + subId
3150 + ",callingPackage=" + getCurrentPackageName());
3151 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003152 final long identity = Binder.clearCallingIdentity();
3153 try {
3154 final Phone phone = getPhone(subId);
3155 if (phone != null) {
3156 phone.setRadioPower(turnOn);
3157 return true;
3158 } else {
3159 return false;
3160 }
3161 } finally {
3162 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003163 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003164 }
3165
Thomas Nguyenfd0572f2022-07-15 22:28:49 +00003166 /**
3167 * Vote on powering off the radio for a reason. The radio will be turned on only when there is
3168 * no reason to power it off. When any of the voters want to power it off, it will be turned
3169 * off. In case of emergency, the radio will be turned on even if there are some reasons for
3170 * powering it off, and these radio off votes will be cleared.
3171 * Multiple apps can vote for the same reason and the last vote will take effect. Each app is
3172 * responsible for its vote. A powering-off vote of a reason will be maintained until it is
3173 * cleared by calling {@link clearRadioPowerOffForReason} for that reason, or an emergency call
3174 * is made, or the device is rebooted. When an app comes backup from a crash, it needs to make
3175 * sure if its vote is as expected. An app can use the API {@link getRadioPowerOffReasons} to
3176 * check its vote.
3177 *
3178 * @param subId The subscription ID.
3179 * @param reason The reason for powering off radio.
3180 * @return true on success and false on failure.
3181 */
3182 public boolean requestRadioPowerOffForReason(int subId,
3183 @TelephonyManager.RadioPowerReason int reason) {
3184 enforceModifyPermission();
3185
Ling Ma83dc5ea2023-01-12 15:06:04 -08003186 log("requestRadioPowerOffForReason: subId=" + subId
3187 + ",reason=" + reason + ",callingPackage=" + getCurrentPackageName());
Thomas Nguyenfd0572f2022-07-15 22:28:49 +00003188 final long identity = Binder.clearCallingIdentity();
3189 try {
3190 final Phone phone = getPhone(subId);
3191 if (phone != null) {
3192 phone.setRadioPowerForReason(false, reason);
3193 return true;
3194 } else {
3195 return false;
3196 }
3197 } finally {
3198 Binder.restoreCallingIdentity(identity);
3199 }
3200 }
3201
3202 /**
3203 * Remove the vote on powering off the radio for a reason, as requested by
3204 * {@link requestRadioPowerOffForReason}.
3205 *
3206 * @param subId The subscription ID.
3207 * @param reason The reason for powering off radio.
3208 * @return true on success and false on failure.
3209 */
3210 public boolean clearRadioPowerOffForReason(int subId,
3211 @TelephonyManager.RadioPowerReason int reason) {
3212 enforceModifyPermission();
3213
3214 final long identity = Binder.clearCallingIdentity();
3215 try {
3216 final Phone phone = getPhone(subId);
3217 if (phone != null) {
3218 phone.setRadioPowerForReason(true, reason);
3219 return true;
3220 } else {
3221 return false;
3222 }
3223 } finally {
3224 Binder.restoreCallingIdentity(identity);
3225 }
3226 }
3227
3228 /**
3229 * Get reasons for powering off radio, as requested by {@link requestRadioPowerOffForReason}.
3230 *
3231 * @param subId The subscription ID.
3232 * @param callingPackage The package making the call.
3233 * @param callingFeatureId The feature in the package.
3234 * @return List of reasons for powering off radio.
3235 */
3236 public List getRadioPowerOffReasons(int subId, String callingPackage, String callingFeatureId) {
3237 enforceReadPrivilegedPermission("getRadioPowerOffReasons");
3238
3239 final long identity = Binder.clearCallingIdentity();
3240 List result = new ArrayList();
3241 try {
3242 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId,
3243 callingPackage, callingFeatureId, "getRadioPowerOffReasons")) {
3244 return result;
3245 }
3246
3247 final Phone phone = getPhone(subId);
3248 if (phone != null) {
3249 result.addAll(phone.getRadioPowerOffReasons());
3250 }
3251 } finally {
3252 Binder.restoreCallingIdentity(identity);
3253 }
3254 return result;
3255 }
3256
Wink Saville36469e72014-06-11 15:17:00 -07003257 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07003258 @Override
Sarah Chinecc78c42022-03-31 21:16:48 -07003259 public boolean enableDataConnectivity(String callingPackage) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003260 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003261
3262 final long identity = Binder.clearCallingIdentity();
3263 try {
Jack Yu285100e2022-12-02 22:48:35 -08003264 int subId = SubscriptionManager.getDefaultDataSubscriptionId();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003265 final Phone phone = getPhone(subId);
3266 if (phone != null) {
Jack Yu7968c6d2022-07-31 00:43:21 -07003267 phone.getDataSettingsManager().setDataEnabled(
3268 TelephonyManager.DATA_ENABLED_REASON_USER, true, callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003269 return true;
3270 } else {
3271 return false;
3272 }
3273 } finally {
3274 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003275 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003276 }
3277
Wink Saville36469e72014-06-11 15:17:00 -07003278 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07003279 @Override
Sarah Chinecc78c42022-03-31 21:16:48 -07003280 public boolean disableDataConnectivity(String callingPackage) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003281 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003282
3283 final long identity = Binder.clearCallingIdentity();
3284 try {
Jack Yu285100e2022-12-02 22:48:35 -08003285 int subId = SubscriptionManager.getDefaultDataSubscriptionId();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003286 final Phone phone = getPhone(subId);
3287 if (phone != null) {
Jack Yu7968c6d2022-07-31 00:43:21 -07003288 phone.getDataSettingsManager().setDataEnabled(
3289 TelephonyManager.DATA_ENABLED_REASON_USER, false, callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003290 return true;
3291 } else {
3292 return false;
3293 }
3294 } finally {
3295 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003296 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003297 }
3298
Sanket Padawe356d7632015-06-22 14:03:32 -07003299 @Override
Jack Yuacf8a132017-05-01 17:00:48 -07003300 public boolean isDataConnectivityPossible(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003301 final long identity = Binder.clearCallingIdentity();
3302 try {
3303 final Phone phone = getPhone(subId);
3304 if (phone != null) {
Jack Yu59824e12022-03-23 01:42:44 -07003305 return phone.isDataAllowed();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003306 } else {
3307 return false;
3308 }
3309 } finally {
3310 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003311 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003312 }
3313
3314 public boolean handlePinMmi(String dialString) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07003315 return handlePinMmiForSubscriber(getDefaultSubscription(), dialString);
Wink Saville36469e72014-06-11 15:17:00 -07003316 }
3317
pkanwarae03a6b2016-11-06 20:37:09 -08003318 public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003319 enforceCallPermission();
3320
3321 final long identity = Binder.clearCallingIdentity();
3322 try {
3323 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3324 return;
3325 }
3326 Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback);
3327 sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId);
3328 } finally {
3329 Binder.restoreCallingIdentity(identity);
3330 }
pkanwar32d516d2016-10-14 19:37:38 -07003331 };
3332
Wink Savilleb564aae2014-10-23 10:18:09 -07003333 public boolean handlePinMmiForSubscriber(int subId, String dialString) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003334 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003335
3336 final long identity = Binder.clearCallingIdentity();
3337 try {
3338 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3339 return false;
3340 }
3341 return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
3342 } finally {
3343 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003344 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003345 }
3346
Brad Ebinger4f6208e2021-03-23 21:04:45 +00003347 /**
3348 * @deprecated This method is deprecated and is only being kept due to an UnsupportedAppUsage
3349 * tag on getCallState Binder call.
3350 */
3351 @Deprecated
3352 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003353 public int getCallState() {
Brad Ebinger4f6208e2021-03-23 21:04:45 +00003354 if (CompatChanges.isChangeEnabled(
3355 TelecomManager.ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION,
3356 Binder.getCallingUid())) {
3357 // Do not allow this API to be called on API version 31+, it should only be
3358 // called on old apps using this Binder call directly.
3359 throw new SecurityException("This method can only be used for applications "
3360 + "targeting API version 30 or less.");
3361 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003362 final long identity = Binder.clearCallingIdentity();
3363 try {
Brad Ebinger4f6208e2021-03-23 21:04:45 +00003364 Phone phone = getPhone(getDefaultSubscription());
3365 return phone == null ? TelephonyManager.CALL_STATE_IDLE :
3366 PhoneConstantConversions.convertCallState(phone.getState());
3367 } finally {
3368 Binder.restoreCallingIdentity(identity);
3369 }
3370 }
3371
3372 @Override
3373 public int getCallStateForSubscription(int subId, String callingPackage, String featureId) {
3374 if (CompatChanges.isChangeEnabled(
3375 TelecomManager.ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION,
3376 Binder.getCallingUid())) {
3377 // Check READ_PHONE_STATE for API version 31+
3378 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
3379 featureId, "getCallStateForSubscription")) {
3380 throw new SecurityException("getCallState requires READ_PHONE_STATE for apps "
3381 + "targeting API level 31+.");
3382 }
3383 }
3384 final long identity = Binder.clearCallingIdentity();
3385 try {
3386 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003387 return phone == null ? TelephonyManager.CALL_STATE_IDLE :
3388 PhoneConstantConversions.convertCallState(phone.getState());
3389 } finally {
3390 Binder.restoreCallingIdentity(identity);
3391 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003392 }
3393
Sanket Padawe356d7632015-06-22 14:03:32 -07003394 @Override
Nathan Harolde037c472019-06-26 00:41:07 +00003395 public int getDataState() {
Jack Yu285100e2022-12-02 22:48:35 -08003396 return getDataStateForSubId(SubscriptionManager.getDefaultDataSubscriptionId());
Nathan Haroldc4689b12019-06-14 16:58:30 -07003397 }
3398
3399 @Override
3400 public int getDataStateForSubId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003401 final long identity = Binder.clearCallingIdentity();
3402 try {
Nathan Haroldc4689b12019-06-14 16:58:30 -07003403 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003404 if (phone != null) {
Jack Yu7968c6d2022-07-31 00:43:21 -07003405 return phone.getDataNetworkController().getInternetDataNetworkState();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003406 } else {
3407 return PhoneConstantConversions.convertDataState(
3408 PhoneConstants.DataState.DISCONNECTED);
3409 }
3410 } finally {
3411 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003412 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003413 }
3414
Sanket Padawe356d7632015-06-22 14:03:32 -07003415 @Override
Jack Yu0eda6842022-04-18 00:34:46 -07003416 public @DataActivityType int getDataActivity() {
Jack Yu285100e2022-12-02 22:48:35 -08003417 return getDataActivityForSubId(SubscriptionManager.getDefaultDataSubscriptionId());
Nathan Haroldc4689b12019-06-14 16:58:30 -07003418 }
3419
3420 @Override
Jack Yu0eda6842022-04-18 00:34:46 -07003421 public @DataActivityType int getDataActivityForSubId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003422 final long identity = Binder.clearCallingIdentity();
3423 try {
Nathan Haroldc4689b12019-06-14 16:58:30 -07003424 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003425 if (phone != null) {
Jack Yu0eda6842022-04-18 00:34:46 -07003426 return phone.getDataActivityState();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003427 } else {
3428 return TelephonyManager.DATA_ACTIVITY_NONE;
3429 }
3430 } finally {
3431 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003432 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003433 }
3434
3435 @Override
Meng Wanga10e89e2019-12-09 13:13:01 -08003436 public CellIdentity getCellLocation(String callingPackage, String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003437 mApp.getSystemService(AppOpsManager.class)
Hall Liu1aa510f2017-11-22 17:40:08 -08003438 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08003439
3440 LocationAccessPolicy.LocationPermissionResult locationResult =
3441 LocationAccessPolicy.checkLocationPermission(mApp,
3442 new LocationAccessPolicy.LocationPermissionQuery.Builder()
3443 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003444 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08003445 .setCallingPid(Binder.getCallingPid())
3446 .setCallingUid(Binder.getCallingUid())
3447 .setMethod("getCellLocation")
Hall Liu773ba022020-01-24 18:07:12 -08003448 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
Hall Liuf19c44f2018-11-27 14:38:17 -08003449 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
3450 .build());
3451 switch (locationResult) {
3452 case DENIED_HARD:
3453 throw new SecurityException("Not allowed to access cell location");
3454 case DENIED_SOFT:
Meng Wanga10e89e2019-12-09 13:13:01 -08003455 return (getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
3456 ? new CellIdentityCdma() : new CellIdentityGsm();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003457 }
3458
Narayan Kamathf04b5a12018-01-09 11:47:15 +00003459 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003460 final long identity = Binder.clearCallingIdentity();
3461 try {
3462 if (DBG_LOC) log("getCellLocation: is active user");
Jack Yu285100e2022-12-02 22:48:35 -08003463 int subId = SubscriptionManager.getDefaultDataSubscriptionId();
Meng Wanga10e89e2019-12-09 13:13:01 -08003464 return (CellIdentity) sendRequest(CMD_GET_CELL_LOCATION, workSource, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003465 } finally {
3466 Binder.restoreCallingIdentity(identity);
3467 }
Svetoslav64fad262015-04-14 14:35:21 -07003468 }
3469
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003470 @Override
Jack Yueb1e7fe2020-02-22 19:38:58 -08003471 public String getNetworkCountryIsoForPhone(int phoneId) {
Jonathan Basseribf5362b2017-07-19 12:22:35 -07003472 // Reporting the correct network country is ambiguous when IWLAN could conflict with
3473 // registered cell info, so return a NULL country instead.
3474 final long identity = Binder.clearCallingIdentity();
3475 try {
Malcolm Chen3732c2b2018-07-18 20:15:24 -07003476 if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
3477 // Get default phone in this case.
3478 phoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
3479 }
Jack Yu285100e2022-12-02 22:48:35 -08003480 final int subId = SubscriptionManager.getSubscriptionId(phoneId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003481 Phone phone = PhoneFactory.getPhone(phoneId);
Nathan Harold532f51c2020-04-21 19:31:10 -07003482 if (phone == null) return "";
3483 ServiceStateTracker sst = phone.getServiceStateTracker();
3484 if (sst == null) return "";
3485 LocaleTracker lt = sst.getLocaleTracker();
3486 if (lt == null) return "";
Shuo Qian9418a922021-03-09 11:21:16 -08003487 return lt.getCurrentCountry();
Jonathan Basseribf5362b2017-07-19 12:22:35 -07003488 } finally {
3489 Binder.restoreCallingIdentity(identity);
3490 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07003491 }
3492
Nathan Harold7c8d0f12020-05-28 20:40:31 -07003493 /**
3494 * This method was removed due to potential issues caused by performing partial
3495 * updates of service state, and lack of a credible use case.
3496 *
3497 * This has the ability to break the telephony implementation by disabling notification of
3498 * changes in device connectivity. DO NOT USE THIS!
3499 */
Jonathan Basseribf5362b2017-07-19 12:22:35 -07003500 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003501 public void enableLocationUpdates() {
3502 mApp.enforceCallingOrSelfPermission(
3503 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003504 }
3505
Nathan Harold7c8d0f12020-05-28 20:40:31 -07003506 /**
3507 * This method was removed due to potential issues caused by performing partial
3508 * updates of service state, and lack of a credible use case.
3509 *
3510 * This has the ability to break the telephony implementation by disabling notification of
3511 * changes in device connectivity. DO NOT USE THIS!
3512 */
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003513 @Override
3514 public void disableLocationUpdates() {
3515 mApp.enforceCallingOrSelfPermission(
3516 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003517 }
3518
3519 @Override
3520 @SuppressWarnings("unchecked")
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003521 public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage,
3522 String callingFeatureId) {
Nathan Haroldb55f63b2021-07-27 11:27:38 -07003523 try {
3524 mApp.getSystemService(AppOpsManager.class)
3525 .checkPackage(Binder.getCallingUid(), callingPackage);
3526 } catch (SecurityException e) {
3527 EventLog.writeEvent(0x534e4554, "190619791", Binder.getCallingUid());
3528 throw e;
3529 }
3530
Nathan Haroldf096d982020-11-18 17:18:06 -08003531 final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
Nathan Harolddbea45a2018-08-30 14:35:07 -07003532 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
3533 throw new SecurityException(
3534 "getNeighboringCellInfo() is unavailable to callers targeting Q+ SDK levels.");
3535 }
Nathan Haroldb4d55612018-07-20 13:13:08 -07003536
Jordan Liu1617b712019-07-10 15:06:26 -07003537 if (mAppOps.noteOp(AppOpsManager.OPSTR_NEIGHBORING_CELLS, Binder.getCallingUid(),
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003538 callingPackage) != AppOpsManager.MODE_ALLOWED) {
3539 return null;
3540 }
Svetoslav64fad262015-04-14 14:35:21 -07003541
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07003542 if (DBG_LOC) log("getNeighboringCellInfo: is active user");
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003543
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003544 List<CellInfo> info = getAllCellInfo(callingPackage, callingFeatureId);
Nathan Haroldf180aac2018-06-01 18:43:55 -07003545 if (info == null) return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003546
Nathan Haroldf180aac2018-06-01 18:43:55 -07003547 List<NeighboringCellInfo> neighbors = new ArrayList<NeighboringCellInfo>();
3548 for (CellInfo ci : info) {
3549 if (ci instanceof CellInfoGsm) {
3550 neighbors.add(new NeighboringCellInfo((CellInfoGsm) ci));
3551 } else if (ci instanceof CellInfoWcdma) {
3552 neighbors.add(new NeighboringCellInfo((CellInfoWcdma) ci));
3553 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003554 }
Nathan Haroldf180aac2018-06-01 18:43:55 -07003555 return (neighbors.size()) > 0 ? neighbors : null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003556 }
3557
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07003558 private List<CellInfo> getCachedCellInfo() {
3559 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
3560 for (Phone phone : PhoneFactory.getPhones()) {
3561 List<CellInfo> info = phone.getAllCellInfo();
3562 if (info != null) cellInfos.addAll(info);
3563 }
3564 return cellInfos;
3565 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003566
3567 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003568 public List<CellInfo> getAllCellInfo(String callingPackage, String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003569 mApp.getSystemService(AppOpsManager.class)
Hall Liu1aa510f2017-11-22 17:40:08 -08003570 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08003571
3572 LocationAccessPolicy.LocationPermissionResult locationResult =
3573 LocationAccessPolicy.checkLocationPermission(mApp,
3574 new LocationAccessPolicy.LocationPermissionQuery.Builder()
3575 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003576 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08003577 .setCallingPid(Binder.getCallingPid())
3578 .setCallingUid(Binder.getCallingUid())
3579 .setMethod("getAllCellInfo")
Nathan Harold5ae50b52019-02-20 15:46:36 -08003580 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
Hall Liuf19c44f2018-11-27 14:38:17 -08003581 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
3582 .build());
3583 switch (locationResult) {
3584 case DENIED_HARD:
3585 throw new SecurityException("Not allowed to access cell info");
3586 case DENIED_SOFT:
3587 return new ArrayList<>();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003588 }
3589
Nathan Haroldf096d982020-11-18 17:18:06 -08003590 final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07003591 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
3592 return getCachedCellInfo();
3593 }
3594
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07003595 if (DBG_LOC) log("getAllCellInfo: is active user");
Narayan Kamathf04b5a12018-01-09 11:47:15 +00003596 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003597 final long identity = Binder.clearCallingIdentity();
3598 try {
3599 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
3600 for (Phone phone : PhoneFactory.getPhones()) {
Nathan Harold3ff88932018-08-14 10:19:49 -07003601 final List<CellInfo> info = (List<CellInfo>) sendRequest(
Nathan Harold92bed182018-10-12 18:16:49 -07003602 CMD_GET_ALL_CELL_INFO, null, phone, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003603 if (info != null) cellInfos.addAll(info);
3604 }
3605 return cellInfos;
3606 } finally {
3607 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003608 }
3609 }
3610
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07003611 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003612 public void requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage,
3613 String callingFeatureId) {
3614 requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId,
3615 getWorkSource(Binder.getCallingUid()));
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07003616 }
3617
3618 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003619 public void requestCellInfoUpdateWithWorkSource(int subId, ICellInfoCallback cb,
3620 String callingPackage, String callingFeatureId, WorkSource workSource) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07003621 enforceModifyPermission();
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003622 requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId, workSource);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07003623 }
3624
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003625 private void requestCellInfoUpdateInternal(int subId, ICellInfoCallback cb,
3626 String callingPackage, String callingFeatureId, WorkSource workSource) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003627 mApp.getSystemService(AppOpsManager.class)
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07003628 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08003629
3630 LocationAccessPolicy.LocationPermissionResult locationResult =
3631 LocationAccessPolicy.checkLocationPermission(mApp,
3632 new LocationAccessPolicy.LocationPermissionQuery.Builder()
3633 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003634 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08003635 .setCallingPid(Binder.getCallingPid())
3636 .setCallingUid(Binder.getCallingUid())
3637 .setMethod("requestCellInfoUpdate")
Hall Liud60acc92020-05-21 17:09:35 -07003638 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
3639 .setMinSdkVersionForFine(Build.VERSION_CODES.BASE)
Hall Liuf19c44f2018-11-27 14:38:17 -08003640 .build());
3641 switch (locationResult) {
3642 case DENIED_HARD:
Nathan Haroldf096d982020-11-18 17:18:06 -08003643 if (TelephonyPermissions
3644 .getTargetSdk(mApp, callingPackage) < Build.VERSION_CODES.Q) {
Hall Liud60acc92020-05-21 17:09:35 -07003645 // Safetynet logging for b/154934934
3646 EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
3647 }
Hall Liuf19c44f2018-11-27 14:38:17 -08003648 throw new SecurityException("Not allowed to access cell info");
3649 case DENIED_SOFT:
Nathan Haroldf096d982020-11-18 17:18:06 -08003650 if (TelephonyPermissions
3651 .getTargetSdk(mApp, callingPackage) < Build.VERSION_CODES.Q) {
Hall Liud60acc92020-05-21 17:09:35 -07003652 // Safetynet logging for b/154934934
3653 EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
3654 }
Nathan Harold5320c422019-05-09 10:26:08 -07003655 try {
3656 cb.onCellInfo(new ArrayList<CellInfo>());
3657 } catch (RemoteException re) {
3658 // Drop without consequences
3659 }
Hall Liuf19c44f2018-11-27 14:38:17 -08003660 return;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07003661 }
3662
Nathan Harolda939a962019-05-09 10:13:47 -07003663
3664 final Phone phone = getPhoneFromSubId(subId);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07003665 if (phone == null) throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
3666
3667 sendRequestAsync(CMD_REQUEST_CELL_INFO_UPDATE, cb, phone, workSource);
3668 }
3669
3670 @Override
Aishwarya Mallampati0603fb12022-08-24 21:16:56 +00003671 public void setCellInfoListRate(int rateInMillis, int subId) {
Jack Yua8d8cb82017-01-16 10:15:34 -08003672 enforceModifyPermission();
Narayan Kamathf04b5a12018-01-09 11:47:15 +00003673 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003674
3675 final long identity = Binder.clearCallingIdentity();
3676 try {
Aishwarya Mallampati0603fb12022-08-24 21:16:56 +00003677 Phone phone = getPhone(subId);
3678 if (phone == null) {
3679 getDefaultPhone().setCellInfoListRate(rateInMillis, workSource);
3680 } else {
3681 phone.setCellInfoListRate(rateInMillis, workSource);
3682 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003683 } finally {
3684 Binder.restoreCallingIdentity(identity);
3685 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003686 }
3687
Shishir Agrawala9f32182016-04-12 12:00:16 -07003688 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003689 public String getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
Jeff Davidson913390f2018-02-23 17:11:49 -08003690 Phone phone = PhoneFactory.getPhone(slotIndex);
3691 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003692 return null;
3693 }
Jeff Davidson913390f2018-02-23 17:11:49 -08003694 int subId = phone.getSubId();
Grace Jia0ddb3612021-04-22 13:35:26 -07003695 enforceCallingPackage(callingPackage, Binder.getCallingUid(), "getImeiForSlot");
Michael Groover70af6dc2018-10-01 16:23:15 -07003696 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003697 callingPackage, callingFeatureId, "getImeiForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08003698 return null;
3699 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003700
3701 final long identity = Binder.clearCallingIdentity();
3702 try {
3703 return phone.getImei();
3704 } finally {
3705 Binder.restoreCallingIdentity(identity);
3706 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07003707 }
3708
3709 @Override
arunvoddud5c6ce02022-12-11 06:03:12 +00003710 public String getPrimaryImei(String callingPackage, String callingFeatureId) {
3711 enforceCallingPackage(callingPackage, Binder.getCallingUid(), "getPrimaryImei");
3712 if (!checkCallingOrSelfReadDeviceIdentifiersForAnySub(mApp, callingPackage,
3713 callingFeatureId, "getPrimaryImei")) {
3714 throw new SecurityException("Caller does not have permission");
3715 }
3716 final long identity = Binder.clearCallingIdentity();
3717 try {
3718 for (Phone phone : PhoneFactory.getPhones()) {
3719 if (phone.getImeiType() == Phone.IMEI_TYPE_PRIMARY) {
3720 return phone.getImei();
3721 }
3722 }
3723 throw new UnsupportedOperationException("Operation not supported");
3724 } finally {
3725 Binder.restoreCallingIdentity(identity);
3726 }
3727 }
3728
3729 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00003730 public String getTypeAllocationCodeForSlot(int slotIndex) {
3731 Phone phone = PhoneFactory.getPhone(slotIndex);
3732 String tac = null;
3733 if (phone != null) {
3734 String imei = phone.getImei();
Vala Zadehab005552021-09-21 15:54:29 -07003735 try {
3736 tac = imei == null ? null : imei.substring(0, TYPE_ALLOCATION_CODE_LENGTH);
3737 } catch (IndexOutOfBoundsException e) {
3738 Log.e(LOG_TAG, "IMEI length shorter than upper index.");
3739 return null;
3740 }
David Kelly5e06a7f2018-03-12 14:10:59 +00003741 }
3742 return tac;
3743 }
3744
3745 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003746 public String getMeidForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
Shuo Qian13d89152021-05-10 23:58:11 -07003747 try {
3748 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3749 } catch (SecurityException se) {
3750 EventLog.writeEvent(0x534e4554, "186530496", Binder.getCallingUid());
3751 throw new SecurityException("Package " + callingPackage + " does not belong to "
3752 + Binder.getCallingUid());
3753 }
Jeff Davidson913390f2018-02-23 17:11:49 -08003754 Phone phone = PhoneFactory.getPhone(slotIndex);
3755 if (phone == null) {
Jack Yu2af8d712017-03-15 17:14:14 -07003756 return null;
3757 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003758
Jeff Davidson913390f2018-02-23 17:11:49 -08003759 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07003760 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003761 callingPackage, callingFeatureId, "getMeidForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08003762 return null;
3763 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003764
3765 final long identity = Binder.clearCallingIdentity();
3766 try {
3767 return phone.getMeid();
3768 } finally {
3769 Binder.restoreCallingIdentity(identity);
3770 }
Jack Yu2af8d712017-03-15 17:14:14 -07003771 }
3772
3773 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00003774 public String getManufacturerCodeForSlot(int slotIndex) {
3775 Phone phone = PhoneFactory.getPhone(slotIndex);
3776 String manufacturerCode = null;
3777 if (phone != null) {
3778 String meid = phone.getMeid();
Vala Zadehab005552021-09-21 15:54:29 -07003779 try {
3780 manufacturerCode =
3781 meid == null ? null : meid.substring(0, MANUFACTURER_CODE_LENGTH);
3782 } catch (IndexOutOfBoundsException e) {
3783 Log.e(LOG_TAG, "MEID length shorter than upper index.");
3784 return null;
3785 }
David Kelly5e06a7f2018-03-12 14:10:59 +00003786 }
3787 return manufacturerCode;
3788 }
3789
3790 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003791 public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage,
3792 String callingFeatureId) {
Jeff Davidson913390f2018-02-23 17:11:49 -08003793 Phone phone = PhoneFactory.getPhone(slotIndex);
3794 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003795 return null;
3796 }
Jeff Davidson913390f2018-02-23 17:11:49 -08003797 int subId = phone.getSubId();
3798 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003799 mApp, subId, callingPackage, callingFeatureId,
3800 "getDeviceSoftwareVersionForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08003801 return null;
3802 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003803
3804 final long identity = Binder.clearCallingIdentity();
3805 try {
3806 return phone.getDeviceSvn();
3807 } finally {
3808 Binder.restoreCallingIdentity(identity);
3809 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07003810 }
3811
fionaxu43304da2017-11-27 22:51:16 -08003812 @Override
3813 public int getSubscriptionCarrierId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003814 final long identity = Binder.clearCallingIdentity();
3815 try {
3816 final Phone phone = getPhone(subId);
3817 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getCarrierId();
3818 } finally {
3819 Binder.restoreCallingIdentity(identity);
3820 }
fionaxu43304da2017-11-27 22:51:16 -08003821 }
3822
3823 @Override
3824 public String getSubscriptionCarrierName(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003825 final long identity = Binder.clearCallingIdentity();
3826 try {
3827 final Phone phone = getPhone(subId);
3828 return phone == null ? null : phone.getCarrierName();
3829 } finally {
3830 Binder.restoreCallingIdentity(identity);
3831 }
fionaxu43304da2017-11-27 22:51:16 -08003832 }
3833
calvinpanffe225e2018-11-01 19:43:06 +08003834 @Override
chen xu0026ca62019-03-06 15:28:50 -08003835 public int getSubscriptionSpecificCarrierId(int subId) {
chen xu25637222018-11-04 17:17:00 -08003836 final long identity = Binder.clearCallingIdentity();
3837 try {
3838 final Phone phone = getPhone(subId);
3839 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID
chen xu0026ca62019-03-06 15:28:50 -08003840 : phone.getSpecificCarrierId();
chen xu25637222018-11-04 17:17:00 -08003841 } finally {
3842 Binder.restoreCallingIdentity(identity);
3843 }
3844 }
3845
3846 @Override
chen xu0026ca62019-03-06 15:28:50 -08003847 public String getSubscriptionSpecificCarrierName(int subId) {
chen xu25637222018-11-04 17:17:00 -08003848 final long identity = Binder.clearCallingIdentity();
3849 try {
3850 final Phone phone = getPhone(subId);
chen xu0026ca62019-03-06 15:28:50 -08003851 return phone == null ? null : phone.getSpecificCarrierName();
chen xu25637222018-11-04 17:17:00 -08003852 } finally {
3853 Binder.restoreCallingIdentity(identity);
3854 }
3855 }
3856
chen xu651eec72018-11-11 19:03:44 -08003857 @Override
chen xu864e11c2018-12-06 22:10:03 -08003858 public int getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc) {
3859 if (!isSubscriptionMccMnc) {
3860 enforceReadPrivilegedPermission("getCarrierIdFromMccMnc");
3861 }
chen xu651eec72018-11-11 19:03:44 -08003862 final Phone phone = PhoneFactory.getPhone(slotIndex);
3863 if (phone == null) {
3864 return TelephonyManager.UNKNOWN_CARRIER_ID;
3865 }
3866 final long identity = Binder.clearCallingIdentity();
3867 try {
3868 return CarrierResolver.getCarrierIdFromMccMnc(phone.getContext(), mccmnc);
3869 } finally {
3870 Binder.restoreCallingIdentity(identity);
3871 }
3872 }
3873
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003874 //
3875 // Internal helper methods.
3876 //
3877
Sanket Padaweee13a9b2016-03-08 17:30:28 -08003878 /**
Grace Jia0ddb3612021-04-22 13:35:26 -07003879 * Make sure the caller is the calling package itself
3880 *
3881 * @throws SecurityException if the caller is not the calling package
3882 */
3883 private void enforceCallingPackage(String callingPackage, int callingUid, String message) {
3884 int packageUid = -1;
Grace Jiadbefca02021-04-26 15:13:31 -07003885 PackageManager pm = mApp.getBaseContext().createContextAsUser(
3886 UserHandle.getUserHandleForUid(callingUid), 0).getPackageManager();
Grace Jia0ddb3612021-04-22 13:35:26 -07003887 try {
Grace Jiadbefca02021-04-26 15:13:31 -07003888 packageUid = pm.getPackageUid(callingPackage, 0);
Grace Jia0ddb3612021-04-22 13:35:26 -07003889 } catch (PackageManager.NameNotFoundException e) {
3890 // packageUid is -1
3891 }
3892 if (packageUid != callingUid) {
3893 throw new SecurityException(message + ": Package " + callingPackage
3894 + " does not belong to " + callingUid);
3895 }
3896 }
3897
3898 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003899 * Make sure the caller has the MODIFY_PHONE_STATE permission.
3900 *
3901 * @throws SecurityException if the caller does not have the required permission
3902 */
Gil Cukierman1c0eb932022-12-06 22:28:24 +00003903 @VisibleForTesting
3904 public void enforceModifyPermission() {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003905 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
3906 }
3907
Gil Cukierman1c0eb932022-12-06 22:28:24 +00003908 /**
arunvoddud7401012022-12-15 16:08:12 +00003909 * Make sure the caller has the READ_PHONE_STATE permission.
Gil Cukierman1c0eb932022-12-06 22:28:24 +00003910 *
3911 * @throws SecurityException if the caller does not have the required permission
3912 */
3913 @VisibleForTesting
3914 public void enforceReadPermission() {
arunvoddud7401012022-12-15 16:08:12 +00003915 enforceReadPermission(null);
3916 }
3917
3918 /**
3919 * Make sure the caller has the READ_PHONE_STATE permissions.
3920 *
3921 * @throws SecurityException if the caller does not have the READ_PHONE_STATE permission.
3922 */
3923 @VisibleForTesting
3924 public void enforceReadPermission(String msg) {
3925 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE, msg);
Gil Cukierman1c0eb932022-12-06 22:28:24 +00003926 }
3927
Shuo Qian3b6ee772019-11-13 17:43:31 -08003928 private void enforceActiveEmergencySessionPermission() {
3929 mApp.enforceCallingOrSelfPermission(
3930 android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION, null);
3931 }
3932
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003933 /**
3934 * Make sure the caller has the CALL_PHONE permission.
3935 *
3936 * @throws SecurityException if the caller does not have the required permission
3937 */
3938 private void enforceCallPermission() {
3939 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
3940 }
3941
paulhu5a773602019-08-23 19:17:33 +08003942 private void enforceSettingsPermission() {
3943 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.NETWORK_SETTINGS, null);
Stuart Scott8eef64f2015-04-08 15:13:54 -07003944 }
3945
Michele Berionne5e411512020-11-13 02:36:59 +00003946 private void enforceRebootPermission() {
3947 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
3948 }
3949
Aishwarya Mallampati60fe1132023-01-24 19:07:21 +00003950 /**
3951 * Make sure the caller has SATELLITE_COMMUNICATION permission.
3952 * @param message - log message to print.
3953 * @throws SecurityException if the caller does not have the required permission
3954 */
3955 private void enforceSatelliteCommunicationPermission(String message) {
3956 mApp.enforceCallingOrSelfPermission(permission.SATELLITE_COMMUNICATION, message);
3957 }
3958
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003959 private String createTelUrl(String number) {
3960 if (TextUtils.isEmpty(number)) {
3961 return null;
3962 }
3963
Jake Hambye994d462014-02-03 13:10:13 -08003964 return "tel:" + number;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003965 }
3966
Ihab Awadf9e92732013-12-05 18:02:52 -08003967 private static void log(String msg) {
Ling Ma83dc5ea2023-01-12 15:06:04 -08003968 Log.d(LOG_TAG, msg);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003969 }
3970
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07003971 private static void logv(String msg) {
3972 Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg);
3973 }
3974
Ihab Awadf9e92732013-12-05 18:02:52 -08003975 private static void loge(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003976 Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg);
3977 }
3978
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003979 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003980 public int getActivePhoneType() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07003981 return getActivePhoneTypeForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07003982 }
3983
Sanket Padawe356d7632015-06-22 14:03:32 -07003984 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07003985 public int getActivePhoneTypeForSlot(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003986 final long identity = Binder.clearCallingIdentity();
3987 try {
3988 final Phone phone = PhoneFactory.getPhone(slotIndex);
3989 if (phone == null) {
3990 return PhoneConstants.PHONE_TYPE_NONE;
3991 } else {
3992 return phone.getPhoneType();
3993 }
3994 } finally {
3995 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003996 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003997 }
3998
3999 /**
4000 * Returns the CDMA ERI icon index to display
4001 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004002 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004003 public int getCdmaEriIconIndex(String callingPackage, String callingFeatureId) {
4004 return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage,
4005 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07004006 }
4007
Sanket Padawe356d7632015-06-22 14:03:32 -07004008 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004009 public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage,
4010 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004011 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004012 mApp, subId, callingPackage, callingFeatureId,
4013 "getCdmaEriIconIndexForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004014 return -1;
4015 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004016
4017 final long identity = Binder.clearCallingIdentity();
4018 try {
4019 final Phone phone = getPhone(subId);
4020 if (phone != null) {
4021 return phone.getCdmaEriIconIndex();
4022 } else {
4023 return -1;
4024 }
4025 } finally {
4026 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004027 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004028 }
4029
4030 /**
4031 * Returns the CDMA ERI icon mode,
4032 * 0 - ON
4033 * 1 - FLASHING
4034 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004035 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004036 public int getCdmaEriIconMode(String callingPackage, String callingFeatureId) {
4037 return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage,
4038 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07004039 }
4040
Sanket Padawe356d7632015-06-22 14:03:32 -07004041 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004042 public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage,
4043 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004044 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004045 mApp, subId, callingPackage, callingFeatureId,
4046 "getCdmaEriIconModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004047 return -1;
4048 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004049
4050 final long identity = Binder.clearCallingIdentity();
4051 try {
4052 final Phone phone = getPhone(subId);
4053 if (phone != null) {
4054 return phone.getCdmaEriIconMode();
4055 } else {
4056 return -1;
4057 }
4058 } finally {
4059 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004060 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004061 }
4062
4063 /**
4064 * Returns the CDMA ERI text,
4065 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004066 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004067 public String getCdmaEriText(String callingPackage, String callingFeatureId) {
4068 return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage,
4069 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07004070 }
4071
Sanket Padawe356d7632015-06-22 14:03:32 -07004072 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004073 public String getCdmaEriTextForSubscriber(int subId, String callingPackage,
4074 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004075 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004076 mApp, subId, callingPackage, callingFeatureId,
4077 "getCdmaEriIconTextForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004078 return null;
4079 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004080
4081 final long identity = Binder.clearCallingIdentity();
4082 try {
4083 final Phone phone = getPhone(subId);
4084 if (phone != null) {
4085 return phone.getCdmaEriText();
4086 } else {
4087 return null;
4088 }
4089 } finally {
4090 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004091 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004092 }
4093
4094 /**
Junda Liuca05d5d2014-08-14 22:36:34 -07004095 * Returns the CDMA MDN.
4096 */
Sanket Padawe356d7632015-06-22 14:03:32 -07004097 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07004098 public String getCdmaMdn(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004099 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4100 mApp, subId, "getCdmaMdn");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004101
4102 final long identity = Binder.clearCallingIdentity();
4103 try {
4104 final Phone phone = getPhone(subId);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004105 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004106 return phone.getLine1Number();
4107 } else {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004108 loge("getCdmaMdn: no phone found. Invalid subId: " + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004109 return null;
4110 }
4111 } finally {
4112 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07004113 }
4114 }
4115
4116 /**
4117 * Returns the CDMA MIN.
4118 */
Sanket Padawe356d7632015-06-22 14:03:32 -07004119 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07004120 public String getCdmaMin(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004121 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4122 mApp, subId, "getCdmaMin");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004123
4124 final long identity = Binder.clearCallingIdentity();
4125 try {
4126 final Phone phone = getPhone(subId);
4127 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
4128 return phone.getCdmaMin();
4129 } else {
4130 return null;
4131 }
4132 } finally {
4133 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07004134 }
4135 }
4136
Hall Liud892bec2018-11-30 14:51:45 -08004137 @Override
4138 public void requestNumberVerification(PhoneNumberRange range, long timeoutMillis,
4139 INumberVerificationCallback callback, String callingPackage) {
4140 if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
4141 != PERMISSION_GRANTED) {
4142 throw new SecurityException("Caller must hold the MODIFY_PHONE_STATE permission");
4143 }
4144 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4145
4146 String authorizedPackage = NumberVerificationManager.getAuthorizedPackage(mApp);
4147 if (!TextUtils.equals(callingPackage, authorizedPackage)) {
Hall Liub9d8feb2021-01-13 10:28:04 -08004148 throw new SecurityException("Calling package must be configured in the device config: "
4149 + "calling package: " + callingPackage
4150 + ", configured package: " + authorizedPackage);
Hall Liud892bec2018-11-30 14:51:45 -08004151 }
4152
4153 if (range == null) {
4154 throw new NullPointerException("Range must be non-null");
4155 }
4156
4157 timeoutMillis = Math.min(timeoutMillis,
Hall Liubd069e32019-02-28 18:56:30 -08004158 TelephonyManager.getMaxNumberVerificationTimeoutMillis());
Hall Liud892bec2018-11-30 14:51:45 -08004159
4160 NumberVerificationManager.getInstance().requestVerification(range, callback, timeoutMillis);
4161 }
4162
Junda Liuca05d5d2014-08-14 22:36:34 -07004163 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004164 * Returns true if CDMA provisioning needs to run.
4165 */
4166 public boolean needsOtaServiceProvisioning() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004167 final long identity = Binder.clearCallingIdentity();
4168 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004169 return getDefaultPhone().needsOtaServiceProvisioning();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004170 } finally {
4171 Binder.restoreCallingIdentity(identity);
4172 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004173 }
4174
4175 /**
Shishir Agrawal76d5da92014-11-09 16:17:25 -08004176 * Sets the voice mail number of a given subId.
4177 */
4178 @Override
4179 public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08004180 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
4181 mApp, subId, "setVoiceMailNumber");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004182
4183 final long identity = Binder.clearCallingIdentity();
4184 try {
4185 Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
4186 new Pair<String, String>(alphaTag, number), new Integer(subId));
4187 return success;
4188 } finally {
4189 Binder.restoreCallingIdentity(identity);
4190 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08004191 }
4192
Ta-wei Yen87c49842016-05-13 21:19:52 -07004193 @Override
Ta-wei Yenc9df0432017-04-17 17:09:07 -07004194 public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
4195 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07004196 TelecomManager tm = mApp.getSystemService(TelecomManager.class);
4197 String systemDialer = tm.getSystemDialerPackage();
Ta-wei Yenc9df0432017-04-17 17:09:07 -07004198 if (!TextUtils.equals(callingPackage, systemDialer)) {
4199 throw new SecurityException("caller must be system dialer");
4200 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004201
4202 final long identity = Binder.clearCallingIdentity();
4203 try {
4204 PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
4205 if (phoneAccountHandle == null) {
4206 return null;
4207 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004208 return VisualVoicemailSettingsUtil.dump(mApp, phoneAccountHandle);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004209 } finally {
4210 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc9df0432017-04-17 17:09:07 -07004211 }
Ta-wei Yenc9df0432017-04-17 17:09:07 -07004212 }
4213
4214 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004215 public String getVisualVoicemailPackageName(String callingPackage, String callingFeatureId,
4216 int subId) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08004217 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jeff Davidson7e17e312018-02-13 18:17:36 -08004218 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004219 mApp, subId, callingPackage, callingFeatureId,
4220 "getVisualVoicemailPackageName")) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08004221 return null;
4222 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004223
Jeff Davidsona8e4e242018-03-15 17:16:18 -07004224 final long identity = Binder.clearCallingIdentity();
4225 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004226 return RemoteVvmTaskManager.getRemotePackage(mApp, subId).getPackageName();
Jeff Davidsona8e4e242018-03-15 17:16:18 -07004227 } finally {
4228 Binder.restoreCallingIdentity(identity);
4229 }
Ta-wei Yendca928f2017-01-10 16:17:08 -08004230 }
4231
4232 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07004233 public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
4234 VisualVoicemailSmsFilterSettings settings) {
4235 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004236
4237 final long identity = Binder.clearCallingIdentity();
4238 try {
4239 VisualVoicemailSmsFilterConfig.enableVisualVoicemailSmsFilter(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004240 mApp, callingPackage, subId, settings);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004241 } finally {
4242 Binder.restoreCallingIdentity(identity);
4243 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07004244 }
4245
4246 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07004247 public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
4248 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004249
4250 final long identity = Binder.clearCallingIdentity();
4251 try {
4252 VisualVoicemailSmsFilterConfig.disableVisualVoicemailSmsFilter(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004253 mApp, callingPackage, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004254 } finally {
4255 Binder.restoreCallingIdentity(identity);
4256 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07004257 }
4258
4259 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07004260 public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
4261 String callingPackage, int subId) {
4262 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004263
4264 final long identity = Binder.clearCallingIdentity();
4265 try {
4266 return VisualVoicemailSmsFilterConfig.getVisualVoicemailSmsFilterSettings(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004267 mApp, callingPackage, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004268 } finally {
4269 Binder.restoreCallingIdentity(identity);
4270 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07004271 }
4272
4273 @Override
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004274 public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07004275 enforceReadPrivilegedPermission("getActiveVisualVoicemailSmsFilterSettings");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004276
4277 final long identity = Binder.clearCallingIdentity();
4278 try {
4279 return VisualVoicemailSmsFilterConfig.getActiveVisualVoicemailSmsFilterSettings(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004280 mApp, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004281 } finally {
4282 Binder.restoreCallingIdentity(identity);
4283 }
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004284 }
4285
4286 @Override
Philip P. Moltmann2f6f8ce2020-03-18 18:17:02 -07004287 public void sendVisualVoicemailSmsForSubscriber(String callingPackage,
4288 String callingAttributionTag, int subId, String number, int port, String text,
4289 PendingIntent sentIntent) {
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004290 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Ta-wei Yen527a9c02017-01-06 15:29:25 -08004291 enforceVisualVoicemailPackage(callingPackage, subId);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004292 enforceSendSmsPermission();
Amit Mahajandccb3f12019-05-13 13:48:32 -07004293 SmsController smsController = PhoneFactory.getSmsController();
Philip P. Moltmann2f6f8ce2020-03-18 18:17:02 -07004294 smsController.sendVisualVoicemailSmsForSubscriber(callingPackage, callingAttributionTag,
4295 subId, number, port, text, sentIntent);
Ta-wei Yen87c49842016-05-13 21:19:52 -07004296 }
Amit Mahajandccb3f12019-05-13 13:48:32 -07004297
Shishir Agrawal76d5da92014-11-09 16:17:25 -08004298 /**
fionaxu0152e512016-11-14 13:36:14 -08004299 * Sets the voice activation state of a given subId.
4300 */
4301 @Override
4302 public void setVoiceActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004303 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4304 mApp, subId, "setVoiceActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004305
4306 final long identity = Binder.clearCallingIdentity();
4307 try {
4308 final Phone phone = getPhone(subId);
4309 if (phone != null) {
4310 phone.setVoiceActivationState(activationState);
4311 } else {
4312 loge("setVoiceActivationState fails with invalid subId: " + subId);
4313 }
4314 } finally {
4315 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08004316 }
4317 }
4318
4319 /**
4320 * Sets the data activation state of a given subId.
4321 */
4322 @Override
4323 public void setDataActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004324 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4325 mApp, subId, "setDataActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004326
4327 final long identity = Binder.clearCallingIdentity();
4328 try {
4329 final Phone phone = getPhone(subId);
4330 if (phone != null) {
4331 phone.setDataActivationState(activationState);
4332 } else {
Taesu Leef8fbed92019-10-07 18:47:02 +09004333 loge("setDataActivationState fails with invalid subId: " + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004334 }
4335 } finally {
4336 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08004337 }
4338 }
4339
4340 /**
4341 * Returns the voice activation state of a given subId.
4342 */
4343 @Override
4344 public int getVoiceActivationState(int subId, String callingPackage) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07004345 enforceReadPrivilegedPermission("getVoiceActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004346
fionaxu0152e512016-11-14 13:36:14 -08004347 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004348 final long identity = Binder.clearCallingIdentity();
4349 try {
4350 if (phone != null) {
4351 return phone.getVoiceActivationState();
4352 } else {
4353 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
4354 }
4355 } finally {
4356 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08004357 }
4358 }
4359
4360 /**
4361 * Returns the data activation state of a given subId.
4362 */
4363 @Override
4364 public int getDataActivationState(int subId, String callingPackage) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07004365 enforceReadPrivilegedPermission("getDataActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004366
fionaxu0152e512016-11-14 13:36:14 -08004367 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004368 final long identity = Binder.clearCallingIdentity();
4369 try {
4370 if (phone != null) {
4371 return phone.getDataActivationState();
4372 } else {
4373 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
4374 }
4375 } finally {
4376 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08004377 }
4378 }
4379
4380 /**
Wink Saville36469e72014-06-11 15:17:00 -07004381 * Returns the unread count of voicemails for a subId
4382 */
Sanket Padawe356d7632015-06-22 14:03:32 -07004383 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004384 public int getVoiceMessageCountForSubscriber(int subId, String callingPackage,
4385 String callingFeatureId) {
Brad Ebingerf7664ba2018-11-29 12:43:38 -08004386 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004387 mApp, subId, callingPackage, callingFeatureId,
4388 "getVoiceMessageCountForSubscriber")) {
Brad Ebingerf7664ba2018-11-29 12:43:38 -08004389 return 0;
4390 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004391 final long identity = Binder.clearCallingIdentity();
4392 try {
4393 final Phone phone = getPhone(subId);
4394 if (phone != null) {
4395 return phone.getVoiceMessageCount();
4396 } else {
4397 return 0;
4398 }
4399 } finally {
4400 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004401 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004402 }
4403
4404 /**
pkanwar8a4dcfb2017-01-19 13:43:16 -08004405 * returns true, if the device is in a state where both voice and data
4406 * are supported simultaneously. This can change based on location or network condition.
4407 */
4408 @Override
4409 public boolean isConcurrentVoiceAndDataAllowed(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004410 final long identity = Binder.clearCallingIdentity();
4411 try {
4412 final Phone phone = getPhone(subId);
4413 return (phone == null ? false : phone.isConcurrentVoiceAndDataAllowed());
4414 } finally {
4415 Binder.restoreCallingIdentity(identity);
4416 }
pkanwar8a4dcfb2017-01-19 13:43:16 -08004417 }
4418
4419 /**
fionaxu235cc5e2017-03-06 22:25:57 -08004420 * Send the dialer code if called from the current default dialer or the caller has
4421 * carrier privilege.
4422 * @param inputCode The dialer code to send
4423 */
4424 @Override
4425 public void sendDialerSpecialCode(String callingPackage, String inputCode) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004426 final Phone defaultPhone = getDefaultPhone();
fionaxu235cc5e2017-03-06 22:25:57 -08004427 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07004428 TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
4429 String defaultDialer = tm.getDefaultDialerPackage();
fionaxu235cc5e2017-03-06 22:25:57 -08004430 if (!TextUtils.equals(callingPackage, defaultDialer)) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08004431 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
Jeff Davidson7e17e312018-02-13 18:17:36 -08004432 getDefaultSubscription(), "sendDialerSpecialCode");
fionaxu235cc5e2017-03-06 22:25:57 -08004433 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004434
4435 final long identity = Binder.clearCallingIdentity();
4436 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004437 defaultPhone.sendDialerSpecialCode(inputCode);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004438 } finally {
4439 Binder.restoreCallingIdentity(identity);
4440 }
fionaxu235cc5e2017-03-06 22:25:57 -08004441 }
4442
Pengquan Menga1bb6272018-09-06 09:59:22 -07004443 @Override
4444 public int getNetworkSelectionMode(int subId) {
shilufc958392020-01-20 11:36:01 -08004445 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07004446 .enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
shilufc958392020-01-20 11:36:01 -08004447 mApp, subId, "getNetworkSelectionMode");
4448 final long identity = Binder.clearCallingIdentity();
4449 try {
4450 if (!isActiveSubscription(subId)) {
4451 return TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
4452 }
4453 return (int) sendRequest(CMD_GET_NETWORK_SELECTION_MODE, null /* argument */, subId);
4454 } finally {
4455 Binder.restoreCallingIdentity(identity);
Pengquan Menge92a50d2018-09-21 15:54:48 -07004456 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07004457 }
4458
Brad Ebinger35c841c2018-10-01 10:40:55 -07004459 @Override
Brad Ebingerb2b65522019-03-15 13:48:47 -07004460 public boolean isInEmergencySmsMode() {
4461 enforceReadPrivilegedPermission("isInEmergencySmsMode");
4462 final long identity = Binder.clearCallingIdentity();
4463 try {
4464 for (Phone phone : PhoneFactory.getPhones()) {
4465 if (phone.isInEmergencySmsMode()) {
4466 return true;
4467 }
4468 }
4469 } finally {
4470 Binder.restoreCallingIdentity(identity);
4471 }
4472 return false;
4473 }
4474
shilu366312e2019-12-17 09:28:10 -08004475 /**
4476 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4477 * @param subId The subscription to use to check the configuration.
4478 * @param c The callback that will be used to send the result.
4479 */
Brad Ebingerb2b65522019-03-15 13:48:47 -07004480 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08004481 public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback c)
4482 throws RemoteException {
Nathan Harold62c68512021-04-06 11:26:02 -07004483 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004484 mApp, subId, "registerImsRegistrationCallback");
Brad Ebingera2628302022-02-18 03:44:55 +00004485
4486 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4487 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4488 "IMS not available on device.");
4489 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07004490 final long token = Binder.clearCallingIdentity();
4491 try {
Brad Ebingera2628302022-02-18 03:44:55 +00004492 int slotId = getSlotIndexOrException(subId);
4493 verifyImsMmTelConfiguredOrThrow(slotId);
joonhunshin49f0aed2022-08-05 08:33:05 +00004494
4495 ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
4496 if (controller != null) {
4497 ImsManager imsManager = controller.getImsManager(subId);
4498 if (imsManager != null) {
4499 imsManager.addRegistrationCallbackForSubscription(c, subId);
4500 } else {
4501 throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
4502 }
4503 } else {
4504 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
4505 }
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004506 } catch (ImsException e) {
4507 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004508 } finally {
4509 Binder.restoreCallingIdentity(token);
4510 }
4511 }
4512
shilu366312e2019-12-17 09:28:10 -08004513 /**
4514 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4515 * @param subId The subscription to use to check the configuration.
4516 * @param c The callback that will be used to send the result.
4517 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07004518 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08004519 public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c) {
Nathan Harold62c68512021-04-06 11:26:02 -07004520 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004521 mApp, subId, "unregisterImsRegistrationCallback");
Brad Ebinger4ae57f92019-01-09 16:51:30 -08004522 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4523 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
4524 }
Meng Wangafbc5852019-09-19 17:37:13 -07004525 final long token = Binder.clearCallingIdentity();
joonhunshin49f0aed2022-08-05 08:33:05 +00004526
Meng Wangafbc5852019-09-19 17:37:13 -07004527 try {
joonhunshin49f0aed2022-08-05 08:33:05 +00004528 ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
4529 if (controller != null) {
4530 ImsManager imsManager = controller.getImsManager(subId);
4531 if (imsManager != null) {
4532 imsManager.removeRegistrationCallbackForSubscription(c, subId);
4533 } else {
4534 Log.i(LOG_TAG, "unregisterImsRegistrationCallback: " + subId
4535 + "is inactive, ignoring unregister.");
4536 // If the ImsManager is not valid, just return, since the callback
4537 // will already have been removed internally.
4538 }
4539 }
Meng Wangafbc5852019-09-19 17:37:13 -07004540 } finally {
4541 Binder.restoreCallingIdentity(token);
4542 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07004543 }
4544
Brad Ebingera34a6c22019-10-22 17:36:18 -07004545 /**
4546 * Get the IMS service registration state for the MmTelFeature associated with this sub id.
4547 */
4548 @Override
4549 public void getImsMmTelRegistrationState(int subId, IIntegerConsumer consumer) {
4550 enforceReadPrivilegedPermission("getImsMmTelRegistrationState");
4551 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4552 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4553 "IMS not available on device.");
4554 }
4555 final long token = Binder.clearCallingIdentity();
4556 try {
4557 Phone phone = getPhone(subId);
4558 if (phone == null) {
4559 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
4560 + subId + "'");
4561 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
4562 }
4563 phone.getImsRegistrationState(regState -> {
4564 try {
4565 consumer.accept((regState == null)
4566 ? RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED : regState);
4567 } catch (RemoteException e) {
4568 // Ignore if the remote process is no longer available to call back.
4569 Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
4570 }
4571 });
4572 } finally {
4573 Binder.restoreCallingIdentity(token);
4574 }
4575 }
4576
4577 /**
4578 * Get the transport type for the IMS service registration state.
4579 */
4580 @Override
4581 public void getImsMmTelRegistrationTransportType(int subId, IIntegerConsumer consumer) {
Nathan Harold62c68512021-04-06 11:26:02 -07004582 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004583 mApp, subId, "getImsMmTelRegistrationTransportType");
Brad Ebingera34a6c22019-10-22 17:36:18 -07004584 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4585 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4586 "IMS not available on device.");
4587 }
4588 final long token = Binder.clearCallingIdentity();
4589 try {
4590 Phone phone = getPhone(subId);
4591 if (phone == null) {
4592 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
4593 + subId + "'");
4594 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
4595 }
4596 phone.getImsRegistrationTech(regTech -> {
4597 // Convert registration tech from ImsRegistrationImplBase -> RegistrationManager
4598 int regTechConverted = (regTech == null)
4599 ? ImsRegistrationImplBase.REGISTRATION_TECH_NONE : regTech;
4600 regTechConverted = RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(
4601 regTechConverted);
4602 try {
4603 consumer.accept(regTechConverted);
4604 } catch (RemoteException e) {
4605 // Ignore if the remote process is no longer available to call back.
4606 Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
4607 }
4608 });
4609 } finally {
4610 Binder.restoreCallingIdentity(token);
4611 }
4612 }
4613
shilu366312e2019-12-17 09:28:10 -08004614 /**
4615 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4616 * @param subId The subscription to use to check the configuration.
4617 * @param c The callback that will be used to send the result.
4618 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07004619 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08004620 public void registerMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)
4621 throws RemoteException {
Nathan Harold62c68512021-04-06 11:26:02 -07004622 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004623 mApp, subId, "registerMmTelCapabilityCallback");
Brad Ebingera2628302022-02-18 03:44:55 +00004624 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4625 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4626 "IMS not available on device.");
4627 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07004628 final long token = Binder.clearCallingIdentity();
4629 try {
Brad Ebingera2628302022-02-18 03:44:55 +00004630 int slotId = getSlotIndexOrException(subId);
4631 verifyImsMmTelConfiguredOrThrow(slotId);
Hwangoo Park8646b0d2023-01-13 02:42:34 +00004632
4633 ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
4634 if (controller != null) {
4635 ImsManager imsManager = controller.getImsManager(subId);
4636 if (imsManager != null) {
4637 imsManager.addCapabilitiesCallbackForSubscription(c, subId);
4638 } else {
4639 throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
4640 }
4641 } else {
4642 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
4643 }
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004644 } catch (ImsException e) {
4645 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004646 } finally {
4647 Binder.restoreCallingIdentity(token);
4648 }
4649 }
4650
shilu366312e2019-12-17 09:28:10 -08004651 /**
4652 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4653 * @param subId The subscription to use to check the configuration.
4654 * @param c The callback that will be used to send the result.
4655 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07004656 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08004657 public void unregisterMmTelCapabilityCallback(int subId, IImsCapabilityCallback c) {
Nathan Harold62c68512021-04-06 11:26:02 -07004658 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004659 mApp, subId, "unregisterMmTelCapabilityCallback");
Brad Ebinger4ae57f92019-01-09 16:51:30 -08004660 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4661 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
4662 }
Meng Wangafbc5852019-09-19 17:37:13 -07004663
4664 final long token = Binder.clearCallingIdentity();
4665 try {
Hwangoo Park8646b0d2023-01-13 02:42:34 +00004666 ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
4667 if (controller != null) {
4668 ImsManager imsManager = controller.getImsManager(subId);
4669 if (imsManager != null) {
4670 imsManager.removeCapabilitiesCallbackForSubscription(c, subId);
4671 } else {
4672 Log.i(LOG_TAG, "unregisterMmTelCapabilityCallback: " + subId
4673 + " is inactive, ignoring unregister.");
4674 // If the ImsManager is not valid, just return, since the callback
4675 // will already have been removed internally.
4676 }
4677 }
Meng Wangafbc5852019-09-19 17:37:13 -07004678 } finally {
4679 Binder.restoreCallingIdentity(token);
4680 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07004681 }
4682
4683 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08004684 public boolean isCapable(int subId, int capability, int regTech) {
4685 enforceReadPrivilegedPermission("isCapable");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004686 final long token = Binder.clearCallingIdentity();
4687 try {
Brad Ebingera2628302022-02-18 03:44:55 +00004688 int slotId = getSlotIndexOrException(subId);
4689 verifyImsMmTelConfiguredOrThrow(slotId);
4690 return ImsManager.getInstance(mApp, slotId).queryMmTelCapability(capability, regTech);
4691 } catch (com.android.ims.ImsException e) {
4692 Log.w(LOG_TAG, "IMS isCapable - service unavailable: " + e.getMessage());
4693 return false;
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004694 } catch (ImsException e) {
Brad Ebinger6b5ac222019-02-04 14:36:52 -08004695 Log.i(LOG_TAG, "isCapable: " + subId + " is inactive, returning false.");
4696 return false;
Brad Ebinger35c841c2018-10-01 10:40:55 -07004697 } finally {
4698 Binder.restoreCallingIdentity(token);
4699 }
4700 }
4701
4702 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08004703 public boolean isAvailable(int subId, int capability, int regTech) {
4704 enforceReadPrivilegedPermission("isAvailable");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004705 final long token = Binder.clearCallingIdentity();
4706 try {
4707 Phone phone = getPhone(subId);
4708 if (phone == null) return false;
4709 return phone.isImsCapabilityAvailable(capability, regTech);
Daniel Bright5e40e4e2020-03-11 16:35:39 -07004710 } catch (com.android.ims.ImsException e) {
4711 Log.w(LOG_TAG, "IMS isAvailable - service unavailable: " + e.getMessage());
4712 return false;
Brad Ebinger35c841c2018-10-01 10:40:55 -07004713 } finally {
4714 Binder.restoreCallingIdentity(token);
4715 }
4716 }
4717
Brad Ebingerbc7dd582019-10-17 17:03:22 -07004718 /**
4719 * Determines if the MmTel feature capability is supported by the carrier configuration for this
4720 * subscription.
4721 * @param subId The subscription to use to check the configuration.
4722 * @param callback The callback that will be used to send the result.
4723 * @param capability The MmTelFeature capability that will be used to send the result.
4724 * @param transportType The transport type of the MmTelFeature capability.
4725 */
4726 @Override
4727 public void isMmTelCapabilitySupported(int subId, IIntegerConsumer callback, int capability,
4728 int transportType) {
4729 enforceReadPrivilegedPermission("isMmTelCapabilitySupported");
Brad Ebingera2628302022-02-18 03:44:55 +00004730 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4731 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4732 "IMS not available on device.");
4733 }
Brad Ebingerbc7dd582019-10-17 17:03:22 -07004734 final long token = Binder.clearCallingIdentity();
4735 try {
Brad Ebingera2628302022-02-18 03:44:55 +00004736 int slotId = getSlotIndex(subId);
4737 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4738 Log.w(LOG_TAG, "isMmTelCapabilitySupported: called with an inactive subscription '"
4739 + subId + "'");
4740 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
4741 }
4742 verifyImsMmTelConfiguredOrThrow(slotId);
4743 ImsManager.getInstance(mApp, slotId).isSupported(capability,
4744 transportType, aBoolean -> {
4745 try {
4746 callback.accept((aBoolean == null) ? 0 : (aBoolean ? 1 : 0));
4747 } catch (RemoteException e) {
4748 Log.w(LOG_TAG, "isMmTelCapabilitySupported: remote caller is not "
4749 + "running. Ignore");
4750 }
4751 });
Brad Ebinger919631e2021-06-02 17:46:35 -07004752 } catch (ImsException e) {
4753 throw new ServiceSpecificException(e.getCode());
Brad Ebingerbc7dd582019-10-17 17:03:22 -07004754 } finally {
4755 Binder.restoreCallingIdentity(token);
4756 }
4757 }
4758
shilu366312e2019-12-17 09:28:10 -08004759 /**
4760 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4761 * @param subId The subscription to use to check the configuration.
4762 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07004763 @Override
4764 public boolean isAdvancedCallingSettingEnabled(int subId) {
Nathan Harold62c68512021-04-06 11:26:02 -07004765 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004766 mApp, subId, "isAdvancedCallingSettingEnabled");
shilu366312e2019-12-17 09:28:10 -08004767
Brad Ebinger35c841c2018-10-01 10:40:55 -07004768 final long token = Binder.clearCallingIdentity();
4769 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004770 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004771 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07004772 return ImsManager.getInstance(mApp, slotId).isEnhanced4gLteModeSettingEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004773 } catch (ImsException e) {
4774 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004775 } finally {
4776 Binder.restoreCallingIdentity(token);
4777 }
4778 }
4779
4780 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08004781 public void setAdvancedCallingSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07004782 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08004783 "setAdvancedCallingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004784 final long identity = Binder.clearCallingIdentity();
4785 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004786 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004787 // This setting doesn't require an active ImsService connection, so do not verify. The
4788 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07004789 ImsManager.getInstance(mApp, slotId).setEnhanced4gLteModeSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004790 } catch (ImsException e) {
4791 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004792 } finally {
4793 Binder.restoreCallingIdentity(identity);
4794 }
4795 }
4796
shilu366312e2019-12-17 09:28:10 -08004797 /**
4798 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4799 * @param subId The subscription to use to check the configuration.
4800 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07004801 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08004802 public boolean isVtSettingEnabled(int subId) {
Nathan Harold62c68512021-04-06 11:26:02 -07004803 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004804 mApp, subId, "isVtSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004805 final long identity = Binder.clearCallingIdentity();
4806 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004807 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004808 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07004809 return ImsManager.getInstance(mApp, slotId).isVtEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004810 } catch (ImsException e) {
4811 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004812 } finally {
4813 Binder.restoreCallingIdentity(identity);
4814 }
4815 }
4816
4817 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08004818 public void setVtSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07004819 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08004820 "setVtSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004821 final long identity = Binder.clearCallingIdentity();
4822 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004823 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004824 // This setting doesn't require an active ImsService connection, so do not verify. The
4825 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07004826 ImsManager.getInstance(mApp, slotId).setVtSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004827 } catch (ImsException e) {
4828 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004829 } finally {
4830 Binder.restoreCallingIdentity(identity);
4831 }
4832 }
4833
shilu366312e2019-12-17 09:28:10 -08004834 /**
4835 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4836 * @param subId The subscription to use to check the configuration.
4837 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07004838 @Override
4839 public boolean isVoWiFiSettingEnabled(int subId) {
Nathan Harold62c68512021-04-06 11:26:02 -07004840 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004841 mApp, subId, "isVoWiFiSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004842 final long identity = Binder.clearCallingIdentity();
4843 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004844 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004845 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07004846 return ImsManager.getInstance(mApp, slotId).isWfcEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004847 } catch (ImsException e) {
4848 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004849 } finally {
4850 Binder.restoreCallingIdentity(identity);
4851 }
4852 }
4853
4854 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08004855 public void setVoWiFiSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07004856 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08004857 "setVoWiFiSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004858 final long identity = Binder.clearCallingIdentity();
4859 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004860 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004861 // This setting doesn't require an active ImsService connection, so do not verify. The
4862 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07004863 ImsManager.getInstance(mApp, slotId).setWfcSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004864 } catch (ImsException e) {
4865 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004866 } finally {
4867 Binder.restoreCallingIdentity(identity);
4868 }
4869 }
4870
shilu366312e2019-12-17 09:28:10 -08004871 /**
Sooraj Sasindrane655add2020-11-23 19:40:38 -08004872 * @return true if the user's setting for Voice over Cross SIM is enabled and false if it is not
4873 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4874 * @param subId The subscription to use to check the configuration.
4875 */
4876 @Override
4877 public boolean isCrossSimCallingEnabledByUser(int subId) {
Nathan Harold62c68512021-04-06 11:26:02 -07004878 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Sooraj Sasindrane655add2020-11-23 19:40:38 -08004879 mApp, subId, "isCrossSimCallingEnabledByUser");
4880 final long identity = Binder.clearCallingIdentity();
4881 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004882 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004883 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07004884 return ImsManager.getInstance(mApp, slotId).isCrossSimCallingEnabledByUser();
Sooraj Sasindrane655add2020-11-23 19:40:38 -08004885 } catch (ImsException e) {
4886 throw new ServiceSpecificException(e.getCode());
4887 } finally {
4888 Binder.restoreCallingIdentity(identity);
4889 }
4890 }
4891
4892 /**
4893 * Sets the user's setting for whether or not Voice over Cross SIM is enabled.
4894 * Requires MODIFY_PHONE_STATE permission.
4895 * @param subId The subscription to use to check the configuration.
4896 * @param isEnabled true if the user's setting for Voice over Cross SIM is enabled,
4897 * false otherwise
4898 */
4899 @Override
4900 public void setCrossSimCallingEnabled(int subId, boolean isEnabled) {
4901 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4902 "setCrossSimCallingEnabled");
4903 final long identity = Binder.clearCallingIdentity();
4904 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004905 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004906 // This setting doesn't require an active ImsService connection, so do not verify. The
4907 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07004908 ImsManager.getInstance(mApp, slotId).setCrossSimCallingEnabled(isEnabled);
Sooraj Sasindrane655add2020-11-23 19:40:38 -08004909 } catch (ImsException e) {
4910 throw new ServiceSpecificException(e.getCode());
4911 } finally {
4912 Binder.restoreCallingIdentity(identity);
4913 }
4914 }
4915
4916 /**
shilu366312e2019-12-17 09:28:10 -08004917 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4918 * @param subId The subscription to use to check the configuration.
4919 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07004920 @Override
Nathan Harold62c68512021-04-06 11:26:02 -07004921
Brad Ebinger35c841c2018-10-01 10:40:55 -07004922 public boolean isVoWiFiRoamingSettingEnabled(int subId) {
Nathan Harold62c68512021-04-06 11:26:02 -07004923 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004924 mApp, subId, "isVoWiFiRoamingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004925 final long identity = Binder.clearCallingIdentity();
4926 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004927 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004928 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07004929 return ImsManager.getInstance(mApp, slotId).isWfcRoamingEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004930 } catch (ImsException e) {
4931 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004932 } finally {
4933 Binder.restoreCallingIdentity(identity);
4934 }
4935 }
4936
4937 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08004938 public void setVoWiFiRoamingSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07004939 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08004940 "setVoWiFiRoamingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004941 final long identity = Binder.clearCallingIdentity();
4942 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004943 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004944 // This setting doesn't require an active ImsService connection, so do not verify. The
4945 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07004946 ImsManager.getInstance(mApp, slotId).setWfcRoamingSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004947 } catch (ImsException e) {
4948 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004949 } finally {
4950 Binder.restoreCallingIdentity(identity);
4951 }
4952 }
4953
4954 @Override
4955 public void setVoWiFiNonPersistent(int subId, boolean isCapable, int mode) {
4956 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4957 "setVoWiFiNonPersistent");
4958 final long identity = Binder.clearCallingIdentity();
4959 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004960 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004961 // This setting will be ignored if the ImsService isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07004962 ImsManager.getInstance(mApp, slotId).setWfcNonPersistent(isCapable, mode);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004963 } catch (ImsException e) {
4964 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004965 } finally {
4966 Binder.restoreCallingIdentity(identity);
4967 }
4968 }
4969
shilu366312e2019-12-17 09:28:10 -08004970 /**
4971 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4972 * @param subId The subscription to use to check the configuration.
4973 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07004974 @Override
4975 public int getVoWiFiModeSetting(int subId) {
Nathan Harold62c68512021-04-06 11:26:02 -07004976 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004977 mApp, subId, "getVoWiFiModeSetting");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004978 final long identity = Binder.clearCallingIdentity();
4979 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004980 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004981 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07004982 return ImsManager.getInstance(mApp, slotId).getWfcMode(false /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004983 } catch (ImsException e) {
4984 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004985 } finally {
4986 Binder.restoreCallingIdentity(identity);
4987 }
4988 }
4989
4990 @Override
4991 public void setVoWiFiModeSetting(int subId, int mode) {
4992 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4993 "setVoWiFiModeSetting");
4994 final long identity = Binder.clearCallingIdentity();
4995 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004996 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004997 // This setting doesn't require an active ImsService connection, so do not verify. The
4998 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07004999 ImsManager.getInstance(mApp, slotId).setWfcMode(mode, false /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005000 } catch (ImsException e) {
5001 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07005002 } finally {
5003 Binder.restoreCallingIdentity(identity);
5004 }
5005 }
5006
5007 @Override
5008 public int getVoWiFiRoamingModeSetting(int subId) {
5009 enforceReadPrivilegedPermission("getVoWiFiRoamingModeSetting");
5010 final long identity = Binder.clearCallingIdentity();
5011 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07005012 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07005013 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07005014 return ImsManager.getInstance(mApp, slotId).getWfcMode(true /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005015 } catch (ImsException e) {
5016 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07005017 } finally {
5018 Binder.restoreCallingIdentity(identity);
5019 }
5020 }
5021
5022 @Override
5023 public void setVoWiFiRoamingModeSetting(int subId, int mode) {
5024 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5025 "setVoWiFiRoamingModeSetting");
5026 final long identity = Binder.clearCallingIdentity();
5027 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07005028 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07005029 // This setting doesn't require an active ImsService connection, so do not verify. The
5030 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07005031 ImsManager.getInstance(mApp, slotId).setWfcMode(mode, true /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005032 } catch (ImsException e) {
5033 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07005034 } finally {
5035 Binder.restoreCallingIdentity(identity);
5036 }
5037 }
5038
5039 @Override
5040 public void setRttCapabilitySetting(int subId, boolean isEnabled) {
5041 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5042 "setRttCapabilityEnabled");
5043 final long identity = Binder.clearCallingIdentity();
5044 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07005045 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07005046 // This setting doesn't require an active ImsService connection, so do not verify. The
5047 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07005048 ImsManager.getInstance(mApp, slotId).setRttEnabled(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005049 } catch (ImsException e) {
5050 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07005051 } finally {
5052 Binder.restoreCallingIdentity(identity);
5053 }
5054 }
5055
shilu366312e2019-12-17 09:28:10 -08005056 /**
5057 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
5058 * @param subId The subscription to use to check the configuration.
5059 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07005060 @Override
5061 public boolean isTtyOverVolteEnabled(int subId) {
Nathan Harold62c68512021-04-06 11:26:02 -07005062 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08005063 mApp, subId, "isTtyOverVolteEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07005064 final long identity = Binder.clearCallingIdentity();
5065 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07005066 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07005067 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07005068 return ImsManager.getInstance(mApp, slotId).isTtyOnVoLteCapable();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005069 } catch (ImsException e) {
5070 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07005071 } finally {
5072 Binder.restoreCallingIdentity(identity);
5073 }
5074 }
5075
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005076 @Override
5077 public void registerImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
5078 enforceReadPrivilegedPermission("registerImsProvisioningChangedCallback");
joonhunshincffb7fc2021-11-28 07:32:01 +00005079
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005080 final long identity = Binder.clearCallingIdentity();
5081 try {
Brad Ebingera2628302022-02-18 03:44:55 +00005082 if (!isImsAvailableOnDevice()) {
5083 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
5084 "IMS not available on device.");
5085 }
5086 int slotId = getSlotIndexOrException(subId);
5087 verifyImsMmTelConfiguredOrThrow(slotId);
Hwangoo Park8646b0d2023-01-13 02:42:34 +00005088
5089 ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
5090 if (controller != null) {
5091 ImsManager imsManager = controller.getImsManager(subId);
5092 if (imsManager != null) {
5093 imsManager.addProvisioningCallbackForSubscription(callback, subId);
5094 } else {
5095 throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
5096 }
5097 } else {
5098 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
5099 }
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005100 } catch (ImsException e) {
5101 throw new ServiceSpecificException(e.getCode());
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005102 } finally {
5103 Binder.restoreCallingIdentity(identity);
5104 }
5105 }
5106
5107 @Override
5108 public void unregisterImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
5109 enforceReadPrivilegedPermission("unregisterImsProvisioningChangedCallback");
joonhunshincffb7fc2021-11-28 07:32:01 +00005110
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005111 final long identity = Binder.clearCallingIdentity();
Brad Ebinger4ae57f92019-01-09 16:51:30 -08005112 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5113 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
5114 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005115 try {
Hwangoo Park8646b0d2023-01-13 02:42:34 +00005116 ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
5117 if (controller != null) {
5118 ImsManager imsManager = controller.getImsManager(subId);
5119 if (imsManager != null) {
5120 imsManager.removeProvisioningCallbackForSubscription(callback, subId);
5121 } else {
5122 Log.i(LOG_TAG, "unregisterImsProvisioningChangedCallback: " + subId
5123 + " is inactive, ignoring unregister.");
5124 // If the ImsManager is not valid, just return, since the callback will already
5125 // have been removed internally.
5126 }
5127 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005128 } finally {
5129 Binder.restoreCallingIdentity(identity);
5130 }
5131 }
5132
joonhunshincffb7fc2021-11-28 07:32:01 +00005133 @Override
5134 public void registerFeatureProvisioningChangedCallback(int subId,
5135 IFeatureProvisioningCallback callback) {
5136 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5137 mApp, subId, "registerFeatureProvisioningChangedCallback");
5138
5139 final long identity = Binder.clearCallingIdentity();
5140 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5141 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
5142 }
5143
joonhunshin91bc1952022-04-29 08:47:15 +00005144 try {
5145 ImsProvisioningController controller = ImsProvisioningController.getInstance();
5146 if (controller == null) {
5147 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
5148 "Device does not support IMS");
5149 }
5150 controller.addFeatureProvisioningChangedCallback(subId, callback);
5151 } finally {
5152 Binder.restoreCallingIdentity(identity);
5153 }
joonhunshincffb7fc2021-11-28 07:32:01 +00005154 }
5155
5156 @Override
5157 public void unregisterFeatureProvisioningChangedCallback(int subId,
5158 IFeatureProvisioningCallback callback) {
5159 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5160 mApp, subId, "unregisterFeatureProvisioningChangedCallback");
5161
5162 final long identity = Binder.clearCallingIdentity();
5163 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5164 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
5165 }
5166
joonhunshin91bc1952022-04-29 08:47:15 +00005167 try {
5168 ImsProvisioningController controller = ImsProvisioningController.getInstance();
5169 if (controller == null) {
5170 loge("unregisterFeatureProvisioningChangedCallback: Device does not support IMS");
5171 return;
5172 }
5173 controller.removeFeatureProvisioningChangedCallback(subId, callback);
5174 } finally {
5175 Binder.restoreCallingIdentity(identity);
5176 }
joonhunshincffb7fc2021-11-28 07:32:01 +00005177 }
allenwtsu99c623b2020-01-03 18:24:23 +08005178
5179 private void checkModifyPhoneStatePermission(int subId, String message) {
5180 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5181 message);
5182 }
5183
allenwtsu99c623b2020-01-03 18:24:23 +08005184 @Override
joonhunshincffb7fc2021-11-28 07:32:01 +00005185 public void setRcsProvisioningStatusForCapability(int subId, int capability, int tech,
allenwtsu99c623b2020-01-03 18:24:23 +08005186 boolean isProvisioned) {
5187 checkModifyPhoneStatePermission(subId, "setRcsProvisioningStatusForCapability");
5188
5189 final long identity = Binder.clearCallingIdentity();
5190 try {
joonhunshin91bc1952022-04-29 08:47:15 +00005191 ImsProvisioningController controller = ImsProvisioningController.getInstance();
5192 if (controller == null) {
5193 loge("setRcsProvisioningStatusForCapability: Device does not support IMS");
5194 return;
5195 }
5196 controller.setRcsProvisioningStatusForCapability(
5197 subId, capability, tech, isProvisioned);
allenwtsu99c623b2020-01-03 18:24:23 +08005198 } finally {
5199 Binder.restoreCallingIdentity(identity);
5200 }
allenwtsu99c623b2020-01-03 18:24:23 +08005201 }
5202
5203
5204 @Override
joonhunshincffb7fc2021-11-28 07:32:01 +00005205 public boolean getRcsProvisioningStatusForCapability(int subId, int capability, int tech) {
5206 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5207 mApp, subId, "getRcsProvisioningStatusForCapability");
5208
allenwtsu99c623b2020-01-03 18:24:23 +08005209 final long identity = Binder.clearCallingIdentity();
5210 try {
joonhunshin91bc1952022-04-29 08:47:15 +00005211 ImsProvisioningController controller = ImsProvisioningController.getInstance();
5212 if (controller == null) {
5213 loge("getRcsProvisioningStatusForCapability: Device does not support IMS");
5214
5215 // device does not support IMS, this method will return true always.
5216 return true;
5217 }
5218 return controller.getRcsProvisioningStatusForCapability(subId, capability, tech);
allenwtsu99c623b2020-01-03 18:24:23 +08005219 } finally {
5220 Binder.restoreCallingIdentity(identity);
5221 }
5222 }
5223
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005224 @Override
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005225 public void setImsProvisioningStatusForCapability(int subId, int capability, int tech,
5226 boolean isProvisioned) {
allenwtsu99c623b2020-01-03 18:24:23 +08005227 checkModifyPhoneStatePermission(subId, "setImsProvisioningStatusForCapability");
joonhunshincffb7fc2021-11-28 07:32:01 +00005228
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005229 final long identity = Binder.clearCallingIdentity();
5230 try {
joonhunshin91bc1952022-04-29 08:47:15 +00005231 ImsProvisioningController controller = ImsProvisioningController.getInstance();
5232 if (controller == null) {
5233 loge("setImsProvisioningStatusForCapability: Device does not support IMS");
5234 return;
5235 }
5236 controller.setImsProvisioningStatusForCapability(
5237 subId, capability, tech, isProvisioned);
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005238 } finally {
5239 Binder.restoreCallingIdentity(identity);
5240 }
5241 }
5242
5243 @Override
5244 public boolean getImsProvisioningStatusForCapability(int subId, int capability, int tech) {
joonhunshincffb7fc2021-11-28 07:32:01 +00005245 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5246 mApp, subId, "getProvisioningStatusForCapability");
5247
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005248 final long identity = Binder.clearCallingIdentity();
5249 try {
joonhunshin91bc1952022-04-29 08:47:15 +00005250 ImsProvisioningController controller = ImsProvisioningController.getInstance();
5251 if (controller == null) {
5252 loge("getImsProvisioningStatusForCapability: Device does not support IMS");
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005253
joonhunshin91bc1952022-04-29 08:47:15 +00005254 // device does not support IMS, this method will return true always.
5255 return true;
5256 }
5257 return controller.getImsProvisioningStatusForCapability(subId, capability, tech);
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005258 } finally {
5259 Binder.restoreCallingIdentity(identity);
5260 }
5261 }
5262
5263 @Override
joonhunshincffb7fc2021-11-28 07:32:01 +00005264 public boolean isProvisioningRequiredForCapability(int subId, int capability, int tech) {
5265 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5266 mApp, subId, "isProvisioningRequiredForCapability");
5267
5268 final long identity = Binder.clearCallingIdentity();
5269 try {
joonhunshin91bc1952022-04-29 08:47:15 +00005270 ImsProvisioningController controller = ImsProvisioningController.getInstance();
5271 if (controller == null) {
5272 loge("isProvisioningRequiredForCapability: Device does not support IMS");
5273
5274 // device does not support IMS, this method will return false
5275 return false;
5276 }
5277 return controller.isImsProvisioningRequiredForCapability(subId, capability, tech);
joonhunshincffb7fc2021-11-28 07:32:01 +00005278 } finally {
5279 Binder.restoreCallingIdentity(identity);
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005280 }
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005281 }
5282
5283 @Override
joonhunshincffb7fc2021-11-28 07:32:01 +00005284 public boolean isRcsProvisioningRequiredForCapability(int subId, int capability, int tech) {
5285 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5286 mApp, subId, "isProvisioningRequiredForCapability");
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005287
joonhunshincffb7fc2021-11-28 07:32:01 +00005288 final long identity = Binder.clearCallingIdentity();
5289 try {
joonhunshin91bc1952022-04-29 08:47:15 +00005290 ImsProvisioningController controller = ImsProvisioningController.getInstance();
5291 if (controller == null) {
5292 loge("isRcsProvisioningRequiredForCapability: Device does not support IMS");
5293
5294 // device does not support IMS, this method will return false
5295 return false;
5296 }
5297 return controller.isRcsProvisioningRequiredForCapability(subId, capability, tech);
joonhunshincffb7fc2021-11-28 07:32:01 +00005298 } finally {
5299 Binder.restoreCallingIdentity(identity);
5300 }
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005301 }
5302
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005303 @Override
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005304 public int getImsProvisioningInt(int subId, int key) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005305 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5306 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
5307 }
joonhunshincffb7fc2021-11-28 07:32:01 +00005308 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5309 mApp, subId, "getImsProvisioningInt");
5310
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005311 final long identity = Binder.clearCallingIdentity();
5312 try {
5313 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005314 int slotId = getSlotIndex(subId);
5315 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5316 Log.w(LOG_TAG, "getImsProvisioningInt: called with an inactive subscription '"
5317 + subId + "' for key:" + key);
5318 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
5319 }
joonhunshincffb7fc2021-11-28 07:32:01 +00005320
joonhunshin91bc1952022-04-29 08:47:15 +00005321 ImsProvisioningController controller = ImsProvisioningController.getInstance();
5322 if (controller == null) {
5323 loge("getImsProvisioningInt: Device does not support IMS");
5324
5325 // device does not support IMS, this method will return CONFIG_RESULT_UNKNOWN.
5326 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
5327 }
5328 int retVal = controller.getProvisioningValue(subId, key);
joonhunshincffb7fc2021-11-28 07:32:01 +00005329 if (retVal != ImsConfigImplBase.CONFIG_RESULT_UNKNOWN) {
5330 return retVal;
5331 }
5332
calvinpanb5a34062021-02-08 19:59:36 +08005333 return ImsManager.getInstance(mApp, slotId).getConfigInt(key);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005334 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005335 Log.w(LOG_TAG, "getImsProvisioningInt: ImsService is not available for subscription '"
5336 + subId + "' for key:" + key);
5337 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005338 } finally {
5339 Binder.restoreCallingIdentity(identity);
5340 }
5341 }
5342
5343 @Override
5344 public String getImsProvisioningString(int subId, int key) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005345 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5346 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
5347 }
joonhunshincffb7fc2021-11-28 07:32:01 +00005348 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5349 mApp, subId, "getImsProvisioningString");
5350
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005351 final long identity = Binder.clearCallingIdentity();
5352 try {
5353 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005354 int slotId = getSlotIndex(subId);
5355 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5356 Log.w(LOG_TAG, "getImsProvisioningString: called for an inactive subscription id '"
5357 + subId + "' for key:" + key);
5358 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_GENERIC;
5359 }
calvinpanb5a34062021-02-08 19:59:36 +08005360 return ImsManager.getInstance(mApp, slotId).getConfigString(key);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005361 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005362 Log.w(LOG_TAG, "getImsProvisioningString: ImsService is not available for sub '"
5363 + subId + "' for key:" + key);
5364 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_NOT_READY;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005365 } finally {
5366 Binder.restoreCallingIdentity(identity);
5367 }
5368 }
5369
5370 @Override
5371 public int setImsProvisioningInt(int subId, int key, int value) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005372 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5373 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
5374 }
Brad Ebinger3d0b34e2018-11-15 14:13:12 -08005375 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5376 "setImsProvisioningInt");
joonhunshincffb7fc2021-11-28 07:32:01 +00005377
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005378 final long identity = Binder.clearCallingIdentity();
5379 try {
5380 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005381 int slotId = getSlotIndex(subId);
5382 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5383 Log.w(LOG_TAG, "setImsProvisioningInt: called with an inactive subscription id '"
5384 + subId + "' for key:" + key);
5385 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
5386 }
joonhunshincffb7fc2021-11-28 07:32:01 +00005387
joonhunshin91bc1952022-04-29 08:47:15 +00005388 ImsProvisioningController controller = ImsProvisioningController.getInstance();
5389 if (controller == null) {
5390 loge("setImsProvisioningInt: Device does not support IMS");
5391
5392 // device does not support IMS, this method will return CONFIG_RESULT_FAILED.
5393 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
5394 }
5395 int retVal = controller.setProvisioningValue(subId, key, value);
joonhunshincffb7fc2021-11-28 07:32:01 +00005396 if (retVal != ImsConfigImplBase.CONFIG_RESULT_UNKNOWN) {
5397 return retVal;
5398 }
5399
calvinpanb5a34062021-02-08 19:59:36 +08005400 return ImsManager.getInstance(mApp, slotId).setConfig(key, value);
5401 } catch (com.android.ims.ImsException | RemoteException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005402 Log.w(LOG_TAG, "setImsProvisioningInt: ImsService unavailable for sub '" + subId
calvinpanb5a34062021-02-08 19:59:36 +08005403 + "' for key:" + key, e);
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005404 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005405 } finally {
5406 Binder.restoreCallingIdentity(identity);
5407 }
5408 }
5409
5410 @Override
5411 public int setImsProvisioningString(int subId, int key, String value) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005412 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5413 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
5414 }
Brad Ebinger3d0b34e2018-11-15 14:13:12 -08005415 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5416 "setImsProvisioningString");
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005417 final long identity = Binder.clearCallingIdentity();
5418 try {
5419 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005420 int slotId = getSlotIndex(subId);
5421 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5422 Log.w(LOG_TAG, "setImsProvisioningString: called with an inactive subscription id '"
5423 + subId + "' for key:" + key);
5424 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
5425 }
calvinpanb5a34062021-02-08 19:59:36 +08005426 return ImsManager.getInstance(mApp, slotId).setConfig(key, value);
5427 } catch (com.android.ims.ImsException | RemoteException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005428 Log.w(LOG_TAG, "setImsProvisioningString: ImsService unavailable for sub '" + subId
calvinpanb5a34062021-02-08 19:59:36 +08005429 + "' for key:" + key, e);
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005430 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005431 } finally {
5432 Binder.restoreCallingIdentity(identity);
5433 }
5434 }
5435
Brad Ebinger919631e2021-06-02 17:46:35 -07005436 /**
5437 * Throw an ImsException if the IMS resolver does not have an ImsService configured for MMTEL
5438 * for the given slot ID or no ImsResolver instance has been created.
5439 * @param slotId The slot ID that the IMS service is created for.
5440 * @throws ImsException If there is no ImsService configured for this slot.
5441 */
5442 private void verifyImsMmTelConfiguredOrThrow(int slotId) throws ImsException {
5443 if (mImsResolver == null || !mImsResolver.isImsServiceConfiguredForFeature(slotId,
5444 ImsFeature.FEATURE_MMTEL)) {
5445 throw new ImsException("This subscription does not support MMTEL over IMS",
5446 ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
5447 }
5448 }
5449
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005450 private int getSlotIndexOrException(int subId) throws ImsException {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005451 int slotId = SubscriptionManager.getSlotIndex(subId);
5452 if (!SubscriptionManager.isValidSlotIndex(slotId)) {
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005453 throw new ImsException("Invalid Subscription Id, subId=" + subId,
5454 ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
Brad Ebinger35c841c2018-10-01 10:40:55 -07005455 }
5456 return slotId;
5457 }
5458
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005459 private int getSlotIndex(int subId) {
5460 int slotId = SubscriptionManager.getSlotIndex(subId);
5461 if (!SubscriptionManager.isValidSlotIndex(slotId)) {
5462 return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
5463 }
5464 return slotId;
5465 }
5466
Wink Saville36469e72014-06-11 15:17:00 -07005467 /**
Nathan Harold9042f0b2019-05-21 15:51:27 -07005468 * Returns the data network type for a subId; does not throw SecurityException.
Wink Saville36469e72014-06-11 15:17:00 -07005469 */
5470 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005471 public int getNetworkTypeForSubscriber(int subId, String callingPackage,
5472 String callingFeatureId) {
Shuo Qian13d89152021-05-10 23:58:11 -07005473 try {
5474 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
5475 } catch (SecurityException se) {
5476 EventLog.writeEvent(0x534e4554, "186776740", Binder.getCallingUid());
5477 throw new SecurityException("Package " + callingPackage + " does not belong to "
5478 + Binder.getCallingUid());
5479 }
Nathan Haroldf096d982020-11-18 17:18:06 -08005480 final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
Nathan Haroldef60dba2019-05-22 13:55:14 -07005481 if (targetSdk > android.os.Build.VERSION_CODES.Q) {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005482 return getDataNetworkTypeForSubscriber(subId, callingPackage, callingFeatureId);
Nathan Haroldef60dba2019-05-22 13:55:14 -07005483 } else if (targetSdk == android.os.Build.VERSION_CODES.Q
Nathan Harold9042f0b2019-05-21 15:51:27 -07005484 && !TelephonyPermissions.checkCallingOrSelfReadPhoneStateNoThrow(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005485 mApp, subId, callingPackage, callingFeatureId,
5486 "getNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07005487 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5488 }
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07005489
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005490 final long identity = Binder.clearCallingIdentity();
5491 try {
5492 final Phone phone = getPhone(subId);
5493 if (phone != null) {
5494 return phone.getServiceState().getDataNetworkType();
5495 } else {
5496 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5497 }
5498 } finally {
5499 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07005500 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005501 }
5502
5503 /**
5504 * Returns the data network type
5505 */
5506 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005507 public int getDataNetworkType(String callingPackage, String callingFeatureId) {
Jack Yu285100e2022-12-02 22:48:35 -08005508 return getDataNetworkTypeForSubscriber(SubscriptionManager.getDefaultDataSubscriptionId(),
Zoey Chenfd61f7f2021-04-21 13:42:10 +08005509 callingPackage, callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07005510 }
5511
5512 /**
5513 * Returns the data network type for a subId
5514 */
5515 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005516 public int getDataNetworkTypeForSubscriber(int subId, String callingPackage,
5517 String callingFeatureId) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07005518 String functionName = "getDataNetworkTypeForSubscriber";
5519 if (!TelephonyPermissions.checkCallingOrSelfReadNonDangerousPhoneStateNoThrow(
5520 mApp, functionName)) {
5521 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5522 mApp, subId, callingPackage, callingFeatureId, functionName)) {
5523 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5524 }
Robert Greenwalt36b23af2015-07-06 17:59:14 -07005525 }
5526
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005527 final long identity = Binder.clearCallingIdentity();
5528 try {
5529 final Phone phone = getPhone(subId);
5530 if (phone != null) {
5531 return phone.getServiceState().getDataNetworkType();
5532 } else {
5533 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5534 }
5535 } finally {
5536 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07005537 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005538 }
5539
5540 /**
Wink Saville36469e72014-06-11 15:17:00 -07005541 * Returns the Voice network type for a subId
5542 */
5543 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005544 public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage,
5545 String callingFeatureId) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07005546 String functionName = "getVoiceNetworkTypeForSubscriber";
5547 if (!TelephonyPermissions.checkCallingOrSelfReadNonDangerousPhoneStateNoThrow(
5548 mApp, functionName)) {
5549 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5550 mApp, subId, callingPackage, callingFeatureId, functionName)) {
5551 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5552 }
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07005553 }
5554
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005555 final long identity = Binder.clearCallingIdentity();
5556 try {
5557 final Phone phone = getPhone(subId);
5558 if (phone != null) {
5559 return phone.getServiceState().getVoiceNetworkType();
5560 } else {
5561 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5562 }
5563 } finally {
5564 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07005565 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005566 }
5567
5568 /**
5569 * @return true if a ICC card is present
5570 */
5571 public boolean hasIccCard() {
Wink Saville36469e72014-06-11 15:17:00 -07005572 // FIXME Make changes to pass defaultSimId of type int
Jack Yu285100e2022-12-02 22:48:35 -08005573 return hasIccCardUsingSlotIndex(SubscriptionManager.getSlotIndex(
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005574 getDefaultSubscription()));
Wink Saville36469e72014-06-11 15:17:00 -07005575 }
5576
5577 /**
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005578 * @return true if a ICC card is present for a slotIndex
Wink Saville36469e72014-06-11 15:17:00 -07005579 */
Sanket Padawe356d7632015-06-22 14:03:32 -07005580 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005581 public boolean hasIccCardUsingSlotIndex(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005582 final long identity = Binder.clearCallingIdentity();
5583 try {
5584 final Phone phone = PhoneFactory.getPhone(slotIndex);
5585 if (phone != null) {
5586 return phone.getIccCard().hasIccCard();
5587 } else {
5588 return false;
5589 }
5590 } finally {
5591 Binder.restoreCallingIdentity(identity);
Amit Mahajana6fc2a82015-01-06 11:53:51 -08005592 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005593 }
5594
5595 /**
5596 * Return if the current radio is LTE on CDMA. This
5597 * is a tri-state return value as for a period of time
5598 * the mode may be unknown.
5599 *
Robert Greenwalt36b23af2015-07-06 17:59:14 -07005600 * @param callingPackage the name of the package making the call.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005601 * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
Jake Hambye994d462014-02-03 13:10:13 -08005602 * or {@link Phone#LTE_ON_CDMA_TRUE}
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005603 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07005604 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005605 public int getLteOnCdmaMode(String callingPackage, String callingFeatureId) {
5606 return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage,
5607 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07005608 }
5609
Sanket Padawe356d7632015-06-22 14:03:32 -07005610 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005611 public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage,
5612 String callingFeatureId) {
Sarah Chin790d2922020-01-16 12:17:23 -08005613 try {
5614 enforceReadPrivilegedPermission("getLteOnCdmaModeForSubscriber");
5615 } catch (SecurityException e) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07005616 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
5617 }
5618
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005619 final long identity = Binder.clearCallingIdentity();
5620 try {
5621 final Phone phone = getPhone(subId);
5622 if (phone == null) {
5623 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
5624 } else {
Nathan Harold05ad6332020-07-10 11:54:36 -07005625 return TelephonyProperties.lte_on_cdma_device()
5626 .orElse(PhoneConstants.LTE_ON_CDMA_FALSE);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005627 }
5628 } finally {
5629 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07005630 }
Wink Saville36469e72014-06-11 15:17:00 -07005631 }
5632
Wink Saville36469e72014-06-11 15:17:00 -07005633 /**
5634 * {@hide}
5635 * Returns Default subId, 0 in the case of single standby.
5636 */
Wink Savilleb564aae2014-10-23 10:18:09 -07005637 private int getDefaultSubscription() {
Jack Yu285100e2022-12-02 22:48:35 -08005638 return SubscriptionManager.getDefaultSubscriptionId();
Wink Saville36469e72014-06-11 15:17:00 -07005639 }
5640
Shishir Agrawala9f32182016-04-12 12:00:16 -07005641 private int getSlotForDefaultSubscription() {
Jack Yu285100e2022-12-02 22:48:35 -08005642 return SubscriptionManager.getPhoneId(getDefaultSubscription());
Shishir Agrawala9f32182016-04-12 12:00:16 -07005643 }
5644
Wink Savilleb564aae2014-10-23 10:18:09 -07005645 private int getPreferredVoiceSubscription() {
Jack Yu285100e2022-12-02 22:48:35 -08005646 return SubscriptionManager.getDefaultVoiceSubscriptionId();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005647 }
Ihab Awadf2177b72013-11-25 13:33:23 -08005648
Pengquan Menge92a50d2018-09-21 15:54:48 -07005649 private boolean isActiveSubscription(int subId) {
Jack Yu285100e2022-12-02 22:48:35 -08005650 if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
5651 return SubscriptionManagerService.getInstance().isActiveSubId(subId,
5652 mApp.getOpPackageName(), mApp.getFeatureId());
5653 }
Pengquan Menge92a50d2018-09-21 15:54:48 -07005654 return mSubscriptionController.isActiveSubId(subId);
5655 }
5656
Ihab Awadf2177b72013-11-25 13:33:23 -08005657 /**
5658 * @see android.telephony.TelephonyManager.WifiCallingChoices
5659 */
5660 public int getWhenToMakeWifiCalls() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005661 final long identity = Binder.clearCallingIdentity();
5662 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005663 return Settings.System.getInt(mApp.getContentResolver(),
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005664 Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
5665 getWhenToMakeWifiCallsDefaultPreference());
5666 } finally {
5667 Binder.restoreCallingIdentity(identity);
5668 }
Ihab Awadf2177b72013-11-25 13:33:23 -08005669 }
5670
5671 /**
5672 * @see android.telephony.TelephonyManager.WifiCallingChoices
5673 */
5674 public void setWhenToMakeWifiCalls(int preference) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005675 final long identity = Binder.clearCallingIdentity();
5676 try {
5677 if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005678 Settings.System.putInt(mApp.getContentResolver(),
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005679 Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference);
5680 } finally {
5681 Binder.restoreCallingIdentity(identity);
5682 }
Ihab Awadf9e92732013-12-05 18:02:52 -08005683 }
5684
Sailesh Nepald1e68152013-12-12 19:08:02 -08005685 private static int getWhenToMakeWifiCallsDefaultPreference() {
Santos Cordonda120f42014-08-06 04:44:34 -07005686 // TODO: Use a build property to choose this value.
Evan Charlton9829e882013-12-19 15:30:38 -08005687 return TelephonyManager.WifiCallingChoices.ALWAYS_USE;
Ihab Awadf2177b72013-11-25 13:33:23 -08005688 }
Shishir Agrawal69f68122013-12-16 17:25:49 -08005689
Muralidhar Reddybd38d952021-12-02 21:04:16 +00005690 private Phone getPhoneFromSlotPortIndexOrThrowException(int slotIndex, int portIndex) {
5691 int phoneId = UiccController.getInstance().getPhoneIdFromSlotPortIndex(slotIndex,
5692 portIndex);
Jordan Liu4c733742019-02-28 12:03:40 -08005693 if (phoneId == -1) {
Muralidhar Reddybd38d952021-12-02 21:04:16 +00005694 throw new IllegalArgumentException("Given slot index: " + slotIndex + " port index: "
5695 + portIndex + " does not correspond to an active phone");
Jordan Liu4c733742019-02-28 12:03:40 -08005696 }
5697 return PhoneFactory.getPhone(phoneId);
5698 }
5699
Shishir Agrawal566b7612013-10-28 14:41:00 -07005700 @Override
Derek Tan740e1672017-06-27 14:56:27 -07005701 public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
Rambo Wanga1782702021-11-10 20:15:19 -08005702 @NonNull IccLogicalChannelRequest request) {
5703 Phone phone = getPhoneFromValidIccLogicalChannelRequest(request,
5704 /*message=*/ "iccOpenLogicalChannel");
5705
5706 if (DBG) log("iccOpenLogicalChannel: request=" + request);
5707 // Verify that the callingPackage in the request belongs to the calling UID
5708 mAppOps.checkPackage(Binder.getCallingUid(), request.callingPackage);
5709
5710 return iccOpenLogicalChannelWithPermission(phone, request);
Jordan Liu4c733742019-02-28 12:03:40 -08005711 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07005712
Rambo Wanga1782702021-11-10 20:15:19 -08005713 private Phone getPhoneFromValidIccLogicalChannelRequest(
5714 @NonNull IccLogicalChannelRequest request, String message) {
5715 Phone phone;
5716 if (request.subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
5717 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5718 mApp, request.subId, message);
5719 phone = getPhoneFromSubId(request.subId);
5720 } else if (request.slotIndex != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5721 enforceModifyPermission();
5722 phone = getPhoneFromSlotPortIndexOrThrowException(request.slotIndex, request.portIndex);
5723 } else {
5724 throw new IllegalArgumentException("Both subId and slotIndex in request are invalid.");
Jordan Liu4c733742019-02-28 12:03:40 -08005725 }
Rambo Wanga1782702021-11-10 20:15:19 -08005726 return phone;
Jordan Liu4c733742019-02-28 12:03:40 -08005727 }
5728
5729 private IccOpenLogicalChannelResponse iccOpenLogicalChannelWithPermission(Phone phone,
Rambo Wanga1782702021-11-10 20:15:19 -08005730 IccLogicalChannelRequest channelRequest) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005731 final long identity = Binder.clearCallingIdentity();
5732 try {
Rambo Wanga1782702021-11-10 20:15:19 -08005733 if (TextUtils.equals(ISDR_AID, channelRequest.aid)) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005734 // Only allows LPA to open logical channel to ISD-R.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005735 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
5736 .getContext().getPackageManager());
Rambo Wanga1782702021-11-10 20:15:19 -08005737 if (bestComponent == null || !TextUtils.equals(channelRequest.callingPackage,
5738 bestComponent.packageName)) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005739 loge("The calling package is not allowed to access ISD-R.");
5740 throw new SecurityException(
5741 "The calling package is not allowed to access ISD-R.");
5742 }
Derek Tan740e1672017-06-27 14:56:27 -07005743 }
Derek Tan740e1672017-06-27 14:56:27 -07005744
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005745 IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse) sendRequest(
Rambo Wanga1782702021-11-10 20:15:19 -08005746 CMD_OPEN_CHANNEL, channelRequest, phone, null /* workSource */);
5747 if (DBG) log("iccOpenLogicalChannelWithPermission: response=" + response);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005748 return response;
5749 } finally {
5750 Binder.restoreCallingIdentity(identity);
5751 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07005752 }
5753
5754 @Override
Rambo Wanga1782702021-11-10 20:15:19 -08005755 public boolean iccCloseLogicalChannel(@NonNull IccLogicalChannelRequest request) {
5756 Phone phone = getPhoneFromValidIccLogicalChannelRequest(request,
5757 /*message=*/"iccCloseLogicalChannel");
5758
5759 if (DBG) log("iccCloseLogicalChannel: request=" + request);
5760
5761 return iccCloseLogicalChannelWithPermission(phone, request);
Jordan Liu4c733742019-02-28 12:03:40 -08005762 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07005763
Rambo Wanga1782702021-11-10 20:15:19 -08005764 private boolean iccCloseLogicalChannelWithPermission(Phone phone,
5765 IccLogicalChannelRequest request) {
Chen Xua8f0dff2022-02-12 00:34:15 -08005766 // before this feature is enabled, this API should only return false if
5767 // the operation fails instead of throwing runtime exception for
5768 // backward-compatibility.
5769 final boolean shouldThrowExceptionOnFailure = CompatChanges.isChangeEnabled(
5770 ICC_CLOSE_CHANNEL_EXCEPTION_ON_FAILURE, Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005771 final long identity = Binder.clearCallingIdentity();
5772 try {
Rambo Wanga1782702021-11-10 20:15:19 -08005773 if (request.channel < 0) {
Chen Xu540470b2021-12-14 17:15:47 -08005774 throw new IllegalArgumentException("request.channel is less than 0");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005775 }
Chen Xue9d737e2022-01-01 23:41:31 -08005776 Object result = sendRequest(CMD_CLOSE_CHANNEL, request.channel, phone,
Jordan Liu4c733742019-02-28 12:03:40 -08005777 null /* workSource */);
Chen Xue9d737e2022-01-01 23:41:31 -08005778 Boolean success = false;
5779 if (result instanceof RuntimeException) {
5780 // if there is an exception returned, throw from the binder thread here.
Chen Xua8f0dff2022-02-12 00:34:15 -08005781 if (shouldThrowExceptionOnFailure) {
5782 throw (RuntimeException) result;
5783 } else {
5784 return false;
5785 }
Chen Xue9d737e2022-01-01 23:41:31 -08005786 } else if (result instanceof Boolean) {
5787 success = (Boolean) result;
5788 } else {
5789 loge("iccCloseLogicalChannelWithPermission: supported return type " + result);
5790 }
Rambo Wanga1782702021-11-10 20:15:19 -08005791 if (DBG) log("iccCloseLogicalChannelWithPermission: success=" + success);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005792 return success;
5793 } finally {
5794 Binder.restoreCallingIdentity(identity);
Shishir Agrawal566b7612013-10-28 14:41:00 -07005795 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07005796 }
5797
5798 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08005799 public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
Shishir Agrawal566b7612013-10-28 14:41:00 -07005800 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005801 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5802 mApp, subId, "iccTransmitApduLogicalChannel");
Jordan Liu4c733742019-02-28 12:03:40 -08005803 if (DBG) {
5804 log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel
5805 + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
5806 + p3 + " data=" + data);
5807 }
5808 return iccTransmitApduLogicalChannelWithPermission(getPhoneFromSubId(subId), channel, cla,
5809 command, p1, p2, p3, data);
5810 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07005811
Jordan Liu4c733742019-02-28 12:03:40 -08005812 @Override
Muralidhar Reddybd38d952021-12-02 21:04:16 +00005813 public String iccTransmitApduLogicalChannelByPort(int slotIndex, int portIndex, int channel,
5814 int cla, int command, int p1, int p2, int p3, String data) {
Jordan Liu4c733742019-02-28 12:03:40 -08005815 enforceModifyPermission();
5816 if (DBG) {
Muralidhar Reddybd38d952021-12-02 21:04:16 +00005817 log("iccTransmitApduLogicalChannelByPort: slotIndex=" + slotIndex + " portIndex="
5818 + portIndex + " chnl=" + channel + " cla=" + cla + " cmd=" + command + " p1="
5819 + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
Jordan Liu4c733742019-02-28 12:03:40 -08005820 }
5821 return iccTransmitApduLogicalChannelWithPermission(
Muralidhar Reddybd38d952021-12-02 21:04:16 +00005822 getPhoneFromSlotPortIndexOrThrowException(slotIndex, portIndex), channel, cla,
5823 command, p1, p2, p3, data);
Jordan Liu4c733742019-02-28 12:03:40 -08005824 }
5825
5826 private String iccTransmitApduLogicalChannelWithPermission(Phone phone, int channel, int cla,
5827 int command, int p1, int p2, int p3, String data) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005828 final long identity = Binder.clearCallingIdentity();
5829 try {
Hall Liu4fd771b2019-05-02 09:16:29 -07005830 if (channel <= 0) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005831 return "";
5832 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07005833
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005834 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL,
Jordan Liu4c733742019-02-28 12:03:40 -08005835 new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), phone,
5836 null /* workSource */);
5837 if (DBG) log("iccTransmitApduLogicalChannelWithPermission: " + response);
Shishir Agrawal566b7612013-10-28 14:41:00 -07005838
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005839 // Append the returned status code to the end of the response payload.
5840 String s = Integer.toHexString(
5841 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
5842 if (response.payload != null) {
5843 s = IccUtils.bytesToHexString(response.payload) + s;
5844 }
5845 return s;
5846 } finally {
5847 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07005848 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07005849 }
Jake Hambye994d462014-02-03 13:10:13 -08005850
Evan Charltonc66da362014-05-16 14:06:40 -07005851 @Override
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08005852 public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
5853 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005854 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5855 mApp, subId, "iccTransmitApduBasicChannel");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005856 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jordan Liu4c733742019-02-28 12:03:40 -08005857 if (DBG) {
5858 log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd="
5859 + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
5860 }
5861 return iccTransmitApduBasicChannelWithPermission(getPhoneFromSubId(subId), callingPackage,
5862 cla, command, p1, p2, p3, data);
5863 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07005864
Jordan Liu4c733742019-02-28 12:03:40 -08005865 @Override
Muralidhar Reddybd38d952021-12-02 21:04:16 +00005866 public String iccTransmitApduBasicChannelByPort(int slotIndex, int portIndex,
5867 String callingPackage, int cla, int command, int p1, int p2, int p3, String data) {
Jordan Liu4c733742019-02-28 12:03:40 -08005868 enforceModifyPermission();
5869 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
5870 if (DBG) {
Muralidhar Reddybd38d952021-12-02 21:04:16 +00005871 log("iccTransmitApduBasicChannelByPort: slotIndex=" + slotIndex + " portIndex="
5872 + portIndex + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2="
5873 + p2 + " p3=" + p3 + " data=" + data);
Jordan Liu4c733742019-02-28 12:03:40 -08005874 }
5875
5876 return iccTransmitApduBasicChannelWithPermission(
Muralidhar Reddybd38d952021-12-02 21:04:16 +00005877 getPhoneFromSlotPortIndexOrThrowException(slotIndex, portIndex), callingPackage,
5878 cla, command, p1, p2, p3, data);
Jordan Liu4c733742019-02-28 12:03:40 -08005879 }
5880
5881 // open APDU basic channel assuming the caller has sufficient permissions
5882 private String iccTransmitApduBasicChannelWithPermission(Phone phone, String callingPackage,
5883 int cla, int command, int p1, int p2, int p3, String data) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005884 final long identity = Binder.clearCallingIdentity();
5885 try {
5886 if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
5887 && TextUtils.equals(ISDR_AID, data)) {
5888 // Only allows LPA to select ISD-R.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005889 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
5890 .getContext().getPackageManager());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005891 if (bestComponent == null
5892 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
5893 loge("The calling package is not allowed to select ISD-R.");
5894 throw new SecurityException(
5895 "The calling package is not allowed to select ISD-R.");
5896 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08005897 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08005898
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005899 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL,
Jordan Liu4c733742019-02-28 12:03:40 -08005900 new IccAPDUArgument(0, cla, command, p1, p2, p3, data), phone,
5901 null /* workSource */);
5902 if (DBG) log("iccTransmitApduBasicChannelWithPermission: " + response);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07005903
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005904 // Append the returned status code to the end of the response payload.
5905 String s = Integer.toHexString(
5906 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
5907 if (response.payload != null) {
5908 s = IccUtils.bytesToHexString(response.payload) + s;
5909 }
5910 return s;
5911 } finally {
5912 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07005913 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07005914 }
5915
5916 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08005917 public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07005918 String filePath) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005919 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5920 mApp, subId, "iccExchangeSimIO");
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07005921
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005922 final long identity = Binder.clearCallingIdentity();
5923 try {
5924 if (DBG) {
5925 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " "
5926 + p1 + " " + p2 + " " + p3 + ":" + filePath);
5927 }
5928
5929 IccIoResult response =
5930 (IccIoResult) sendRequest(CMD_EXCHANGE_SIM_IO,
5931 new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath),
5932 subId);
5933
5934 if (DBG) {
5935 log("Exchange SIM_IO [R]" + response);
5936 }
5937
5938 byte[] result = null;
5939 int length = 2;
5940 if (response.payload != null) {
5941 length = 2 + response.payload.length;
5942 result = new byte[length];
5943 System.arraycopy(response.payload, 0, result, 0, response.payload.length);
5944 } else {
5945 result = new byte[length];
5946 }
5947
5948 result[length - 1] = (byte) response.sw2;
5949 result[length - 2] = (byte) response.sw1;
5950 return result;
5951 } finally {
5952 Binder.restoreCallingIdentity(identity);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07005953 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07005954 }
5955
Nathan Haroldb3014052017-01-25 15:57:32 -08005956 /**
5957 * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
5958 * on a particular subscription
5959 */
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005960 public String[] getForbiddenPlmns(int subId, int appType, String callingPackage,
5961 String callingFeatureId) {
sqianb6e41952018-03-12 14:54:01 -07005962 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005963 mApp, subId, callingPackage, callingFeatureId, "getForbiddenPlmns")) {
sqianb6e41952018-03-12 14:54:01 -07005964 return null;
5965 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005966
5967 final long identity = Binder.clearCallingIdentity();
5968 try {
5969 if (appType != TelephonyManager.APPTYPE_USIM
5970 && appType != TelephonyManager.APPTYPE_SIM) {
5971 loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
5972 return null;
5973 }
5974 Object response = sendRequest(
5975 CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
5976 if (response instanceof String[]) {
5977 return (String[]) response;
5978 }
yincheng zhao2737e882019-09-06 17:06:54 -07005979 // Response is an Exception of some kind
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005980 // which is signalled to the user as a NULL retval
Nathan Haroldb3014052017-01-25 15:57:32 -08005981 return null;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005982 } finally {
5983 Binder.restoreCallingIdentity(identity);
Nathan Haroldb3014052017-01-25 15:57:32 -08005984 }
Nathan Haroldb3014052017-01-25 15:57:32 -08005985 }
5986
yincheng zhao2737e882019-09-06 17:06:54 -07005987 /**
5988 * Set the forbidden PLMN list from the given app type (ex APPTYPE_USIM) on a particular
5989 * subscription.
5990 *
5991 * @param subId the id of the subscription.
5992 * @param appType the uicc app type, must be USIM or SIM.
5993 * @param fplmns the Forbiden plmns list that needed to be written to the SIM.
5994 * @param callingPackage the op Package name.
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005995 * @param callingFeatureId the feature in the package.
yincheng zhao2737e882019-09-06 17:06:54 -07005996 * @return number of fplmns that is successfully written to the SIM.
5997 */
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005998 public int setForbiddenPlmns(int subId, int appType, List<String> fplmns, String callingPackage,
5999 String callingFeatureId) {
Jayachandran C5b0d75a2021-10-21 22:15:27 -07006000 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6001 mApp, subId, "setForbiddenPlmns");
6002
yincheng zhao2737e882019-09-06 17:06:54 -07006003 if (appType != TelephonyManager.APPTYPE_USIM && appType != TelephonyManager.APPTYPE_SIM) {
6004 loge("setForbiddenPlmnList(): App Type must be USIM or SIM");
6005 throw new IllegalArgumentException("Invalid appType: App Type must be USIM or SIM");
6006 }
6007 if (fplmns == null) {
6008 throw new IllegalArgumentException("Fplmn List provided is null");
6009 }
6010 for (String fplmn : fplmns) {
6011 if (!CellIdentity.isValidPlmn(fplmn)) {
6012 throw new IllegalArgumentException("Invalid fplmn provided: " + fplmn);
6013 }
6014 }
6015 final long identity = Binder.clearCallingIdentity();
6016 try {
6017 Object response = sendRequest(
6018 CMD_SET_FORBIDDEN_PLMNS,
6019 new Pair<Integer, List<String>>(new Integer(appType), fplmns),
6020 subId);
6021 return (int) response;
6022 } finally {
6023 Binder.restoreCallingIdentity(identity);
6024 }
6025 }
6026
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07006027 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08006028 public String sendEnvelopeWithStatus(int subId, String content) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006029 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6030 mApp, subId, "sendEnvelopeWithStatus");
Evan Charltonc66da362014-05-16 14:06:40 -07006031
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006032 final long identity = Binder.clearCallingIdentity();
6033 try {
6034 IccIoResult response = (IccIoResult) sendRequest(CMD_SEND_ENVELOPE, content, subId);
6035 if (response.payload == null) {
6036 return "";
6037 }
Evan Charltonc66da362014-05-16 14:06:40 -07006038
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006039 // Append the returned status code to the end of the response payload.
6040 String s = Integer.toHexString(
6041 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
6042 s = IccUtils.bytesToHexString(response.payload) + s;
6043 return s;
6044 } finally {
6045 Binder.restoreCallingIdentity(identity);
6046 }
Evan Charltonc66da362014-05-16 14:06:40 -07006047 }
6048
Jake Hambye994d462014-02-03 13:10:13 -08006049 /**
6050 * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
6051 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
6052 *
6053 * @param itemID the ID of the item to read
6054 * @return the NV item as a String, or null on error.
6055 */
6056 @Override
6057 public String nvReadItem(int itemID) {
vagdeviaf9a5b92018-08-15 16:01:53 -07006058 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08006059 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6060 mApp, getDefaultSubscription(), "nvReadItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006061
6062 final long identity = Binder.clearCallingIdentity();
6063 try {
6064 if (DBG) log("nvReadItem: item " + itemID);
vagdeviaf9a5b92018-08-15 16:01:53 -07006065 String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006066 if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
6067 return value;
6068 } finally {
6069 Binder.restoreCallingIdentity(identity);
6070 }
Jake Hambye994d462014-02-03 13:10:13 -08006071 }
6072
6073 /**
6074 * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
6075 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
6076 *
6077 * @param itemID the ID of the item to read
6078 * @param itemValue the value to write, as a String
6079 * @return true on success; false on any failure
6080 */
6081 @Override
6082 public boolean nvWriteItem(int itemID, String itemValue) {
vagdeviaf9a5b92018-08-15 16:01:53 -07006083 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08006084 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6085 mApp, getDefaultSubscription(), "nvWriteItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006086
6087 final long identity = Binder.clearCallingIdentity();
6088 try {
6089 if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
6090 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
vagdeviaf9a5b92018-08-15 16:01:53 -07006091 new Pair<Integer, String>(itemID, itemValue), workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006092 if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
6093 return success;
6094 } finally {
6095 Binder.restoreCallingIdentity(identity);
6096 }
Jake Hambye994d462014-02-03 13:10:13 -08006097 }
6098
6099 /**
6100 * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
6101 * Used for device configuration by some CDMA operators.
6102 *
6103 * @param preferredRoamingList byte array containing the new PRL
6104 * @return true on success; false on any failure
6105 */
6106 @Override
6107 public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006108 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6109 mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006110
6111 final long identity = Binder.clearCallingIdentity();
6112 try {
6113 if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
6114 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
6115 if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
6116 return success;
6117 } finally {
6118 Binder.restoreCallingIdentity(identity);
6119 }
Jake Hambye994d462014-02-03 13:10:13 -08006120 }
6121
6122 /**
chen xu6dac5ab2018-10-26 17:39:23 -07006123 * Rollback modem configurations to factory default except some config which are in whitelist.
Jake Hambye994d462014-02-03 13:10:13 -08006124 * Used for device configuration by some CDMA operators.
6125 *
chen xu6dac5ab2018-10-26 17:39:23 -07006126 * @param slotIndex - device slot.
6127 *
Jake Hambye994d462014-02-03 13:10:13 -08006128 * @return true on success; false on any failure
6129 */
6130 @Override
chen xu6dac5ab2018-10-26 17:39:23 -07006131 public boolean resetModemConfig(int slotIndex) {
6132 Phone phone = PhoneFactory.getPhone(slotIndex);
6133 if (phone != null) {
6134 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6135 mApp, phone.getSubId(), "resetModemConfig");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006136
chen xu6dac5ab2018-10-26 17:39:23 -07006137 final long identity = Binder.clearCallingIdentity();
6138 try {
6139 Boolean success = (Boolean) sendRequest(CMD_RESET_MODEM_CONFIG, null);
6140 if (DBG) log("resetModemConfig:" + ' ' + (success ? "ok" : "fail"));
6141 return success;
6142 } finally {
6143 Binder.restoreCallingIdentity(identity);
6144 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006145 }
chen xu6dac5ab2018-10-26 17:39:23 -07006146 return false;
6147 }
6148
6149 /**
6150 * Generate a radio modem reset. Used for device configuration by some CDMA operators.
6151 *
6152 * @param slotIndex - device slot.
6153 *
6154 * @return true on success; false on any failure
6155 */
6156 @Override
6157 public boolean rebootModem(int slotIndex) {
6158 Phone phone = PhoneFactory.getPhone(slotIndex);
6159 if (phone != null) {
6160 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6161 mApp, phone.getSubId(), "rebootModem");
6162
6163 final long identity = Binder.clearCallingIdentity();
6164 try {
6165 Boolean success = (Boolean) sendRequest(CMD_MODEM_REBOOT, null);
6166 if (DBG) log("rebootModem:" + ' ' + (success ? "ok" : "fail"));
6167 return success;
6168 } finally {
6169 Binder.restoreCallingIdentity(identity);
6170 }
6171 }
6172 return false;
Jake Hambye994d462014-02-03 13:10:13 -08006173 }
Jake Hamby7c27be32014-03-03 13:25:59 -08006174
Brad Ebinger51f743a2017-01-23 13:50:20 -08006175 /**
Grace Jiaaa2eb6b2020-01-09 16:26:08 -08006176 * Toggle IMS disable and enable for the framework to reset it. See {@link #enableIms(int)} and
6177 * {@link #disableIms(int)}.
6178 * @param slotIndex device slot.
6179 */
6180 public void resetIms(int slotIndex) {
6181 enforceModifyPermission();
6182
6183 final long identity = Binder.clearCallingIdentity();
6184 try {
6185 if (mImsResolver == null) {
6186 // may happen if the does not support IMS.
6187 return;
6188 }
Hyunhoa17ac7c2022-08-30 12:03:04 +00006189 mImsResolver.resetIms(slotIndex);
Grace Jiaaa2eb6b2020-01-09 16:26:08 -08006190 } finally {
6191 Binder.restoreCallingIdentity(identity);
6192 }
6193 }
6194
6195 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08006196 * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
6197 * status updates, if not already enabled.
Brad Ebinger51f743a2017-01-23 13:50:20 -08006198 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08006199 public void enableIms(int slotId) {
Brad Ebinger51f743a2017-01-23 13:50:20 -08006200 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006201
6202 final long identity = Binder.clearCallingIdentity();
6203 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08006204 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08006205 // may happen if the device does not support IMS.
6206 return;
6207 }
Brad Ebinger24c29992019-12-05 13:03:21 -08006208 mImsResolver.enableIms(slotId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006209 } finally {
6210 Binder.restoreCallingIdentity(identity);
6211 }
Brad Ebinger34bef922017-11-09 10:27:08 -08006212 }
6213
6214 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08006215 * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
6216 * status updates to disabled.
Brad Ebinger34bef922017-11-09 10:27:08 -08006217 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08006218 public void disableIms(int slotId) {
6219 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006220
6221 final long identity = Binder.clearCallingIdentity();
6222 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08006223 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08006224 // may happen if the device does not support IMS.
6225 return;
6226 }
Brad Ebinger24c29992019-12-05 13:03:21 -08006227 mImsResolver.disableIms(slotId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006228 } finally {
6229 Binder.restoreCallingIdentity(identity);
6230 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08006231 }
6232
6233 /**
Brad Ebinger67b3e042020-09-11 12:45:11 -07006234 * Registers for updates to the MmTelFeature connection through the IImsServiceFeatureCallback
6235 * callback.
Brad Ebinger22bc3e42018-01-16 09:39:35 -08006236 */
Brad Ebinger67b3e042020-09-11 12:45:11 -07006237 @Override
Brad Ebingerf6aca002020-10-01 13:51:05 -07006238 public void registerMmTelFeatureCallback(int slotId, IImsServiceFeatureCallback callback) {
Brad Ebinger34bef922017-11-09 10:27:08 -08006239 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006240
6241 final long identity = Binder.clearCallingIdentity();
6242 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08006243 if (mImsResolver == null) {
Brad Ebinger67b3e042020-09-11 12:45:11 -07006244 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
6245 "Device does not support IMS");
Brad Ebinger9c0eb502019-01-23 15:06:19 -08006246 }
Brad Ebingerf6aca002020-10-01 13:51:05 -07006247 mImsResolver.listenForFeature(slotId, ImsFeature.FEATURE_MMTEL, callback);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006248 } finally {
6249 Binder.restoreCallingIdentity(identity);
6250 }
Brad Ebinger34bef922017-11-09 10:27:08 -08006251 }
Brad Ebinger5f64b052017-12-14 14:26:15 -08006252 /**
Brad Ebinger075ff3a2020-05-18 17:52:58 -07006253 * Unregister a previously registered IImsServiceFeatureCallback associated with an ImsFeature.
6254 */
Brad Ebinger67b3e042020-09-11 12:45:11 -07006255 @Override
6256 public void unregisterImsFeatureCallback(IImsServiceFeatureCallback callback) {
Brad Ebinger075ff3a2020-05-18 17:52:58 -07006257 enforceModifyPermission();
6258
6259 final long identity = Binder.clearCallingIdentity();
6260 try {
6261 if (mImsResolver == null) return;
Brad Ebinger67b3e042020-09-11 12:45:11 -07006262 mImsResolver.unregisterImsFeatureCallback(callback);
Brad Ebinger075ff3a2020-05-18 17:52:58 -07006263 } finally {
6264 Binder.restoreCallingIdentity(identity);
6265 }
6266 }
6267
6268 /**
Brad Ebinger5f64b052017-12-14 14:26:15 -08006269 * Returns the {@link IImsRegistration} structure associated with the slotId and feature
Brad Ebinger9c0eb502019-01-23 15:06:19 -08006270 * specified or null if IMS is not supported on the slot specified.
Brad Ebinger5f64b052017-12-14 14:26:15 -08006271 */
6272 public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
6273 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006274
6275 final long identity = Binder.clearCallingIdentity();
6276 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08006277 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08006278 // may happen if the device does not support IMS.
6279 return null;
6280 }
Brad Ebinger24c29992019-12-05 13:03:21 -08006281 return mImsResolver.getImsRegistration(slotId, feature);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006282 } finally {
6283 Binder.restoreCallingIdentity(identity);
6284 }
Brad Ebinger5f64b052017-12-14 14:26:15 -08006285 }
6286
Brad Ebinger22bc3e42018-01-16 09:39:35 -08006287 /**
6288 * Returns the {@link IImsConfig} structure associated with the slotId and feature
Brad Ebinger9c0eb502019-01-23 15:06:19 -08006289 * specified or null if IMS is not supported on the slot specified.
Brad Ebinger22bc3e42018-01-16 09:39:35 -08006290 */
6291 public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
6292 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006293
6294 final long identity = Binder.clearCallingIdentity();
6295 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08006296 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08006297 // may happen if the device does not support IMS.
6298 return null;
6299 }
Brad Ebinger24c29992019-12-05 13:03:21 -08006300 return mImsResolver.getImsConfig(slotId, feature);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006301 } finally {
6302 Binder.restoreCallingIdentity(identity);
6303 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08006304 }
6305
Brad Ebinger884c07b2018-02-15 16:17:40 -08006306 /**
Brad Ebingerdac2f002018-04-03 15:17:52 -07006307 * Sets the ImsService Package Name that Telephony will bind to.
6308 *
Brad Ebinger24c29992019-12-05 13:03:21 -08006309 * @param slotIndex the slot ID that the ImsService should bind for.
6310 * @param isCarrierService true if the ImsService is the carrier override, false if the
Brad Ebingerdac2f002018-04-03 15:17:52 -07006311 * ImsService is the device default ImsService.
Brad Ebinger24c29992019-12-05 13:03:21 -08006312 * @param featureTypes An integer array of feature types associated with a packageName.
6313 * @param packageName The name of the package that the current configuration will be replaced
6314 * with.
Brad Ebingerdac2f002018-04-03 15:17:52 -07006315 * @return true if setting the ImsService to bind to succeeded, false if it did not.
Brad Ebingerdac2f002018-04-03 15:17:52 -07006316 */
Brad Ebinger24c29992019-12-05 13:03:21 -08006317 public boolean setBoundImsServiceOverride(int slotIndex, boolean isCarrierService,
6318 int[] featureTypes, String packageName) {
Brad Ebinger24c29992019-12-05 13:03:21 -08006319 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setBoundImsServiceOverride");
Brad Ebingerde696de2018-04-06 09:56:40 -07006320 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
Jack Yu00ece8c2022-11-19 22:29:12 -08006321 SubscriptionManager.getSubscriptionId(slotIndex), "setBoundImsServiceOverride");
Brad Ebingerde696de2018-04-06 09:56:40 -07006322
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006323 final long identity = Binder.clearCallingIdentity();
6324 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08006325 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08006326 // may happen if the device does not support IMS.
6327 return false;
6328 }
Brad Ebinger24c29992019-12-05 13:03:21 -08006329 Map<Integer, String> featureConfig = new HashMap<>();
6330 for (int featureType : featureTypes) {
6331 featureConfig.put(featureType, packageName);
6332 }
6333 return mImsResolver.overrideImsServiceConfiguration(slotIndex, isCarrierService,
6334 featureConfig);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006335 } finally {
6336 Binder.restoreCallingIdentity(identity);
6337 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07006338 }
6339
6340 /**
Brad Ebinger999d3302020-11-25 14:31:39 -08006341 * Clears any carrier ImsService overrides for the slot index specified that were previously
6342 * set with {@link #setBoundImsServiceOverride(int, boolean, int[], String)}.
6343 *
6344 * This should only be used for testing.
6345 *
6346 * @param slotIndex the slot ID that the ImsService should bind for.
6347 * @return true if clearing the carrier ImsService override succeeded or false if it did not.
6348 */
6349 @Override
6350 public boolean clearCarrierImsServiceOverride(int slotIndex) {
Brad Ebinger999d3302020-11-25 14:31:39 -08006351 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
6352 "clearCarrierImsServiceOverride");
6353 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
Jack Yu00ece8c2022-11-19 22:29:12 -08006354 SubscriptionManager.getSubscriptionId(slotIndex), "clearCarrierImsServiceOverride");
Brad Ebinger999d3302020-11-25 14:31:39 -08006355
6356 final long identity = Binder.clearCallingIdentity();
6357 try {
6358 if (mImsResolver == null) {
6359 // may happen if the device does not support IMS.
6360 return false;
6361 }
6362 return mImsResolver.clearCarrierImsServiceConfiguration(slotIndex);
6363 } finally {
6364 Binder.restoreCallingIdentity(identity);
6365 }
6366 }
6367
6368 /**
Brad Ebinger24c29992019-12-05 13:03:21 -08006369 * Return the package name of the currently bound ImsService.
Brad Ebingerdac2f002018-04-03 15:17:52 -07006370 *
6371 * @param slotId The slot that the ImsService is associated with.
6372 * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
6373 * the device default.
Brad Ebinger24c29992019-12-05 13:03:21 -08006374 * @param featureType The feature associated with the queried configuration.
Brad Ebingerdac2f002018-04-03 15:17:52 -07006375 * @return the package name of the ImsService configuration.
6376 */
Brad Ebinger24c29992019-12-05 13:03:21 -08006377 public String getBoundImsServicePackage(int slotId, boolean isCarrierImsService,
6378 @ImsFeature.FeatureType int featureType) {
Brad Ebinger24c29992019-12-05 13:03:21 -08006379 TelephonyPermissions
Jack Yu00ece8c2022-11-19 22:29:12 -08006380 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(mApp,
6381 SubscriptionManager.getSubscriptionId(slotId), "getBoundImsServicePackage");
Brad Ebingerde696de2018-04-06 09:56:40 -07006382
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006383 final long identity = Binder.clearCallingIdentity();
6384 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08006385 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08006386 // may happen if the device does not support IMS.
6387 return "";
6388 }
Brad Ebingera80c3312019-12-02 10:59:39 -08006389 // TODO: change API to query RCS separately.
Brad Ebinger24c29992019-12-05 13:03:21 -08006390 return mImsResolver.getImsServiceConfiguration(slotId, isCarrierImsService,
6391 featureType);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006392 } finally {
6393 Binder.restoreCallingIdentity(identity);
6394 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07006395 }
6396
Brad Ebingerbc7dd582019-10-17 17:03:22 -07006397 /**
6398 * Get the MmTelFeature state associated with the requested subscription id.
6399 * @param subId The subscription that the MmTelFeature is associated with.
6400 * @param callback A callback with an integer containing the
6401 * {@link android.telephony.ims.feature.ImsFeature.ImsState} associated with the MmTelFeature.
6402 */
6403 @Override
6404 public void getImsMmTelFeatureState(int subId, IIntegerConsumer callback) {
6405 enforceReadPrivilegedPermission("getImsMmTelFeatureState");
Brad Ebingera2628302022-02-18 03:44:55 +00006406 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
6407 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
6408 "IMS not available on device.");
6409 }
Brad Ebingerbc7dd582019-10-17 17:03:22 -07006410 final long token = Binder.clearCallingIdentity();
6411 try {
Brad Ebingera2628302022-02-18 03:44:55 +00006412 int slotId = getSlotIndex(subId);
6413 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
6414 Log.w(LOG_TAG, "getImsMmTelFeatureState: called with an inactive subscription '"
6415 + subId + "'");
6416 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
6417 }
6418 verifyImsMmTelConfiguredOrThrow(slotId);
6419 ImsManager.getInstance(mApp, slotId).getImsServiceState(anInteger -> {
6420 try {
6421 callback.accept(anInteger == null ? ImsFeature.STATE_UNAVAILABLE : anInteger);
6422 } catch (RemoteException e) {
6423 Log.w(LOG_TAG, "getImsMmTelFeatureState: remote caller is no longer running. "
6424 + "Ignore");
6425 }
Brad Ebingerbc7dd582019-10-17 17:03:22 -07006426 });
Brad Ebinger919631e2021-06-02 17:46:35 -07006427 } catch (ImsException e) {
6428 throw new ServiceSpecificException(e.getCode());
Brad Ebingerbc7dd582019-10-17 17:03:22 -07006429 } finally {
6430 Binder.restoreCallingIdentity(token);
6431 }
6432 }
6433
Daniel Brightbb5840b2021-01-12 15:48:18 -08006434 /**
6435 * Sets the ims registration state on all valid {@link Phone}s.
6436 */
6437 public void setImsRegistrationState(final boolean registered) {
Wink Saville36469e72014-06-11 15:17:00 -07006438 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006439
6440 final long identity = Binder.clearCallingIdentity();
6441 try {
Daniel Brightbb5840b2021-01-12 15:48:18 -08006442 // NOTE: Before S, this method only set the default phone.
6443 for (final Phone phone : PhoneFactory.getPhones()) {
6444 if (SubscriptionManager.isValidSubscriptionId(phone.getSubId())) {
6445 phone.setImsRegistrationState(registered);
6446 }
6447 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006448 } finally {
6449 Binder.restoreCallingIdentity(identity);
6450 }
Wink Saville36469e72014-06-11 15:17:00 -07006451 }
6452
6453 /**
Stuart Scott54788802015-03-30 13:18:01 -07006454 * Set the network selection mode to automatic.
6455 *
6456 */
6457 @Override
6458 public void setNetworkSelectionModeAutomatic(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006459 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6460 mApp, subId, "setNetworkSelectionModeAutomatic");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006461
6462 final long identity = Binder.clearCallingIdentity();
6463 try {
shilufc958392020-01-20 11:36:01 -08006464 if (!isActiveSubscription(subId)) {
6465 return;
6466 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006467 if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
Rambo Wang0f050d82021-02-12 11:43:36 -08006468 sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId,
6469 SET_NETWORK_SELECTION_MODE_AUTOMATIC_TIMEOUT_MS);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006470 } finally {
6471 Binder.restoreCallingIdentity(identity);
6472 }
Stuart Scott54788802015-03-30 13:18:01 -07006473 }
6474
Jack Yud10cdd42020-09-28 20:28:01 -07006475 /**
Pengquan Mengea84e042018-09-20 14:57:26 -07006476 * Ask the radio to connect to the input network and change selection mode to manual.
6477 *
6478 * @param subId the id of the subscription.
6479 * @param operatorInfo the operator information, included the PLMN, long name and short name of
6480 * the operator to attach to.
6481 * @param persistSelection whether the selection will persist until reboot. If true, only allows
6482 * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
6483 * normal network selection next time.
6484 * @return {@code true} on success; {@code true} on any failure.
Shishir Agrawal302c8692015-06-19 13:49:39 -07006485 */
6486 @Override
Pengquan Mengea84e042018-09-20 14:57:26 -07006487 public boolean setNetworkSelectionModeManual(
6488 int subId, OperatorInfo operatorInfo, boolean persistSelection) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006489 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6490 mApp, subId, "setNetworkSelectionModeManual");
Pengquan Menge92a50d2018-09-21 15:54:48 -07006491
Jack Yu285100e2022-12-02 22:48:35 -08006492 final long identity = Binder.clearCallingIdentity();
Pengquan Menge92a50d2018-09-21 15:54:48 -07006493 if (!isActiveSubscription(subId)) {
6494 return false;
6495 }
6496
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006497 try {
Pengquan Mengea84e042018-09-20 14:57:26 -07006498 ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operatorInfo,
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006499 persistSelection);
Pengquan Mengea84e042018-09-20 14:57:26 -07006500 if (DBG) {
6501 log("setNetworkSelectionModeManual: subId: " + subId
6502 + " operator: " + operatorInfo);
6503 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006504 return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
6505 } finally {
6506 Binder.restoreCallingIdentity(identity);
6507 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07006508 }
shilu84f6e8b2019-12-19 13:58:01 -08006509 /**
6510 * Get the manual network selection
6511 *
6512 * @param subId the id of the subscription.
6513 *
6514 * @return the previously saved user selected PLMN
6515 */
6516 @Override
6517 public String getManualNetworkSelectionPlmn(int subId) {
6518 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07006519 .enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
shilu84f6e8b2019-12-19 13:58:01 -08006520 mApp, subId, "getManualNetworkSelectionPlmn");
6521
6522 final long identity = Binder.clearCallingIdentity();
6523 try {
6524 if (!isActiveSubscription(subId)) {
shilufa1c2592020-03-10 10:59:43 -07006525 throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
shilu84f6e8b2019-12-19 13:58:01 -08006526 }
6527
6528 final Phone phone = getPhone(subId);
6529 if (phone == null) {
shilufa1c2592020-03-10 10:59:43 -07006530 throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
shilu84f6e8b2019-12-19 13:58:01 -08006531 }
6532 OperatorInfo networkSelection = phone.getSavedNetworkSelection();
6533 return TextUtils.isEmpty(networkSelection.getOperatorNumeric())
6534 ? phone.getManualNetworkSelectionPlmn() : networkSelection.getOperatorNumeric();
6535 } finally {
6536 Binder.restoreCallingIdentity(identity);
6537 }
6538 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07006539
6540 /**
6541 * Scans for available networks.
6542 */
6543 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07006544 public CellNetworkScanResult getCellNetworkScanResults(int subId, String callingPackage,
6545 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006546 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6547 mApp, subId, "getCellNetworkScanResults");
Hall Liuf19c44f2018-11-27 14:38:17 -08006548 LocationAccessPolicy.LocationPermissionResult locationResult =
6549 LocationAccessPolicy.checkLocationPermission(mApp,
6550 new LocationAccessPolicy.LocationPermissionQuery.Builder()
6551 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07006552 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08006553 .setCallingPid(Binder.getCallingPid())
6554 .setCallingUid(Binder.getCallingUid())
6555 .setMethod("getCellNetworkScanResults")
6556 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
Hall Liuc4a3e422020-05-26 17:18:03 -07006557 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
6558 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
Hall Liuf19c44f2018-11-27 14:38:17 -08006559 .build());
6560 switch (locationResult) {
6561 case DENIED_HARD:
6562 throw new SecurityException("Not allowed to access scan results -- location");
6563 case DENIED_SOFT:
6564 return null;
6565 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006566
Pengquan Menga1bb6272018-09-06 09:59:22 -07006567 long identity = Binder.clearCallingIdentity();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006568 try {
6569 if (DBG) log("getCellNetworkScanResults: subId " + subId);
Pengquan Menga1bb6272018-09-06 09:59:22 -07006570 return (CellNetworkScanResult) sendRequest(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006571 CMD_PERFORM_NETWORK_SCAN, null, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006572 } finally {
6573 Binder.restoreCallingIdentity(identity);
6574 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07006575 }
6576
6577 /**
Shuo Qian4a594052020-01-23 11:59:30 -08006578 * Get the call forwarding info, given the call forwarding reason.
6579 */
6580 @Override
Hall Liu27d24262020-09-18 19:04:59 -07006581 public void getCallForwarding(int subId, int callForwardingReason,
6582 ICallForwardingInfoCallback callback) {
Shuo Qian4a594052020-01-23 11:59:30 -08006583 enforceReadPrivilegedPermission("getCallForwarding");
6584 long identity = Binder.clearCallingIdentity();
6585 try {
6586 if (DBG) {
6587 log("getCallForwarding: subId " + subId
6588 + " callForwardingReason" + callForwardingReason);
6589 }
Hall Liu27d24262020-09-18 19:04:59 -07006590
6591 Phone phone = getPhone(subId);
6592 if (phone == null) {
6593 try {
Hall Liu940c4ca2020-09-29 17:10:18 -07006594 callback.onError(
6595 TelephonyManager.CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN);
Hall Liu27d24262020-09-18 19:04:59 -07006596 } catch (RemoteException e) {
6597 // ignore
6598 }
6599 return;
6600 }
6601
6602 Pair<Integer, TelephonyManager.CallForwardingInfoCallback> argument = Pair.create(
6603 callForwardingReason, new TelephonyManager.CallForwardingInfoCallback() {
6604 @Override
6605 public void onCallForwardingInfoAvailable(CallForwardingInfo info) {
6606 try {
6607 callback.onCallForwardingInfoAvailable(info);
6608 } catch (RemoteException e) {
6609 // ignore
6610 }
6611 }
6612
6613 @Override
6614 public void onError(int error) {
6615 try {
6616 callback.onError(error);
6617 } catch (RemoteException e) {
6618 // ignore
6619 }
6620 }
6621 });
6622 sendRequestAsync(CMD_GET_CALL_FORWARDING, argument, phone, null);
Shuo Qian4a594052020-01-23 11:59:30 -08006623 } finally {
6624 Binder.restoreCallingIdentity(identity);
6625 }
6626 }
6627
6628 /**
6629 * Sets the voice call forwarding info including status (enable/disable), call forwarding
6630 * reason, the number to forward, and the timeout before the forwarding is attempted.
6631 */
6632 @Override
Hall Liu27d24262020-09-18 19:04:59 -07006633 public void setCallForwarding(int subId, CallForwardingInfo callForwardingInfo,
6634 IIntegerConsumer callback) {
Shuo Qian4a594052020-01-23 11:59:30 -08006635 enforceModifyPermission();
6636 long identity = Binder.clearCallingIdentity();
6637 try {
6638 if (DBG) {
6639 log("setCallForwarding: subId " + subId
6640 + " callForwardingInfo" + callForwardingInfo);
6641 }
Hall Liu27d24262020-09-18 19:04:59 -07006642
6643 Phone phone = getPhone(subId);
6644 if (phone == null) {
6645 try {
Hall Liu940c4ca2020-09-29 17:10:18 -07006646 callback.accept(
6647 TelephonyManager.CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN);
Hall Liu27d24262020-09-18 19:04:59 -07006648 } catch (RemoteException e) {
6649 // ignore
6650 }
6651 return;
6652 }
6653
6654 Pair<CallForwardingInfo, Consumer<Integer>> arguments = Pair.create(callForwardingInfo,
6655 FunctionalUtils.ignoreRemoteException(callback::accept));
6656
6657 sendRequestAsync(CMD_SET_CALL_FORWARDING, arguments, phone, null);
Shuo Qian4a594052020-01-23 11:59:30 -08006658 } finally {
6659 Binder.restoreCallingIdentity(identity);
6660 }
6661 }
6662
6663 /**
Hall Liu27d24262020-09-18 19:04:59 -07006664 * Get the call waiting status for a subId.
Shuo Qian4a594052020-01-23 11:59:30 -08006665 */
6666 @Override
Hall Liu27d24262020-09-18 19:04:59 -07006667 public void getCallWaitingStatus(int subId, IIntegerConsumer callback) {
SongFerngWang0e767992021-03-31 22:08:45 +08006668 enforceReadPrivilegedPermission("getCallWaitingStatus");
Shuo Qian4a594052020-01-23 11:59:30 -08006669 long identity = Binder.clearCallingIdentity();
6670 try {
Hall Liu27d24262020-09-18 19:04:59 -07006671 Phone phone = getPhone(subId);
6672 if (phone == null) {
6673 try {
6674 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
6675 } catch (RemoteException e) {
6676 // ignore
6677 }
6678 return;
6679 }
SongFerngWang0e767992021-03-31 22:08:45 +08006680 CarrierConfigManager configManager = new CarrierConfigManager(phone.getContext());
6681 PersistableBundle c = configManager.getConfigForSubId(subId);
6682 boolean requireUssd = c.getBoolean(
6683 CarrierConfigManager.KEY_USE_CALL_WAITING_USSD_BOOL, false);
Hall Liu27d24262020-09-18 19:04:59 -07006684
Shuo Qian4a594052020-01-23 11:59:30 -08006685 if (DBG) log("getCallWaitingStatus: subId " + subId);
SongFerngWang0e767992021-03-31 22:08:45 +08006686 if (requireUssd) {
6687 CarrierXmlParser carrierXmlParser = new CarrierXmlParser(phone.getContext(),
6688 getSubscriptionCarrierId(subId));
6689 String newUssdCommand = "";
6690 try {
6691 newUssdCommand = carrierXmlParser.getFeature(
6692 CarrierXmlParser.FEATURE_CALL_WAITING)
6693 .makeCommand(CarrierXmlParser.SsEntry.SSAction.QUERY, null);
6694 } catch (NullPointerException e) {
6695 loge("Failed to generate USSD number" + e);
6696 }
6697 ResultReceiver wrappedCallback = new CallWaitingUssdResultReceiver(
6698 mMainThreadHandler, callback, carrierXmlParser,
6699 CarrierXmlParser.SsEntry.SSAction.QUERY);
6700 final String ussdCommand = newUssdCommand;
6701 Executors.newSingleThreadExecutor().execute(() -> {
6702 handleUssdRequest(subId, ussdCommand, wrappedCallback);
6703 });
6704 } else {
6705 Consumer<Integer> argument = FunctionalUtils.ignoreRemoteException(
6706 callback::accept);
6707 sendRequestAsync(CMD_GET_CALL_WAITING, argument, phone, null);
6708 }
Shuo Qian4a594052020-01-23 11:59:30 -08006709 } finally {
6710 Binder.restoreCallingIdentity(identity);
6711 }
6712 }
6713
6714 /**
Hall Liu27d24262020-09-18 19:04:59 -07006715 * Sets whether call waiting is enabled for a given subId.
Shuo Qian4a594052020-01-23 11:59:30 -08006716 */
6717 @Override
Hall Liu27d24262020-09-18 19:04:59 -07006718 public void setCallWaitingStatus(int subId, boolean enable, IIntegerConsumer callback) {
Shuo Qian4a594052020-01-23 11:59:30 -08006719 enforceModifyPermission();
6720 long identity = Binder.clearCallingIdentity();
6721 try {
Hall Liu27d24262020-09-18 19:04:59 -07006722 if (DBG) log("setCallWaitingStatus: subId " + subId + " enable: " + enable);
6723
6724 Phone phone = getPhone(subId);
6725 if (phone == null) {
6726 try {
6727 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
6728 } catch (RemoteException e) {
6729 // ignore
6730 }
6731 return;
6732 }
6733
SongFerngWang0e767992021-03-31 22:08:45 +08006734 CarrierConfigManager configManager = new CarrierConfigManager(phone.getContext());
6735 PersistableBundle c = configManager.getConfigForSubId(subId);
6736 boolean requireUssd = c.getBoolean(
6737 CarrierConfigManager.KEY_USE_CALL_WAITING_USSD_BOOL, false);
Hall Liu27d24262020-09-18 19:04:59 -07006738
SongFerngWang0e767992021-03-31 22:08:45 +08006739 if (DBG) log("getCallWaitingStatus: subId " + subId);
6740 if (requireUssd) {
6741 CarrierXmlParser carrierXmlParser = new CarrierXmlParser(phone.getContext(),
6742 getSubscriptionCarrierId(subId));
6743 CarrierXmlParser.SsEntry.SSAction ssAction =
6744 enable ? CarrierXmlParser.SsEntry.SSAction.UPDATE_ACTIVATE
6745 : CarrierXmlParser.SsEntry.SSAction.UPDATE_DEACTIVATE;
6746 String newUssdCommand = "";
6747 try {
6748 newUssdCommand = carrierXmlParser.getFeature(
6749 CarrierXmlParser.FEATURE_CALL_WAITING)
6750 .makeCommand(ssAction, null);
6751 } catch (NullPointerException e) {
6752 loge("Failed to generate USSD number" + e);
6753 }
6754 ResultReceiver wrappedCallback = new CallWaitingUssdResultReceiver(
6755 mMainThreadHandler, callback, carrierXmlParser, ssAction);
6756 final String ussdCommand = newUssdCommand;
6757 Executors.newSingleThreadExecutor().execute(() -> {
6758 handleUssdRequest(subId, ussdCommand, wrappedCallback);
6759 });
6760 } else {
6761 Pair<Boolean, Consumer<Integer>> arguments = Pair.create(enable,
6762 FunctionalUtils.ignoreRemoteException(callback::accept));
6763
6764 sendRequestAsync(CMD_SET_CALL_WAITING, arguments, phone, null);
6765 }
Shuo Qian4a594052020-01-23 11:59:30 -08006766 } finally {
6767 Binder.restoreCallingIdentity(identity);
6768 }
6769 }
6770
6771 /**
yinxub1bed742017-04-17 11:45:04 -07006772 * Starts a new network scan and returns the id of this scan.
yinxu504e1392017-04-12 16:03:22 -07006773 *
yinxub1bed742017-04-17 11:45:04 -07006774 * @param subId id of the subscription
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08006775 * @param renounceFineLocationAccess Set this to true if the caller would not like to receive
6776 * location related information which will be sent if the caller already possess
6777 * {@android.Manifest.permission.ACCESS_FINE_LOCATION} and do not renounce the permission
yinxub1bed742017-04-17 11:45:04 -07006778 * @param request contains the radio access networks with bands/channels to scan
6779 * @param messenger callback messenger for scan results or errors
6780 * @param binder for the purpose of auto clean when the user thread crashes
yinxu504e1392017-04-12 16:03:22 -07006781 * @return the id of the requested scan which can be used to stop the scan.
6782 */
6783 @Override
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08006784 public int requestNetworkScan(int subId, boolean renounceFineLocationAccess,
6785 NetworkScanRequest request, Messenger messenger,
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07006786 IBinder binder, String callingPackage, String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006787 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6788 mApp, subId, "requestNetworkScan");
Hall Liuf19c44f2018-11-27 14:38:17 -08006789 LocationAccessPolicy.LocationPermissionResult locationResult =
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08006790 LocationAccessPolicy.LocationPermissionResult.DENIED_HARD;
6791 if (!renounceFineLocationAccess) {
6792 locationResult = LocationAccessPolicy.checkLocationPermission(mApp,
6793 new LocationAccessPolicy.LocationPermissionQuery.Builder()
6794 .setCallingPackage(callingPackage)
6795 .setCallingFeatureId(callingFeatureId)
6796 .setCallingPid(Binder.getCallingPid())
6797 .setCallingUid(Binder.getCallingUid())
6798 .setMethod("requestNetworkScan")
6799 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
6800 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
6801 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
6802 .build());
6803 }
Hall Liub2ac8ef2019-02-28 15:56:23 -08006804 if (locationResult != LocationAccessPolicy.LocationPermissionResult.ALLOWED) {
Nathan Harold1c11dba2020-09-22 17:54:53 -07006805 SecurityException e = checkNetworkRequestForSanitizedLocationAccess(
6806 request, subId, callingPackage);
Hall Liub2ac8ef2019-02-28 15:56:23 -08006807 if (e != null) {
6808 if (locationResult == LocationAccessPolicy.LocationPermissionResult.DENIED_HARD) {
6809 throw e;
6810 } else {
Hall Liu0e5abaf2019-04-04 01:25:30 -07006811 loge(e.getMessage());
Hall Liub2ac8ef2019-02-28 15:56:23 -08006812 return TelephonyScanManager.INVALID_SCAN_ID;
6813 }
6814 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006815 }
Hall Liu912dfd32019-04-25 14:02:26 -07006816 int callingUid = Binder.getCallingUid();
6817 int callingPid = Binder.getCallingPid();
Ying Xu94a46582019-04-18 17:14:56 -07006818 final long identity = Binder.clearCallingIdentity();
6819 try {
6820 return mNetworkScanRequestTracker.startNetworkScan(
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08006821 renounceFineLocationAccess, request, messenger, binder, getPhone(subId),
Hall Liu912dfd32019-04-25 14:02:26 -07006822 callingUid, callingPid, callingPackage);
Ying Xu94a46582019-04-18 17:14:56 -07006823 } finally {
6824 Binder.restoreCallingIdentity(identity);
6825 }
yinxu504e1392017-04-12 16:03:22 -07006826 }
6827
Hall Liub2ac8ef2019-02-28 15:56:23 -08006828 private SecurityException checkNetworkRequestForSanitizedLocationAccess(
Nathan Harold1c11dba2020-09-22 17:54:53 -07006829 NetworkScanRequest request, int subId, String callingPackage) {
Rambo Wang3dee30a2022-10-20 16:52:29 +00006830 boolean hasCarrierPriv;
6831 final long identity = Binder.clearCallingIdentity();
6832 try {
6833 hasCarrierPriv = checkCarrierPrivilegesForPackage(subId, callingPackage)
6834 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
6835 } finally {
6836 Binder.restoreCallingIdentity(identity);
6837 }
Hall Liu558027f2019-05-15 19:14:05 -07006838 boolean hasNetworkScanPermission =
6839 mApp.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_SCAN)
6840 == PERMISSION_GRANTED;
6841
6842 if (!hasCarrierPriv && !hasNetworkScanPermission) {
6843 return new SecurityException("permission.NETWORK_SCAN or carrier privileges is needed"
6844 + " for network scans without location access.");
Hall Liub2ac8ef2019-02-28 15:56:23 -08006845 }
6846
6847 if (request.getSpecifiers() != null && request.getSpecifiers().length > 0) {
6848 for (RadioAccessSpecifier ras : request.getSpecifiers()) {
Hall Liub2ac8ef2019-02-28 15:56:23 -08006849 if (ras.getChannels() != null && ras.getChannels().length > 0) {
6850 return new SecurityException("Specific channels must not be"
6851 + " scanned without location access.");
6852 }
6853 }
6854 }
6855
Hall Liub2ac8ef2019-02-28 15:56:23 -08006856 return null;
6857 }
6858
yinxu504e1392017-04-12 16:03:22 -07006859 /**
6860 * Stops an existing network scan with the given scanId.
yinxub1bed742017-04-17 11:45:04 -07006861 *
6862 * @param subId id of the subscription
6863 * @param scanId id of the scan that needs to be stopped
yinxu504e1392017-04-12 16:03:22 -07006864 */
6865 @Override
6866 public void stopNetworkScan(int subId, int scanId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006867 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6868 mApp, subId, "stopNetworkScan");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006869
Hall Liu912dfd32019-04-25 14:02:26 -07006870 int callingUid = Binder.getCallingUid();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006871 final long identity = Binder.clearCallingIdentity();
6872 try {
Hall Liu912dfd32019-04-25 14:02:26 -07006873 mNetworkScanRequestTracker.stopNetworkScan(scanId, callingUid);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006874 } finally {
6875 Binder.restoreCallingIdentity(identity);
6876 }
yinxu504e1392017-04-12 16:03:22 -07006877 }
6878
6879 /**
SongFerngWang3ef3e072020-12-21 16:41:52 +08006880 * Get the allowed network types bitmask.
Junda Liu84d15a22014-07-02 11:21:04 -07006881 *
SongFerngWang3ef3e072020-12-21 16:41:52 +08006882 * @return the allowed network types bitmask, defined in RILConstants.java.
Junda Liu84d15a22014-07-02 11:21:04 -07006883 */
6884 @Override
SongFerngWang3ef3e072020-12-21 16:41:52 +08006885 public int getAllowedNetworkTypesBitmask(int subId) {
Pengquan Menga4009cb2018-12-20 11:00:24 -08006886 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07006887 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
SongFerngWang3ef3e072020-12-21 16:41:52 +08006888 mApp, subId, "getAllowedNetworkTypesBitmask");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006889
6890 final long identity = Binder.clearCallingIdentity();
6891 try {
SongFerngWang3ef3e072020-12-21 16:41:52 +08006892 if (DBG) log("getAllowedNetworkTypesBitmask");
6893 int[] result = (int[]) sendRequest(CMD_GET_ALLOWED_NETWORK_TYPES_BITMASK, null, subId);
6894 int networkTypesBitmask = (result != null ? result[0] : -1);
6895 if (DBG) log("getAllowedNetworkTypesBitmask: " + networkTypesBitmask);
6896 return networkTypesBitmask;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006897 } finally {
6898 Binder.restoreCallingIdentity(identity);
6899 }
Jake Hamby7c27be32014-03-03 13:25:59 -08006900 }
6901
6902 /**
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07006903 * Get the allowed network types for certain reason.
6904 *
6905 * @param subId the id of the subscription.
6906 * @param reason the reason the allowed network type change is taking place
6907 * @return the allowed network types.
6908 */
6909 @Override
6910 public long getAllowedNetworkTypesForReason(int subId,
6911 @TelephonyManager.AllowedNetworkTypesReason int reason) {
Nathan Harold62c68512021-04-06 11:26:02 -07006912 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
SongFerngWang8c6e82e2021-03-02 22:09:29 +08006913 mApp, subId, "getAllowedNetworkTypesForReason");
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07006914 final long identity = Binder.clearCallingIdentity();
6915 try {
6916 return getPhoneFromSubId(subId).getAllowedNetworkTypes(reason);
6917 } finally {
6918 Binder.restoreCallingIdentity(identity);
6919 }
6920 }
6921
6922 /**
Sooraj Sasindran37444802020-08-11 10:40:43 -07006923 * Enable/Disable E-UTRA-NR Dual Connectivity
6924 * @param subId subscription id of the sim card
6925 * @param nrDualConnectivityState expected NR dual connectivity state
6926 * This can be passed following states
6927 * <ol>
6928 * <li>Enable NR dual connectivity {@link TelephonyManager#NR_DUAL_CONNECTIVITY_ENABLE}
6929 * <li>Disable NR dual connectivity {@link TelephonyManager#NR_DUAL_CONNECTIVITY_DISABLE}
6930 * <li>Disable NR dual connectivity and force secondary cell to be released
6931 * {@link TelephonyManager#NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE}
6932 * </ol>
6933 * @return operation result.
6934 */
6935 @Override
6936 public int setNrDualConnectivityState(int subId,
6937 @TelephonyManager.NrDualConnectivityState int nrDualConnectivityState) {
6938 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6939 mApp, subId, "enableNRDualConnectivity");
Sooraj Sasindran0e4e00a2021-03-16 18:02:32 -07006940 if (!isRadioInterfaceCapabilitySupported(
Sooraj Sasindrandfd595b2021-03-11 17:38:13 -08006941 TelephonyManager.CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE)) {
6942 return TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED;
6943 }
6944
Sooraj Sasindran37444802020-08-11 10:40:43 -07006945 WorkSource workSource = getWorkSource(Binder.getCallingUid());
6946 final long identity = Binder.clearCallingIdentity();
6947 try {
6948 int result = (int) sendRequest(CMD_ENABLE_NR_DUAL_CONNECTIVITY,
6949 nrDualConnectivityState, subId,
6950 workSource);
6951 if (DBG) log("enableNRDualConnectivity result: " + result);
6952 return result;
6953 } finally {
6954 Binder.restoreCallingIdentity(identity);
6955 }
6956 }
6957
6958 /**
6959 * Is E-UTRA-NR Dual Connectivity enabled
6960 * @return true if dual connectivity is enabled else false
6961 */
6962 @Override
6963 public boolean isNrDualConnectivityEnabled(int subId) {
6964 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07006965 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Sooraj Sasindran37444802020-08-11 10:40:43 -07006966 mApp, subId, "isNRDualConnectivityEnabled");
Sooraj Sasindran0e4e00a2021-03-16 18:02:32 -07006967 if (!isRadioInterfaceCapabilitySupported(
Sooraj Sasindrandfd595b2021-03-11 17:38:13 -08006968 TelephonyManager.CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE)) {
6969 return false;
6970 }
Sooraj Sasindran37444802020-08-11 10:40:43 -07006971 WorkSource workSource = getWorkSource(Binder.getCallingUid());
6972 final long identity = Binder.clearCallingIdentity();
6973 try {
6974 boolean isEnabled = (boolean) sendRequest(CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED,
6975 null, subId, workSource);
6976 if (DBG) log("isNRDualConnectivityEnabled: " + isEnabled);
6977 return isEnabled;
6978 } finally {
6979 Binder.restoreCallingIdentity(identity);
6980 }
6981 }
6982
6983 /**
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07006984 * Set the allowed network types of the device and
6985 * provide the reason triggering the allowed network change.
6986 *
6987 * @param subId the id of the subscription.
6988 * @param reason the reason the allowed network type change is taking place
6989 * @param allowedNetworkTypes the allowed network types.
6990 * @return true on success; false on any failure.
6991 */
6992 @Override
6993 public boolean setAllowedNetworkTypesForReason(int subId,
SongFerngWang3ef3e072020-12-21 16:41:52 +08006994 @TelephonyManager.AllowedNetworkTypesReason int reason,
6995 @TelephonyManager.NetworkTypeBitMask long allowedNetworkTypes) {
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07006996 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6997 mApp, subId, "setAllowedNetworkTypesForReason");
Gil Cukierman1d3d3752022-10-03 21:31:33 +00006998 // If the caller only has carrier privileges, then they should not be able to override
6999 // any network types which were set for security reasons.
7000 if (mApp.checkCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE)
7001 != PERMISSION_GRANTED
Gil Cukierman2a8f48b2023-01-26 20:26:20 +00007002 && reason == TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G) {
Gil Cukierman1d3d3752022-10-03 21:31:33 +00007003 throw new SecurityException(
7004 "setAllowedNetworkTypesForReason cannot be called with carrier privileges for"
Gil Cukierman2a8f48b2023-01-26 20:26:20 +00007005 + " reason " + reason);
Gil Cukierman1d3d3752022-10-03 21:31:33 +00007006 }
SongFerngWang3ef3e072020-12-21 16:41:52 +08007007 if (!TelephonyManager.isValidAllowedNetworkTypesReason(reason)) {
Jack Yu5b494332023-01-23 18:18:04 +00007008 loge("setAllowedNetworkTypesForReason: Invalid allowed network type reason: " + reason);
SongFerngWang7ffc2732021-04-15 19:46:33 +08007009 return false;
7010 }
7011 if (!SubscriptionManager.isUsableSubscriptionId(subId)) {
7012 loge("setAllowedNetworkTypesForReason: Invalid subscriptionId:" + subId);
SongFerngWang3ef3e072020-12-21 16:41:52 +08007013 return false;
7014 }
7015
Jack Yu5b494332023-01-23 18:18:04 +00007016 log("setAllowedNetworkTypesForReason: subId=" + subId + ", reason=" + reason + " value: "
7017 + TelephonyManager.convertNetworkTypeBitmaskToString(allowedNetworkTypes));
SongFerngWang8c6e82e2021-03-02 22:09:29 +08007018
Jack Yue37dd262022-12-16 11:53:37 -08007019 Phone phone = getPhone(subId);
7020 if (phone == null) {
7021 return false;
7022 }
SongFerngWang8c6e82e2021-03-02 22:09:29 +08007023
Jack Yue37dd262022-12-16 11:53:37 -08007024 if (allowedNetworkTypes == phone.getAllowedNetworkTypes(reason)) {
Jack Yu5b494332023-01-23 18:18:04 +00007025 log("setAllowedNetworkTypesForReason: " + reason + "does not change value");
SongFerngWang8c6e82e2021-03-02 22:09:29 +08007026 return true;
SongFerngWang3ef3e072020-12-21 16:41:52 +08007027 }
SongFerngWang8c6e82e2021-03-02 22:09:29 +08007028
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07007029 final long identity = Binder.clearCallingIdentity();
7030 try {
SongFerngWang3ef3e072020-12-21 16:41:52 +08007031 Boolean success = (Boolean) sendRequest(
7032 CMD_SET_ALLOWED_NETWORK_TYPES_FOR_REASON,
7033 new Pair<Integer, Long>(reason, allowedNetworkTypes), subId);
7034
7035 if (DBG) log("setAllowedNetworkTypesForReason: " + (success ? "ok" : "fail"));
7036 return success;
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07007037 } finally {
7038 Binder.restoreCallingIdentity(identity);
7039 }
7040 }
7041
7042 /**
Miaoa84611c2019-03-15 09:21:10 +08007043 * Check whether DUN APN is required for tethering with subId.
Junda Liu475951f2014-11-07 16:45:03 -08007044 *
Miaoa84611c2019-03-15 09:21:10 +08007045 * @param subId the id of the subscription to require tethering.
Amit Mahajanfe58cdf2017-07-11 12:01:53 -07007046 * @return {@code true} if DUN APN is required for tethering.
Junda Liu475951f2014-11-07 16:45:03 -08007047 * @hide
7048 */
7049 @Override
SongFerngWangf08d8122019-11-15 14:58:44 +08007050 public boolean isTetheringApnRequiredForSubscriber(int subId) {
Shishir Agrawalc04d9752016-02-19 10:41:00 -08007051 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007052 final long identity = Binder.clearCallingIdentity();
Miaoa84611c2019-03-15 09:21:10 +08007053 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007054 try {
Miaoa84611c2019-03-15 09:21:10 +08007055 if (phone != null) {
7056 return phone.hasMatchedTetherApnSetting();
7057 } else {
7058 return false;
7059 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007060 } finally {
7061 Binder.restoreCallingIdentity(identity);
Junda Liu475951f2014-11-07 16:45:03 -08007062 }
Junda Liu475951f2014-11-07 16:45:03 -08007063 }
7064
7065 /**
Malcolm Chen964682d2017-11-28 16:20:07 -08007066 * Get the user enabled state of Mobile Data.
7067 *
7068 * TODO: remove and use isUserDataEnabled.
7069 * This can't be removed now because some vendor codes
7070 * calls through ITelephony directly while they should
7071 * use TelephonyManager.
7072 *
7073 * @return true on enabled
7074 */
7075 @Override
7076 public boolean getDataEnabled(int subId) {
7077 return isUserDataEnabled(subId);
7078 }
7079
7080 /**
7081 * Get whether mobile data is enabled per user setting.
7082 *
7083 * There are other factors deciding whether mobile data is actually enabled, but they are
7084 * not considered here. See {@link #isDataEnabled(int)} for more details.
Robert Greenwalt646120a2014-05-23 11:54:03 -07007085 *
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007086 * Accepts either READ_BASIC_PHONE_STATE, ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE
7087 * or carrier privileges.
Robert Greenwalted86e582014-05-21 20:03:20 -07007088 *
7089 * @return {@code true} if data is enabled else {@code false}
7090 */
7091 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08007092 public boolean isUserDataEnabled(int subId) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007093 String functionName = "isUserDataEnabled";
Robert Greenwalt646120a2014-05-23 11:54:03 -07007094 try {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007095 try {
7096 mApp.enforceCallingOrSelfPermission(permission.READ_BASIC_PHONE_STATE,
7097 functionName);
Sooraj Sasindran12545cc2022-08-22 14:30:25 -07007098 } catch (SecurityException e) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007099 mApp.enforceCallingOrSelfPermission(permission.ACCESS_NETWORK_STATE, functionName);
7100 }
Sooraj Sasindran12545cc2022-08-22 14:30:25 -07007101 } catch (SecurityException e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08007102 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007103 mApp, subId, functionName);
7104
Robert Greenwalt646120a2014-05-23 11:54:03 -07007105 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007106
7107 final long identity = Binder.clearCallingIdentity();
7108 try {
Jack Yu285100e2022-12-02 22:48:35 -08007109 int phoneId = SubscriptionManager.getPhoneId(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007110 if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
7111 Phone phone = PhoneFactory.getPhone(phoneId);
7112 if (phone != null) {
7113 boolean retVal = phone.isUserDataEnabled();
7114 if (DBG) log("isUserDataEnabled: subId=" + subId + " retVal=" + retVal);
7115 return retVal;
7116 } else {
7117 if (DBG) loge("isUserDataEnabled: no phone subId=" + subId + " retVal=false");
7118 return false;
7119 }
7120 } finally {
7121 Binder.restoreCallingIdentity(identity);
Malcolm Chen964682d2017-11-28 16:20:07 -08007122 }
7123 }
7124
7125 /**
Shuo Qian8ee4e882020-01-08 14:30:06 -08007126 * Checks if the device is capable of mobile data by considering whether whether the
7127 * user has enabled mobile data, whether the carrier has enabled mobile data, and
7128 * whether the network policy allows data connections.
Malcolm Chen964682d2017-11-28 16:20:07 -08007129 *
Shuo Qian8ee4e882020-01-08 14:30:06 -08007130 * @return {@code true} if the overall data connection is capable; {@code false} if not.
Malcolm Chen964682d2017-11-28 16:20:07 -08007131 */
7132 @Override
7133 public boolean isDataEnabled(int subId) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007134 String functionName = "isDataEnabled";
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07007135 try {
7136 try {
7137 mApp.enforceCallingOrSelfPermission(
7138 android.Manifest.permission.ACCESS_NETWORK_STATE,
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007139 functionName);
Sooraj Sasindran12545cc2022-08-22 14:30:25 -07007140 } catch (SecurityException e) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007141 try {
7142 mApp.enforceCallingOrSelfPermission(
7143 android.Manifest.permission.READ_PHONE_STATE,
7144 functionName);
Sooraj Sasindran12545cc2022-08-22 14:30:25 -07007145 } catch (SecurityException e2) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007146 mApp.enforceCallingOrSelfPermission(
7147 permission.READ_BASIC_PHONE_STATE, functionName);
7148 }
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07007149 }
Sooraj Sasindran12545cc2022-08-22 14:30:25 -07007150 } catch (SecurityException e) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007151 enforceReadPrivilegedPermission(functionName);
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07007152 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007153
7154 final long identity = Binder.clearCallingIdentity();
7155 try {
Jack Yu285100e2022-12-02 22:48:35 -08007156 int phoneId = SubscriptionManager.getPhoneId(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007157 Phone phone = PhoneFactory.getPhone(phoneId);
7158 if (phone != null) {
Sarah Chine04784a2022-10-31 20:32:34 -07007159 boolean retVal = phone.getDataSettingsManager().isDataEnabled();
Jack Yu4ad64e52021-12-03 14:23:53 -08007160 if (DBG) log("isDataEnabled: " + retVal + ", subId=" + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007161 return retVal;
7162 } else {
7163 if (DBG) loge("isDataEnabled: no phone subId=" + subId + " retVal=false");
7164 return false;
7165 }
7166 } finally {
7167 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08007168 }
Robert Greenwalted86e582014-05-21 20:03:20 -07007169 }
Shishir Agrawal60f9c952014-06-23 12:00:43 -07007170
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007171 /**
7172 * Check if data is enabled for a specific reason
7173 * @param subId Subscription index
7174 * @param reason the reason the data enable change is taking place
7175 * @return {@code true} if the overall data is enabled; {@code false} if not.
7176 */
7177 @Override
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07007178 public boolean isDataEnabledForReason(int subId,
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007179 @TelephonyManager.DataEnabledReason int reason) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007180 String functionName = "isDataEnabledForReason";
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007181 try {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007182 try {
7183 mApp.enforceCallingOrSelfPermission(
7184 android.Manifest.permission.ACCESS_NETWORK_STATE,
7185 functionName);
Sooraj Sasindran12545cc2022-08-22 14:30:25 -07007186 } catch (SecurityException e) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007187 mApp.enforceCallingOrSelfPermission(permission.READ_BASIC_PHONE_STATE,
7188 functionName);
7189 }
Sooraj Sasindran12545cc2022-08-22 14:30:25 -07007190 } catch (SecurityException e) {
Sooraj Sasindran0d909a02021-11-08 12:01:16 -08007191 try {
7192 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE,
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007193 functionName);
Sooraj Sasindran12545cc2022-08-22 14:30:25 -07007194 } catch (SecurityException e2) {
Sooraj Sasindran0d909a02021-11-08 12:01:16 -08007195 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007196 mApp, subId, functionName);
Sooraj Sasindran0d909a02021-11-08 12:01:16 -08007197 }
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007198 }
7199
7200
7201 final long identity = Binder.clearCallingIdentity();
7202 try {
Jack Yu285100e2022-12-02 22:48:35 -08007203 int phoneId = SubscriptionManager.getPhoneId(subId);
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007204 if (DBG) {
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07007205 log("isDataEnabledForReason: subId=" + subId + " phoneId=" + phoneId
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007206 + " reason=" + reason);
7207 }
7208 Phone phone = PhoneFactory.getPhone(phoneId);
7209 if (phone != null) {
7210 boolean retVal;
Jack Yu7968c6d2022-07-31 00:43:21 -07007211 retVal = phone.getDataSettingsManager().isDataEnabledForReason(reason);
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07007212 if (DBG) log("isDataEnabledForReason: retVal=" + retVal);
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007213 return retVal;
7214 } else {
7215 if (DBG) {
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07007216 loge("isDataEnabledForReason: no phone subId="
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007217 + subId + " retVal=false");
7218 }
7219 return false;
7220 }
7221 } finally {
7222 Binder.restoreCallingIdentity(identity);
7223 }
7224 }
7225
Shishir Agrawal60f9c952014-06-23 12:00:43 -07007226 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08007227 public int getCarrierPrivilegeStatus(int subId) {
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007228 // No permission needed; this only lets the caller inspect their own status.
7229 return getCarrierPrivilegeStatusForUidWithPermission(subId, Binder.getCallingUid());
Shishir Agrawal60f9c952014-06-23 12:00:43 -07007230 }
Junda Liu29340342014-07-10 15:23:27 -07007231
7232 @Override
Jeff Davidson7e17e312018-02-13 18:17:36 -08007233 public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08007234 enforceReadPrivilegedPermission("getCarrierPrivilegeStatusForUid");
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007235 return getCarrierPrivilegeStatusForUidWithPermission(subId, uid);
7236 }
7237
7238 private int getCarrierPrivilegeStatusForUidWithPermission(int subId, int uid) {
7239 Phone phone = getPhone(subId);
Jeff Davidson7e17e312018-02-13 18:17:36 -08007240 if (phone == null) {
Taesu Leef8fbed92019-10-07 18:47:02 +09007241 loge("getCarrierPrivilegeStatusForUid: Invalid subId");
Jeff Davidson7e17e312018-02-13 18:17:36 -08007242 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
7243 }
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007244 CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7245 if (cpt == null) {
7246 loge("getCarrierPrivilegeStatusForUid: No CarrierPrivilegesTracker");
Jeff Davidson7e17e312018-02-13 18:17:36 -08007247 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
7248 }
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007249 return cpt.getCarrierPrivilegeStatusForUid(uid);
Jeff Davidson7e17e312018-02-13 18:17:36 -08007250 }
7251
7252 @Override
chen xuf7e9fe82019-05-09 19:31:02 -07007253 public int checkCarrierPrivilegesForPackage(int subId, String pkgName) {
Nazanin1adf4562021-03-29 15:35:30 -07007254 enforceReadPrivilegedPermission("checkCarrierPrivilegesForPackage");
chen xuf7e9fe82019-05-09 19:31:02 -07007255 if (TextUtils.isEmpty(pkgName)) {
Junda Liu317d70b2016-03-08 09:33:53 -08007256 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
chen xuf7e9fe82019-05-09 19:31:02 -07007257 }
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007258 Phone phone = getPhone(subId);
7259 if (phone == null) {
7260 loge("checkCarrierPrivilegesForPackage: Invalid subId");
7261 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
7262 }
7263 CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7264 if (cpt == null) {
7265 loge("checkCarrierPrivilegesForPackage: No CarrierPrivilegesTracker");
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07007266 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
7267 }
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007268 return cpt.getCarrierPrivilegeStatusForPackage(pkgName);
Zach Johnson50ecba32015-05-19 00:24:21 -07007269 }
7270
7271 @Override
7272 public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007273 enforceReadPrivilegedPermission("checkCarrierPrivilegesForPackageAnyPhone");
Rambo Wange7209ce2022-02-23 13:41:02 -08007274 return checkCarrierPrivilegesForPackageAnyPhoneWithPermission(pkgName);
7275 }
7276
7277 private int checkCarrierPrivilegesForPackageAnyPhoneWithPermission(String pkgName) {
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007278 if (TextUtils.isEmpty(pkgName)) {
Junda Liu317d70b2016-03-08 09:33:53 -08007279 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007280 }
Zach Johnson50ecba32015-05-19 00:24:21 -07007281 int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007282 for (int phoneId = 0; phoneId < TelephonyManager.getDefault().getPhoneCount(); phoneId++) {
7283 Phone phone = PhoneFactory.getPhone(phoneId);
7284 if (phone == null) {
7285 continue;
Zach Johnson50ecba32015-05-19 00:24:21 -07007286 }
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007287 CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7288 if (cpt == null) {
7289 continue;
7290 }
7291 result = cpt.getCarrierPrivilegeStatusForPackage(pkgName);
Zach Johnson50ecba32015-05-19 00:24:21 -07007292 if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
7293 break;
7294 }
7295 }
Zach Johnson50ecba32015-05-19 00:24:21 -07007296 return result;
Junda Liu29340342014-07-10 15:23:27 -07007297 }
Derek Tan89e89d42014-07-08 17:00:10 -07007298
7299 @Override
Junda Liue64de782015-04-16 17:19:16 -07007300 public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
Nazanin1adf4562021-03-29 15:35:30 -07007301 enforceReadPrivilegedPermission("getCarrierPackageNamesForIntentAndPhone");
Rambo Wang8a247eb2022-02-08 21:11:18 +00007302 Phone phone = PhoneFactory.getPhone(phoneId);
7303 if (phone == null) {
7304 return Collections.emptyList();
Junda Liue64de782015-04-16 17:19:16 -07007305 }
Rambo Wang8a247eb2022-02-08 21:11:18 +00007306 CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7307 if (cpt == null) {
7308 return Collections.emptyList();
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07007309 }
Rambo Wang8a247eb2022-02-08 21:11:18 +00007310 return cpt.getCarrierPackageNamesForIntent(intent);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07007311 }
7312
Amith Yamasani6e118872016-02-19 12:53:51 -08007313 @Override
chen xuf7e9fe82019-05-09 19:31:02 -07007314 public List<String> getPackagesWithCarrierPrivileges(int phoneId) {
Nazanin1adf4562021-03-29 15:35:30 -07007315 enforceReadPrivilegedPermission("getPackagesWithCarrierPrivileges");
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007316 Phone phone = PhoneFactory.getPhone(phoneId);
7317 if (phone == null) {
7318 return Collections.emptyList();
Amith Yamasani6e118872016-02-19 12:53:51 -08007319 }
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007320 CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7321 if (cpt == null) {
7322 return Collections.emptyList();
7323 }
7324 return new ArrayList<>(cpt.getPackagesWithCarrierPrivileges());
Amith Yamasani6e118872016-02-19 12:53:51 -08007325 }
7326
chen xuf7e9fe82019-05-09 19:31:02 -07007327 @Override
7328 public List<String> getPackagesWithCarrierPrivilegesForAllPhones() {
Shuo Qian067a06d2019-12-03 23:40:18 +00007329 enforceReadPrivilegedPermission("getPackagesWithCarrierPrivilegesForAllPhones");
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007330 Set<String> privilegedPackages = new ArraySet<>();
Shuo Qian067a06d2019-12-03 23:40:18 +00007331 final long identity = Binder.clearCallingIdentity();
Shuo Qian067a06d2019-12-03 23:40:18 +00007332 try {
7333 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
7334 privilegedPackages.addAll(getPackagesWithCarrierPrivileges(i));
7335 }
7336 } finally {
7337 Binder.restoreCallingIdentity(identity);
chen xuf7e9fe82019-05-09 19:31:02 -07007338 }
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007339 return new ArrayList<>(privilegedPackages);
chen xuf7e9fe82019-05-09 19:31:02 -07007340 }
7341
Rambo Wang6812ffb2022-03-15 16:54:17 -07007342 @Override
7343 public @Nullable String getCarrierServicePackageNameForLogicalSlot(int logicalSlotIndex) {
7344 enforceReadPrivilegedPermission("getCarrierServicePackageNameForLogicalSlot");
7345
7346 final Phone phone = PhoneFactory.getPhone(logicalSlotIndex);
7347 if (phone == null) {
7348 return null;
7349 }
7350 final CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7351 if (cpt == null) {
7352 return null;
7353 }
7354 return cpt.getCarrierServicePackageName();
7355 }
7356
Wink Savilleb564aae2014-10-23 10:18:09 -07007357 private String getIccId(int subId) {
Sanket Padawe356d7632015-06-22 14:03:32 -07007358 final Phone phone = getPhone(subId);
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00007359 UiccPort port = phone == null ? null : phone.getUiccPort();
7360 if (port == null) {
Derek Tan97ebb422014-09-05 16:55:38 -07007361 return null;
7362 }
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00007363 String iccId = port.getIccId();
Derek Tan97ebb422014-09-05 16:55:38 -07007364 if (TextUtils.isEmpty(iccId)) {
Derek Tan97ebb422014-09-05 16:55:38 -07007365 return null;
7366 }
7367 return iccId;
7368 }
7369
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07007370 @Override
Shuo Qiane4e11672020-12-15 22:15:33 -08007371 public void setCallComposerStatus(int subId, int status) {
7372 enforceModifyPermission();
7373
7374 final long identity = Binder.clearCallingIdentity();
7375 try {
7376 Phone phone = getPhone(subId);
7377 if (phone != null) {
7378 Phone defaultPhone = phone.getImsPhone();
7379 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
7380 ImsPhone imsPhone = (ImsPhone) defaultPhone;
7381 imsPhone.setCallComposerStatus(status);
Shuo Qian284ae752020-12-22 19:10:14 -08007382 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
7383 .updateImsServiceConfig();
Shuo Qiane4e11672020-12-15 22:15:33 -08007384 }
7385 }
Shuo Qian284ae752020-12-22 19:10:14 -08007386 } catch (ImsException e) {
7387 throw new ServiceSpecificException(e.getCode());
7388 } finally {
Shuo Qiane4e11672020-12-15 22:15:33 -08007389 Binder.restoreCallingIdentity(identity);
7390 }
7391 }
7392
7393 @Override
7394 public int getCallComposerStatus(int subId) {
7395 enforceReadPrivilegedPermission("getCallComposerStatus");
7396
7397 final long identity = Binder.clearCallingIdentity();
7398 try {
7399 Phone phone = getPhone(subId);
7400 if (phone != null) {
7401 Phone defaultPhone = phone.getImsPhone();
7402 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
7403 ImsPhone imsPhone = (ImsPhone) defaultPhone;
7404 return imsPhone.getCallComposerStatus();
7405 }
7406 }
7407 } finally {
7408 Binder.restoreCallingIdentity(identity);
7409 }
7410 return TelephonyManager.CALL_COMPOSER_STATUS_OFF;
7411 }
7412
7413 @Override
Jeff Sharkey85190e62014-12-05 09:40:12 -08007414 public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
7415 String number) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08007416 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
Jeff Davidson7e17e312018-02-13 18:17:36 -08007417 subId, "setLine1NumberForDisplayForSubscriber");
Derek Tan97ebb422014-09-05 16:55:38 -07007418
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007419 final long identity = Binder.clearCallingIdentity();
7420 try {
7421 final String iccId = getIccId(subId);
7422 final Phone phone = getPhone(subId);
7423 if (phone == null) {
7424 return false;
7425 }
7426 final String subscriberId = phone.getSubscriberId();
7427
7428 if (DBG_MERGE) {
Amit Mahajanb8f13202020-01-27 18:16:07 -08007429 Rlog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId="
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007430 + subscriberId + " to " + number);
7431 }
7432
7433 if (TextUtils.isEmpty(iccId)) {
7434 return false;
7435 }
7436
7437 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
7438
7439 final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
7440 if (alphaTag == null) {
7441 editor.remove(alphaTagPrefKey);
7442 } else {
7443 editor.putString(alphaTagPrefKey, alphaTag);
7444 }
7445
7446 // Record both the line number and IMSI for this ICCID, since we need to
7447 // track all merged IMSIs based on line number
7448 final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
7449 final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
7450 if (number == null) {
7451 editor.remove(numberPrefKey);
7452 editor.remove(subscriberPrefKey);
7453 } else {
7454 editor.putString(numberPrefKey, number);
7455 editor.putString(subscriberPrefKey, subscriberId);
7456 }
7457
7458 editor.commit();
7459 return true;
7460 } finally {
7461 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07007462 }
Derek Tan7226c842014-07-02 17:42:23 -07007463 }
7464
7465 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007466 public String getLine1NumberForDisplay(int subId, String callingPackage,
7467 String callingFeatureId) {
Makoto Onukifee69342015-06-29 14:44:50 -07007468 // This is open to apps with WRITE_SMS.
Jeff Davidson7e17e312018-02-13 18:17:36 -08007469 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007470 mApp, subId, callingPackage, callingFeatureId, "getLine1NumberForDisplay")) {
Amit Mahajan9cf11512015-11-09 11:40:48 -08007471 if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
Svet Ganovb320e182015-04-16 12:30:10 -07007472 return null;
7473 }
Derek Tan97ebb422014-09-05 16:55:38 -07007474
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007475 final long identity = Binder.clearCallingIdentity();
7476 try {
7477 String iccId = getIccId(subId);
7478 if (iccId != null) {
7479 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
7480 if (DBG_MERGE) {
7481 log("getLine1NumberForDisplay returning "
7482 + mTelephonySharedPreferences.getString(numberPrefKey, null));
7483 }
7484 return mTelephonySharedPreferences.getString(numberPrefKey, null);
Amit Mahajan9cf11512015-11-09 11:40:48 -08007485 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007486 if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null");
7487 return null;
7488 } finally {
7489 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07007490 }
Derek Tan7226c842014-07-02 17:42:23 -07007491 }
7492
7493 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007494 public String getLine1AlphaTagForDisplay(int subId, String callingPackage,
7495 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08007496 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007497 mApp, subId, callingPackage, callingFeatureId, "getLine1AlphaTagForDisplay")) {
Svet Ganovb320e182015-04-16 12:30:10 -07007498 return null;
7499 }
Derek Tan97ebb422014-09-05 16:55:38 -07007500
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007501 final long identity = Binder.clearCallingIdentity();
7502 try {
7503 String iccId = getIccId(subId);
7504 if (iccId != null) {
7505 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
7506 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null);
7507 }
7508 return null;
7509 } finally {
7510 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07007511 }
Derek Tan7226c842014-07-02 17:42:23 -07007512 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07007513
7514 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007515 public String[] getMergedSubscriberIds(int subId, String callingPackage,
7516 String callingFeatureId) {
Jeff Davidson913390f2018-02-23 17:11:49 -08007517 // This API isn't public, so no need to provide a valid subscription ID - we're not worried
7518 // about carrier-privileged callers not having access.
Jeff Davidson7e17e312018-02-13 18:17:36 -08007519 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08007520 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007521 callingFeatureId, "getMergedSubscriberIds")) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07007522 return null;
7523 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08007524
Jordan Liub49b04b2019-05-06 14:45:15 -07007525 // Clear calling identity, when calling TelephonyManager, because callerUid must be
7526 // the process, where TelephonyManager was instantiated.
7527 // Otherwise AppOps check will fail.
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07007528 final long identity = Binder.clearCallingIdentity();
7529 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007530 final Context context = mApp;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007531 final TelephonyManager tele = TelephonyManager.from(context);
7532 final SubscriptionManager sub = SubscriptionManager.from(context);
7533
7534 // Figure out what subscribers are currently active
7535 final ArraySet<String> activeSubscriberIds = new ArraySet<>();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007536
Jordan Liub49b04b2019-05-06 14:45:15 -07007537 // Only consider subs which match the current subId
7538 // This logic can be simplified. See b/131189269 for progress.
7539 if (isActiveSubscription(subId)) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07007540 activeSubscriberIds.add(tele.getSubscriberId(subId));
7541 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007542
7543 // First pass, find a number override for an active subscriber
7544 String mergeNumber = null;
7545 final Map<String, ?> prefs = mTelephonySharedPreferences.getAll();
7546 for (String key : prefs.keySet()) {
7547 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) {
7548 final String subscriberId = (String) prefs.get(key);
7549 if (activeSubscriberIds.contains(subscriberId)) {
7550 final String iccId = key.substring(
7551 PREF_CARRIERS_SUBSCRIBER_PREFIX.length());
7552 final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
7553 mergeNumber = (String) prefs.get(numberKey);
7554 if (DBG_MERGE) {
Amit Mahajanb8f13202020-01-27 18:16:07 -08007555 Rlog.d(LOG_TAG, "Found line number " + mergeNumber
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007556 + " for active subscriber " + subscriberId);
7557 }
7558 if (!TextUtils.isEmpty(mergeNumber)) {
7559 break;
7560 }
7561 }
7562 }
7563 }
7564
7565 // Shortcut when no active merged subscribers
7566 if (TextUtils.isEmpty(mergeNumber)) {
7567 return null;
7568 }
7569
7570 // Second pass, find all subscribers under that line override
7571 final ArraySet<String> result = new ArraySet<>();
7572 for (String key : prefs.keySet()) {
7573 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) {
7574 final String number = (String) prefs.get(key);
7575 if (mergeNumber.equals(number)) {
7576 final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length());
7577 final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
7578 final String subscriberId = (String) prefs.get(subscriberKey);
7579 if (!TextUtils.isEmpty(subscriberId)) {
7580 result.add(subscriberId);
7581 }
7582 }
7583 }
7584 }
7585
7586 final String[] resultArray = result.toArray(new String[result.size()]);
7587 Arrays.sort(resultArray);
7588 if (DBG_MERGE) {
Amit Mahajanb8f13202020-01-27 18:16:07 -08007589 Rlog.d(LOG_TAG,
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007590 "Found subscribers " + Arrays.toString(resultArray) + " after merge");
7591 }
7592 return resultArray;
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07007593 } finally {
7594 Binder.restoreCallingIdentity(identity);
Jeff Sharkey85190e62014-12-05 09:40:12 -08007595 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08007596 }
7597
7598 @Override
zoey chen38003472019-12-13 17:16:31 +08007599 public String[] getMergedImsisFromGroup(int subId, String callingPackage) {
7600 enforceReadPrivilegedPermission("getMergedImsisFromGroup");
Malcolm Chen6ca97372019-07-01 16:28:21 -07007601
7602 final long identity = Binder.clearCallingIdentity();
7603 try {
7604 final TelephonyManager telephonyManager = mApp.getSystemService(
7605 TelephonyManager.class);
7606 String subscriberId = telephonyManager.getSubscriberId(subId);
7607 if (subscriberId == null) {
7608 if (DBG) {
zoey chen38003472019-12-13 17:16:31 +08007609 log("getMergedImsisFromGroup can't find subscriberId for subId "
Malcolm Chen6ca97372019-07-01 16:28:21 -07007610 + subId);
7611 }
7612 return null;
7613 }
7614
Jack Yu285100e2022-12-02 22:48:35 -08007615 ParcelUuid groupUuid;
7616 if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
7617 final SubscriptionInfo info = SubscriptionManagerService.getInstance()
7618 .getSubscriptionInfo(subId);
7619 groupUuid = info.getGroupUuid();
7620 } else {
7621 final SubscriptionInfo info = mSubscriptionController
7622 .getSubscriptionInfo(subId);
7623 groupUuid = info.getGroupUuid();
7624 }
Malcolm Chen6ca97372019-07-01 16:28:21 -07007625 // If it doesn't belong to any group, return just subscriberId of itself.
7626 if (groupUuid == null) {
7627 return new String[]{subscriberId};
7628 }
7629
7630 // Get all subscriberIds from the group.
7631 final List<String> mergedSubscriberIds = new ArrayList<>();
Jack Yu285100e2022-12-02 22:48:35 -08007632 List<SubscriptionInfo> groupInfos;
7633 if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
7634 groupInfos = SubscriptionManagerService.getInstance()
7635 .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName(),
7636 mApp.getAttributionTag());
7637 } else {
7638 groupInfos = mSubscriptionController
7639 .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName(),
7640 mApp.getAttributionTag());
7641 }
Malcolm Chen6ca97372019-07-01 16:28:21 -07007642 for (SubscriptionInfo subInfo : groupInfos) {
7643 subscriberId = telephonyManager.getSubscriberId(subInfo.getSubscriptionId());
7644 if (subscriberId != null) {
7645 mergedSubscriberIds.add(subscriberId);
7646 }
7647 }
7648
7649 return mergedSubscriberIds.toArray(new String[mergedSubscriberIds.size()]);
7650 } finally {
7651 Binder.restoreCallingIdentity(identity);
7652
7653 }
7654 }
7655
7656 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08007657 public boolean setOperatorBrandOverride(int subId, String brand) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08007658 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
Jeff Davidson7e17e312018-02-13 18:17:36 -08007659 subId, "setOperatorBrandOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007660
7661 final long identity = Binder.clearCallingIdentity();
7662 try {
7663 final Phone phone = getPhone(subId);
7664 return phone == null ? false : phone.setOperatorBrandOverride(brand);
7665 } finally {
7666 Binder.restoreCallingIdentity(identity);
7667 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07007668 }
Steven Liu4bf01bc2014-07-17 11:05:29 -05007669
7670 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08007671 public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
Shishir Agrawal621a47c2014-12-01 10:25:09 -08007672 List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
7673 List<String> cdmaNonRoamingList) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08007674 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
7675 mApp, subId, "setRoamingOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007676
7677 final long identity = Binder.clearCallingIdentity();
7678 try {
7679 final Phone phone = getPhone(subId);
7680 if (phone == null) {
7681 return false;
7682 }
7683 return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList,
7684 cdmaNonRoamingList);
7685 } finally {
7686 Binder.restoreCallingIdentity(identity);
Shishir Agrawalc04d9752016-02-19 10:41:00 -08007687 }
Shishir Agrawal621a47c2014-12-01 10:25:09 -08007688 }
7689
7690 @Override
Shuo Qian850e4d6a2018-04-25 21:02:08 +00007691 @Deprecated
7692 public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
7693 enforceModifyPermission();
7694
7695 int returnValue = 0;
7696 try {
vagdeviaf9a5b92018-08-15 16:01:53 -07007697 AsyncResult result = (AsyncResult) sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
Shuo Qian850e4d6a2018-04-25 21:02:08 +00007698 if(result.exception == null) {
7699 if (result.result != null) {
7700 byte[] responseData = (byte[])(result.result);
7701 if(responseData.length > oemResp.length) {
7702 Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +
7703 responseData.length + "bytes. Buffer Size is " +
7704 oemResp.length + "bytes.");
7705 }
7706 System.arraycopy(responseData, 0, oemResp, 0, responseData.length);
7707 returnValue = responseData.length;
7708 }
7709 } else {
7710 CommandException ex = (CommandException) result.exception;
7711 returnValue = ex.getCommandError().ordinal();
7712 if(returnValue > 0) returnValue *= -1;
7713 }
7714 } catch (RuntimeException e) {
7715 Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");
7716 returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());
7717 if(returnValue > 0) returnValue *= -1;
7718 }
7719
7720 return returnValue;
7721 }
7722
7723 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07007724 public int getRadioAccessFamily(int phoneId, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08007725 Phone phone = PhoneFactory.getPhone(phoneId);
Shuo Qiandee53402020-05-29 14:08:15 -07007726 try {
7727 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07007728 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Shuo Qiandee53402020-05-29 14:08:15 -07007729 mApp, phone.getSubId(), "getRadioAccessFamily");
7730 } catch (SecurityException e) {
7731 EventLog.writeEvent(0x534e4554, "150857259", -1, "Missing Permission");
7732 throw e;
7733 }
chen xub97461a2018-10-26 14:17:57 -07007734 int raf = RadioAccessFamily.RAF_UNKNOWN;
Jeff Davidson913390f2018-02-23 17:11:49 -08007735 if (phone == null) {
chen xub97461a2018-10-26 14:17:57 -07007736 return raf;
Jeff Davidson913390f2018-02-23 17:11:49 -08007737 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007738 final long identity = Binder.clearCallingIdentity();
7739 try {
chen xub97461a2018-10-26 14:17:57 -07007740 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07007741 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
chen xub97461a2018-10-26 14:17:57 -07007742 mApp, phone.getSubId(), "getRadioAccessFamily");
7743 raf = ProxyController.getInstance().getRadioAccessFamily(phoneId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007744 } finally {
7745 Binder.restoreCallingIdentity(identity);
7746 }
chen xub97461a2018-10-26 14:17:57 -07007747 return raf;
Wink Saville5d475dd2014-10-17 15:00:58 -07007748 }
Andrew Leedf14ead2014-10-17 14:22:52 -07007749
7750 @Override
Hall Liu82694d52020-12-11 18:22:04 -08007751 public void uploadCallComposerPicture(int subscriptionId, String callingPackage,
Hall Liue31bac62020-12-23 19:16:10 -08007752 String contentType, ParcelFileDescriptor fd, ResultReceiver callback) {
Hall Liu82694d52020-12-11 18:22:04 -08007753 try {
7754 if (!Objects.equals(mApp.getPackageManager().getPackageUid(callingPackage, 0),
7755 Binder.getCallingUid())) {
Tyler Gunnb87925a2021-06-10 14:54:27 -07007756 throw new SecurityException("Invalid package:" + callingPackage);
Hall Liu82694d52020-12-11 18:22:04 -08007757 }
7758 } catch (PackageManager.NameNotFoundException e) {
Tyler Gunnb87925a2021-06-10 14:54:27 -07007759 throw new SecurityException("Invalid package:" + callingPackage);
Hall Liu82694d52020-12-11 18:22:04 -08007760 }
7761 RoleManager rm = mApp.getSystemService(RoleManager.class);
7762 List<String> dialerRoleHolders = rm.getRoleHolders(RoleManager.ROLE_DIALER);
7763 if (!dialerRoleHolders.contains(callingPackage)) {
7764 throw new SecurityException("App must be the dialer role holder to"
7765 + " upload a call composer pic");
7766 }
7767
7768 Executors.newSingleThreadExecutor().execute(() -> {
7769 ByteArrayOutputStream output = new ByteArrayOutputStream(
7770 (int) TelephonyManager.getMaximumCallComposerPictureSize());
7771 InputStream input = new ParcelFileDescriptor.AutoCloseInputStream(fd);
7772 boolean readUntilEnd = false;
7773 int totalBytesRead = 0;
7774 byte[] buffer = new byte[16 * 1024];
7775 while (true) {
7776 int numRead;
7777 try {
7778 numRead = input.read(buffer);
7779 } catch (IOException e) {
7780 try {
7781 fd.checkError();
7782 callback.send(TelephonyManager.CallComposerException.ERROR_INPUT_CLOSED,
7783 null);
7784 } catch (IOException e1) {
7785 // This means that the other side closed explicitly with an error. If this
7786 // happens, log and ignore.
7787 loge("Remote end of call composer picture pipe closed: " + e1);
7788 }
7789 break;
7790 }
7791 if (numRead == -1) {
7792 readUntilEnd = true;
7793 break;
7794 }
7795 totalBytesRead += numRead;
7796 if (totalBytesRead > TelephonyManager.getMaximumCallComposerPictureSize()) {
7797 loge("Too many bytes read for call composer picture: " + totalBytesRead);
7798 try {
7799 input.close();
7800 } catch (IOException e) {
7801 // ignore
7802 }
7803 break;
7804 }
7805 output.write(buffer, 0, numRead);
7806 }
7807 // Generally, the remote end will close the file descriptors. The only case where we
7808 // close is above, where the picture size is too big.
7809
7810 try {
7811 fd.checkError();
7812 } catch (IOException e) {
7813 loge("Remote end for call composer closed with an error: " + e);
7814 return;
7815 }
7816
Hall Liuaa4211e2021-01-20 15:43:39 -08007817 if (!readUntilEnd) {
7818 loge("Did not finish reading entire image; aborting");
7819 return;
7820 }
Hall Liu82694d52020-12-11 18:22:04 -08007821
Hall Liuaa4211e2021-01-20 15:43:39 -08007822 ImageData imageData = new ImageData(output.toByteArray(), contentType, null);
7823 CallComposerPictureManager.getInstance(mApp, subscriptionId).handleUploadToServer(
7824 new CallComposerPictureTransfer.Factory() {},
7825 imageData,
7826 (result) -> {
7827 if (result.first != null) {
7828 ParcelUuid parcelUuid = new ParcelUuid(result.first);
7829 Bundle outputResult = new Bundle();
7830 outputResult.putParcelable(
7831 TelephonyManager.KEY_CALL_COMPOSER_PICTURE_HANDLE, parcelUuid);
7832 callback.send(TelephonyManager.CallComposerException.SUCCESS,
7833 outputResult);
7834 } else {
7835 callback.send(result.second, null);
7836 }
7837 }
7838 );
Hall Liu82694d52020-12-11 18:22:04 -08007839 });
7840 }
7841
7842 @Override
Andrew Leedf14ead2014-10-17 14:22:52 -07007843 public void enableVideoCalling(boolean enable) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007844 final Phone defaultPhone = getDefaultPhone();
Andrew Leedf14ead2014-10-17 14:22:52 -07007845 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007846
7847 final long identity = Binder.clearCallingIdentity();
7848 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007849 ImsManager.getInstance(defaultPhone.getContext(),
7850 defaultPhone.getPhoneId()).setVtSetting(enable);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007851 } finally {
7852 Binder.restoreCallingIdentity(identity);
7853 }
Andrew Leedf14ead2014-10-17 14:22:52 -07007854 }
7855
7856 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007857 public boolean isVideoCallingEnabled(String callingPackage, String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007858 final Phone defaultPhone = getDefaultPhone();
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007859 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
7860 callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
Amit Mahajan578e53d2018-03-20 16:18:38 +00007861 return false;
7862 }
Svet Ganovb320e182015-04-16 12:30:10 -07007863
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007864 final long identity = Binder.clearCallingIdentity();
7865 try {
7866 // Check the user preference and the system-level IMS setting. Even if the user has
7867 // enabled video calling, if IMS is disabled we aren't able to support video calling.
7868 // In the long run, we may instead need to check if there exists a connection service
7869 // which can support video calling.
7870 ImsManager imsManager =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007871 ImsManager.getInstance(defaultPhone.getContext(), defaultPhone.getPhoneId());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007872 return imsManager.isVtEnabledByPlatform()
7873 && imsManager.isEnhanced4gLteModeSettingEnabledByUser()
7874 && imsManager.isVtEnabledByUser();
7875 } finally {
7876 Binder.restoreCallingIdentity(identity);
7877 }
Andrew Leedf14ead2014-10-17 14:22:52 -07007878 }
Libin.Tang@motorola.comafe82642014-12-18 13:27:53 -06007879
Andrew Leea1239f22015-03-02 17:44:07 -08007880 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007881 public boolean canChangeDtmfToneLength(int subId, String callingPackage,
7882 String callingFeatureId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007883 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007884 mApp, subId, callingPackage, callingFeatureId,
7885 "isVideoCallingEnabled")) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007886 return false;
7887 }
7888
7889 final long identity = Binder.clearCallingIdentity();
7890 try {
7891 CarrierConfigManager configManager =
7892 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007893 return configManager.getConfigForSubId(subId)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007894 .getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL);
7895 } finally {
7896 Binder.restoreCallingIdentity(identity);
7897 }
Andrew Leea1239f22015-03-02 17:44:07 -08007898 }
7899
7900 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007901 public boolean isWorldPhone(int subId, String callingPackage, String callingFeatureId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007902 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007903 mApp, subId, callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007904 return false;
7905 }
7906
7907 final long identity = Binder.clearCallingIdentity();
7908 try {
7909 CarrierConfigManager configManager =
7910 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007911 return configManager.getConfigForSubId(subId)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007912 .getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL);
7913 } finally {
7914 Binder.restoreCallingIdentity(identity);
7915 }
Andrew Leea1239f22015-03-02 17:44:07 -08007916 }
7917
Andrew Lee9431b832015-03-09 18:46:45 -07007918 @Override
7919 public boolean isTtyModeSupported() {
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07007920 TelecomManager telecomManager = mApp.getSystemService(TelecomManager.class);
Wooki Wu1f82f7a2016-02-15 15:59:58 +08007921 return telecomManager.isTtySupported();
Andrew Lee9431b832015-03-09 18:46:45 -07007922 }
7923
7924 @Override
7925 public boolean isHearingAidCompatibilitySupported() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007926 final long identity = Binder.clearCallingIdentity();
7927 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007928 return mApp.getResources().getBoolean(R.bool.hac_enabled);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007929 } finally {
7930 Binder.restoreCallingIdentity(identity);
7931 }
Andrew Lee9431b832015-03-09 18:46:45 -07007932 }
7933
Hall Liuf6668912018-10-31 17:05:23 -07007934 /**
7935 * Determines whether the device currently supports RTT (Real-time text). Based both on carrier
7936 * support for the feature and device firmware support.
7937 *
7938 * @return {@code true} if the device and carrier both support RTT, {@code false} otherwise.
7939 */
7940 @Override
7941 public boolean isRttSupported(int subscriptionId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007942 final long identity = Binder.clearCallingIdentity();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007943 final Phone phone = getPhone(subscriptionId);
7944 if (phone == null) {
7945 loge("isRttSupported: no Phone found. Invalid subId:" + subscriptionId);
7946 return false;
7947 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007948 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007949 boolean isCarrierSupported = mApp.getCarrierConfigForSubId(subscriptionId).getBoolean(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007950 CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
7951 boolean isDeviceSupported =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007952 phone.getContext().getResources().getBoolean(R.bool.config_support_rtt);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007953 return isCarrierSupported && isDeviceSupported;
7954 } finally {
7955 Binder.restoreCallingIdentity(identity);
7956 }
Hall Liu98187582018-01-22 19:15:32 -08007957 }
7958
Hall Liuf6668912018-10-31 17:05:23 -07007959 /**
Hall Liuf2daa022019-07-23 18:39:00 -07007960 * Determines whether the user has turned on RTT. If the carrier wants to ignore the user-set
7961 * RTT setting, will return true if the device and carrier both support RTT.
7962 * Otherwise. only returns true if the device and carrier both also support RTT.
Hall Liuf6668912018-10-31 17:05:23 -07007963 */
7964 public boolean isRttEnabled(int subscriptionId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007965 final long identity = Binder.clearCallingIdentity();
7966 try {
Hall Liu5bab75c2019-12-11 23:58:20 +00007967 boolean isRttSupported = isRttSupported(subscriptionId);
7968 boolean isUserRttSettingOn = Settings.Secure.getInt(
7969 mApp.getContentResolver(), Settings.Secure.RTT_CALLING_MODE, 0) != 0;
7970 boolean shouldIgnoreUserRttSetting = mApp.getCarrierConfigForSubId(subscriptionId)
7971 .getBoolean(CarrierConfigManager.KEY_IGNORE_RTT_MODE_SETTING_BOOL);
7972 return isRttSupported && (isUserRttSettingOn || shouldIgnoreUserRttSetting);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007973 } finally {
7974 Binder.restoreCallingIdentity(identity);
7975 }
Hall Liu3ad5f012018-04-06 16:23:39 -07007976 }
7977
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007978 @Deprecated
7979 @Override
7980 public String getDeviceId(String callingPackage) {
7981 return getDeviceIdWithFeature(callingPackage, null);
7982 }
7983
Sanket Padawe7310cc72015-01-14 09:53:20 -08007984 /**
7985 * Returns the unique device ID of phone, for example, the IMEI for
7986 * GSM and the MEID for CDMA phones. Return null if device ID is not available.
7987 *
7988 * <p>Requires Permission:
7989 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
7990 */
7991 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007992 public String getDeviceIdWithFeature(String callingPackage, String callingFeatureId) {
Shuo Qian13d89152021-05-10 23:58:11 -07007993 try {
7994 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
7995 } catch (SecurityException se) {
7996 EventLog.writeEvent(0x534e4554, "186530889", Binder.getCallingUid());
7997 throw new SecurityException("Package " + callingPackage + " does not belong to "
7998 + Binder.getCallingUid());
7999 }
Sanket Padawe7310cc72015-01-14 09:53:20 -08008000 final Phone phone = PhoneFactory.getPhone(0);
Jeff Davidson913390f2018-02-23 17:11:49 -08008001 if (phone == null) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08008002 return null;
8003 }
Jeff Davidson913390f2018-02-23 17:11:49 -08008004 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07008005 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008006 callingPackage, callingFeatureId, "getDeviceId")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08008007 return null;
8008 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008009
8010 final long identity = Binder.clearCallingIdentity();
8011 try {
8012 return phone.getDeviceId();
8013 } finally {
8014 Binder.restoreCallingIdentity(identity);
8015 }
Sanket Padawe7310cc72015-01-14 09:53:20 -08008016 }
8017
Ping Sunc67b7c22016-03-02 19:16:45 +08008018 /**
8019 * {@hide}
8020 * Returns the IMS Registration Status on a particular subid
8021 *
8022 * @param subId
8023 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08008024 public boolean isImsRegistered(int subId) {
Ping Sunc67b7c22016-03-02 19:16:45 +08008025 Phone phone = getPhone(subId);
8026 if (phone != null) {
8027 return phone.isImsRegistered();
8028 } else {
8029 return false;
8030 }
8031 }
8032
Santos Cordon7a1885b2015-02-03 11:15:19 -08008033 @Override
Shuo Qian6e6137d2019-10-30 16:33:31 -07008034 public int getSubIdForPhoneAccountHandle(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008035 PhoneAccountHandle phoneAccountHandle, String callingPackage, String callingFeatureId) {
Shuo Qian6e6137d2019-10-30 16:33:31 -07008036 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, getDefaultSubscription(),
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008037 callingPackage, callingFeatureId, "getSubIdForPhoneAccountHandle")) {
Shuo Qian6e6137d2019-10-30 16:33:31 -07008038 throw new SecurityException("Requires READ_PHONE_STATE permission.");
8039 }
8040 final long identity = Binder.clearCallingIdentity();
8041 try {
8042 return PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle);
8043 } finally {
8044 Binder.restoreCallingIdentity(identity);
8045 }
8046 }
8047
8048 @Override
Tyler Gunnf70ed162019-04-03 15:28:53 -07008049 public @Nullable PhoneAccountHandle getPhoneAccountHandleForSubscriptionId(int subscriptionId) {
Alireza Forouzan4ac4f982021-03-16 22:18:52 -07008050 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07008051 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Alireza Forouzan4ac4f982021-03-16 22:18:52 -07008052 mApp,
8053 subscriptionId,
8054 "getPhoneAccountHandleForSubscriptionId, " + "subscriptionId: " + subscriptionId);
Tyler Gunnf70ed162019-04-03 15:28:53 -07008055 final long identity = Binder.clearCallingIdentity();
8056 try {
8057 Phone phone = getPhone(subscriptionId);
8058 if (phone == null) {
8059 return null;
8060 }
8061 return PhoneUtils.makePstnPhoneAccountHandle(phone);
8062 } finally {
8063 Binder.restoreCallingIdentity(identity);
8064 }
8065 }
8066
Brad Ebinger1f2b5082018-02-08 16:11:32 -08008067 /**
8068 * @return the VoWiFi calling availability.
Nathan Haroldc55097a2015-03-11 18:14:50 -07008069 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08008070 public boolean isWifiCallingAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008071 final long identity = Binder.clearCallingIdentity();
8072 try {
8073 Phone phone = getPhone(subId);
8074 if (phone != null) {
8075 return phone.isWifiCallingEnabled();
8076 } else {
8077 return false;
8078 }
8079 } finally {
8080 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08008081 }
Nathan Haroldc55097a2015-03-11 18:14:50 -07008082 }
8083
Brad Ebinger1f2b5082018-02-08 16:11:32 -08008084 /**
Brad Ebinger1f2b5082018-02-08 16:11:32 -08008085 * @return the VT calling availability.
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07008086 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08008087 public boolean isVideoTelephonyAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008088 final long identity = Binder.clearCallingIdentity();
8089 try {
8090 Phone phone = getPhone(subId);
8091 if (phone != null) {
8092 return phone.isVideoEnabled();
8093 } else {
8094 return false;
8095 }
8096 } finally {
8097 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08008098 }
8099 }
8100
8101 /**
8102 * @return the IMS registration technology for the MMTEL feature. Valid return values are
8103 * defined in {@link ImsRegistrationImplBase}.
8104 */
8105 public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008106 final long identity = Binder.clearCallingIdentity();
8107 try {
8108 Phone phone = getPhone(subId);
8109 if (phone != null) {
8110 return phone.getImsRegistrationTech();
8111 } else {
8112 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
8113 }
8114 } finally {
8115 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08008116 }
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07008117 }
8118
Stuart Scott8eef64f2015-04-08 15:13:54 -07008119 @Override
Sarah Chinecc78c42022-03-31 21:16:48 -07008120 public void factoryReset(int subId, String callingPackage) {
paulhu5a773602019-08-23 19:17:33 +08008121 enforceSettingsPermission();
Stuart Scott981d8582015-04-21 14:09:50 -07008122 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
8123 return;
8124 }
Kai Shif70f46f2021-03-03 13:59:46 -08008125 Phone defaultPhone = getDefaultPhone();
8126 if (defaultPhone != null) {
8127 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8128 mApp, getDefaultPhone().getSubId(), "factoryReset");
8129 }
Svet Ganovcc087f82015-05-12 20:35:54 -07008130 final long identity = Binder.clearCallingIdentity();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008131
Svet Ganovcc087f82015-05-12 20:35:54 -07008132 try {
Stuart Scott981d8582015-04-21 14:09:50 -07008133 if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
8134 UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07008135 setDataEnabledForReason(subId, TelephonyManager.DATA_ENABLED_REASON_USER,
Sarah Chinecc78c42022-03-31 21:16:48 -07008136 getDefaultDataEnabled(), callingPackage);
Svet Ganovcc087f82015-05-12 20:35:54 -07008137 setNetworkSelectionModeAutomatic(subId);
SongFerngWang8c6e82e2021-03-02 22:09:29 +08008138 Phone phone = getPhone(subId);
SongFerngWangfd89b102021-05-27 22:44:54 +08008139 cleanUpAllowedNetworkTypes(phone, subId);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008140 setDataRoamingEnabled(subId, getDefaultDataRoamingEnabled(subId));
Jordan Liu857e73a2021-03-05 16:24:04 -08008141 getPhone(subId).resetCarrierKeysForImsiEncryption();
Svet Ganovcc087f82015-05-12 20:35:54 -07008142 }
Amit Mahajan7dbbd822019-03-13 17:33:47 -07008143 // There has been issues when Sms raw table somehow stores orphan
8144 // fragments. They lead to garbled message when new fragments come
8145 // in and combined with those stale ones. In case this happens again,
8146 // user can reset all network settings which will clean up this table.
8147 cleanUpSmsRawTable(getDefaultPhone().getContext());
Brad Ebingerbc7dd582019-10-17 17:03:22 -07008148 // Clean up IMS settings as well here.
8149 int slotId = getSlotIndex(subId);
8150 if (slotId > SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
8151 ImsManager.getInstance(mApp, slotId).factoryReset();
8152 }
Naina Nallurid63128d2019-09-17 14:10:30 -07008153
Kai Shif70f46f2021-03-03 13:59:46 -08008154 if (defaultPhone == null) {
8155 return;
8156 }
Naina Nallurid63128d2019-09-17 14:10:30 -07008157 // Erase modem config if erase modem on network setting is enabled.
8158 String configValue = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_TELEPHONY,
8159 RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED);
8160 if (configValue != null && Boolean.parseBoolean(configValue)) {
Kai Shif70f46f2021-03-03 13:59:46 -08008161 sendEraseModemConfig(defaultPhone);
Naina Nallurid63128d2019-09-17 14:10:30 -07008162 }
Kai Shif70f46f2021-03-03 13:59:46 -08008163
8164 sendEraseDataInSharedPreferences(defaultPhone);
Svet Ganovcc087f82015-05-12 20:35:54 -07008165 } finally {
8166 Binder.restoreCallingIdentity(identity);
Stuart Scott8eef64f2015-04-08 15:13:54 -07008167 }
8168 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01008169
SongFerngWangfd89b102021-05-27 22:44:54 +08008170 @VisibleForTesting
8171 void cleanUpAllowedNetworkTypes(Phone phone, int subId) {
8172 if (phone == null || !SubscriptionManager.isUsableSubscriptionId(subId)) {
8173 return;
8174 }
8175 long defaultNetworkType = RadioAccessFamily.getRafFromNetworkType(
8176 RILConstants.PREFERRED_NETWORK_MODE);
8177 SubscriptionManager.setSubscriptionProperty(subId,
8178 SubscriptionManager.ALLOWED_NETWORK_TYPES,
8179 "user=" + defaultNetworkType);
8180 phone.loadAllowedNetworksFromSubscriptionDatabase();
8181 phone.setAllowedNetworkTypes(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER,
8182 defaultNetworkType, null);
8183 }
8184
Amit Mahajan7dbbd822019-03-13 17:33:47 -07008185 private void cleanUpSmsRawTable(Context context) {
8186 ContentResolver resolver = context.getContentResolver();
8187 Uri uri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete");
8188 resolver.delete(uri, null, null);
8189 }
8190
Narayan Kamath1c496c22015-04-16 14:40:19 +01008191 @Override
chen xu5d3637b2019-01-21 23:31:38 -08008192 public String getSimLocaleForSubscriber(int subId) {
8193 enforceReadPrivilegedPermission("getSimLocaleForSubscriber, subId: " + subId);
8194 final Phone phone = getPhone(subId);
8195 if (phone == null) {
8196 log("getSimLocaleForSubscriber, invalid subId");
chen xu2bb91e42019-01-24 14:35:54 -08008197 return null;
chen xu5d3637b2019-01-21 23:31:38 -08008198 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008199 final long identity = Binder.clearCallingIdentity();
8200 try {
Jack Yu285100e2022-12-02 22:48:35 -08008201 SubscriptionInfo info;
8202 if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
8203 info = SubscriptionManagerService.getInstance().getActiveSubscriptionInfo(subId,
8204 phone.getContext().getOpPackageName(),
8205 phone.getContext().getAttributionTag());
8206 if (info == null) {
8207 log("getSimLocaleForSubscriber, inactive subId: " + subId);
8208 return null;
8209 }
8210 } else {
8211 info = mSubscriptionController.getActiveSubscriptionInfo(subId,
8212 phone.getContext().getOpPackageName(),
8213 phone.getContext().getAttributionTag());
8214 if (info == null) {
8215 log("getSimLocaleForSubscriber, inactive subId: " + subId);
8216 return null;
8217 }
chen xu6291c472019-02-04 12:55:53 -08008218 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008219 // Try and fetch the locale from the carrier properties or from the SIM language
8220 // preferences (EF-PL and EF-LI)...
8221 final int mcc = info.getMcc();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008222 String simLanguage = null;
chen xu5d3637b2019-01-21 23:31:38 -08008223 final Locale localeFromDefaultSim = phone.getLocaleFromSimAndCarrierPrefs();
8224 if (localeFromDefaultSim != null) {
8225 if (!localeFromDefaultSim.getCountry().isEmpty()) {
8226 if (DBG) log("Using locale from subId: " + subId + " locale: "
8227 + localeFromDefaultSim);
tom hsu60a8dc52022-10-27 00:10:04 +08008228 return matchLocaleFromSupportedLocaleList(phone, localeFromDefaultSim);
chen xu5d3637b2019-01-21 23:31:38 -08008229 } else {
8230 simLanguage = localeFromDefaultSim.getLanguage();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008231 }
8232 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01008233
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008234 // The SIM language preferences only store a language (e.g. fr = French), not an
8235 // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
8236 // the SIM and carrier preferences does not include a country we add the country
8237 // determined from the SIM MCC to provide an exact locale.
zoey chenc730df82019-12-18 17:07:20 +08008238 final Locale mccLocale = LocaleUtils.getLocaleFromMcc(mApp, mcc, simLanguage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008239 if (mccLocale != null) {
chen xu5d3637b2019-01-21 23:31:38 -08008240 if (DBG) log("No locale from SIM, using mcc locale:" + mccLocale);
tom hsu60a8dc52022-10-27 00:10:04 +08008241 return matchLocaleFromSupportedLocaleList(phone, mccLocale);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008242 }
8243
8244 if (DBG) log("No locale found - returning null");
8245 return null;
8246 } finally {
8247 Binder.restoreCallingIdentity(identity);
8248 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01008249 }
8250
tom hsu0b59d292022-09-29 23:49:21 +08008251 @VisibleForTesting
tom hsu60a8dc52022-10-27 00:10:04 +08008252 String matchLocaleFromSupportedLocaleList(Phone phone, @NonNull Locale inputLocale) {
tom hsu0b59d292022-09-29 23:49:21 +08008253 String[] supportedLocale = com.android.internal.app.LocalePicker.getSupportedLocales(
tom hsu60a8dc52022-10-27 00:10:04 +08008254 phone.getContext());
tom hsu0b59d292022-09-29 23:49:21 +08008255 for (String localeTag : supportedLocale) {
tom hsu60a8dc52022-10-27 00:10:04 +08008256 if (LocaleList.matchesLanguageAndScript(inputLocale, Locale.forLanguageTag(localeTag))
8257 && TextUtils.equals(inputLocale.getCountry(),
tom hsu0b59d292022-09-29 23:49:21 +08008258 Locale.forLanguageTag(localeTag).getCountry())) {
8259 return localeTag;
8260 }
8261 }
8262 return inputLocale.toLanguageTag();
8263 }
8264
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008265 /**
8266 * NOTE: this method assumes permission checks are done and caller identity has been cleared.
8267 */
8268 private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
Jack Yu285100e2022-12-02 22:48:35 -08008269 if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
8270 return SubscriptionManagerService.getInstance().getActiveSubscriptionInfoList(
8271 mApp.getOpPackageName(), mApp.getAttributionTag());
8272 }
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008273 return mSubscriptionController.getActiveSubscriptionInfoList(mApp.getOpPackageName(),
Philip P. Moltmann8d34f0c2020-03-05 16:24:02 -08008274 mApp.getAttributionTag());
Narayan Kamath1c496c22015-04-16 14:40:19 +01008275 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07008276
Gary Jian3aa9a762022-01-24 16:41:19 +08008277 private ActivityStatsTechSpecificInfo[] mLastModemActivitySpecificInfo = null;
8278 private ModemActivityInfo mLastModemActivityInfo = null;
Chenjie Yu1ba97252018-01-11 18:16:20 -08008279
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07008280 /**
Adam Lesinski903a54c2016-04-11 14:49:52 -07008281 * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
8282 * representing the state of the modem.
8283 *
Chenjie Yu1ba97252018-01-11 18:16:20 -08008284 * NOTE: The underlying implementation clears the modem state, so there should only ever be one
8285 * caller to it. Everyone should call this class to get cumulative data.
Adam Lesinski903a54c2016-04-11 14:49:52 -07008286 * @hide
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07008287 */
8288 @Override
Adam Lesinski903a54c2016-04-11 14:49:52 -07008289 public void requestModemActivityInfo(ResultReceiver result) {
8290 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07008291 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008292
8293 final long identity = Binder.clearCallingIdentity();
8294 try {
Shuo Qian8f4750a2020-02-20 17:12:10 -08008295 sendRequestAsync(CMD_GET_MODEM_ACTIVITY_INFO, result, null, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008296 } finally {
8297 Binder.restoreCallingIdentity(identity);
Chenjie Yu1ba97252018-01-11 18:16:20 -08008298 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07008299 }
Jack Yu85bd38a2015-11-09 11:34:32 -08008300
Gary Jian76280a42022-12-07 16:18:33 +08008301 // Checks that ModemActivityInfo is valid. Sleep time and Idle time should be
Siddharth Rayb8114062018-06-17 15:02:38 -07008302 // less than total activity duration.
8303 private boolean isModemActivityInfoValid(ModemActivityInfo info) {
8304 if (info == null) {
8305 return false;
8306 }
8307 int activityDurationMs =
Hall Liu49656c02020-10-09 19:00:11 -07008308 (int) (info.getTimestampMillis() - mLastModemActivityInfo.getTimestampMillis());
Gary Jian76280a42022-12-07 16:18:33 +08008309 activityDurationMs += MODEM_ACTIVITY_TIME_OFFSET_CORRECTION_MS;
8310
Hall Liu49656c02020-10-09 19:00:11 -07008311 int totalTxTimeMs = Arrays.stream(info.getTransmitTimeMillis()).sum();
8312
Siddharth Rayb8114062018-06-17 15:02:38 -07008313 return (info.isValid()
8314 && (info.getSleepTimeMillis() <= activityDurationMs)
Gary Jian76280a42022-12-07 16:18:33 +08008315 && (info.getIdleTimeMillis() <= activityDurationMs));
Siddharth Rayb8114062018-06-17 15:02:38 -07008316 }
8317
Gary Jian3aa9a762022-01-24 16:41:19 +08008318 private void updateLastModemActivityInfo(ModemActivityInfo info, int rat, int freq) {
8319 int[] mergedTxTimeMs = new int [ModemActivityInfo.getNumTxPowerLevels()];
8320 int[] txTimeMs = info.getTransmitTimeMillis(rat, freq);
8321 int[] lastModemTxTimeMs = mLastModemActivityInfo.getTransmitTimeMillis(rat, freq);
8322
8323 for (int lvl = 0; lvl < mergedTxTimeMs.length; lvl++) {
8324 mergedTxTimeMs[lvl] = txTimeMs[lvl] + lastModemTxTimeMs[lvl];
8325 }
8326
8327 mLastModemActivityInfo.setTransmitTimeMillis(rat, freq, mergedTxTimeMs);
8328 mLastModemActivityInfo.setReceiveTimeMillis(
8329 rat,
8330 freq,
8331 info.getReceiveTimeMillis(rat, freq)
8332 + mLastModemActivityInfo.getReceiveTimeMillis(rat, freq));
8333 }
8334
8335 private void updateLastModemActivityInfo(ModemActivityInfo info, int rat) {
8336 int[] mergedTxTimeMs = new int [ModemActivityInfo.getNumTxPowerLevels()];
8337 int[] txTimeMs = info.getTransmitTimeMillis(rat);
8338 int[] lastModemTxTimeMs = mLastModemActivityInfo.getTransmitTimeMillis(rat);
8339
8340 for (int lvl = 0; lvl < mergedTxTimeMs.length; lvl++) {
8341 mergedTxTimeMs[lvl] = txTimeMs[lvl] + lastModemTxTimeMs[lvl];
8342 }
8343 mLastModemActivityInfo.setTransmitTimeMillis(rat, mergedTxTimeMs);
8344 mLastModemActivityInfo.setReceiveTimeMillis(
8345 rat,
8346 info.getReceiveTimeMillis(rat) + mLastModemActivityInfo.getReceiveTimeMillis(rat));
8347 }
8348
8349 /**
8350 * Merge this ModemActivityInfo with mLastModemActivitySpecificInfo
8351 * @param info recent ModemActivityInfo
8352 */
8353 private void mergeModemActivityInfo(ModemActivityInfo info) {
8354 List<ActivityStatsTechSpecificInfo> merged = new ArrayList<>();
Kai Shi917fdc62022-11-28 14:01:02 -08008355 ActivityStatsTechSpecificInfo deltaSpecificInfo;
Gary Jian3aa9a762022-01-24 16:41:19 +08008356 boolean matched;
8357 for (int i = 0; i < info.getSpecificInfoLength(); i++) {
8358 matched = false;
8359 int rat = info.getSpecificInfoRat(i);
8360 int freq = info.getSpecificInfoFrequencyRange(i);
8361 //Check each ActivityStatsTechSpecificInfo in this ModemActivityInfo for new rat returns
8362 //Add a new ActivityStatsTechSpecificInfo if is a new rat, and merge with the original
8363 //if it already exists
8364 for (int j = 0; j < mLastModemActivitySpecificInfo.length; j++) {
8365 if (rat == mLastModemActivityInfo.getSpecificInfoRat(j) && !matched) {
8366 //Merged based on frequency range (MMWAVE vs SUB6) for 5G
8367 if (rat == AccessNetworkConstants.AccessNetworkType.NGRAN) {
8368 if (freq == mLastModemActivityInfo.getSpecificInfoFrequencyRange(j)) {
8369 updateLastModemActivityInfo(info, rat, freq);
8370 matched = true;
8371 }
8372 } else {
8373 updateLastModemActivityInfo(info, rat);
8374 matched = true;
8375 }
8376 }
8377 }
8378
8379 if (!matched) {
Kai Shi917fdc62022-11-28 14:01:02 -08008380 deltaSpecificInfo =
Gary Jian3aa9a762022-01-24 16:41:19 +08008381 new ActivityStatsTechSpecificInfo(
8382 rat,
8383 freq,
8384 info.getTransmitTimeMillis(rat, freq),
8385 (int) info.getReceiveTimeMillis(rat, freq));
Kai Shi917fdc62022-11-28 14:01:02 -08008386 merged.addAll(Arrays.asList(deltaSpecificInfo));
Gary Jian3aa9a762022-01-24 16:41:19 +08008387 }
8388 }
8389 merged.addAll(Arrays.asList(mLastModemActivitySpecificInfo));
8390 mLastModemActivitySpecificInfo =
8391 new ActivityStatsTechSpecificInfo[merged.size()];
8392 merged.toArray(mLastModemActivitySpecificInfo);
8393
8394 mLastModemActivityInfo.setTimestamp(info.getTimestampMillis());
8395 mLastModemActivityInfo.setSleepTimeMillis(
8396 info.getSleepTimeMillis()
8397 + mLastModemActivityInfo.getSleepTimeMillis());
8398 mLastModemActivityInfo.setIdleTimeMillis(
8399 info.getIdleTimeMillis()
8400 + mLastModemActivityInfo.getIdleTimeMillis());
Kai Shi917fdc62022-11-28 14:01:02 -08008401
8402 mLastModemActivityInfo =
8403 new ModemActivityInfo(
8404 mLastModemActivityInfo.getTimestampMillis(),
8405 mLastModemActivityInfo.getSleepTimeMillis(),
8406 mLastModemActivityInfo.getIdleTimeMillis(),
8407 mLastModemActivitySpecificInfo);
8408 }
8409
8410 private ActivityStatsTechSpecificInfo[] deepCopyModemActivitySpecificInfo(
8411 ActivityStatsTechSpecificInfo[] info) {
8412 int infoSize = info.length;
8413 ActivityStatsTechSpecificInfo[] ret = new ActivityStatsTechSpecificInfo[infoSize];
8414 for (int i = 0; i < infoSize; i++) {
8415 ret[i] = new ActivityStatsTechSpecificInfo(
8416 info[i].getRat(), info[i].getFrequencyRange(),
8417 info[i].getTransmitTimeMillis(),
8418 (int) info[i].getReceiveTimeMillis());
8419 }
8420 return ret;
Gary Jian3aa9a762022-01-24 16:41:19 +08008421 }
8422
Jack Yu85bd38a2015-11-09 11:34:32 -08008423 /**
Jack Yu85bd38a2015-11-09 11:34:32 -08008424 * Returns the service state information on specified subscription.
8425 */
8426 @Override
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08008427 public ServiceState getServiceStateForSubscriber(int subId,
8428 boolean renounceFineLocationAccess, boolean renounceCoarseLocationAccess,
8429 String callingPackage, String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08008430 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008431 mApp, subId, callingPackage, callingFeatureId, "getServiceStateForSubscriber")) {
Jack Yu85bd38a2015-11-09 11:34:32 -08008432 return null;
8433 }
8434
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08008435 boolean hasFinePermission = false;
8436 boolean hasCoarsePermission = false;
8437 if (!renounceFineLocationAccess) {
8438 LocationAccessPolicy.LocationPermissionResult fineLocationResult =
8439 LocationAccessPolicy.checkLocationPermission(mApp,
8440 new LocationAccessPolicy.LocationPermissionQuery.Builder()
8441 .setCallingPackage(callingPackage)
8442 .setCallingFeatureId(callingFeatureId)
8443 .setCallingPid(Binder.getCallingPid())
8444 .setCallingUid(Binder.getCallingUid())
8445 .setMethod("getServiceStateForSubscriber")
8446 .setLogAsInfo(true)
8447 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
8448 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
8449 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
8450 .build());
8451 hasFinePermission =
8452 fineLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
8453 }
Hall Liuf19c44f2018-11-27 14:38:17 -08008454
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08008455 if (!renounceCoarseLocationAccess) {
8456 LocationAccessPolicy.LocationPermissionResult coarseLocationResult =
8457 LocationAccessPolicy.checkLocationPermission(mApp,
8458 new LocationAccessPolicy.LocationPermissionQuery.Builder()
8459 .setCallingPackage(callingPackage)
8460 .setCallingFeatureId(callingFeatureId)
8461 .setCallingPid(Binder.getCallingPid())
8462 .setCallingUid(Binder.getCallingUid())
8463 .setMethod("getServiceStateForSubscriber")
8464 .setLogAsInfo(true)
8465 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
8466 .setMinSdkVersionForFine(Integer.MAX_VALUE)
8467 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
8468 .build());
8469 hasCoarsePermission =
8470 coarseLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
8471 }
Hall Liuf19c44f2018-11-27 14:38:17 -08008472
Jack Yu479f40e2020-10-27 21:29:25 -07008473 final Phone phone = getPhone(subId);
8474 if (phone == null) {
8475 return null;
8476 }
8477
Jordan Liu0f2bc442020-11-18 16:47:37 -08008478 final long identity = Binder.clearCallingIdentity();
8479
Jack Yu479f40e2020-10-27 21:29:25 -07008480 boolean isCallingPackageDataService = phone.getDataServicePackages()
8481 .contains(callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008482 try {
Jordan Liuc437b192020-08-17 10:59:12 -07008483 // isActiveSubId requires READ_PHONE_STATE, which we already check for above
Jack Yu285100e2022-12-02 22:48:35 -08008484 if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
8485 SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
8486 .getSubscriptionInfoInternal(subId);
8487 if (subInfo == null || !subInfo.isActive()) {
8488 Rlog.d(LOG_TAG, "getServiceStateForSubscriber returning null for inactive "
8489 + "subId=" + subId);
8490 return null;
8491 }
8492 } else {
8493 if (!mSubscriptionController.isActiveSubId(subId, callingPackage,
8494 callingFeatureId)) {
8495 Rlog.d(LOG_TAG, "getServiceStateForSubscriber returning null for inactive "
8496 + "subId=" + subId);
8497 return null;
8498 }
Jordan Liuc437b192020-08-17 10:59:12 -07008499 }
8500
Hall Liuf19c44f2018-11-27 14:38:17 -08008501 ServiceState ss = phone.getServiceState();
8502
8503 // Scrub out the location info in ServiceState depending on what level of access
8504 // the caller has.
Jack Yu479f40e2020-10-27 21:29:25 -07008505 if (hasFinePermission || isCallingPackageDataService) return ss;
Malcolm Chen5052de62019-12-30 13:56:38 -08008506 if (hasCoarsePermission) return ss.createLocationInfoSanitizedCopy(false);
8507 return ss.createLocationInfoSanitizedCopy(true);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008508 } finally {
8509 Binder.restoreCallingIdentity(identity);
8510 }
Jack Yu85bd38a2015-11-09 11:34:32 -08008511 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08008512
8513 /**
8514 * Returns the URI for the per-account voicemail ringtone set in Phone settings.
8515 *
8516 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
8517 * voicemail ringtone.
8518 * @return The URI for the ringtone to play when receiving a voicemail from a specific
8519 * PhoneAccount.
8520 */
8521 @Override
8522 public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008523 final long identity = Binder.clearCallingIdentity();
8524 try {
8525 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
8526 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008527 phone = getDefaultPhone();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008528 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08008529
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008530 return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext());
8531 } finally {
8532 Binder.restoreCallingIdentity(identity);
8533 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08008534 }
8535
8536 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008537 * Sets the per-account voicemail ringtone.
8538 *
8539 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
8540 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
8541 *
8542 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
8543 * voicemail ringtone.
8544 * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
8545 * PhoneAccount.
8546 */
8547 @Override
8548 public void setVoicemailRingtoneUri(String callingPackage,
8549 PhoneAccountHandle phoneAccountHandle, Uri uri) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008550 final Phone defaultPhone = getDefaultPhone();
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008551 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07008552 TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
8553 if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08008554 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8555 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
8556 "setVoicemailRingtoneUri");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008557 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008558
8559 final long identity = Binder.clearCallingIdentity();
8560 try {
8561 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
8562 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008563 phone = defaultPhone;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008564 }
8565 VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri);
8566 } finally {
8567 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008568 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008569 }
8570
8571 /**
Nancy Chen31f9ba12016-01-06 11:42:12 -08008572 * Returns whether vibration is set for voicemail notification in Phone settings.
8573 *
8574 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
8575 * voicemail vibration setting.
8576 * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
8577 */
8578 @Override
8579 public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008580 final long identity = Binder.clearCallingIdentity();
8581 try {
8582 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
8583 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008584 phone = getDefaultPhone();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008585 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08008586
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008587 return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext());
8588 } finally {
8589 Binder.restoreCallingIdentity(identity);
8590 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08008591 }
8592
Youhan Wange64578a2016-05-02 15:32:42 -07008593 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008594 * Sets the per-account voicemail vibration.
8595 *
8596 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
8597 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
8598 *
8599 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
8600 * voicemail vibration setting.
8601 * @param enabled Whether to enable or disable vibration for voicemail notifications from a
8602 * specific PhoneAccount.
8603 */
8604 @Override
8605 public void setVoicemailVibrationEnabled(String callingPackage,
8606 PhoneAccountHandle phoneAccountHandle, boolean enabled) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008607 final Phone defaultPhone = getDefaultPhone();
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008608 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07008609 TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
8610 if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08008611 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8612 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
8613 "setVoicemailVibrationEnabled");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008614 }
8615
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008616 final long identity = Binder.clearCallingIdentity();
8617 try {
8618 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
8619 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008620 phone = defaultPhone;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008621 }
8622 VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled);
8623 } finally {
8624 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008625 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008626 }
8627
8628 /**
Youhan Wange64578a2016-05-02 15:32:42 -07008629 * Make sure either called from same process as self (phone) or IPC caller has read privilege.
8630 *
8631 * @throws SecurityException if the caller does not have the required permission
8632 */
arunvoddud7401012022-12-15 16:08:12 +00008633 @VisibleForTesting
8634 public void enforceReadPrivilegedPermission(String message) {
Youhan Wange64578a2016-05-02 15:32:42 -07008635 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
Brad Ebinger35c841c2018-10-01 10:40:55 -07008636 message);
Youhan Wange64578a2016-05-02 15:32:42 -07008637 }
8638
8639 /**
Ta-wei Yen30a69c82016-12-27 14:52:32 -08008640 * Make sure either called from same process as self (phone) or IPC caller has send SMS
8641 * permission.
8642 *
8643 * @throws SecurityException if the caller does not have the required permission
8644 */
8645 private void enforceSendSmsPermission() {
8646 mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null);
8647 }
8648
8649 /**
Aishwarya Mallampatifbc70d32022-11-10 20:33:02 +00008650 * Make sure either called from same process as self (phone) or IPC caller has interact across
8651 * users permission.
8652 *
8653 * @throws SecurityException if the caller does not have the required permission
8654 */
8655 private void enforceInteractAcrossUsersPermission(String message) {
8656 mApp.enforceCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS, message);
8657 }
8658
8659 /**
Ta-wei Yen527a9c02017-01-06 15:29:25 -08008660 * Make sure called from the package in charge of visual voicemail.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08008661 *
Ta-wei Yen527a9c02017-01-06 15:29:25 -08008662 * @throws SecurityException if the caller is not the visual voicemail package.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08008663 */
Ta-wei Yen527a9c02017-01-06 15:29:25 -08008664 private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008665 final long identity = Binder.clearCallingIdentity();
8666 try {
8667 ComponentName componentName =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008668 RemoteVvmTaskManager.getRemotePackage(mApp, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008669 if (componentName == null) {
8670 throw new SecurityException(
8671 "Caller not current active visual voicemail package[null]");
8672 }
8673 String vvmPackage = componentName.getPackageName();
8674 if (!callingPackage.equals(vvmPackage)) {
Hui Wang7f657552022-08-16 16:58:25 +00008675 throw new SecurityException("Caller not current active visual voicemail package");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008676 }
8677 } finally {
8678 Binder.restoreCallingIdentity(identity);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08008679 }
8680 }
8681
8682 /**
Youhan Wange64578a2016-05-02 15:32:42 -07008683 * Return the application ID for the app type.
8684 *
8685 * @param subId the subscription ID that this request applies to.
8686 * @param appType the uicc app type.
8687 * @return Application ID for specificied app type, or null if no uicc.
8688 */
8689 @Override
8690 public String getAidForAppType(int subId, int appType) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07008691 enforceReadPrivilegedPermission("getAidForAppType");
Youhan Wange64578a2016-05-02 15:32:42 -07008692 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008693
8694 final long identity = Binder.clearCallingIdentity();
Youhan Wange64578a2016-05-02 15:32:42 -07008695 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008696 if (phone == null) {
8697 return null;
8698 }
8699 String aid = null;
8700 try {
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00008701 aid = UiccController.getInstance().getUiccPort(phone.getPhoneId())
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008702 .getApplicationByType(appType).getAid();
8703 } catch (Exception e) {
8704 Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e);
8705 }
8706 return aid;
8707 } finally {
8708 Binder.restoreCallingIdentity(identity);
Youhan Wange64578a2016-05-02 15:32:42 -07008709 }
Youhan Wange64578a2016-05-02 15:32:42 -07008710 }
8711
Youhan Wang4001d252016-05-11 10:29:41 -07008712 /**
8713 * Return the Electronic Serial Number.
8714 *
8715 * @param subId the subscription ID that this request applies to.
8716 * @return ESN or null if error.
8717 */
8718 @Override
8719 public String getEsn(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07008720 enforceReadPrivilegedPermission("getEsn");
Youhan Wang4001d252016-05-11 10:29:41 -07008721 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008722
8723 final long identity = Binder.clearCallingIdentity();
Youhan Wang4001d252016-05-11 10:29:41 -07008724 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008725 if (phone == null) {
8726 return null;
8727 }
8728 String esn = null;
8729 try {
8730 esn = phone.getEsn();
8731 } catch (Exception e) {
8732 Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e);
8733 }
8734 return esn;
8735 } finally {
8736 Binder.restoreCallingIdentity(identity);
Youhan Wang4001d252016-05-11 10:29:41 -07008737 }
Youhan Wang4001d252016-05-11 10:29:41 -07008738 }
8739
Sanket Padawe99ef1e32016-05-18 16:12:33 -07008740 /**
Youhan Wang66ad5d72016-07-18 17:56:58 -07008741 * Return the Preferred Roaming List Version.
8742 *
8743 * @param subId the subscription ID that this request applies to.
8744 * @return PRLVersion or null if error.
8745 */
8746 @Override
8747 public String getCdmaPrlVersion(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07008748 enforceReadPrivilegedPermission("getCdmaPrlVersion");
Youhan Wang66ad5d72016-07-18 17:56:58 -07008749 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008750
8751 final long identity = Binder.clearCallingIdentity();
Youhan Wang66ad5d72016-07-18 17:56:58 -07008752 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008753 if (phone == null) {
8754 return null;
8755 }
8756 String cdmaPrlVersion = null;
8757 try {
8758 cdmaPrlVersion = phone.getCdmaPrlVersion();
8759 } catch (Exception e) {
8760 Log.e(LOG_TAG, "Not getting PRLVersion", e);
8761 }
8762 return cdmaPrlVersion;
8763 } finally {
8764 Binder.restoreCallingIdentity(identity);
Youhan Wang66ad5d72016-07-18 17:56:58 -07008765 }
Youhan Wang66ad5d72016-07-18 17:56:58 -07008766 }
8767
8768 /**
Sanket Padawe99ef1e32016-05-18 16:12:33 -07008769 * Get snapshot of Telephony histograms
8770 * @return List of Telephony histograms
8771 * @hide
8772 */
8773 @Override
8774 public List<TelephonyHistogram> getTelephonyHistograms() {
Jeff Davidson7e17e312018-02-13 18:17:36 -08008775 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8776 mApp, getDefaultSubscription(), "getTelephonyHistograms");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008777
8778 final long identity = Binder.clearCallingIdentity();
8779 try {
8780 return RIL.getTelephonyRILTimingHistograms();
8781 } finally {
8782 Binder.restoreCallingIdentity(identity);
8783 }
Sanket Padawe99ef1e32016-05-18 16:12:33 -07008784 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07008785
8786 /**
8787 * {@hide}
Michele Berionne482f8202018-11-27 18:57:59 -08008788 * Set the allowed carrier list and the excluded carrier list, indicating the priority between
8789 * the two lists.
Meng Wang1a7c35a2016-05-05 20:56:15 -07008790 * Require system privileges. In the future we may add this to carrier APIs.
8791 *
Michele Berionne482f8202018-11-27 18:57:59 -08008792 * @return Integer with the result of the operation, as defined in {@link TelephonyManager}.
Meng Wang1a7c35a2016-05-05 20:56:15 -07008793 */
8794 @Override
Michele Berionne482f8202018-11-27 18:57:59 -08008795 @TelephonyManager.SetCarrierRestrictionResult
8796 public int setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules) {
Meng Wang1a7c35a2016-05-05 20:56:15 -07008797 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07008798 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Sanket Padawe13bac7b2017-03-20 15:04:47 -07008799
Michele Berionne482f8202018-11-27 18:57:59 -08008800 if (carrierRestrictionRules == null) {
8801 throw new NullPointerException("carrier restriction cannot be null");
Meng Wang9b7c4e92017-02-17 11:41:27 -08008802 }
Sanket Padawe13bac7b2017-03-20 15:04:47 -07008803
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008804 final long identity = Binder.clearCallingIdentity();
8805 try {
Michele Berionne482f8202018-11-27 18:57:59 -08008806 return (int) sendRequest(CMD_SET_ALLOWED_CARRIERS, carrierRestrictionRules,
vagdeviaf9a5b92018-08-15 16:01:53 -07008807 workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008808 } finally {
8809 Binder.restoreCallingIdentity(identity);
8810 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07008811 }
8812
8813 /**
8814 * {@hide}
Michele Berionne482f8202018-11-27 18:57:59 -08008815 * Get the allowed carrier list and the excluded carrier list, including the priority between
8816 * the two lists.
Meng Wang1a7c35a2016-05-05 20:56:15 -07008817 * Require system privileges. In the future we may add this to carrier APIs.
8818 *
Michele Berionne482f8202018-11-27 18:57:59 -08008819 * @return {@link android.telephony.CarrierRestrictionRules}
Meng Wang1a7c35a2016-05-05 20:56:15 -07008820 */
8821 @Override
Michele Berionne482f8202018-11-27 18:57:59 -08008822 public CarrierRestrictionRules getAllowedCarriers() {
Brad Ebinger35c841c2018-10-01 10:40:55 -07008823 enforceReadPrivilegedPermission("getAllowedCarriers");
vagdeviaf9a5b92018-08-15 16:01:53 -07008824 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008825
8826 final long identity = Binder.clearCallingIdentity();
8827 try {
Michele Berionne482f8202018-11-27 18:57:59 -08008828 Object response = sendRequest(CMD_GET_ALLOWED_CARRIERS, null, workSource);
8829 if (response instanceof CarrierRestrictionRules) {
8830 return (CarrierRestrictionRules) response;
8831 }
8832 // Response is an Exception of some kind,
8833 // which is signalled to the user as a NULL retval
8834 return null;
8835 } catch (Exception e) {
8836 Log.e(LOG_TAG, "getAllowedCarriers. Exception ex=" + e);
8837 return null;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008838 } finally {
8839 Binder.restoreCallingIdentity(identity);
8840 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07008841 }
8842
fionaxu59545b42016-05-25 15:53:37 -07008843 /**
arunvoddud7401012022-12-15 16:08:12 +00008844 * Fetches the carrier restriction status of the device and sends the status to the caller
8845 * through the callback.
8846 *
8847 * @param callback The callback that will be used to send the result.
8848 * @throws SecurityException if the caller does not have the required permission/privileges or
8849 * the caller is not allowlisted.
8850 */
8851 @Override
8852 public void getCarrierRestrictionStatus(IIntegerConsumer callback, String packageName) {
8853 enforceReadPermission("getCarrierRestrictionStatus");
8854 int carrierId = validateCallerAndGetCarrierId(packageName);
8855 if (carrierId == CarrierAllowListInfo.INVALID_CARRIER_ID) {
8856 Rlog.e(LOG_TAG, "getCarrierRestrictionStatus: caller is not registered");
8857 throw new SecurityException("Not an authorized caller");
8858 }
8859 final long identity = Binder.clearCallingIdentity();
8860 try {
8861 Consumer<Integer> consumer = FunctionalUtils.ignoreRemoteException(callback::accept);
8862 CallerCallbackInfo callbackInfo = new CallerCallbackInfo(consumer, carrierId);
8863 sendRequestAsync(CMD_GET_ALLOWED_CARRIERS, callbackInfo);
8864 } finally {
8865 Binder.restoreCallingIdentity(identity);
8866 }
8867 }
8868
8869 @VisibleForTesting
8870 public int validateCallerAndGetCarrierId(String packageName) {
8871 CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mApp);
8872 return allowListInfo.validateCallerAndGetCarrierId(packageName);
8873 }
8874
8875 /**
fionaxu59545b42016-05-25 15:53:37 -07008876 * Action set from carrier signalling broadcast receivers to enable/disable radio
8877 * @param subId the subscription ID that this action applies to.
8878 * @param enabled control enable or disable radio.
8879 * {@hide}
8880 */
8881 @Override
8882 public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
8883 enforceModifyPermission();
8884 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008885
8886 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07008887 if (phone == null) {
8888 loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
8889 return;
8890 }
8891 try {
8892 phone.carrierActionSetRadioEnabled(enabled);
8893 } catch (Exception e) {
8894 Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008895 } finally {
8896 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07008897 }
8898 }
8899
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07008900 /**
Sooraj Sasindrandaf060f2021-06-15 14:52:55 -07008901 * Enable or disable Voice over NR (VoNR)
8902 * @param subId the subscription ID that this action applies to.
8903 * @param enabled enable or disable VoNR.
8904 * @return operation result.
8905 */
8906 @Override
8907 public int setVoNrEnabled(int subId, boolean enabled) {
8908 enforceModifyPermission();
8909 final Phone phone = getPhone(subId);
8910
8911 final long identity = Binder.clearCallingIdentity();
8912 if (phone == null) {
8913 loge("setVoNrEnabled fails with no phone object for subId: " + subId);
8914 return TelephonyManager.ENABLE_VONR_RADIO_NOT_AVAILABLE;
8915 }
8916
8917 WorkSource workSource = getWorkSource(Binder.getCallingUid());
8918 try {
8919 int result = (int) sendRequest(CMD_ENABLE_VONR, enabled, subId,
8920 workSource);
8921 if (DBG) log("setVoNrEnabled result: " + result);
Gary Jian8dd305f2021-10-14 16:31:35 +08008922
8923 if (result == TelephonyManager.ENABLE_VONR_SUCCESS) {
8924 if (DBG) {
8925 log("Set VoNR settings in siminfo db; subId=" + subId + ", value:" + enabled);
8926 }
8927 SubscriptionManager.setSubscriptionProperty(
8928 subId, SubscriptionManager.NR_ADVANCED_CALLING_ENABLED,
8929 (enabled ? "1" : "0"));
8930 }
8931
Sooraj Sasindrandaf060f2021-06-15 14:52:55 -07008932 return result;
8933 } finally {
8934 Binder.restoreCallingIdentity(identity);
8935 }
8936 }
8937
8938 /**
8939 * Is voice over NR enabled
8940 * @return true if VoNR is enabled else false
8941 */
8942 @Override
8943 public boolean isVoNrEnabled(int subId) {
8944 enforceReadPrivilegedPermission("isVoNrEnabled");
8945 WorkSource workSource = getWorkSource(Binder.getCallingUid());
8946 final long identity = Binder.clearCallingIdentity();
8947 try {
8948 boolean isEnabled = (boolean) sendRequest(CMD_IS_VONR_ENABLED,
8949 null, subId, workSource);
8950 if (DBG) log("isVoNrEnabled: " + isEnabled);
8951 return isEnabled;
8952 } finally {
8953 Binder.restoreCallingIdentity(identity);
8954 }
8955 }
8956
8957 /**
fionaxu8da9cb12017-05-23 15:02:46 -07008958 * Action set from carrier signalling broadcast receivers to start/stop reporting the default
8959 * network status based on which carrier apps could apply actions accordingly,
8960 * enable/disable default url handler for example.
8961 *
8962 * @param subId the subscription ID that this action applies to.
8963 * @param report control start/stop reporting the default network status.
8964 * {@hide}
8965 */
8966 @Override
8967 public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
8968 enforceModifyPermission();
8969 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008970
8971 final long identity = Binder.clearCallingIdentity();
fionaxu8da9cb12017-05-23 15:02:46 -07008972 if (phone == null) {
8973 loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId);
8974 return;
8975 }
8976 try {
8977 phone.carrierActionReportDefaultNetworkStatus(report);
8978 } catch (Exception e) {
8979 Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008980 } finally {
8981 Binder.restoreCallingIdentity(identity);
fionaxu8da9cb12017-05-23 15:02:46 -07008982 }
8983 }
8984
8985 /**
fionaxud9622282017-07-17 17:51:30 -07008986 * Action set from carrier signalling broadcast receivers to reset all carrier actions
8987 * @param subId the subscription ID that this action applies to.
8988 * {@hide}
8989 */
8990 @Override
8991 public void carrierActionResetAll(int subId) {
8992 enforceModifyPermission();
8993 final Phone phone = getPhone(subId);
8994 if (phone == null) {
8995 loge("carrierAction: ResetAll fails with invalid sibId: " + subId);
8996 return;
8997 }
8998 try {
8999 phone.carrierActionResetAll();
9000 } catch (Exception e) {
9001 Log.e(LOG_TAG, "carrierAction: ResetAll fails. Exception ex=" + e);
9002 }
9003 }
9004
9005 /**
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07009006 * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a
9007 * bug report is being generated.
9008 */
9009 @Override
Ta-wei Yen99282e02016-06-21 18:19:35 -07009010 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08009011 if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
9012 != PackageManager.PERMISSION_GRANTED) {
dcashman22b950d2016-06-27 11:39:02 -07009013 writer.println("Permission Denial: can't dump Phone from pid="
9014 + Binder.getCallingPid()
9015 + ", uid=" + Binder.getCallingUid()
9016 + "without permission "
9017 + android.Manifest.permission.DUMP);
9018 return;
9019 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08009020 DumpsysHandler.dump(mApp, fd, writer, args);
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07009021 }
Jack Yueb89b242016-06-22 13:27:47 -07009022
Brad Ebingerdac2f002018-04-03 15:17:52 -07009023 @Override
Hall Liua1548bd2019-12-24 14:14:12 -08009024 public int handleShellCommand(@NonNull ParcelFileDescriptor in,
9025 @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
9026 @NonNull String[] args) {
9027 return new TelephonyShellCommand(this, getDefaultPhone().getContext()).exec(
9028 this, in.getFileDescriptor(), out.getFileDescriptor(),
9029 err.getFileDescriptor(), args);
Brad Ebingerdac2f002018-04-03 15:17:52 -07009030 }
9031
Jack Yueb89b242016-06-22 13:27:47 -07009032 /**
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00009033 * Policy control of data connection with reason {@@TelephonyManager.DataEnabledReason}
Greg Kaiser17f41752020-05-05 16:47:47 +00009034 * @param subId Subscription index
Sarah Chinecc78c42022-03-31 21:16:48 -07009035 * @param reason The reason the data enable change is taking place.
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00009036 * @param enabled True if enabling the data, otherwise disabling.
Sarah Chinecc78c42022-03-31 21:16:48 -07009037 * @param callingPackage The package that changed the data enabled state.
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00009038 * @hide
Jack Yu75ab2952016-07-08 14:29:33 -07009039 */
9040 @Override
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07009041 public void setDataEnabledForReason(int subId, @TelephonyManager.DataEnabledReason int reason,
Sarah Chinecc78c42022-03-31 21:16:48 -07009042 boolean enabled, String callingPackage) {
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00009043 if (reason == TelephonyManager.DATA_ENABLED_REASON_USER
9044 || reason == TelephonyManager.DATA_ENABLED_REASON_CARRIER) {
9045 try {
9046 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07009047 mApp, subId, "setDataEnabledForReason");
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00009048 } catch (SecurityException se) {
9049 enforceModifyPermission();
9050 }
9051 } else {
9052 enforceModifyPermission();
9053 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009054
9055 final long identity = Binder.clearCallingIdentity();
9056 try {
9057 Phone phone = getPhone(subId);
9058 if (phone != null) {
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00009059 if (reason == TelephonyManager.DATA_ENABLED_REASON_CARRIER) {
9060 phone.carrierActionSetMeteredApnsEnabled(enabled);
9061 } else {
Jack Yu7968c6d2022-07-31 00:43:21 -07009062 phone.getDataSettingsManager().setDataEnabled(
9063 reason, enabled, callingPackage);
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00009064 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009065 }
9066 } finally {
9067 Binder.restoreCallingIdentity(identity);
Jack Yu75ab2952016-07-08 14:29:33 -07009068 }
9069 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07009070
9071 /**
9072 * Get Client request stats
9073 * @return List of Client Request Stats
9074 * @hide
9075 */
9076 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009077 public List<ClientRequestStats> getClientRequestStats(String callingPackage,
9078 String callingFeatureId, int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08009079 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009080 mApp, subId, callingPackage, callingFeatureId, "getClientRequestStats")) {
Sooraj Sasindran9a909312016-07-18 11:57:25 -07009081 return null;
9082 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07009083 Phone phone = getPhone(subId);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07009084
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009085 final long identity = Binder.clearCallingIdentity();
9086 try {
9087 if (phone != null) {
9088 return phone.getClientRequestStats();
9089 }
9090
9091 return null;
9092 } finally {
9093 Binder.restoreCallingIdentity(identity);
9094 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07009095 }
9096
Narayan Kamathf04b5a12018-01-09 11:47:15 +00009097 private WorkSource getWorkSource(int uid) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08009098 String packageName = mApp.getPackageManager().getNameForUid(uid);
Hunter Knepshieldd03383b2022-03-29 22:47:54 +00009099 if (uid == Process.ROOT_UID && packageName == null) {
9100 // Downstream WorkSource attribution inside the RIL requires both a UID and package name
9101 // to be set for wakelock tracking, otherwise RIL requests fail with a runtime
9102 // exception. ROOT_UID seems not to have a valid package name returned by
9103 // PackageManager, so just fake it here to avoid issues when running telephony shell
9104 // commands that plumb through the RIL as root, like so:
9105 // $ adb root
9106 // $ adb shell cmd phone ...
9107 packageName = "root";
9108 }
Narayan Kamathf04b5a12018-01-09 11:47:15 +00009109 return new WorkSource(uid, packageName);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07009110 }
Jack Yueb4124c2017-02-16 15:32:43 -08009111
9112 /**
Grace Chen70990072017-03-24 17:21:30 -07009113 * Set SIM card power state.
Jack Yueb4124c2017-02-16 15:32:43 -08009114 *
Sanket Padawe13bac7b2017-03-20 15:04:47 -07009115 * @param slotIndex SIM slot id.
Grace Chen70990072017-03-24 17:21:30 -07009116 * @param state State of SIM (power down, power up, pass through)
9117 * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
9118 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
9119 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
Jack Yueb4124c2017-02-16 15:32:43 -08009120 *
9121 **/
9122 @Override
Grace Chen70990072017-03-24 17:21:30 -07009123 public void setSimPowerStateForSlot(int slotIndex, int state) {
Jack Yueb4124c2017-02-16 15:32:43 -08009124 enforceModifyPermission();
Sanket Padawe13bac7b2017-03-20 15:04:47 -07009125 Phone phone = PhoneFactory.getPhone(slotIndex);
9126
vagdeviaf9a5b92018-08-15 16:01:53 -07009127 WorkSource workSource = getWorkSource(Binder.getCallingUid());
9128
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009129 final long identity = Binder.clearCallingIdentity();
9130 try {
9131 if (phone != null) {
Jordan Liu109698e2020-11-24 14:50:34 -08009132 phone.setSimPowerState(state, null, workSource);
9133 }
9134 } finally {
9135 Binder.restoreCallingIdentity(identity);
9136 }
9137 }
9138
9139 /**
9140 * Set SIM card power state.
9141 *
9142 * @param slotIndex SIM slot id.
9143 * @param state State of SIM (power down, power up, pass through)
9144 * @param callback callback to trigger after success or failure
9145 * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
9146 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
9147 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
9148 *
9149 **/
9150 @Override
9151 public void setSimPowerStateForSlotWithCallback(int slotIndex, int state,
9152 IIntegerConsumer callback) {
9153 enforceModifyPermission();
9154 Phone phone = PhoneFactory.getPhone(slotIndex);
9155
9156 WorkSource workSource = getWorkSource(Binder.getCallingUid());
9157
9158 final long identity = Binder.clearCallingIdentity();
9159 try {
9160 if (phone != null) {
9161 Pair<Integer, IIntegerConsumer> arguments = Pair.create(state, callback);
9162 sendRequestAsync(CMD_SET_SIM_POWER, arguments, phone, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009163 }
9164 } finally {
9165 Binder.restoreCallingIdentity(identity);
Jack Yueb4124c2017-02-16 15:32:43 -08009166 }
9167 }
Shuo Qiandd210312017-04-12 22:11:33 +00009168
Tyler Gunn65d45c22017-06-05 11:22:26 -07009169 private boolean isUssdApiAllowed(int subId) {
9170 CarrierConfigManager configManager =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08009171 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Tyler Gunn65d45c22017-06-05 11:22:26 -07009172 if (configManager == null) {
9173 return false;
9174 }
9175 PersistableBundle pb = configManager.getConfigForSubId(subId);
9176 if (pb == null) {
9177 return false;
9178 }
9179 return pb.getBoolean(
9180 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL);
9181 }
9182
Shuo Qiandd210312017-04-12 22:11:33 +00009183 /**
9184 * Check if phone is in emergency callback mode
9185 * @return true if phone is in emergency callback mode
9186 * @param subId sub id
9187 */
goneil9c5f4872017-12-05 14:07:56 -08009188 @Override
Shuo Qiandd210312017-04-12 22:11:33 +00009189 public boolean getEmergencyCallbackMode(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07009190 enforceReadPrivilegedPermission("getEmergencyCallbackMode");
Shuo Qiandd210312017-04-12 22:11:33 +00009191 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009192
9193 final long identity = Binder.clearCallingIdentity();
9194 try {
9195 if (phone != null) {
9196 return phone.isInEcm();
9197 } else {
9198 return false;
9199 }
9200 } finally {
9201 Binder.restoreCallingIdentity(identity);
Shuo Qiandd210312017-04-12 22:11:33 +00009202 }
9203 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08009204
9205 /**
9206 * Get the current signal strength information for the given subscription.
9207 * Because this information is not updated when the device is in a low power state
9208 * it should not be relied-upon to be current.
9209 * @param subId Subscription index
9210 * @return the most recent cached signal strength info from the modem
9211 */
9212 @Override
9213 public SignalStrength getSignalStrength(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009214 final long identity = Binder.clearCallingIdentity();
9215 try {
9216 Phone p = getPhone(subId);
9217 if (p == null) {
9218 return null;
9219 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08009220
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009221 return p.getSignalStrength();
9222 } finally {
9223 Binder.restoreCallingIdentity(identity);
9224 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08009225 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00009226
Pengquan Meng77b7f132018-08-22 14:49:57 -07009227 /**
Chen Xuf792fd62018-10-17 17:54:36 +00009228 * Get the current modem radio state for the given slot.
9229 * @param slotIndex slot index.
9230 * @param callingPackage the name of the package making the call.
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009231 * @param callingFeatureId The feature in the package.
Chen Xuf792fd62018-10-17 17:54:36 +00009232 * @return the current radio power state from the modem
9233 */
9234 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009235 public int getRadioPowerState(int slotIndex, String callingPackage, String callingFeatureId) {
Chen Xuf792fd62018-10-17 17:54:36 +00009236 Phone phone = PhoneFactory.getPhone(slotIndex);
9237 if (phone != null) {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009238 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, phone.getSubId(),
9239 callingPackage, callingFeatureId, "getRadioPowerState")) {
Chen Xuf792fd62018-10-17 17:54:36 +00009240 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
9241 }
9242
9243 final long identity = Binder.clearCallingIdentity();
9244 try {
9245 return phone.getRadioPowerState();
9246 } finally {
9247 Binder.restoreCallingIdentity(identity);
9248 }
9249 }
9250 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
9251 }
9252
9253 /**
Pengquan Meng77b7f132018-08-22 14:49:57 -07009254 * Checks if data roaming is enabled on the subscription with id {@code subId}.
9255 *
9256 * <p>Requires one of the following permissions:
9257 * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07009258 * {@link android.Manifest.permission#READ_BASIC_PHONE_STATE},
Pengquan Meng77b7f132018-08-22 14:49:57 -07009259 * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
9260 * privileges.
9261 *
9262 * @param subId subscription id
9263 * @return {@code true} if data roaming is enabled on this subscription, otherwise return
9264 * {@code false}.
9265 */
9266 @Override
9267 public boolean isDataRoamingEnabled(int subId) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07009268 String functionName = "isDataRoamingEnabled";
Shuo Qian093013d2020-08-13 15:42:55 -07009269 try {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07009270 try {
9271 mApp.enforceCallingOrSelfPermission(
9272 android.Manifest.permission.ACCESS_NETWORK_STATE,
9273 functionName);
Sooraj Sasindran12545cc2022-08-22 14:30:25 -07009274 } catch (SecurityException e) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07009275 mApp.enforceCallingOrSelfPermission(
9276 permission.READ_BASIC_PHONE_STATE, functionName);
9277 }
Sooraj Sasindran12545cc2022-08-22 14:30:25 -07009278 } catch (SecurityException e) {
Nathan Harold62c68512021-04-06 11:26:02 -07009279 TelephonyPermissions.enforceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07009280 mApp, subId, functionName);
Shuo Qian093013d2020-08-13 15:42:55 -07009281 }
Pengquan Meng44e66f12019-04-01 10:48:20 -07009282
Pengquan Menga1bb6272018-09-06 09:59:22 -07009283 boolean isEnabled = false;
9284 final long identity = Binder.clearCallingIdentity();
Pengquan Meng77b7f132018-08-22 14:49:57 -07009285 try {
Pengquan Menga1bb6272018-09-06 09:59:22 -07009286 Phone phone = getPhone(subId);
9287 isEnabled = phone != null ? phone.getDataRoamingEnabled() : false;
Pengquan Menga1bb6272018-09-06 09:59:22 -07009288 } finally {
9289 Binder.restoreCallingIdentity(identity);
Pengquan Meng77b7f132018-08-22 14:49:57 -07009290 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07009291 return isEnabled;
Pengquan Meng77b7f132018-08-22 14:49:57 -07009292 }
9293
9294
9295 /**
9296 * Enables/Disables the data roaming on the subscription with id {@code subId}.
9297 *
9298 * <p> Requires permission:
9299 * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier
9300 * privileges.
9301 *
9302 * @param subId subscription id
9303 * @param isEnabled {@code true} means enable, {@code false} means disable.
9304 */
9305 @Override
9306 public void setDataRoamingEnabled(int subId, boolean isEnabled) {
Pengquan Meng44e66f12019-04-01 10:48:20 -07009307 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
9308 mApp, subId, "setDataRoamingEnabled");
9309
Pengquan Menga1bb6272018-09-06 09:59:22 -07009310 final long identity = Binder.clearCallingIdentity();
9311 try {
Pengquan Menga1bb6272018-09-06 09:59:22 -07009312 Phone phone = getPhone(subId);
9313 if (phone != null) {
9314 phone.setDataRoamingEnabled(isEnabled);
9315 }
9316 } finally {
9317 Binder.restoreCallingIdentity(identity);
Pengquan Meng77b7f132018-08-22 14:49:57 -07009318 }
9319 }
9320
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00009321 @Override
Pengquan Meng6884a2c2018-10-03 12:19:13 -07009322 public boolean isManualNetworkSelectionAllowed(int subId) {
tom hsuc91afc72020-01-06 23:46:07 +08009323 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07009324 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Pengquan Meng44e66f12019-04-01 10:48:20 -07009325 mApp, subId, "isManualNetworkSelectionAllowed");
9326
Pengquan Meng6884a2c2018-10-03 12:19:13 -07009327 boolean isAllowed = true;
9328 final long identity = Binder.clearCallingIdentity();
9329 try {
Pengquan Meng6884a2c2018-10-03 12:19:13 -07009330 Phone phone = getPhone(subId);
9331 if (phone != null) {
9332 isAllowed = phone.isCspPlmnEnabled();
9333 }
9334 } finally {
9335 Binder.restoreCallingIdentity(identity);
9336 }
9337 return isAllowed;
9338 }
9339
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009340 private boolean haveCarrierPrivilegeAccess(UiccPort port, String callingPackage) {
9341 UiccProfile profile = port.getUiccProfile();
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08009342 if (profile == null) {
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009343 return false;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00009344 }
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08009345 Phone phone = PhoneFactory.getPhone(profile.getPhoneId());
9346 if (phone == null) {
9347 return false;
9348 }
9349 CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
9350 return cpt != null && cpt.getCarrierPrivilegeStatusForPackage(callingPackage)
9351 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00009352 }
9353
Pengquan Meng6884a2c2018-10-03 12:19:13 -07009354 @Override
Jordan Liu75f43ea2019-01-17 16:56:37 -08009355 public List<UiccCardInfo> getUiccCardsInfo(String callingPackage) {
sandeepjsa208e3b2021-11-17 04:05:58 +00009356 // Verify that the callingPackage belongs to the calling UID
Jordan Liu4cda4552020-03-23 11:55:07 -07009357 mApp.getSystemService(AppOpsManager.class)
9358 .checkPackage(Binder.getCallingUid(), callingPackage);
9359
Jordan Liu1e142fc2019-04-22 15:10:43 -07009360 boolean hasReadPermission = false;
sandeepjsb6c87872021-09-27 15:34:44 +00009361 boolean isIccIdAccessRestricted = false;
Jordan Liuc65bc952019-02-12 17:54:02 -08009362 try {
9363 enforceReadPrivilegedPermission("getUiccCardsInfo");
Jordan Liu1e142fc2019-04-22 15:10:43 -07009364 hasReadPermission = true;
Jordan Liuc65bc952019-02-12 17:54:02 -08009365 } catch (SecurityException e) {
9366 // even without READ_PRIVILEGED_PHONE_STATE, we allow the call to continue if the caller
9367 // has carrier privileges on an active UICC
Rambo Wange7209ce2022-02-23 13:41:02 -08009368 if (checkCarrierPrivilegesForPackageAnyPhoneWithPermission(callingPackage)
Jordan Liuc65bc952019-02-12 17:54:02 -08009369 != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
Jordan Liu1e142fc2019-04-22 15:10:43 -07009370 throw new SecurityException("Caller does not have permission.");
Jordan Liuc65bc952019-02-12 17:54:02 -08009371 }
Jordan Liu75f43ea2019-01-17 16:56:37 -08009372 }
sandeepjsb6c87872021-09-27 15:34:44 +00009373 // checking compatibility, if calling app's target SDK is T and beyond.
9374 if (CompatChanges.isChangeEnabled(GET_API_SIGNATURES_FROM_UICC_PORT_INFO,
9375 Binder.getCallingUid())) {
9376 isIccIdAccessRestricted = true;
9377 }
Jordan Liu5aa07002018-12-18 15:44:48 -08009378 final long identity = Binder.clearCallingIdentity();
9379 try {
Jordan Liu75f43ea2019-01-17 16:56:37 -08009380 UiccController uiccController = UiccController.getInstance();
9381 ArrayList<UiccCardInfo> cardInfos = uiccController.getAllUiccCardInfos();
Jordan Liu1e142fc2019-04-22 15:10:43 -07009382 if (hasReadPermission) {
9383 return cardInfos;
Jordan Liu75f43ea2019-01-17 16:56:37 -08009384 }
Jordan Liu1e142fc2019-04-22 15:10:43 -07009385
9386 // Remove private info if the caller doesn't have access
9387 ArrayList<UiccCardInfo> filteredInfos = new ArrayList<>();
9388 for (UiccCardInfo cardInfo : cardInfos) {
sandeepjsb6c87872021-09-27 15:34:44 +00009389 //setting the value after compatibility check
9390 cardInfo.setIccIdAccessRestricted(isIccIdAccessRestricted);
Jordan Liu1e142fc2019-04-22 15:10:43 -07009391 // For an inactive eUICC, the UiccCard will be null even though the UiccCardInfo
9392 // is available
sandeepjsb6c87872021-09-27 15:34:44 +00009393 UiccCard card = uiccController.getUiccCardForSlot(cardInfo.getPhysicalSlotIndex());
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009394 if (card == null) {
9395 // assume no access if the card is unavailable
sandeepjsb6c87872021-09-27 15:34:44 +00009396 filteredInfos.add(getUiccCardInfoUnPrivileged(cardInfo));
Jordan Liu1e142fc2019-04-22 15:10:43 -07009397 continue;
9398 }
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009399 Collection<UiccPortInfo> portInfos = cardInfo.getPorts();
9400 if (portInfos.isEmpty()) {
sandeepjsb6c87872021-09-27 15:34:44 +00009401 filteredInfos.add(getUiccCardInfoUnPrivileged(cardInfo));
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009402 continue;
Jordan Liu1e142fc2019-04-22 15:10:43 -07009403 }
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009404 List<UiccPortInfo> uiccPortInfos = new ArrayList<>();
9405 for (UiccPortInfo portInfo : portInfos) {
9406 UiccPort port = uiccController.getUiccPortForSlot(
9407 cardInfo.getPhysicalSlotIndex(), portInfo.getPortIndex());
9408 if (port == null) {
9409 // assume no access if port is null
9410 uiccPortInfos.add(getUiccPortInfoUnPrivileged(portInfo));
9411 continue;
9412 }
9413 if (haveCarrierPrivilegeAccess(port, callingPackage)) {
9414 uiccPortInfos.add(portInfo);
9415 } else {
9416 uiccPortInfos.add(getUiccPortInfoUnPrivileged(portInfo));
9417 }
9418 }
9419 filteredInfos.add(new UiccCardInfo(
9420 cardInfo.isEuicc(),
9421 cardInfo.getCardId(),
9422 null,
9423 cardInfo.getPhysicalSlotIndex(),
9424 cardInfo.isRemovable(),
9425 cardInfo.isMultipleEnabledProfilesSupported(),
9426 uiccPortInfos));
Jordan Liu1e142fc2019-04-22 15:10:43 -07009427 }
9428 return filteredInfos;
Jordan Liu5aa07002018-12-18 15:44:48 -08009429 } finally {
9430 Binder.restoreCallingIdentity(identity);
9431 }
9432 }
9433
sandeepjsb6c87872021-09-27 15:34:44 +00009434 /**
9435 * Returns a copy of the UiccCardinfo with the EID and ICCID set to null. These values are
9436 * generally private and require carrier privileges to view.
9437 *
9438 * @hide
9439 */
9440 @NonNull
9441 public UiccCardInfo getUiccCardInfoUnPrivileged(UiccCardInfo cardInfo) {
9442 List<UiccPortInfo> portinfo = new ArrayList<>();
9443 for (UiccPortInfo portinfos : cardInfo.getPorts()) {
9444 portinfo.add(getUiccPortInfoUnPrivileged(portinfos));
9445 }
9446 return new UiccCardInfo(
9447 cardInfo.isEuicc(),
9448 cardInfo.getCardId(),
9449 null,
9450 cardInfo.getPhysicalSlotIndex(),
9451 cardInfo.isRemovable(),
9452 cardInfo.isMultipleEnabledProfilesSupported(),
9453 portinfo
9454 );
9455 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00009456
sandeepjsb6c87872021-09-27 15:34:44 +00009457 /**
9458 * @hide
9459 * @return a copy of the UiccPortInfo with ICCID set to {@link UiccPortInfo#ICCID_REDACTED}.
9460 * These values are generally private and require carrier privileges to view.
9461 */
9462 @NonNull
9463 public UiccPortInfo getUiccPortInfoUnPrivileged(UiccPortInfo portInfo) {
9464 return new UiccPortInfo(
9465 UiccPortInfo.ICCID_REDACTED,
9466 portInfo.getPortIndex(),
9467 portInfo.getLogicalSlotIndex(),
9468 portInfo.isActive()
9469 );
9470 }
9471 @Override
9472 public UiccSlotInfo[] getUiccSlotsInfo(String callingPackage) {
sandeepjsa208e3b2021-11-17 04:05:58 +00009473 // Verify that the callingPackage belongs to the calling UID
sandeepjsb6c87872021-09-27 15:34:44 +00009474 mApp.getSystemService(AppOpsManager.class)
9475 .checkPackage(Binder.getCallingUid(), callingPackage);
9476
sandeepjsb6c87872021-09-27 15:34:44 +00009477 boolean isLogicalSlotAccessRestricted = false;
sandeepjsb6c87872021-09-27 15:34:44 +00009478
Aman Guptaf3c90b32022-03-17 04:54:16 +00009479 // This will make sure caller has the READ_PRIVILEGED_PHONE_STATE. Do not remove this as
9480 // we are reading iccId which is PII data.
9481 enforceReadPrivilegedPermission("getUiccSlotsInfo");
sandeepjsb6c87872021-09-27 15:34:44 +00009482
9483 // checking compatibility, if calling app's target SDK is T and beyond.
9484 if (CompatChanges.isChangeEnabled(GET_API_SIGNATURES_FROM_UICC_PORT_INFO,
9485 Binder.getCallingUid())) {
9486 isLogicalSlotAccessRestricted = true;
9487 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009488 final long identity = Binder.clearCallingIdentity();
9489 try {
9490 UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
Muralidhar Reddyd196bbf2022-01-17 17:56:30 +00009491 if (slots == null || slots.length == 0) {
9492 Rlog.i(LOG_TAG, "slots is null or empty.");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009493 return null;
9494 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009495 UiccSlotInfo[] infos = new UiccSlotInfo[slots.length];
9496 for (int i = 0; i < slots.length; i++) {
9497 UiccSlot slot = slots[i];
9498 if (slot == null) {
9499 continue;
9500 }
9501
Jordan Liu7be7e652019-05-06 18:55:02 +00009502 String cardId;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009503 UiccCard card = slot.getUiccCard();
9504 if (card != null) {
9505 cardId = card.getCardId();
Jordan Liu7be7e652019-05-06 18:55:02 +00009506 } else {
Jordan Liu01bd00d2019-09-12 16:19:43 -07009507 cardId = slot.getEid();
9508 if (TextUtils.isEmpty(cardId)) {
Aman Guptaf3c90b32022-03-17 04:54:16 +00009509 // If cardId is null, use iccId of default port as cardId.
9510 cardId = slot.getIccId(TelephonyManager.DEFAULT_PORT_INDEX);
Jordan Liu01bd00d2019-09-12 16:19:43 -07009511 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009512 }
9513
Jordan Liu857451f2019-05-09 16:35:35 -07009514 if (cardId != null) {
9515 // if cardId is an ICCID, strip off trailing Fs before exposing to user
9516 // if cardId is an EID, it's all digits so this is fine
9517 cardId = IccUtils.stripTrailingFs(cardId);
9518 }
9519
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009520 int cardState = 0;
9521 switch (slot.getCardState()) {
9522 case CARDSTATE_ABSENT:
9523 cardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
9524 break;
9525 case CARDSTATE_PRESENT:
9526 cardState = UiccSlotInfo.CARD_STATE_INFO_PRESENT;
9527 break;
9528 case CARDSTATE_ERROR:
9529 cardState = UiccSlotInfo.CARD_STATE_INFO_ERROR;
9530 break;
9531 case CARDSTATE_RESTRICTED:
9532 cardState = UiccSlotInfo.CARD_STATE_INFO_RESTRICTED;
9533 break;
9534 default:
9535 break;
9536
9537 }
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009538 List<UiccPortInfo> portInfos = new ArrayList<>();
9539 int[] portIndexes = slot.getPortList();
9540 for (int portIdx : portIndexes) {
9541 String iccId = IccUtils.stripTrailingFs(getIccId(slot, portIdx,
Aman Guptaf3c90b32022-03-17 04:54:16 +00009542 callingPackage, /* hasReadPermission= */ true));
Muralidhar Reddyfbcff0c2022-01-19 13:07:57 +00009543 portInfos.add(new UiccPortInfo(iccId, portIdx,
9544 slot.getPhoneIdFromPortIndex(portIdx), slot.isPortActive(portIdx)));
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009545 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009546 infos[i] = new UiccSlotInfo(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009547 slot.isEuicc(),
9548 cardId,
9549 cardState,
Jordan Liua2619582019-02-14 12:56:40 -08009550 slot.isExtendedApduSupported(),
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009551 slot.isRemovable(), portInfos);
sandeepjsb6c87872021-09-27 15:34:44 +00009552 //setting the value after compatibility check
9553 infos[i].setLogicalSlotAccessRestricted(isLogicalSlotAccessRestricted);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009554 }
9555 return infos;
9556 } finally {
9557 Binder.restoreCallingIdentity(identity);
Holly Jiuyu Sun1d957c52018-04-04 13:52:42 -07009558 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00009559 }
9560
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009561 /* Returns null if doesn't have read permission or carrier privilege access. */
9562 private String getIccId(UiccSlot slot, int portIndex, String callingPackage,
9563 boolean hasReadPermission) {
9564 String iccId = slot.getIccId(portIndex);
9565 if (hasReadPermission) { // if has read permission
9566 return iccId;
9567 } else {
9568 if (slot.getUiccCard() != null && slot.getUiccCard().getUiccPort(portIndex) != null) {
9569 UiccPort port = slot.getUiccCard().getUiccPort(portIndex);
9570 // if no read permission, checking carrier privilege access
9571 if (haveCarrierPrivilegeAccess(port, callingPackage)) {
9572 return iccId;
9573 }
9574 }
9575 }
9576 // No read permission or carrier privilege access.
9577 return UiccPortInfo.ICCID_REDACTED;
9578 }
9579
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00009580 @Override
sandeepjsb6c87872021-09-27 15:34:44 +00009581 @Deprecated
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00009582 public boolean switchSlots(int[] physicalSlots) {
9583 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009584
9585 final long identity = Binder.clearCallingIdentity();
9586 try {
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009587 List<UiccSlotMapping> slotMappings = new ArrayList<>();
9588 for (int i = 0; i < physicalSlots.length; i++) {
9589 // Deprecated API, hence MEP is not supported. Adding default portIndex 0.
9590 slotMappings.add(new UiccSlotMapping(TelephonyManager.DEFAULT_PORT_INDEX,
9591 physicalSlots[i], i));
9592 }
9593 return (Boolean) sendRequest(CMD_SWITCH_SLOTS, slotMappings);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009594 } finally {
9595 Binder.restoreCallingIdentity(identity);
9596 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00009597 }
Jack Yu4c988042018-02-27 15:30:01 -08009598
9599 @Override
sandeepjsb6c87872021-09-27 15:34:44 +00009600 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
9601 public boolean setSimSlotMapping(@NonNull List<UiccSlotMapping> slotMapping) {
9602 enforceModifyPermission();
9603
9604 final long identity = Binder.clearCallingIdentity();
9605 try {
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009606 return (Boolean) sendRequest(CMD_SWITCH_SLOTS, slotMapping);
sandeepjsb6c87872021-09-27 15:34:44 +00009607 } finally {
9608 Binder.restoreCallingIdentity(identity);
9609 }
9610 }
9611
9612 @Override
Jordan Liu7de49fa2018-12-06 14:48:49 -08009613 public int getCardIdForDefaultEuicc(int subId, String callingPackage) {
Jordan Liu7de49fa2018-12-06 14:48:49 -08009614 final long identity = Binder.clearCallingIdentity();
9615 try {
9616 return UiccController.getInstance().getCardIdForDefaultEuicc();
9617 } finally {
9618 Binder.restoreCallingIdentity(identity);
9619 }
9620 }
9621
Pengquan Meng85728fb2018-03-12 16:31:21 -07009622 /**
goneil47ffb6e2018-04-06 15:40:58 -07009623 * A test API to reload the UICC profile.
9624 *
9625 * <p>Requires that the calling app has permission
9626 * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
9627 * @hide
9628 */
9629 @Override
9630 public void refreshUiccProfile(int subId) {
9631 enforceModifyPermission();
9632
9633 final long identity = Binder.clearCallingIdentity();
9634 try {
9635 Phone phone = getPhone(subId);
9636 if (phone == null) {
9637 return;
9638 }
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00009639 UiccPort uiccPort = phone.getUiccPort();
9640 if (uiccPort == null) {
goneil47ffb6e2018-04-06 15:40:58 -07009641 return;
9642 }
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00009643 UiccProfile uiccProfile = uiccPort.getUiccProfile();
goneil47ffb6e2018-04-06 15:40:58 -07009644 if (uiccProfile == null) {
9645 return;
9646 }
9647 uiccProfile.refresh();
9648 } finally {
9649 Binder.restoreCallingIdentity(identity);
9650 }
9651 }
9652
9653 /**
Pengquan Meng85728fb2018-03-12 16:31:21 -07009654 * Returns false if the mobile data is disabled by default, otherwise return true.
9655 */
9656 private boolean getDefaultDataEnabled() {
Inseob Kim14bb3d02018-12-13 17:11:34 +09009657 return TelephonyProperties.mobile_data().orElse(true);
Pengquan Meng85728fb2018-03-12 16:31:21 -07009658 }
9659
9660 /**
9661 * Returns true if the data roaming is enabled by default, i.e the system property
9662 * of {@link #DEFAULT_DATA_ROAMING_PROPERTY_NAME} is true or the config of
9663 * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} is true.
9664 */
9665 private boolean getDefaultDataRoamingEnabled(int subId) {
9666 final CarrierConfigManager configMgr = (CarrierConfigManager)
Nazanin Bakhshif782e562018-12-11 15:15:39 -08009667 mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Shuo Qian1d84a0e2020-07-15 12:36:44 -07009668 boolean isDataRoamingEnabled = TelephonyProperties.data_roaming().orElse(false);
Pengquan Meng85728fb2018-03-12 16:31:21 -07009669 isDataRoamingEnabled |= configMgr.getConfigForSubId(subId).getBoolean(
9670 CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
9671 return isDataRoamingEnabled;
9672 }
9673
9674 /**
9675 * Returns the default network type for the given {@code subId}, if the default network type is
9676 * not set, return {@link Phone#PREFERRED_NT_MODE}.
9677 */
9678 private int getDefaultNetworkType(int subId) {
Inseob Kim14bb3d02018-12-13 17:11:34 +09009679 List<Integer> list = TelephonyProperties.default_network();
Jack Yu285100e2022-12-02 22:48:35 -08009680 int phoneId = SubscriptionManager.getPhoneId(subId);
Inseob Kim14bb3d02018-12-13 17:11:34 +09009681 if (phoneId >= 0 && phoneId < list.size() && list.get(phoneId) != null) {
9682 return list.get(phoneId);
9683 }
9684 return Phone.PREFERRED_NT_MODE;
Pengquan Meng85728fb2018-03-12 16:31:21 -07009685 }
fionaxua13278b2018-03-21 00:08:13 -07009686
9687 @Override
9688 public void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String
chen xueaba88a2019-03-15 13:15:10 -07009689 gid1, String gid2, String plmn, String spn, String carrierPrivilegeRules, String apn) {
fionaxua13278b2018-03-21 00:08:13 -07009690 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009691
9692 final long identity = Binder.clearCallingIdentity();
9693 try {
9694 final Phone phone = getPhone(subId);
9695 if (phone == null) {
9696 loge("setCarrierTestOverride fails with invalid subId: " + subId);
9697 return;
9698 }
Rambo Wang9c9ffdd2022-01-13 21:51:44 -08009699 CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
9700 if (cpt != null) {
9701 cpt.setTestOverrideCarrierPrivilegeRules(carrierPrivilegeRules);
9702 }
9703 // TODO(b/211796398): remove the legacy logic below once CPT migration is done.
chen xueaba88a2019-03-15 13:15:10 -07009704 phone.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, plmn, spn,
9705 carrierPrivilegeRules, apn);
Jeff Davidson8ab02b22020-03-28 12:24:40 -07009706 if (carrierPrivilegeRules == null) {
9707 mCarrierPrivilegeTestOverrideSubIds.remove(subId);
9708 } else {
9709 mCarrierPrivilegeTestOverrideSubIds.add(subId);
9710 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009711 } finally {
9712 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07009713 }
fionaxua13278b2018-03-21 00:08:13 -07009714 }
9715
9716 @Override
9717 public int getCarrierIdListVersion(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07009718 enforceReadPrivilegedPermission("getCarrierIdListVersion");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009719
9720 final long identity = Binder.clearCallingIdentity();
9721 try {
9722 final Phone phone = getPhone(subId);
9723 if (phone == null) {
9724 loge("getCarrierIdListVersion fails with invalid subId: " + subId);
9725 return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
9726 }
9727 return phone.getCarrierIdListVersion();
9728 } finally {
9729 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07009730 }
fionaxua13278b2018-03-21 00:08:13 -07009731 }
Malcolm Chen2c63d402018-08-14 16:00:53 -07009732
9733 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009734 public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage,
9735 String callingFeatureId) {
Malcolm Chen2c63d402018-08-14 16:00:53 -07009736 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009737 mApp, subId, callingPackage, callingFeatureId,
9738 "getNumberOfModemsWithSimultaneousDataConnections")) {
Malcolm Chen2c63d402018-08-14 16:00:53 -07009739 return -1;
9740 }
9741
9742 final long identity = Binder.clearCallingIdentity();
9743 try {
9744 return mPhoneConfigurationManager.getNumberOfModemsWithSimultaneousDataConnections();
9745 } finally {
9746 Binder.restoreCallingIdentity(identity);
9747 }
9748 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07009749
9750 @Override
9751 public int getCdmaRoamingMode(int subId) {
zoey chen7e6d4e52019-12-17 18:18:59 +08009752 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07009753 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Pengquan Menga1bb6272018-09-06 09:59:22 -07009754 mApp, subId, "getCdmaRoamingMode");
9755
9756 final long identity = Binder.clearCallingIdentity();
9757 try {
9758 return (int) sendRequest(CMD_GET_CDMA_ROAMING_MODE, null /* argument */, subId);
9759 } finally {
9760 Binder.restoreCallingIdentity(identity);
9761 }
9762 }
9763
9764 @Override
9765 public boolean setCdmaRoamingMode(int subId, int mode) {
9766 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
9767 mApp, subId, "setCdmaRoamingMode");
9768
9769 final long identity = Binder.clearCallingIdentity();
9770 try {
9771 return (boolean) sendRequest(CMD_SET_CDMA_ROAMING_MODE, mode, subId);
9772 } finally {
9773 Binder.restoreCallingIdentity(identity);
9774 }
9775 }
9776
9777 @Override
Sarah Chinbaab1432020-10-28 13:46:24 -07009778 public int getCdmaSubscriptionMode(int subId) {
9779 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07009780 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Sarah Chinbaab1432020-10-28 13:46:24 -07009781 mApp, subId, "getCdmaSubscriptionMode");
9782
9783 final long identity = Binder.clearCallingIdentity();
9784 try {
9785 return (int) sendRequest(CMD_GET_CDMA_SUBSCRIPTION_MODE, null /* argument */, subId);
9786 } finally {
9787 Binder.restoreCallingIdentity(identity);
9788 }
9789 }
9790
9791 @Override
Pengquan Menga1bb6272018-09-06 09:59:22 -07009792 public boolean setCdmaSubscriptionMode(int subId, int mode) {
9793 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
9794 mApp, subId, "setCdmaSubscriptionMode");
9795
9796 final long identity = Binder.clearCallingIdentity();
9797 try {
9798 return (boolean) sendRequest(CMD_SET_CDMA_SUBSCRIPTION_MODE, mode, subId);
9799 } finally {
9800 Binder.restoreCallingIdentity(identity);
9801 }
9802 }
Makoto Onukida3bf792018-09-18 16:06:29 -07009803
sqianc5eccab2018-10-19 18:46:41 -07009804 @Override
sqian8c685422019-02-22 15:55:18 -08009805 public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009806 String callingPackage, String callingFeatureId) {
sqian11b7a0e2018-12-05 18:48:28 -08009807 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009808 mApp, getDefaultSubscription(), callingPackage, callingFeatureId,
9809 "getEmergencyNumberList")) {
sqian11b7a0e2018-12-05 18:48:28 -08009810 throw new SecurityException("Requires READ_PHONE_STATE permission.");
9811 }
9812 final long identity = Binder.clearCallingIdentity();
9813 try {
sqian854d44b2018-12-12 16:48:18 -08009814 Map<Integer, List<EmergencyNumber>> emergencyNumberListInternal = new HashMap<>();
9815 for (Phone phone: PhoneFactory.getPhones()) {
9816 if (phone.getEmergencyNumberTracker() != null
9817 && phone.getEmergencyNumberTracker().getEmergencyNumberList() != null) {
9818 emergencyNumberListInternal.put(
9819 phone.getSubId(),
9820 phone.getEmergencyNumberTracker().getEmergencyNumberList());
9821 }
sqian11b7a0e2018-12-05 18:48:28 -08009822 }
sqian854d44b2018-12-12 16:48:18 -08009823 return emergencyNumberListInternal;
sqian11b7a0e2018-12-05 18:48:28 -08009824 } finally {
9825 Binder.restoreCallingIdentity(identity);
9826 }
sqianc5eccab2018-10-19 18:46:41 -07009827 }
9828
9829 @Override
sqian8c685422019-02-22 15:55:18 -08009830 public boolean isEmergencyNumber(String number, boolean exactMatch) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08009831 final Phone defaultPhone = getDefaultPhone();
sqian11b7a0e2018-12-05 18:48:28 -08009832 if (!exactMatch) {
9833 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07009834 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
sqian8c685422019-02-22 15:55:18 -08009835 mApp, defaultPhone.getSubId(), "isEmergencyNumber(Potential)");
sqian11b7a0e2018-12-05 18:48:28 -08009836 }
9837 final long identity = Binder.clearCallingIdentity();
9838 try {
sqian854d44b2018-12-12 16:48:18 -08009839 for (Phone phone: PhoneFactory.getPhones()) {
Chinmay Dhodapkard521bb12022-08-16 15:49:54 -07009840 //Note: we ignore passed in param exactMatch. We can remove it once
9841 // TelephonyManager#isPotentialEmergencyNumber is removed completely
sqian854d44b2018-12-12 16:48:18 -08009842 if (phone.getEmergencyNumberTracker() != null
Taesu Leee050c002020-10-13 17:19:35 +09009843 && phone.getEmergencyNumberTracker()
Chinmay Dhodapkard521bb12022-08-16 15:49:54 -07009844 .isEmergencyNumber(number)) {
Taesu Leee050c002020-10-13 17:19:35 +09009845 return true;
sqian11b7a0e2018-12-05 18:48:28 -08009846 }
sqian11b7a0e2018-12-05 18:48:28 -08009847 }
9848 return false;
9849 } finally {
9850 Binder.restoreCallingIdentity(identity);
9851 }
9852 }
9853
sqianf4ca7ed2019-01-15 18:32:07 -08009854 /**
Shuo Qianccbaf742021-02-22 18:32:21 -08009855 * Start emergency callback mode for GsmCdmaPhone for testing.
9856 */
9857 @Override
9858 public void startEmergencyCallbackMode() {
9859 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
9860 "startEmergencyCallbackMode");
9861 enforceModifyPermission();
9862 final long identity = Binder.clearCallingIdentity();
9863 try {
9864 for (Phone phone : PhoneFactory.getPhones()) {
9865 Rlog.d(LOG_TAG, "startEmergencyCallbackMode phone type: " + phone.getPhoneType());
9866 if (phone != null && ((phone.getPhoneType() == PHONE_TYPE_GSM)
9867 || (phone.getPhoneType() == PHONE_TYPE_CDMA))) {
9868 GsmCdmaPhone gsmCdmaPhone = (GsmCdmaPhone) phone;
9869 gsmCdmaPhone.obtainMessage(
9870 GsmCdmaPhone.EVENT_EMERGENCY_CALLBACK_MODE_ENTER).sendToTarget();
9871 Rlog.d(LOG_TAG, "startEmergencyCallbackMode: triggered");
9872 }
9873 }
9874 } finally {
9875 Binder.restoreCallingIdentity(identity);
9876 }
9877 }
9878
9879 /**
sqianf4ca7ed2019-01-15 18:32:07 -08009880 * Update emergency number list for test mode.
9881 */
9882 @Override
9883 public void updateEmergencyNumberListTestMode(int action, EmergencyNumber num) {
9884 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
9885 "updateEmergencyNumberListTestMode");
9886
9887 final long identity = Binder.clearCallingIdentity();
9888 try {
9889 for (Phone phone: PhoneFactory.getPhones()) {
9890 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
9891 if (tracker != null) {
9892 tracker.executeEmergencyNumberTestModeCommand(action, num);
9893 }
9894 }
9895 } finally {
9896 Binder.restoreCallingIdentity(identity);
9897 }
9898 }
9899
9900 /**
9901 * Get the full emergency number list for test mode.
9902 */
9903 @Override
9904 public List<String> getEmergencyNumberListTestMode() {
9905 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
9906 "getEmergencyNumberListTestMode");
9907
9908 final long identity = Binder.clearCallingIdentity();
9909 try {
9910 Set<String> emergencyNumbers = new HashSet<>();
9911 for (Phone phone: PhoneFactory.getPhones()) {
9912 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
9913 if (tracker != null) {
9914 for (EmergencyNumber num : tracker.getEmergencyNumberList()) {
9915 emergencyNumbers.add(num.getNumber());
9916 }
9917 }
9918 }
9919 return new ArrayList<>(emergencyNumbers);
9920 } finally {
9921 Binder.restoreCallingIdentity(identity);
9922 }
9923 }
9924
chen xud6b45bd2018-10-30 22:27:10 -07009925 @Override
Shuo Qian3b6ee772019-11-13 17:43:31 -08009926 public int getEmergencyNumberDbVersion(int subId) {
9927 enforceReadPrivilegedPermission("getEmergencyNumberDbVersion");
9928
9929 final long identity = Binder.clearCallingIdentity();
9930 try {
9931 final Phone phone = getPhone(subId);
9932 if (phone == null) {
9933 loge("getEmergencyNumberDbVersion fails with invalid subId: " + subId);
9934 return TelephonyManager.INVALID_EMERGENCY_NUMBER_DB_VERSION;
9935 }
9936 return phone.getEmergencyNumberDbVersion();
9937 } finally {
9938 Binder.restoreCallingIdentity(identity);
9939 }
9940 }
9941
9942 @Override
9943 public void notifyOtaEmergencyNumberDbInstalled() {
9944 enforceModifyPermission();
9945
9946 final long identity = Binder.clearCallingIdentity();
9947 try {
9948 for (Phone phone: PhoneFactory.getPhones()) {
9949 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
9950 if (tracker != null) {
9951 tracker.updateOtaEmergencyNumberDatabase();
9952 }
9953 }
9954 } finally {
9955 Binder.restoreCallingIdentity(identity);
9956 }
9957 }
9958
9959 @Override
Shuo Qianc373f112020-03-05 17:55:34 -08009960 public void updateOtaEmergencyNumberDbFilePath(ParcelFileDescriptor otaParcelFileDescriptor) {
Shuo Qian3b6ee772019-11-13 17:43:31 -08009961 enforceActiveEmergencySessionPermission();
9962
9963 final long identity = Binder.clearCallingIdentity();
9964 try {
9965 for (Phone phone: PhoneFactory.getPhones()) {
9966 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
9967 if (tracker != null) {
Shuo Qianc373f112020-03-05 17:55:34 -08009968 tracker.updateOtaEmergencyNumberDbFilePath(otaParcelFileDescriptor);
9969 }
9970 }
9971 } finally {
9972 Binder.restoreCallingIdentity(identity);
9973 }
9974 }
9975
9976 @Override
9977 public void resetOtaEmergencyNumberDbFilePath() {
9978 enforceActiveEmergencySessionPermission();
9979
9980 final long identity = Binder.clearCallingIdentity();
9981 try {
9982 for (Phone phone: PhoneFactory.getPhones()) {
9983 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
9984 if (tracker != null) {
9985 tracker.resetOtaEmergencyNumberDbFilePath();
Shuo Qian3b6ee772019-11-13 17:43:31 -08009986 }
9987 }
9988 } finally {
9989 Binder.restoreCallingIdentity(identity);
9990 }
9991 }
9992
9993 @Override
chen xud6b45bd2018-10-30 22:27:10 -07009994 public List<String> getCertsFromCarrierPrivilegeAccessRules(int subId) {
9995 enforceReadPrivilegedPermission("getCertsFromCarrierPrivilegeAccessRules");
9996 Phone phone = getPhone(subId);
9997 if (phone == null) {
9998 return null;
9999 }
10000 final long identity = Binder.clearCallingIdentity();
10001 try {
10002 UiccProfile profile = UiccController.getInstance()
10003 .getUiccProfileForPhone(phone.getPhoneId());
10004 if (profile != null) {
10005 return profile.getCertsFromCarrierPrivilegeAccessRules();
10006 }
10007 } finally {
10008 Binder.restoreCallingIdentity(identity);
10009 }
10010 return null;
10011 }
Malcolm Chen8e4ed912019-01-15 20:22:16 -080010012
10013 /**
10014 * Enable or disable a modem stack.
10015 */
10016 @Override
10017 public boolean enableModemForSlot(int slotIndex, boolean enable) {
10018 enforceModifyPermission();
10019
10020 final long identity = Binder.clearCallingIdentity();
10021 try {
10022 Phone phone = PhoneFactory.getPhone(slotIndex);
10023 if (phone == null) {
10024 return false;
10025 } else {
10026 return (Boolean) sendRequest(CMD_REQUEST_ENABLE_MODEM, enable, phone, null);
10027 }
10028 } finally {
10029 Binder.restoreCallingIdentity(identity);
10030 }
10031 }
Michelecea4cf22018-12-21 15:00:11 -080010032
Malcolm Chen4bcd9822019-03-27 18:34:05 -070010033 /**
10034 * Whether a modem stack is enabled or not.
10035 */
10036 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -070010037 public boolean isModemEnabledForSlot(int slotIndex, String callingPackage,
10038 String callingFeatureId) {
Malcolm Chen4bcd9822019-03-27 18:34:05 -070010039 Phone phone = PhoneFactory.getPhone(slotIndex);
10040 if (phone == null) return false;
10041
10042 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -070010043 mApp, phone.getSubId(), callingPackage, callingFeatureId,
10044 "isModemEnabledForSlot")) {
Malcolm Chen4bcd9822019-03-27 18:34:05 -070010045 throw new SecurityException("Requires READ_PHONE_STATE permission.");
10046 }
10047
10048 final long identity = Binder.clearCallingIdentity();
10049 try {
Nazanin Bakhshif71371d2019-04-29 17:29:44 -070010050 try {
10051 return mPhoneConfigurationManager.getPhoneStatusFromCache(phone.getPhoneId());
10052 } catch (NoSuchElementException ex) {
10053 return (Boolean) sendRequest(CMD_GET_MODEM_STATUS, null, phone, null);
10054 }
Malcolm Chen4bcd9822019-03-27 18:34:05 -070010055 } finally {
10056 Binder.restoreCallingIdentity(identity);
10057 }
10058 }
10059
Michelecea4cf22018-12-21 15:00:11 -080010060 @Override
Michele0ea7d782019-03-19 14:58:42 -070010061 public void setMultiSimCarrierRestriction(boolean isMultiSimCarrierRestricted) {
Michelecea4cf22018-12-21 15:00:11 -080010062 enforceModifyPermission();
10063
10064 final long identity = Binder.clearCallingIdentity();
10065 try {
10066 mTelephonySharedPreferences.edit()
Michele0ea7d782019-03-19 14:58:42 -070010067 .putBoolean(PREF_MULTI_SIM_RESTRICTED, isMultiSimCarrierRestricted)
Michelecea4cf22018-12-21 15:00:11 -080010068 .commit();
10069 } finally {
10070 Binder.restoreCallingIdentity(identity);
10071 }
10072 }
10073
10074 @Override
Michele0ea7d782019-03-19 14:58:42 -070010075 @TelephonyManager.IsMultiSimSupportedResult
Philip P. Moltmann700a9592019-10-03 11:53:50 -070010076 public int isMultiSimSupported(String callingPackage, String callingFeatureId) {
Michele4245e952019-02-04 11:36:23 -080010077 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp,
Philip P. Moltmann700a9592019-10-03 11:53:50 -070010078 getDefaultPhone().getSubId(), callingPackage, callingFeatureId,
10079 "isMultiSimSupported")) {
Michele0ea7d782019-03-19 14:58:42 -070010080 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele4245e952019-02-04 11:36:23 -080010081 }
Michelecea4cf22018-12-21 15:00:11 -080010082
10083 final long identity = Binder.clearCallingIdentity();
10084 try {
Michele0ea7d782019-03-19 14:58:42 -070010085 return isMultiSimSupportedInternal();
Michelecea4cf22018-12-21 15:00:11 -080010086 } finally {
10087 Binder.restoreCallingIdentity(identity);
10088 }
10089 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -080010090
Michele0ea7d782019-03-19 14:58:42 -070010091 @TelephonyManager.IsMultiSimSupportedResult
10092 private int isMultiSimSupportedInternal() {
Michele30b57b22019-03-01 12:01:14 -080010093 // If the device has less than 2 SIM cards, indicate that multisim is restricted.
10094 int numPhysicalSlots = UiccController.getInstance().getUiccSlots().length;
10095 if (numPhysicalSlots < 2) {
Michele0ea7d782019-03-19 14:58:42 -070010096 loge("isMultiSimSupportedInternal: requires at least 2 cards");
10097 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -080010098 }
10099 // Check if the hardware supports multisim functionality. If usage of multisim is not
10100 // supported by the modem, indicate that it is restricted.
10101 PhoneCapability staticCapability =
10102 mPhoneConfigurationManager.getStaticPhoneCapability();
10103 if (staticCapability == null) {
Michele0ea7d782019-03-19 14:58:42 -070010104 loge("isMultiSimSupportedInternal: no static configuration available");
10105 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -080010106 }
SongFerngWang8236caa2021-01-17 21:51:44 +080010107 if (staticCapability.getLogicalModemList().size() < 2) {
Michele0ea7d782019-03-19 14:58:42 -070010108 loge("isMultiSimSupportedInternal: maximum number of modem is < 2");
10109 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -080010110 }
10111 // Check if support of multiple SIMs is restricted by carrier
10112 if (mTelephonySharedPreferences.getBoolean(PREF_MULTI_SIM_RESTRICTED, false)) {
Michele0ea7d782019-03-19 14:58:42 -070010113 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_CARRIER;
Michele30b57b22019-03-01 12:01:14 -080010114 }
10115
Michele0ea7d782019-03-19 14:58:42 -070010116 return TelephonyManager.MULTISIM_ALLOWED;
Michele30b57b22019-03-01 12:01:14 -080010117 }
10118
Nazanin Bakhshi628473f2019-01-29 17:37:52 -080010119 /**
10120 * Switch configs to enable multi-sim or switch back to single-sim
Nazanin Bakhshi17318782019-03-01 11:56:08 -080010121 * Note: Switch from multi-sim to single-sim is only possible with MODIFY_PHONE_STATE
10122 * permission, but the other way around is possible with either MODIFY_PHONE_STATE
10123 * or carrier privileges
Nazanin Bakhshi628473f2019-01-29 17:37:52 -080010124 * @param numOfSims number of active sims we want to switch to
10125 */
10126 @Override
10127 public void switchMultiSimConfig(int numOfSims) {
Nazanin Bakhshi17318782019-03-01 11:56:08 -080010128 if (numOfSims == 1) {
10129 enforceModifyPermission();
10130 } else {
10131 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
10132 mApp, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, "switchMultiSimConfig");
10133 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -080010134 final long identity = Binder.clearCallingIdentity();
Michele30b57b22019-03-01 12:01:14 -080010135
Nazanin Bakhshi628473f2019-01-29 17:37:52 -080010136 try {
Michele30b57b22019-03-01 12:01:14 -080010137 //only proceed if multi-sim is not restricted
Michele0ea7d782019-03-19 14:58:42 -070010138 if (isMultiSimSupportedInternal() != TelephonyManager.MULTISIM_ALLOWED) {
Michele30b57b22019-03-01 12:01:14 -080010139 loge("switchMultiSimConfig not possible. It is restricted or not supported.");
10140 return;
10141 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -080010142 mPhoneConfigurationManager.switchMultiSimConfig(numOfSims);
10143 } finally {
10144 Binder.restoreCallingIdentity(identity);
10145 }
10146 }
10147
Hyungjun Parkbb07fde2019-01-10 15:28:51 +090010148 @Override
10149 public boolean isApplicationOnUicc(int subId, int appType) {
10150 enforceReadPrivilegedPermission("isApplicationOnUicc");
10151 Phone phone = getPhone(subId);
10152 if (phone == null) {
10153 return false;
10154 }
10155 final long identity = Binder.clearCallingIdentity();
10156 try {
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +000010157 UiccPort uiccPort = phone.getUiccPort();
10158 if (uiccPort == null) {
Hyungjun Parkbb07fde2019-01-10 15:28:51 +090010159 return false;
10160 }
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +000010161 UiccProfile uiccProfile = uiccPort.getUiccProfile();
Hyungjun Parkbb07fde2019-01-10 15:28:51 +090010162 if (uiccProfile == null) {
10163 return false;
10164 }
10165 if (TelephonyManager.APPTYPE_SIM <= appType
10166 && appType <= TelephonyManager.APPTYPE_ISIM) {
10167 return uiccProfile.isApplicationOnIcc(AppType.values()[appType]);
10168 }
10169 return false;
10170 } finally {
10171 Binder.restoreCallingIdentity(identity);
10172 }
10173 }
10174
Nazanin Bakhshi628473f2019-01-29 17:37:52 -080010175 /**
chen xub4baa772019-04-03 10:23:41 -070010176 * Get whether making changes to modem configurations will trigger reboot.
10177 * Return value defaults to true.
Nazanin Bakhshi5fe5ef22019-01-30 10:52:09 -080010178 */
10179 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -070010180 public boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage,
10181 String callingFeatureId) {
chen xub4baa772019-04-03 10:23:41 -070010182 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -070010183 mApp, subId, callingPackage, callingFeatureId,
10184 "doesSwitchMultiSimConfigTriggerReboot")) {
chen xub4baa772019-04-03 10:23:41 -070010185 return false;
10186 }
Nazanin Bakhshi5fe5ef22019-01-30 10:52:09 -080010187 final long identity = Binder.clearCallingIdentity();
10188 try {
10189 return mPhoneConfigurationManager.isRebootRequiredForModemConfigChange();
10190 } finally {
10191 Binder.restoreCallingIdentity(identity);
10192 }
10193 }
10194
Nathan Harold29f5f052019-02-15 13:41:57 -080010195 private void updateModemStateMetrics() {
10196 TelephonyMetrics metrics = TelephonyMetrics.getInstance();
10197 // TODO: check the state for each modem if the api is ready.
10198 metrics.updateEnabledModemBitmap((1 << TelephonyManager.from(mApp).getPhoneCount()) - 1);
10199 }
10200
Pengquan Meng3889a572019-01-23 11:16:29 -080010201 @Override
sandeepjsa208e3b2021-11-17 04:05:58 +000010202 public List<UiccSlotMapping> getSlotsMapping(String callingPackage) {
Pengquan Meng3889a572019-01-23 11:16:29 -080010203 enforceReadPrivilegedPermission("getSlotsMapping");
sandeepjsa208e3b2021-11-17 04:05:58 +000010204 // Verify that the callingPackage belongs to the calling UID
10205 mApp.getSystemService(AppOpsManager.class)
10206 .checkPackage(Binder.getCallingUid(), callingPackage);
Pengquan Meng3889a572019-01-23 11:16:29 -080010207 final long identity = Binder.clearCallingIdentity();
sandeepjsa208e3b2021-11-17 04:05:58 +000010208 List<UiccSlotMapping> slotMap = new ArrayList<>();
Pengquan Meng3889a572019-01-23 11:16:29 -080010209 try {
sandeepjsa208e3b2021-11-17 04:05:58 +000010210 UiccSlotInfo[] slotInfos = getUiccSlotsInfo(mApp.getOpPackageName());
10211 if (slotInfos != null) {
10212 for (int i = 0; i < slotInfos.length; i++) {
10213 for (UiccPortInfo portInfo : slotInfos[i].getPorts()) {
10214 if (SubscriptionManager.isValidPhoneId(portInfo.getLogicalSlotIndex())) {
10215 slotMap.add(new UiccSlotMapping(portInfo.getPortIndex(), i,
10216 portInfo.getLogicalSlotIndex()));
10217 }
10218 }
Pengquan Meng3889a572019-01-23 11:16:29 -080010219 }
10220 }
sandeepjsa208e3b2021-11-17 04:05:58 +000010221 return slotMap;
Pengquan Meng3889a572019-01-23 11:16:29 -080010222 } finally {
10223 Binder.restoreCallingIdentity(identity);
10224 }
10225 }
Nathan Harold48d6fd52019-02-06 19:01:40 -080010226
10227 /**
10228 * Get the IRadio HAL Version
jimsunf9ec1622022-09-13 21:18:43 +080010229 * @deprecated use getHalVersion instead
Nathan Harold48d6fd52019-02-06 19:01:40 -080010230 */
jimsunf9ec1622022-09-13 21:18:43 +080010231 @Deprecated
Nathan Harold48d6fd52019-02-06 19:01:40 -080010232 @Override
10233 public int getRadioHalVersion() {
jimsunf9ec1622022-09-13 21:18:43 +080010234 return getHalVersion(HAL_SERVICE_RADIO);
10235 }
10236
10237 /**
10238 * Get the HAL Version of a specific service
10239 */
10240 @Override
10241 public int getHalVersion(int service) {
Nathan Harold48d6fd52019-02-06 19:01:40 -080010242 Phone phone = getDefaultPhone();
10243 if (phone == null) return -1;
jimsunf9ec1622022-09-13 21:18:43 +080010244 HalVersion hv = phone.getHalVersion(service);
Nathan Harold48d6fd52019-02-06 19:01:40 -080010245 if (hv.equals(HalVersion.UNKNOWN)) return -1;
10246 return hv.major * 100 + hv.minor;
10247 }
Malcolm Chendc8c10e2019-04-10 18:25:07 -070010248
10249 /**
Shuo Qianda2d6ec2020-01-14 15:18:28 -080010250 * Get the current calling package name.
10251 * @return the current calling package name
10252 */
10253 @Override
10254 public String getCurrentPackageName() {
10255 return mApp.getPackageManager().getPackagesForUid(Binder.getCallingUid())[0];
10256 }
10257
10258 /**
Malcolm Chene5ad5792019-04-18 13:51:02 -070010259 * Return whether data is enabled for certain APN type. This will tell if framework will accept
10260 * corresponding network requests on a subId.
10261 *
10262 * Data is enabled if:
Malcolm Chendc8c10e2019-04-10 18:25:07 -070010263 * 1) user data is turned on, or
Malcolm Chene5ad5792019-04-18 13:51:02 -070010264 * 2) APN is un-metered for this subscription, or
10265 * 3) APN type is whitelisted. E.g. MMS is whitelisted if
Hall Liu746e03c2020-09-25 11:13:49 -070010266 * {@link TelephonyManager#MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED} is enabled.
Malcolm Chene5ad5792019-04-18 13:51:02 -070010267 *
10268 * @return whether data is allowed for a apn type.
10269 *
10270 * @hide
Malcolm Chendc8c10e2019-04-10 18:25:07 -070010271 */
10272 @Override
Malcolm Chene5ad5792019-04-18 13:51:02 -070010273 public boolean isDataEnabledForApn(int apnType, int subId, String callingPackage) {
Amit Mahajan5d4e1922019-10-07 16:20:43 -070010274 enforceReadPrivilegedPermission("Needs READ_PRIVILEGED_PHONE_STATE for "
10275 + "isDataEnabledForApn");
Malcolm Chendc8c10e2019-04-10 18:25:07 -070010276
10277 // Now that all security checks passes, perform the operation as ourselves.
10278 final long identity = Binder.clearCallingIdentity();
10279 try {
10280 Phone phone = getPhone(subId);
10281 if (phone == null) return false;
10282
Jack Yu27422a52022-03-21 10:38:05 -070010283 boolean isMetered;
Jack Yu99e87332021-12-17 23:14:15 -080010284 boolean isDataEnabled;
Jack Yu7968c6d2022-07-31 00:43:21 -070010285 isMetered = phone.getDataNetworkController().getDataConfigManager()
10286 .isMeteredCapability(DataUtils.apnTypeToNetworkCapability(apnType),
10287 phone.getServiceState().getDataRoaming());
10288 isDataEnabled = phone.getDataSettingsManager().isDataEnabled(apnType);
Jack Yu99e87332021-12-17 23:14:15 -080010289 return !isMetered || isDataEnabled;
Malcolm Chene5ad5792019-04-18 13:51:02 -070010290 } finally {
10291 Binder.restoreCallingIdentity(identity);
10292 }
10293 }
10294
10295 @Override
Jack Yu41407ee2019-05-13 16:54:09 -070010296 public boolean isApnMetered(@ApnType int apnType, int subId) {
Malcolm Chene5ad5792019-04-18 13:51:02 -070010297 enforceReadPrivilegedPermission("isApnMetered");
10298
10299 // Now that all security checks passes, perform the operation as ourselves.
10300 final long identity = Binder.clearCallingIdentity();
10301 try {
10302 Phone phone = getPhone(subId);
10303 if (phone == null) return true; // By default return true.
Jack Yu7968c6d2022-07-31 00:43:21 -070010304 return phone.getDataNetworkController().getDataConfigManager().isMeteredCapability(
10305 DataUtils.apnTypeToNetworkCapability(apnType),
10306 phone.getServiceState().getDataRoaming());
Malcolm Chendc8c10e2019-04-10 18:25:07 -070010307 } finally {
10308 Binder.restoreCallingIdentity(identity);
10309 }
10310 }
Brad Ebingera63db5f2019-04-23 16:31:13 -070010311
10312 @Override
Hall Liu73f5d362020-01-20 13:42:00 -080010313 public void setSystemSelectionChannels(List<RadioAccessSpecifier> specifiers,
10314 int subscriptionId, IBooleanConsumer resultCallback) {
10315 enforceModifyPermission();
10316 long token = Binder.clearCallingIdentity();
10317 try {
10318 Phone phone = getPhone(subscriptionId);
10319 if (phone == null) {
10320 try {
10321 if (resultCallback != null) {
10322 resultCallback.accept(false);
10323 }
10324 } catch (RemoteException e) {
10325 // ignore
10326 }
10327 return;
10328 }
10329 Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> argument =
10330 Pair.create(specifiers, (x) -> {
10331 try {
10332 if (resultCallback != null) {
10333 resultCallback.accept(x);
10334 }
10335 } catch (RemoteException e) {
10336 // ignore
10337 }
10338 });
10339 sendRequestAsync(CMD_SET_SYSTEM_SELECTION_CHANNELS, argument, phone, null);
10340 } finally {
10341 Binder.restoreCallingIdentity(token);
10342 }
10343 }
10344
10345 @Override
Sarah Chin679c08a2020-11-18 13:39:35 -080010346 public List<RadioAccessSpecifier> getSystemSelectionChannels(int subId) {
10347 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -070010348 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Sarah Chin679c08a2020-11-18 13:39:35 -080010349 mApp, subId, "getSystemSelectionChannels");
10350 WorkSource workSource = getWorkSource(Binder.getCallingUid());
10351 final long identity = Binder.clearCallingIdentity();
10352 try {
Sarah Chin428d1d62021-03-13 03:17:40 -080010353 Object result = sendRequest(CMD_GET_SYSTEM_SELECTION_CHANNELS, null, subId, workSource);
10354 if (result instanceof IllegalStateException) {
10355 throw (IllegalStateException) result;
10356 }
10357 List<RadioAccessSpecifier> specifiers = (List<RadioAccessSpecifier>) result;
Sarah Chin679c08a2020-11-18 13:39:35 -080010358 if (DBG) log("getSystemSelectionChannels: " + specifiers);
10359 return specifiers;
10360 } finally {
10361 Binder.restoreCallingIdentity(identity);
10362 }
10363 }
10364
10365 @Override
Jack Yu8b766fc2022-03-21 09:42:33 -070010366 public boolean isMvnoMatched(int slotIndex, int mvnoType, @NonNull String mvnoMatchData) {
changbettyca3d40d2020-03-03 16:27:31 +080010367 enforceReadPrivilegedPermission("isMvnoMatched");
Jack Yu8b766fc2022-03-21 09:42:33 -070010368 return UiccController.getInstance().mvnoMatches(slotIndex, mvnoType, mvnoMatchData);
changbetty7157e9e2019-12-06 18:16:37 +080010369 }
10370
10371 @Override
Philip P. Moltmannd02b7372020-03-18 17:06:12 -070010372 public void enqueueSmsPickResult(String callingPackage, String callingAttributionTag,
10373 IIntegerConsumer pendingSubIdResult) {
Shuo Qianda2d6ec2020-01-14 15:18:28 -080010374 if (callingPackage == null) {
10375 callingPackage = getCurrentPackageName();
10376 }
Brad Ebingera63db5f2019-04-23 16:31:13 -070010377 SmsPermissions permissions = new SmsPermissions(getDefaultPhone(), mApp,
10378 (AppOpsManager) mApp.getSystemService(Context.APP_OPS_SERVICE));
Philip P. Moltmannd02b7372020-03-18 17:06:12 -070010379 if (!permissions.checkCallingCanSendSms(callingPackage, callingAttributionTag,
10380 "Sending message")) {
Brad Ebingera63db5f2019-04-23 16:31:13 -070010381 throw new SecurityException("Requires SEND_SMS permission to perform this operation");
10382 }
10383 PickSmsSubscriptionActivity.addPendingResult(pendingSubIdResult);
10384 Intent intent = new Intent();
10385 intent.setClass(mApp, PickSmsSubscriptionActivity.class);
10386 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10387 // Bring up choose default SMS subscription dialog right now
10388 intent.putExtra(PickSmsSubscriptionActivity.DIALOG_TYPE_KEY,
10389 PickSmsSubscriptionActivity.SMS_PICK_FOR_MESSAGE);
10390 mApp.startActivity(intent);
10391 }
chen xud5ca2d52019-05-28 15:20:57 -070010392
10393 @Override
Ayush Sharma787854b2022-12-12 14:55:02 +000010394 public void showSwitchToManagedProfileDialog() {
10395 enforceModifyPermission();
10396
10397 Intent intent = new Intent();
10398 intent.setClass(mApp, ErrorDialogActivity.class);
10399 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10400 mApp.startActivity(intent);
10401 }
10402
10403 @Override
chen xud5ca2d52019-05-28 15:20:57 -070010404 public String getMmsUAProfUrl(int subId) {
10405 //TODO investigate if this API should require proper permission check in R b/133791609
10406 final long identity = Binder.clearCallingIdentity();
10407 try {
Guoqiang.Qiu171383d2020-07-13 09:38:32 +080010408 String carrierUAProfUrl = mApp.getCarrierConfigForSubId(subId).getString(
10409 CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING);
10410 if (!TextUtils.isEmpty(carrierUAProfUrl)) {
10411 return carrierUAProfUrl;
10412 }
Daniel Brightebb4eb72020-02-18 15:16:33 -080010413 return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
10414 .getString(com.android.internal.R.string.config_mms_user_agent_profile_url);
chen xud5ca2d52019-05-28 15:20:57 -070010415 } finally {
10416 Binder.restoreCallingIdentity(identity);
10417 }
10418 }
10419
10420 @Override
10421 public String getMmsUserAgent(int subId) {
10422 //TODO investigate if this API should require proper permission check in R b/133791609
10423 final long identity = Binder.clearCallingIdentity();
10424 try {
Guoqiang.Qiu171383d2020-07-13 09:38:32 +080010425 String carrierUserAgent = mApp.getCarrierConfigForSubId(subId).getString(
10426 CarrierConfigManager.KEY_MMS_USER_AGENT_STRING);
10427 if (!TextUtils.isEmpty(carrierUserAgent)) {
10428 return carrierUserAgent;
10429 }
Daniel Brightebb4eb72020-02-18 15:16:33 -080010430 return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
10431 .getString(com.android.internal.R.string.config_mms_user_agent);
chen xud5ca2d52019-05-28 15:20:57 -070010432 } finally {
10433 Binder.restoreCallingIdentity(identity);
10434 }
10435 }
Jack Yub07d4972019-05-28 16:12:25 -070010436
10437 @Override
Hall Liua62f5da2020-09-25 10:42:19 -070010438 public boolean isMobileDataPolicyEnabled(int subscriptionId, int policy) {
10439 enforceReadPrivilegedPermission("isMobileDataPolicyEnabled");
Jack Yub07d4972019-05-28 16:12:25 -070010440
Jack Yub07d4972019-05-28 16:12:25 -070010441 final long identity = Binder.clearCallingIdentity();
10442 try {
Hall Liua62f5da2020-09-25 10:42:19 -070010443 Phone phone = getPhone(subscriptionId);
Jack Yub07d4972019-05-28 16:12:25 -070010444 if (phone == null) return false;
10445
Ling Maf188d502022-09-16 15:22:36 -070010446 return phone.getDataSettingsManager().isMobileDataPolicyEnabled(policy);
Jack Yub07d4972019-05-28 16:12:25 -070010447 } finally {
10448 Binder.restoreCallingIdentity(identity);
10449 }
10450 }
10451
10452 @Override
Hall Liuc66bb112021-02-02 12:09:32 -080010453 public void setMobileDataPolicyEnabled(int subscriptionId, int policy,
Hall Liua62f5da2020-09-25 10:42:19 -070010454 boolean enabled) {
changbettyd5c246e2019-12-24 15:40:37 +080010455 enforceModifyPermission();
10456
changbettyd5c246e2019-12-24 15:40:37 +080010457 final long identity = Binder.clearCallingIdentity();
10458 try {
Hall Liua62f5da2020-09-25 10:42:19 -070010459 Phone phone = getPhone(subscriptionId);
10460 if (phone == null) return;
changbettyd5c246e2019-12-24 15:40:37 +080010461
Ling Maf188d502022-09-16 15:22:36 -070010462 phone.getDataSettingsManager().setMobileDataPolicy(policy, enabled);
changbettyd5c246e2019-12-24 15:40:37 +080010463 } finally {
10464 Binder.restoreCallingIdentity(identity);
10465 }
10466 }
10467
Tyler Gunn7bcdc742019-10-04 15:56:59 -070010468 /**
Hall Liu746e03c2020-09-25 11:13:49 -070010469 * Updates whether conference event package handling is enabled.
Tyler Gunn7bcdc742019-10-04 15:56:59 -070010470 * @param isCepEnabled {@code true} if CEP handling is enabled (default), or {@code false}
10471 * otherwise.
10472 */
10473 @Override
10474 public void setCepEnabled(boolean isCepEnabled) {
10475 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setCepEnabled");
10476
10477 final long identity = Binder.clearCallingIdentity();
10478 try {
10479 Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled);
10480 for (Phone phone : PhoneFactory.getPhones()) {
10481 Phone defaultPhone = phone.getImsPhone();
10482 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
10483 ImsPhone imsPhone = (ImsPhone) defaultPhone;
10484 ImsPhoneCallTracker imsPhoneCallTracker =
10485 (ImsPhoneCallTracker) imsPhone.getCallTracker();
10486 imsPhoneCallTracker.setConferenceEventPackageEnabled(isCepEnabled);
10487 Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled + ", for imsPhone "
10488 + imsPhone.getMsisdn());
10489 }
10490 }
10491 } finally {
10492 Binder.restoreCallingIdentity(identity);
10493 }
10494 }
allenwtsu46dcc572020-01-08 18:24:03 +080010495
10496 /**
10497 * Notify that an RCS autoconfiguration XML file has been received for provisioning.
10498 *
10499 * @param config The XML file to be read. ASCII/UTF8 encoded text if not compressed.
10500 * @param isCompressed The XML file is compressed in gzip format and must be decompressed
10501 * before being read.
10502 */
10503 @Override
10504 public void notifyRcsAutoConfigurationReceived(int subId, @NonNull byte[] config, boolean
10505 isCompressed) {
10506 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
10507 mApp, subId, "notifyRcsAutoConfigurationReceived");
Hui Wang761a6682020-10-31 05:12:53 +000010508 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
10509 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
10510 }
10511 if (!isImsAvailableOnDevice()) {
joonhunshin46b49a32022-12-21 05:33:23 +000010512 // ProvisioningManager can not handle ServiceSpecificException.
10513 // Throw the IllegalStateException and annotate ProvisioningManager.
10514 throw new IllegalStateException("IMS not available on device.");
Hui Wang761a6682020-10-31 05:12:53 +000010515 }
10516
10517 final long identity = Binder.clearCallingIdentity();
allenwtsu46dcc572020-01-08 18:24:03 +080010518 try {
Hui Wang761a6682020-10-31 05:12:53 +000010519 RcsProvisioningMonitor.getInstance().updateConfig(subId, config, isCompressed);
10520 } finally {
10521 Binder.restoreCallingIdentity(identity);
allenwtsu46dcc572020-01-08 18:24:03 +080010522 }
10523 }
zoey chene02881a2019-12-30 16:11:23 +080010524
10525 @Override
10526 public boolean isIccLockEnabled(int subId) {
10527 enforceReadPrivilegedPermission("isIccLockEnabled");
10528
10529 // Now that all security checks passes, perform the operation as ourselves.
10530 final long identity = Binder.clearCallingIdentity();
10531 try {
10532 Phone phone = getPhone(subId);
10533 if (phone != null && phone.getIccCard() != null) {
10534 return phone.getIccCard().getIccLockEnabled();
10535 } else {
10536 return false;
10537 }
10538 } finally {
10539 Binder.restoreCallingIdentity(identity);
10540 }
10541 }
10542
10543 /**
10544 * Set the ICC pin lock enabled or disabled.
10545 *
10546 * @return an integer representing the status of IccLock enabled or disabled in the following
10547 * three cases:
10548 * - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if enabled or disabled IccLock
10549 * successfully.
10550 * - Positive number and zero for remaining password attempts.
10551 * - Negative number for other failure cases (such like enabling/disabling PIN failed).
10552 *
10553 */
10554 @Override
10555 public int setIccLockEnabled(int subId, boolean enabled, String password) {
10556 enforceModifyPermission();
10557
10558 Phone phone = getPhone(subId);
10559 if (phone == null) {
10560 return 0;
10561 }
10562 // Now that all security checks passes, perform the operation as ourselves.
10563 final long identity = Binder.clearCallingIdentity();
10564 try {
10565 int attemptsRemaining = (int) sendRequest(CMD_SET_ICC_LOCK_ENABLED,
10566 new Pair<Boolean, String>(enabled, password), phone, null);
10567 return attemptsRemaining;
10568
10569 } catch (Exception e) {
10570 Log.e(LOG_TAG, "setIccLockEnabled. Exception e =" + e);
10571 } finally {
10572 Binder.restoreCallingIdentity(identity);
10573 }
10574 return 0;
10575 }
10576
10577 /**
10578 * Change the ICC password used in ICC pin lock.
10579 *
10580 * @return an integer representing the status of IccLock changed in the following three cases:
10581 * - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if changed IccLock successfully.
10582 * - Positive number and zero for remaining password attempts.
10583 * - Negative number for other failure cases (such like enabling/disabling PIN failed).
10584 *
10585 */
10586 @Override
10587 public int changeIccLockPassword(int subId, String oldPassword, String newPassword) {
10588 enforceModifyPermission();
10589
10590 Phone phone = getPhone(subId);
10591 if (phone == null) {
10592 return 0;
10593 }
10594 // Now that all security checks passes, perform the operation as ourselves.
10595 final long identity = Binder.clearCallingIdentity();
10596 try {
10597 int attemptsRemaining = (int) sendRequest(CMD_CHANGE_ICC_LOCK_PASSWORD,
10598 new Pair<String, String>(oldPassword, newPassword), phone, null);
10599 return attemptsRemaining;
10600
10601 } catch (Exception e) {
10602 Log.e(LOG_TAG, "changeIccLockPassword. Exception e =" + e);
10603 } finally {
10604 Binder.restoreCallingIdentity(identity);
10605 }
10606 return 0;
10607 }
Peter Wangdafb9ac2020-01-15 14:13:38 -080010608
10609 /**
10610 * Request for receiving user activity notification
10611 */
10612 @Override
10613 public void requestUserActivityNotification() {
10614 if (!mNotifyUserActivity.get()
10615 && !mMainThreadHandler.hasMessages(MSG_NOTIFY_USER_ACTIVITY)) {
10616 mNotifyUserActivity.set(true);
10617 }
10618 }
10619
10620 /**
10621 * Called when userActivity is signalled in the power manager.
10622 * This is safe to call from any thread, with any window manager locks held or not.
10623 */
10624 @Override
10625 public void userActivity() {
10626 // ***************************************
10627 // * Inherited from PhoneWindowManager *
10628 // ***************************************
10629 // THIS IS CALLED FROM DEEP IN THE POWER MANAGER
10630 // WITH ITS LOCKS HELD.
10631 //
10632 // This code must be VERY careful about the locks
10633 // it acquires.
10634 // In fact, the current code acquires way too many,
10635 // and probably has lurking deadlocks.
10636
10637 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10638 throw new SecurityException("Only the OS may call notifyUserActivity()");
10639 }
10640
10641 if (mNotifyUserActivity.getAndSet(false)) {
10642 mMainThreadHandler.sendEmptyMessageDelayed(MSG_NOTIFY_USER_ACTIVITY,
10643 USER_ACTIVITY_NOTIFICATION_DELAY);
10644 }
10645 }
Malcolm Chen4639c562020-04-13 11:59:40 -070010646
10647 @Override
10648 public boolean canConnectTo5GInDsdsMode() {
10649 return mApp.getResources().getBoolean(R.bool.config_5g_connection_in_dsds_mode);
10650 }
Jack Yud10cdd42020-09-28 20:28:01 -070010651
10652 @Override
10653 public @NonNull List<String> getEquivalentHomePlmns(int subId, String callingPackage,
10654 String callingFeatureId) {
10655 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
10656 mApp, subId, callingPackage, callingFeatureId, "getEquivalentHomePlmns")) {
10657 throw new SecurityException("Requires READ_PHONE_STATE permission.");
10658 }
10659
10660 Phone phone = getPhone(subId);
10661 if (phone == null) {
10662 throw new RuntimeException("phone is not available");
10663 }
10664 // Now that all security checks passes, perform the operation as ourselves.
10665 final long identity = Binder.clearCallingIdentity();
10666 try {
10667 return phone.getEquivalentHomePlmns();
10668 } finally {
10669 Binder.restoreCallingIdentity(identity);
10670 }
10671 }
Daniel Bright59e67312020-11-13 11:49:37 -080010672
10673 @Override
10674 public boolean isRadioInterfaceCapabilitySupported(
Daniel Bright95a4c1f2021-02-11 09:57:16 -080010675 final @NonNull @TelephonyManager.RadioInterfaceCapability String capability) {
10676 Set<String> radioInterfaceCapabilities =
Daniel Bright94f43662021-03-01 14:43:40 -080010677 mRadioInterfaceCapabilities.getCapabilities();
Daniel Bright59e67312020-11-13 11:49:37 -080010678 if (radioInterfaceCapabilities == null) {
10679 throw new RuntimeException("radio interface capabilities are not available");
Daniel Bright59e67312020-11-13 11:49:37 -080010680 }
Daniel Bright95a4c1f2021-02-11 09:57:16 -080010681 return radioInterfaceCapabilities.contains(capability);
Daniel Bright59e67312020-11-13 11:49:37 -080010682 }
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010683
Hui Wang641e81c2020-10-12 12:14:23 -070010684 @Override
10685 public void bootstrapAuthenticationRequest(int subId, int appType, Uri nafUrl,
10686 UaSecurityProtocolIdentifier securityProtocol,
Brad Ebinger34c09a52021-02-17 23:23:21 +000010687 boolean forceBootStrapping, IBootstrapAuthenticationCallback callback) {
10688 TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
10689 Binder.getCallingUid(), "bootstrapAuthenticationRequest",
10690 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
10691 Manifest.permission.MODIFY_PHONE_STATE);
Hui Wang641e81c2020-10-12 12:14:23 -070010692 if (DBG) {
10693 log("bootstrapAuthenticationRequest, subId:" + subId + ", appType:"
10694 + appType + ", NAF:" + nafUrl + ", sp:" + securityProtocol
10695 + ", forceBootStrapping:" + forceBootStrapping + ", callback:" + callback);
10696 }
10697
10698 if (!SubscriptionManager.isValidSubscriptionId(subId)
10699 || appType < TelephonyManager.APPTYPE_UNKNOWN
10700 || appType > TelephonyManager.APPTYPE_ISIM
10701 || nafUrl == null || securityProtocol == null || callback == null) {
10702 Log.d(LOG_TAG, "bootstrapAuthenticationRequest failed due to invalid parameters");
10703 if (callback != null) {
10704 try {
10705 callback.onAuthenticationFailure(
10706 0, TelephonyManager.GBA_FAILURE_REASON_FEATURE_NOT_SUPPORTED);
10707 } catch (RemoteException exception) {
10708 log("Fail to notify onAuthenticationFailure due to " + exception);
10709 }
10710 return;
10711 }
10712 }
10713
10714 final long token = Binder.clearCallingIdentity();
10715 try {
10716 getGbaManager(subId).bootstrapAuthenticationRequest(
10717 new GbaAuthRequest(subId, appType, nafUrl, securityProtocol.toByteArray(),
10718 forceBootStrapping, callback));
10719 } finally {
10720 Binder.restoreCallingIdentity(token);
10721 }
10722 }
10723
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010724 /**
Sooraj Sasindran72cff492021-07-29 09:42:42 -070010725 * Attempts to set the radio power state for all phones for thermal reason.
10726 * This does not guarantee that the
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010727 * requested radio power state will actually be set. See {@link
10728 * PhoneInternalInterface#setRadioPowerForReason} for more details.
10729 *
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010730 * @param enable {@code true} if trying to turn radio on.
10731 * @return {@code true} if phone setRadioPowerForReason was called. Otherwise, returns {@code
10732 * false}.
10733 */
Sooraj Sasindran72cff492021-07-29 09:42:42 -070010734 private boolean setRadioPowerForThermal(boolean enable) {
10735 boolean isPhoneAvailable = false;
10736 for (int i = 0; i < TelephonyManager.getDefault().getActiveModemCount(); i++) {
10737 Phone phone = PhoneFactory.getPhone(i);
10738 if (phone != null) {
Thomas Nguyenfd0572f2022-07-15 22:28:49 +000010739 phone.setRadioPowerForReason(enable, TelephonyManager.RADIO_POWER_REASON_THERMAL);
Sooraj Sasindran72cff492021-07-29 09:42:42 -070010740 isPhoneAvailable = true;
10741 }
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010742 }
Sooraj Sasindran72cff492021-07-29 09:42:42 -070010743
10744 // return true if successfully informed the phone object about the thermal radio power
10745 // request.
10746 return isPhoneAvailable;
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010747 }
10748
10749 private int handleDataThrottlingRequest(int subId,
Sarah Chinecc78c42022-03-31 21:16:48 -070010750 DataThrottlingRequest dataThrottlingRequest, String callingPackage) {
Jack Nudelman5d6a98b2021-03-04 14:26:25 -080010751 boolean isDataThrottlingSupported = isRadioInterfaceCapabilitySupported(
10752 TelephonyManager.CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING);
10753 if (!isDataThrottlingSupported && dataThrottlingRequest.getDataThrottlingAction()
10754 != DataThrottlingRequest.DATA_THROTTLING_ACTION_NO_DATA_THROTTLING) {
10755 throw new IllegalArgumentException("modem does not support data throttling");
10756 }
10757
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010758 // Ensure that radio is on. If not able to power on due to phone being unavailable, return
10759 // THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
Sooraj Sasindran72cff492021-07-29 09:42:42 -070010760 if (!setRadioPowerForThermal(true)) {
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010761 return TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
10762 }
10763
Sarah Chinecc78c42022-03-31 21:16:48 -070010764 setDataEnabledForReason(
10765 subId, TelephonyManager.DATA_ENABLED_REASON_THERMAL, true, callingPackage);
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010766
Jack Nudelman5d6a98b2021-03-04 14:26:25 -080010767 if (isDataThrottlingSupported) {
10768 int thermalMitigationResult =
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010769 (int) sendRequest(CMD_SET_DATA_THROTTLING, dataThrottlingRequest, subId);
Jack Nudelman5d6a98b2021-03-04 14:26:25 -080010770 if (thermalMitigationResult == SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS) {
10771 throw new IllegalArgumentException("modem returned INVALID_ARGUMENTS");
10772 } else if (thermalMitigationResult
10773 == MODEM_DOES_NOT_SUPPORT_DATA_THROTTLING_ERROR_CODE) {
Jack Nudelman760d0962021-05-20 13:57:30 -070010774 log("Modem likely does not support data throttling on secondary carrier. Data " +
10775 "throttling action = " + dataThrottlingRequest.getDataThrottlingAction());
10776 return TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
Jack Nudelman5d6a98b2021-03-04 14:26:25 -080010777 }
10778 return thermalMitigationResult;
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010779 }
Jack Nudelman5d6a98b2021-03-04 14:26:25 -080010780
10781 return TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010782 }
10783
Jack Nudelman644b91a2021-03-12 14:09:48 -080010784 private static List<String> getThermalMitigationAllowlist(Context context) {
10785 if (sThermalMitigationAllowlistedPackages.isEmpty()) {
10786 for (String pckg : context.getResources()
10787 .getStringArray(R.array.thermal_mitigation_allowlisted_packages)) {
10788 sThermalMitigationAllowlistedPackages.add(pckg);
10789 }
10790 }
10791
10792 return sThermalMitigationAllowlistedPackages;
10793 }
10794
Jack Nudelmane69bbc82021-05-13 10:00:15 -070010795 private boolean isAnyPhoneInEmergencyState() {
10796 TelecomManager tm = mApp.getSystemService(TelecomManager.class);
10797 if (tm.isInEmergencyCall()) {
10798 Log.e(LOG_TAG , "Phone state is not valid. One of the phones is in an emergency call");
10799 return true;
10800 }
10801 for (Phone phone : PhoneFactory.getPhones()) {
10802 if (phone.isInEmergencySmsMode() || phone.isInEcm()) {
10803 Log.e(LOG_TAG, "Phone state is not valid. isInEmergencySmsMode = "
10804 + phone.isInEmergencySmsMode() + " isInEmergencyCallbackMode = "
10805 + phone.isInEcm());
10806 return true;
10807 }
10808 }
10809
10810 return false;
10811 }
10812
Jack Nudelman644b91a2021-03-12 14:09:48 -080010813 /**
10814 * Used by shell commands to add an authorized package name for thermal mitigation.
10815 * @param packageName name of package to be allowlisted
10816 * @param context
10817 */
10818 static void addPackageToThermalMitigationAllowlist(String packageName, Context context) {
10819 sThermalMitigationAllowlistedPackages = getThermalMitigationAllowlist(context);
10820 sThermalMitigationAllowlistedPackages.add(packageName);
10821 }
10822
10823 /**
10824 * Used by shell commands to remove an authorized package name for thermal mitigation.
10825 * @param packageName name of package to remove from allowlist
10826 * @param context
10827 */
10828 static void removePackageFromThermalMitigationAllowlist(String packageName, Context context) {
10829 sThermalMitigationAllowlistedPackages = getThermalMitigationAllowlist(context);
10830 sThermalMitigationAllowlistedPackages.remove(packageName);
10831 }
10832
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010833 /**
10834 * Thermal mitigation request to control functionalities at modem.
10835 *
10836 * @param subId the id of the subscription.
10837 * @param thermalMitigationRequest holds all necessary information to be passed down to modem.
Jack Nudelman644b91a2021-03-12 14:09:48 -080010838 * @param callingPackage the package name of the calling package.
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010839 *
10840 * @return thermalMitigationResult enum as defined in android.telephony.Annotation.
10841 */
10842 @Override
10843 @ThermalMitigationResult
10844 public int sendThermalMitigationRequest(
10845 int subId,
Jack Nudelman644b91a2021-03-12 14:09:48 -080010846 ThermalMitigationRequest thermalMitigationRequest,
10847 String callingPackage) throws IllegalArgumentException {
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010848 enforceModifyPermission();
10849
Jack Nudelman644b91a2021-03-12 14:09:48 -080010850 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
10851 if (!getThermalMitigationAllowlist(getDefaultPhone().getContext())
10852 .contains(callingPackage)) {
10853 throw new SecurityException("Calling package must be configured in the device config. "
10854 + "calling package: " + callingPackage);
10855 }
10856
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010857 WorkSource workSource = getWorkSource(Binder.getCallingUid());
10858 final long identity = Binder.clearCallingIdentity();
10859
10860 int thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_UNKNOWN_ERROR;
10861 try {
10862 int thermalMitigationAction = thermalMitigationRequest.getThermalMitigationAction();
10863 switch (thermalMitigationAction) {
10864 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_DATA_THROTTLING:
10865 thermalMitigationResult =
10866 handleDataThrottlingRequest(subId,
Sarah Chinecc78c42022-03-31 21:16:48 -070010867 thermalMitigationRequest.getDataThrottlingRequest(),
10868 callingPackage);
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010869 break;
10870 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_VOICE_ONLY:
10871 if (thermalMitigationRequest.getDataThrottlingRequest() != null) {
10872 throw new IllegalArgumentException("dataThrottlingRequest must be null for "
10873 + "ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_VOICE_ONLY");
10874 }
10875
10876 // Ensure that radio is on. If not able to power on due to phone being
10877 // unavailable, return THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
Sooraj Sasindran72cff492021-07-29 09:42:42 -070010878 if (!setRadioPowerForThermal(true)) {
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010879 thermalMitigationResult =
10880 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
10881 break;
10882 }
10883
10884 setDataEnabledForReason(subId, TelephonyManager.DATA_ENABLED_REASON_THERMAL,
Sarah Chinecc78c42022-03-31 21:16:48 -070010885 false, callingPackage);
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010886 thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
10887 break;
10888 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_RADIO_OFF:
10889 if (thermalMitigationRequest.getDataThrottlingRequest() != null) {
10890 throw new IllegalArgumentException("dataThrottlingRequest must be null for"
10891 + " ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_RADIO_OFF");
10892 }
10893
10894 TelecomAccountRegistry registry = TelecomAccountRegistry.getInstance(null);
10895 if (registry != null) {
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010896 Phone phone = getPhone(subId);
10897 if (phone == null) {
10898 thermalMitigationResult =
10899 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
10900 break;
10901 }
10902
Jack Nudelmane69bbc82021-05-13 10:00:15 -070010903 TelephonyConnectionService service =
10904 registry.getTelephonyConnectionService();
Jack Nudelmanb30ac302021-06-17 15:39:58 -070010905 if (service != null && service.isEmergencyCallPending()) {
Jack Nudelmane69bbc82021-05-13 10:00:15 -070010906 Log.e(LOG_TAG, "An emergency call is pending");
10907 thermalMitigationResult =
10908 TelephonyManager.THERMAL_MITIGATION_RESULT_INVALID_STATE;
10909 break;
10910 } else if (isAnyPhoneInEmergencyState()) {
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010911 thermalMitigationResult =
10912 TelephonyManager.THERMAL_MITIGATION_RESULT_INVALID_STATE;
10913 break;
10914 }
10915 } else {
10916 thermalMitigationResult =
10917 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
10918 break;
10919 }
10920
10921 // Turn radio off. If not able to power off due to phone being unavailable,
10922 // return THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
Sooraj Sasindran72cff492021-07-29 09:42:42 -070010923 if (!setRadioPowerForThermal(false)) {
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010924 thermalMitigationResult =
10925 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
10926 break;
10927 }
10928 thermalMitigationResult =
10929 TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
10930 break;
10931 default:
10932 throw new IllegalArgumentException("the requested thermalMitigationAction does "
10933 + "not exist. Requested action: " + thermalMitigationAction);
10934 }
10935 } catch (IllegalArgumentException e) {
10936 throw e;
10937 } catch (Exception e) {
10938 Log.e(LOG_TAG, "thermalMitigationRequest. Exception e =" + e);
10939 thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
10940 } finally {
10941 Binder.restoreCallingIdentity(identity);
10942 }
10943
10944 if (DBG) {
10945 log("thermalMitigationRequest returning with thermalMitigationResult: "
10946 + thermalMitigationResult);
10947 }
10948
10949 return thermalMitigationResult;
10950 }
Hui Wang641e81c2020-10-12 12:14:23 -070010951
10952 /**
10953 * Set the GbaService Package Name that Telephony will bind to.
10954 *
10955 * @param subId The sim that the GbaService is associated with.
10956 * @param packageName The name of the package to be replaced with.
10957 * @return true if setting the GbaService to bind to succeeded, false if it did not.
10958 */
10959 @Override
10960 public boolean setBoundGbaServiceOverride(int subId, String packageName) {
10961 enforceModifyPermission();
10962
10963 final long identity = Binder.clearCallingIdentity();
10964 try {
10965 return getGbaManager(subId).overrideServicePackage(packageName);
10966 } finally {
10967 Binder.restoreCallingIdentity(identity);
10968 }
10969 }
10970
10971 /**
10972 * Return the package name of the currently bound GbaService.
10973 *
10974 * @param subId The sim that the GbaService is associated with.
10975 * @return the package name of the GbaService configuration, null if GBA is not supported.
10976 */
10977 @Override
10978 public String getBoundGbaService(int subId) {
10979 enforceReadPrivilegedPermission("getBoundGbaServicePackage");
10980
10981 final long identity = Binder.clearCallingIdentity();
10982 try {
10983 return getGbaManager(subId).getServicePackage();
10984 } finally {
10985 Binder.restoreCallingIdentity(identity);
10986 }
10987 }
10988
10989 /**
10990 * Set the release time for telephony to unbind GbaService.
10991 *
10992 * @param subId The sim that the GbaService is associated with.
10993 * @param interval The release time to unbind GbaService by millisecond.
10994 * @return true if setting the GbaService to bind to succeeded, false if it did not.
10995 */
10996 @Override
10997 public boolean setGbaReleaseTimeOverride(int subId, int interval) {
10998 enforceModifyPermission();
10999
11000 final long identity = Binder.clearCallingIdentity();
11001 try {
11002 return getGbaManager(subId).overrideReleaseTime(interval);
11003 } finally {
11004 Binder.restoreCallingIdentity(identity);
11005 }
11006 }
11007
11008 /**
11009 * Return the release time for telephony to unbind GbaService.
11010 *
11011 * @param subId The sim that the GbaService is associated with.
11012 * @return The release time to unbind GbaService by millisecond.
11013 */
11014 @Override
11015 public int getGbaReleaseTime(int subId) {
11016 enforceReadPrivilegedPermission("getGbaReleaseTime");
11017
11018 final long identity = Binder.clearCallingIdentity();
11019 try {
11020 return getGbaManager(subId).getReleaseTime();
11021 } finally {
11022 Binder.restoreCallingIdentity(identity);
11023 }
11024 }
11025
11026 private GbaManager getGbaManager(int subId) {
11027 GbaManager instance = GbaManager.getInstance(subId);
11028 if (instance == null) {
11029 String packageName = mApp.getResources().getString(R.string.config_gba_package);
11030 int releaseTime = mApp.getResources().getInteger(R.integer.config_gba_release_time);
11031 instance = GbaManager.make(mApp, subId, packageName, releaseTime);
11032 }
11033 return instance;
11034 }
Hui Wang761a6682020-10-31 05:12:53 +000011035
11036 /**
11037 * indicate whether the device and the carrier can support
11038 * RCS VoLTE single registration.
11039 */
11040 @Override
11041 public boolean isRcsVolteSingleRegistrationCapable(int subId) {
Brad Ebinger34c09a52021-02-17 23:23:21 +000011042 TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
11043 Binder.getCallingUid(), "isRcsVolteSingleRegistrationCapable",
11044 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
11045 permission.READ_PRIVILEGED_PHONE_STATE);
Hui Wang761a6682020-10-31 05:12:53 +000011046
11047 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11048 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11049 }
11050
11051 final long identity = Binder.clearCallingIdentity();
11052 try {
11053 RcsProvisioningMonitor rpm = RcsProvisioningMonitor.getInstance();
11054 if (rpm != null) {
Hui Wang67af90e2021-06-04 16:57:15 -070011055 Boolean isCapable = rpm.isRcsVolteSingleRegistrationEnabled(subId);
11056 if (isCapable != null) {
11057 return isCapable;
11058 }
Hui Wang761a6682020-10-31 05:12:53 +000011059 }
Hui Wang67af90e2021-06-04 16:57:15 -070011060 throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
11061 "service is temporarily unavailable.");
Hui Wang761a6682020-10-31 05:12:53 +000011062 } finally {
11063 Binder.restoreCallingIdentity(identity);
11064 }
11065 }
11066
11067 /**
11068 * Register RCS provisioning callback.
11069 */
11070 @Override
Hui Wang3cac7e52021-01-27 14:45:25 -080011071 public void registerRcsProvisioningCallback(int subId,
Hui Wang761a6682020-10-31 05:12:53 +000011072 IRcsConfigCallback callback) {
Brad Ebinger34c09a52021-02-17 23:23:21 +000011073 TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
Hui Wang3cac7e52021-01-27 14:45:25 -080011074 Binder.getCallingUid(), "registerRcsProvisioningCallback",
Brad Ebinger34c09a52021-02-17 23:23:21 +000011075 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
11076 permission.READ_PRIVILEGED_PHONE_STATE);
Hui Wang761a6682020-10-31 05:12:53 +000011077
11078 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11079 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11080 }
11081 if (!isImsAvailableOnDevice()) {
11082 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
11083 "IMS not available on device.");
11084 }
11085
11086 final long identity = Binder.clearCallingIdentity();
11087 try {
Hui Wang68cd3722021-01-11 20:04:53 -080011088 if (!RcsProvisioningMonitor.getInstance()
Hui Wang3cac7e52021-01-27 14:45:25 -080011089 .registerRcsProvisioningCallback(subId, callback)) {
Brad Ebinger919631e2021-06-02 17:46:35 -070011090 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
11091 "Active subscription not found.");
Hui Wang68cd3722021-01-11 20:04:53 -080011092 }
Hui Wang761a6682020-10-31 05:12:53 +000011093 } finally {
11094 Binder.restoreCallingIdentity(identity);
11095 }
11096 }
11097
11098 /**
11099 * Unregister RCS provisioning callback.
11100 */
11101 @Override
Hui Wang3cac7e52021-01-27 14:45:25 -080011102 public void unregisterRcsProvisioningCallback(int subId,
Hui Wang761a6682020-10-31 05:12:53 +000011103 IRcsConfigCallback callback) {
Brad Ebinger34c09a52021-02-17 23:23:21 +000011104 TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
Hui Wang3cac7e52021-01-27 14:45:25 -080011105 Binder.getCallingUid(), "unregisterRcsProvisioningCallback",
Brad Ebinger34c09a52021-02-17 23:23:21 +000011106 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
11107 permission.READ_PRIVILEGED_PHONE_STATE);
Hui Wang761a6682020-10-31 05:12:53 +000011108
11109 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11110 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11111 }
11112 if (!isImsAvailableOnDevice()) {
joonhunshin46b49a32022-12-21 05:33:23 +000011113 // operation failed silently
11114 Rlog.w(LOG_TAG, "IMS not available on device.");
11115 return;
Hui Wang761a6682020-10-31 05:12:53 +000011116 }
11117
11118 final long identity = Binder.clearCallingIdentity();
11119 try {
Hui Wang68cd3722021-01-11 20:04:53 -080011120 RcsProvisioningMonitor.getInstance()
Hui Wang3cac7e52021-01-27 14:45:25 -080011121 .unregisterRcsProvisioningCallback(subId, callback);
Hui Wang761a6682020-10-31 05:12:53 +000011122 } finally {
11123 Binder.restoreCallingIdentity(identity);
11124 }
11125 }
11126
11127 /**
11128 * trigger RCS reconfiguration.
11129 */
11130 public void triggerRcsReconfiguration(int subId) {
Brad Ebinger34c09a52021-02-17 23:23:21 +000011131 TelephonyPermissions.enforceAnyPermissionGranted(mApp, Binder.getCallingUid(),
11132 "triggerRcsReconfiguration",
11133 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION);
Hui Wang761a6682020-10-31 05:12:53 +000011134
11135 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11136 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11137 }
11138 if (!isImsAvailableOnDevice()) {
joonhunshin46b49a32022-12-21 05:33:23 +000011139 // ProvisioningManager can not handle ServiceSpecificException.
11140 // Throw the IllegalStateException and annotate ProvisioningManager.
11141 throw new IllegalStateException("IMS not available on device.");
Hui Wang761a6682020-10-31 05:12:53 +000011142 }
11143
11144 final long identity = Binder.clearCallingIdentity();
11145 try {
11146 RcsProvisioningMonitor.getInstance().requestReconfig(subId);
11147 } finally {
11148 Binder.restoreCallingIdentity(identity);
11149 }
11150 }
11151
11152 /**
11153 * Provide the client configuration parameters of the RCS application.
11154 */
11155 public void setRcsClientConfiguration(int subId, RcsClientConfiguration rcc) {
Brad Ebinger34c09a52021-02-17 23:23:21 +000011156 TelephonyPermissions.enforceAnyPermissionGranted(mApp, Binder.getCallingUid(),
11157 "setRcsClientConfiguration",
11158 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION);
Hui Wang761a6682020-10-31 05:12:53 +000011159
11160 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11161 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11162 }
11163 if (!isImsAvailableOnDevice()) {
11164 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
11165 "IMS not available on device.");
11166 }
11167
11168 final long identity = Binder.clearCallingIdentity();
11169
11170 try {
11171 IImsConfig configBinder = getImsConfig(getSlotIndex(subId), ImsFeature.FEATURE_RCS);
11172 if (configBinder == null) {
11173 Rlog.e(LOG_TAG, "null result for setRcsClientConfiguration");
Brad Ebinger919631e2021-06-02 17:46:35 -070011174 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
11175 "could not find the requested subscription");
Hui Wang761a6682020-10-31 05:12:53 +000011176 } else {
11177 configBinder.setRcsClientConfiguration(rcc);
11178 }
joonhunshin3e154242021-09-17 06:33:39 +000011179
11180 RcsStats.getInstance().onRcsClientProvisioningStats(subId,
11181 RCS_CLIENT_PROVISIONING_STATS__EVENT__CLIENT_PARAMS_SENT);
Hui Wang761a6682020-10-31 05:12:53 +000011182 } catch (RemoteException e) {
11183 Rlog.e(LOG_TAG, "fail to setRcsClientConfiguration " + e.getMessage());
Brad Ebinger919631e2021-06-02 17:46:35 -070011184 throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
11185 "service is temporarily unavailable.");
Hui Wang761a6682020-10-31 05:12:53 +000011186 } finally {
11187 Binder.restoreCallingIdentity(identity);
11188 }
11189 }
11190
11191 /**
Hui Wangbaaee6a2021-02-19 20:45:36 -080011192 * Enables or disables the test mode for RCS VoLTE single registration.
11193 */
11194 @Override
11195 public void setRcsSingleRegistrationTestModeEnabled(boolean enabled) {
11196 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11197 "setRcsSingleRegistrationTestModeEnabled");
11198
11199 RcsProvisioningMonitor.getInstance().setTestModeEnabled(enabled);
11200 }
11201
11202 /**
11203 * Gets the test mode for RCS VoLTE single registration.
11204 */
11205 @Override
11206 public boolean getRcsSingleRegistrationTestModeEnabled() {
11207 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11208 "getRcsSingleRegistrationTestModeEnabled");
11209
11210 return RcsProvisioningMonitor.getInstance().getTestModeEnabled();
11211 }
11212
11213 /**
Hui Wang761a6682020-10-31 05:12:53 +000011214 * Overrides the config of RCS VoLTE single registration enabled for the device.
11215 */
11216 @Override
11217 public void setDeviceSingleRegistrationEnabledOverride(String enabledStr) {
11218 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11219 "setDeviceSingleRegistrationEnabledOverride");
11220 enforceModifyPermission();
11221
11222 Boolean enabled = "NULL".equalsIgnoreCase(enabledStr) ? null
11223 : Boolean.parseBoolean(enabledStr);
11224 RcsProvisioningMonitor.getInstance().overrideDeviceSingleRegistrationEnabled(enabled);
Brad Ebinger49a72b42021-01-29 00:55:24 +000011225 mApp.imsRcsController.setDeviceSingleRegistrationSupportOverride(enabled);
Hui Wang761a6682020-10-31 05:12:53 +000011226 }
11227
11228 /**
Tyler Gunn92479152021-01-20 16:30:10 -080011229 * Sends a device to device communication message. Only usable via shell.
11230 * @param message message to send.
11231 * @param value message value.
11232 */
11233 @Override
11234 public void sendDeviceToDeviceMessage(int message, int value) {
11235 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
Tyler Gunnbabbda02021-02-10 11:05:02 -080011236 "sendDeviceToDeviceMessage");
Tyler Gunn92479152021-01-20 16:30:10 -080011237 enforceModifyPermission();
11238
11239 final long identity = Binder.clearCallingIdentity();
11240 try {
11241 TelephonyConnectionService service =
11242 TelecomAccountRegistry.getInstance(null).getTelephonyConnectionService();
11243 if (service == null) {
11244 Rlog.e(LOG_TAG, "sendDeviceToDeviceMessage: not in a call.");
11245 return;
11246 }
11247 service.sendTestDeviceToDeviceMessage(message, value);
11248 } finally {
11249 Binder.restoreCallingIdentity(identity);
11250 }
11251 }
11252
Tyler Gunnbabbda02021-02-10 11:05:02 -080011253 /**
11254 * Sets the specified device to device transport active.
11255 * @param transport The transport to set active.
11256 */
11257 @Override
11258 public void setActiveDeviceToDeviceTransport(@NonNull String transport) {
11259 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11260 "setActiveDeviceToDeviceTransport");
11261 enforceModifyPermission();
11262
11263 final long identity = Binder.clearCallingIdentity();
11264 try {
11265 TelephonyConnectionService service =
11266 TelecomAccountRegistry.getInstance(null).getTelephonyConnectionService();
11267 if (service == null) {
11268 Rlog.e(LOG_TAG, "setActiveDeviceToDeviceTransport: not in a call.");
11269 return;
11270 }
11271 service.setActiveDeviceToDeviceTransport(transport);
11272 } finally {
11273 Binder.restoreCallingIdentity(identity);
11274 }
11275 }
Tyler Gunn92479152021-01-20 16:30:10 -080011276
Tyler Gunnd4339262021-05-03 14:46:49 -070011277 @Override
11278 public void setDeviceToDeviceForceEnabled(boolean isForceEnabled) {
11279 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11280 "setDeviceToDeviceForceEnabled");
11281
11282 final long identity = Binder.clearCallingIdentity();
11283 try {
11284 Arrays.stream(PhoneFactory.getPhones()).forEach(
11285 p -> {
11286 Phone thePhone = p.getImsPhone();
11287 if (thePhone != null && thePhone instanceof ImsPhone) {
11288 ImsPhone imsPhone = (ImsPhone) thePhone;
11289 CallTracker tracker = imsPhone.getCallTracker();
11290 if (tracker != null && tracker instanceof ImsPhoneCallTracker) {
11291 ImsPhoneCallTracker imsPhoneCallTracker =
11292 (ImsPhoneCallTracker) tracker;
11293 imsPhoneCallTracker.setDeviceToDeviceForceEnabled(isForceEnabled);
11294 }
11295 }
11296 }
11297 );
11298 } finally {
11299 Binder.restoreCallingIdentity(identity);
11300 }
11301 }
11302
Tyler Gunn92479152021-01-20 16:30:10 -080011303 /**
Hui Wang761a6682020-10-31 05:12:53 +000011304 * Gets the config of RCS VoLTE single registration enabled for the device.
11305 */
11306 @Override
11307 public boolean getDeviceSingleRegistrationEnabled() {
11308 enforceReadPrivilegedPermission("getDeviceSingleRegistrationEnabled");
11309 return RcsProvisioningMonitor.getInstance().getDeviceSingleRegistrationEnabled();
11310 }
11311
11312 /**
11313 * Overrides the config of RCS VoLTE single registration enabled for the carrier/subscription.
11314 */
11315 @Override
11316 public boolean setCarrierSingleRegistrationEnabledOverride(int subId, String enabledStr) {
11317 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11318 "setCarrierSingleRegistrationEnabledOverride");
11319 enforceModifyPermission();
11320
11321 Boolean enabled = "NULL".equalsIgnoreCase(enabledStr) ? null
11322 : Boolean.parseBoolean(enabledStr);
11323 return RcsProvisioningMonitor.getInstance().overrideCarrierSingleRegistrationEnabled(
11324 subId, enabled);
11325 }
11326
11327 /**
11328 * Gets the config of RCS VoLTE single registration enabled for the carrier/subscription.
11329 */
11330 @Override
11331 public boolean getCarrierSingleRegistrationEnabled(int subId) {
11332 enforceReadPrivilegedPermission("getCarrierSingleRegistrationEnabled");
11333 return RcsProvisioningMonitor.getInstance().getCarrierSingleRegistrationEnabled(subId);
11334 }
Chiachang Wangd6d34772020-12-22 11:38:27 +080011335
11336 /**
Hui Wangb647abe2021-02-26 09:33:38 -080011337 * Overrides the ims feature validation result
11338 */
11339 @Override
11340 public boolean setImsFeatureValidationOverride(int subId, String enabledStr) {
11341 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11342 "setImsFeatureValidationOverride");
11343
11344 Boolean enabled = "NULL".equalsIgnoreCase(enabledStr) ? null
11345 : Boolean.parseBoolean(enabledStr);
11346 return RcsProvisioningMonitor.getInstance().overrideImsFeatureValidation(
11347 subId, enabled);
11348 }
11349
11350 /**
11351 * Gets the ims feature validation override value
11352 */
11353 @Override
11354 public boolean getImsFeatureValidationOverride(int subId) {
11355 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11356 "getImsFeatureValidationOverride");
11357 return RcsProvisioningMonitor.getInstance().getImsFeatureValidationOverride(subId);
11358 }
11359
11360 /**
Chiachang Wangd6d34772020-12-22 11:38:27 +080011361 * Get the mobile provisioning url that is used to launch a browser to allow users to manage
11362 * their mobile plan.
11363 */
11364 @Override
11365 public String getMobileProvisioningUrl() {
11366 enforceReadPrivilegedPermission("getMobileProvisioningUrl");
11367 final long identity = Binder.clearCallingIdentity();
11368 try {
11369 return getDefaultPhone().getMobileProvisioningUrl();
11370 } finally {
11371 Binder.restoreCallingIdentity(identity);
11372 }
11373 }
Rambo Wanga5cc9b72021-01-07 10:51:54 -080011374
James.cf Linbcdf8b32021-01-14 16:44:13 +080011375 /**
calvinpane4a8a1d2021-01-25 13:51:18 +080011376 * Get the EAB contact from the EAB database.
11377 */
11378 @Override
11379 public String getContactFromEab(String contact) {
11380 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getContactFromEab");
11381 enforceModifyPermission();
11382 final long identity = Binder.clearCallingIdentity();
11383 try {
11384 return EabUtil.getContactFromEab(getDefaultPhone().getContext(), contact);
11385 } finally {
11386 Binder.restoreCallingIdentity(identity);
11387 }
11388 }
11389
11390 /**
Calvin Pana1434322021-07-01 19:27:01 +080011391 * Get the EAB capability from the EAB database.
11392 */
11393 @Override
11394 public String getCapabilityFromEab(String contact) {
11395 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getCapabilityFromEab");
11396 enforceModifyPermission();
11397 final long identity = Binder.clearCallingIdentity();
11398 try {
11399 return EabUtil.getCapabilityFromEab(getDefaultPhone().getContext(), contact);
11400 } finally {
11401 Binder.restoreCallingIdentity(identity);
11402 }
11403 }
11404
11405 /**
James.cf Linbcdf8b32021-01-14 16:44:13 +080011406 * Remove the EAB contacts from the EAB database.
11407 */
11408 @Override
11409 public int removeContactFromEab(int subId, String contacts) {
11410 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "removeCapabilitiesFromEab");
11411 enforceModifyPermission();
11412 final long identity = Binder.clearCallingIdentity();
11413 try {
11414 return EabUtil.removeContactFromEab(subId, contacts, getDefaultPhone().getContext());
11415 } finally {
11416 Binder.restoreCallingIdentity(identity);
11417 }
11418 }
11419
Rambo Wanga5cc9b72021-01-07 10:51:54 -080011420 @Override
James.cf Lin4b784aa2021-01-31 03:25:15 +080011421 public boolean getDeviceUceEnabled() {
11422 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getDeviceUceEnabled");
11423 final long identity = Binder.clearCallingIdentity();
11424 try {
11425 return mApp.getDeviceUceEnabled();
11426 } finally {
11427 Binder.restoreCallingIdentity(identity);
11428 }
11429 }
11430
11431 @Override
11432 public void setDeviceUceEnabled(boolean isEnabled) {
11433 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setDeviceUceEnabled");
11434 final long identity = Binder.clearCallingIdentity();
11435 try {
11436 mApp.setDeviceUceEnabled(isEnabled);
11437 } finally {
11438 Binder.restoreCallingIdentity(identity);
11439 }
11440 }
11441
Brad Ebinger14d467f2021-02-12 06:18:28 +000011442 /**
11443 * Add new feature tags to the Set used to calculate the capabilities in PUBLISH.
11444 * @return current RcsContactUceCapability instance that will be used for PUBLISH.
11445 */
11446 // Used for SHELL command only right now.
11447 @Override
11448 public RcsContactUceCapability addUceRegistrationOverrideShell(int subId,
11449 List<String> featureTags) {
11450 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11451 "addUceRegistrationOverrideShell");
11452 final long identity = Binder.clearCallingIdentity();
11453 try {
11454 return mApp.imsRcsController.addUceRegistrationOverrideShell(subId,
11455 new ArraySet<>(featureTags));
11456 } catch (ImsException e) {
11457 throw new ServiceSpecificException(e.getCode(), e.getMessage());
11458 } finally {
11459 Binder.restoreCallingIdentity(identity);
11460 }
11461 }
11462
11463 /**
11464 * Remove existing feature tags to the Set used to calculate the capabilities in PUBLISH.
11465 * @return current RcsContactUceCapability instance that will be used for PUBLISH.
11466 */
11467 // Used for SHELL command only right now.
11468 @Override
11469 public RcsContactUceCapability removeUceRegistrationOverrideShell(int subId,
11470 List<String> featureTags) {
11471 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11472 "removeUceRegistrationOverrideShell");
11473 final long identity = Binder.clearCallingIdentity();
11474 try {
11475 return mApp.imsRcsController.removeUceRegistrationOverrideShell(subId,
11476 new ArraySet<>(featureTags));
11477 } catch (ImsException e) {
11478 throw new ServiceSpecificException(e.getCode(), e.getMessage());
11479 } finally {
11480 Binder.restoreCallingIdentity(identity);
11481 }
11482 }
11483
11484 /**
11485 * Clear all overrides in the Set used to calculate the capabilities in PUBLISH.
11486 * @return current RcsContactUceCapability instance that will be used for PUBLISH.
11487 */
11488 // Used for SHELL command only right now.
11489 @Override
11490 public RcsContactUceCapability clearUceRegistrationOverrideShell(int subId) {
11491 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11492 "clearUceRegistrationOverrideShell");
11493 final long identity = Binder.clearCallingIdentity();
11494 try {
11495 return mApp.imsRcsController.clearUceRegistrationOverrideShell(subId);
11496 } catch (ImsException e) {
11497 throw new ServiceSpecificException(e.getCode(), e.getMessage());
11498 } finally {
11499 Binder.restoreCallingIdentity(identity);
11500 }
11501 }
11502
11503 /**
11504 * @return current RcsContactUceCapability instance that will be used for PUBLISH.
11505 */
11506 // Used for SHELL command only right now.
11507 @Override
11508 public RcsContactUceCapability getLatestRcsContactUceCapabilityShell(int subId) {
11509 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11510 "getLatestRcsContactUceCapabilityShell");
11511 final long identity = Binder.clearCallingIdentity();
11512 try {
11513 return mApp.imsRcsController.getLatestRcsContactUceCapabilityShell(subId);
11514 } catch (ImsException e) {
11515 throw new ServiceSpecificException(e.getCode(), e.getMessage());
11516 } finally {
11517 Binder.restoreCallingIdentity(identity);
11518 }
11519 }
11520
11521 /**
11522 * Returns the last PIDF XML sent to the network during the last PUBLISH or "none" if the
11523 * device does not have an active PUBLISH.
11524 */
11525 // Used for SHELL command only right now.
11526 @Override
11527 public String getLastUcePidfXmlShell(int subId) {
11528 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "uceGetLastPidfXml");
11529 final long identity = Binder.clearCallingIdentity();
11530 try {
11531 return mApp.imsRcsController.getLastUcePidfXmlShell(subId);
11532 } catch (ImsException e) {
11533 throw new ServiceSpecificException(e.getCode(), e.getMessage());
11534 } finally {
11535 Binder.restoreCallingIdentity(identity);
11536 }
11537 }
11538
James.cf Line8713a42021-04-29 16:04:26 +080011539 /**
11540 * Remove UCE requests cannot be sent to the network status.
11541 */
11542 // Used for SHELL command only right now.
11543 @Override
11544 public boolean removeUceRequestDisallowedStatus(int subId) {
11545 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "uceRemoveDisallowedStatus");
11546 final long identity = Binder.clearCallingIdentity();
11547 try {
11548 return mApp.imsRcsController.removeUceRequestDisallowedStatus(subId);
11549 } catch (ImsException e) {
11550 throw new ServiceSpecificException(e.getCode(), e.getMessage());
11551 } finally {
11552 Binder.restoreCallingIdentity(identity);
11553 }
11554 }
11555
James.cf Lin18bb9002021-05-25 01:37:38 +080011556 /**
11557 * Remove UCE requests cannot be sent to the network status.
11558 */
11559 // Used for SHELL command only.
11560 @Override
11561 public boolean setCapabilitiesRequestTimeout(int subId, long timeoutAfterMs) {
11562 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setCapRequestTimeout");
11563 final long identity = Binder.clearCallingIdentity();
11564 try {
11565 return mApp.imsRcsController.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
11566 } catch (ImsException e) {
11567 throw new ServiceSpecificException(e.getCode(), e.getMessage());
11568 } finally {
11569 Binder.restoreCallingIdentity(identity);
11570 }
11571 }
Brad Ebinger14d467f2021-02-12 06:18:28 +000011572
James.cf Lin4b784aa2021-01-31 03:25:15 +080011573 @Override
Rambo Wanga5cc9b72021-01-07 10:51:54 -080011574 public void setSignalStrengthUpdateRequest(int subId, SignalStrengthUpdateRequest request,
11575 String callingPackage) {
11576 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
11577 mApp, subId, "setSignalStrengthUpdateRequest");
11578
11579 final int callingUid = Binder.getCallingUid();
11580 // Verify that tha callingPackage belongs to the calling UID
11581 mApp.getSystemService(AppOpsManager.class)
11582 .checkPackage(callingUid, callingPackage);
11583
Rambo Wang3607f502021-02-01 21:51:40 -080011584 validateSignalStrengthUpdateRequest(mApp, request, callingUid);
Rambo Wanga5cc9b72021-01-07 10:51:54 -080011585
11586 final long identity = Binder.clearCallingIdentity();
11587 try {
11588 Object result = sendRequest(CMD_SET_SIGNAL_STRENGTH_UPDATE_REQUEST,
11589 new Pair<Integer, SignalStrengthUpdateRequest>(callingUid, request), subId);
11590
11591 if (result instanceof IllegalStateException) {
11592 throw (IllegalStateException) result;
11593 }
11594 } finally {
11595 Binder.restoreCallingIdentity(identity);
11596 }
11597 }
11598
11599 @Override
11600 public void clearSignalStrengthUpdateRequest(int subId, SignalStrengthUpdateRequest request,
11601 String callingPackage) {
11602 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
11603 mApp, subId, "clearSignalStrengthUpdateRequest");
11604
11605 final int callingUid = Binder.getCallingUid();
11606 // Verify that tha callingPackage belongs to the calling UID
11607 mApp.getSystemService(AppOpsManager.class)
11608 .checkPackage(callingUid, callingPackage);
11609
11610 final long identity = Binder.clearCallingIdentity();
11611 try {
11612 Object result = sendRequest(CMD_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST,
11613 new Pair<Integer, SignalStrengthUpdateRequest>(callingUid, request), subId);
11614
11615 if (result instanceof IllegalStateException) {
11616 throw (IllegalStateException) result;
11617 }
11618 } finally {
11619 Binder.restoreCallingIdentity(identity);
11620 }
11621 }
11622
Rambo Wang3607f502021-02-01 21:51:40 -080011623 private static void validateSignalStrengthUpdateRequest(Context context,
11624 SignalStrengthUpdateRequest request, int callingUid) {
Rambo Wanga5cc9b72021-01-07 10:51:54 -080011625 if (callingUid == Process.PHONE_UID || callingUid == Process.SYSTEM_UID) {
11626 // phone/system process do not have further restriction on request
11627 return;
11628 }
11629
11630 // Applications has restrictions on how to use the request:
Rambo Wang3607f502021-02-01 21:51:40 -080011631 // Non-system callers need permission to set mIsSystemThresholdReportingRequestedWhileIdle
Rambo Wanga5cc9b72021-01-07 10:51:54 -080011632 if (request.isSystemThresholdReportingRequestedWhileIdle()) {
Rambo Wang3607f502021-02-01 21:51:40 -080011633 context.enforceCallingOrSelfPermission(
11634 android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH,
11635 "validateSignalStrengthUpdateRequest");
Rambo Wanga5cc9b72021-01-07 10:51:54 -080011636 }
11637
11638 for (SignalThresholdInfo info : request.getSignalThresholdInfos()) {
Nagendra Prasad Nagarle Basavarajufee544c2022-12-07 16:34:52 +000011639 // Only system caller can set mHysteresisMs/mIsEnabled.
Rambo Wanga5cc9b72021-01-07 10:51:54 -080011640 if (info.getHysteresisMs() != SignalThresholdInfo.HYSTERESIS_MS_DISABLED
Rambo Wanga5cc9b72021-01-07 10:51:54 -080011641 || info.isEnabled()) {
11642 throw new IllegalArgumentException(
11643 "Only system can set hide fields in SignalThresholdInfo");
11644 }
11645
11646 // Thresholds length for each RAN need in range. This has been validated in
11647 // SignalThresholdInfo#Builder#setThreshold. Here we prevent apps calling hide method
11648 // setThresholdUnlimited (e.g. through reflection) with too short or too long thresholds
11649 final int[] thresholds = info.getThresholds();
11650 Objects.requireNonNull(thresholds);
11651 if (thresholds.length < SignalThresholdInfo.getMinimumNumberOfThresholdsAllowed()
11652 || thresholds.length
11653 > SignalThresholdInfo.getMaximumNumberOfThresholdsAllowed()) {
11654 throw new IllegalArgumentException(
11655 "thresholds length is out of range: " + thresholds.length);
11656 }
11657 }
11658 }
SongFerngWang8236caa2021-01-17 21:51:44 +080011659
11660 /**
11661 * Gets the current phone capability.
11662 *
11663 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
11664 * @return the PhoneCapability which describes the data connection capability of modem.
11665 * It's used to evaluate possible phone config change, for example from single
11666 * SIM device to multi-SIM device.
11667 */
11668 @Override
11669 public PhoneCapability getPhoneCapability() {
11670 enforceReadPrivilegedPermission("getPhoneCapability");
11671 final long identity = Binder.clearCallingIdentity();
11672 try {
11673 return mPhoneConfigurationManager.getCurrentPhoneCapability();
11674 } finally {
11675 Binder.restoreCallingIdentity(identity);
11676 }
11677 }
Michele Berionne5e411512020-11-13 02:36:59 +000011678
11679 /**
11680 * Prepare TelephonyManager for an unattended reboot. The reboot is
11681 * required to be done shortly after the API is invoked.
11682 */
11683 @Override
11684 @TelephonyManager.PrepareUnattendedRebootResult
11685 public int prepareForUnattendedReboot() {
Rafael Higuera Silvad9630642021-09-20 15:32:01 +000011686 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Michele Berionne5e411512020-11-13 02:36:59 +000011687 enforceRebootPermission();
11688
11689 final long identity = Binder.clearCallingIdentity();
11690 try {
Rafael Higuera Silvad9630642021-09-20 15:32:01 +000011691 return (int) sendRequest(CMD_PREPARE_UNATTENDED_REBOOT, null, workSource);
Michele Berionne5e411512020-11-13 02:36:59 +000011692 } finally {
11693 Binder.restoreCallingIdentity(identity);
11694 }
11695 }
Hongbo Zeng156aa4a2021-02-08 21:50:28 +080011696
11697 /**
11698 * Request to get the current slicing configuration including URSP rules and
11699 * NSSAIs (configured, allowed and rejected).
11700 *
11701 * Requires carrier privileges or READ_PRIVILEGED_PHONE_STATE permission.
11702 */
11703 @Override
11704 public void getSlicingConfig(ResultReceiver callback) {
Hongbo Zeng1b2063d2022-02-21 01:33:03 +000011705 TelephonyPermissions
11706 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
11707 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, "getSlicingConfig");
Hongbo Zeng156aa4a2021-02-08 21:50:28 +080011708
11709 final long identity = Binder.clearCallingIdentity();
11710 try {
11711 Phone phone = getDefaultPhone();
11712 sendRequestAsync(CMD_GET_SLICING_CONFIG, callback, phone, null);
11713 } finally {
11714 Binder.restoreCallingIdentity(identity);
11715 }
11716 }
Hunsuk Choi3b742d62021-10-25 19:48:34 +000011717
11718 /**
Sarah Chin2ec39f62022-08-31 17:03:26 -070011719 * Check whether the given premium capability is available for purchase from the carrier.
11720 *
11721 * @param capability The premium capability to check.
11722 * @param subId The subId to check the premium capability for.
11723 *
11724 * @return Whether the given premium capability is available to purchase.
11725 */
11726 @Override
11727 public boolean isPremiumCapabilityAvailableForPurchase(int capability, int subId) {
11728 if (!TelephonyPermissions.checkCallingOrSelfReadNonDangerousPhoneStateNoThrow(
11729 mApp, "isPremiumCapabilityAvailableForPurchase")) {
11730 log("Premium capability "
11731 + TelephonyManager.convertPremiumCapabilityToString(capability)
11732 + " is not available for purchase due to missing permissions.");
11733 throw new SecurityException("isPremiumCapabilityAvailableForPurchase requires "
11734 + "permission READ_BASIC_PHONE_STATE.");
11735 }
11736
11737 Phone phone = getPhone(subId);
Thomas Nguyen7216ed62022-11-29 16:45:31 -080011738 if (phone == null) {
11739 loge("isPremiumCapabilityAvailableForPurchase: phone is null, subId=" + subId);
11740 return false;
11741 }
Sarah Chin2ec39f62022-08-31 17:03:26 -070011742 final long identity = Binder.clearCallingIdentity();
11743 try {
Sarah Chin46355ba2022-11-01 23:51:16 -070011744 return SlicePurchaseController.getInstance(phone)
Sarah Chin2ec39f62022-08-31 17:03:26 -070011745 .isPremiumCapabilityAvailableForPurchase(capability);
11746 } finally {
11747 Binder.restoreCallingIdentity(identity);
11748 }
11749 }
11750
11751 /**
11752 * Purchase the given premium capability from the carrier.
11753 *
11754 * @param capability The premium capability to purchase.
11755 * @param callback The result of the purchase request.
11756 * @param subId The subId to purchase the premium capability for.
11757 */
11758 @Override
11759 public void purchasePremiumCapability(int capability, IIntegerConsumer callback, int subId) {
11760 log("purchasePremiumCapability: capability="
11761 + TelephonyManager.convertPremiumCapabilityToString(capability) + ", caller="
11762 + getCurrentPackageName());
11763
11764 if (!TelephonyPermissions.checkCallingOrSelfReadNonDangerousPhoneStateNoThrow(
11765 mApp, "purchasePremiumCapability")) {
11766 log("purchasePremiumCapability "
11767 + TelephonyManager.convertPremiumCapabilityToString(capability)
11768 + " failed due to missing permissions.");
11769 throw new SecurityException("purchasePremiumCapability requires permission "
11770 + "READ_BASIC_PHONE_STATE.");
Sarah Chin532d6bb2022-12-28 22:50:43 -080011771 } else if (!TelephonyPermissions.checkInternetPermissionNoThrow(
11772 mApp, "purchasePremiumCapability")) {
11773 log("purchasePremiumCapability "
11774 + TelephonyManager.convertPremiumCapabilityToString(capability)
11775 + " failed due to missing permissions.");
11776 throw new SecurityException("purchasePremiumCapability requires permission INTERNET.");
Sarah Chin2ec39f62022-08-31 17:03:26 -070011777 }
11778
11779 Phone phone = getPhone(subId);
Sarah Chin19694112022-12-06 15:41:37 -080011780 if (phone == null) {
11781 try {
11782 int result = TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_REQUEST_FAILED;
11783 callback.accept(result);
11784 loge("purchasePremiumCapability: phone is null, subId=" + subId);
11785 } catch (RemoteException e) {
11786 String logStr = "Purchase premium capability "
11787 + TelephonyManager.convertPremiumCapabilityToString(capability)
11788 + " failed due to RemoteException handling null phone: " + e;
11789 if (DBG) log(logStr);
11790 AnomalyReporter.reportAnomaly(
11791 UUID.fromString(PURCHASE_PREMIUM_CAPABILITY_ERROR_UUID), logStr);
11792 }
11793 return;
11794 }
Sarah Chin532d6bb2022-12-28 22:50:43 -080011795
11796 String callingProcess;
Sarah Chin71b3a852022-09-28 15:54:19 -070011797 try {
Sarah Chin532d6bb2022-12-28 22:50:43 -080011798 callingProcess = mApp.getPackageManager().getApplicationInfo(
11799 getCurrentPackageName(), 0).processName;
Sarah Chin71b3a852022-09-28 15:54:19 -070011800 } catch (PackageManager.NameNotFoundException e) {
Sarah Chin532d6bb2022-12-28 22:50:43 -080011801 callingProcess = getCurrentPackageName();
Sarah Chin71b3a852022-09-28 15:54:19 -070011802 }
Sarah Chin532d6bb2022-12-28 22:50:43 -080011803
11804 boolean isVisible = false;
11805 ActivityManager am = mApp.getSystemService(ActivityManager.class);
11806 if (am != null) {
11807 List<ActivityManager.RunningAppProcessInfo> processes = am.getRunningAppProcesses();
11808 if (processes != null) {
11809 for (ActivityManager.RunningAppProcessInfo process : processes) {
11810 log("purchasePremiumCapability: process " + process.processName
11811 + "has importance " + process.importance);
11812 if (process.processName.equals(callingProcess) && process.importance
11813 <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
11814 isVisible = true;
11815 break;
11816 }
11817 }
11818 }
11819 }
11820
11821 if (!isVisible) {
11822 try {
11823 int result = TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_FOREGROUND;
11824 callback.accept(result);
11825 loge("purchasePremiumCapability: " + callingProcess + " is not in the foreground.");
11826 } catch (RemoteException e) {
11827 String logStr = "Purchase premium capability "
11828 + TelephonyManager.convertPremiumCapabilityToString(capability)
11829 + " failed due to RemoteException handling background application: " + e;
11830 if (DBG) log(logStr);
11831 AnomalyReporter.reportAnomaly(
11832 UUID.fromString(PURCHASE_PREMIUM_CAPABILITY_ERROR_UUID), logStr);
11833 }
11834 return;
11835 }
11836
Sarah Chin71b3a852022-09-28 15:54:19 -070011837 sendRequestAsync(CMD_PURCHASE_PREMIUM_CAPABILITY,
Sarah Chinb8218c22023-01-04 13:35:29 -080011838 new PurchasePremiumCapabilityArgument(capability, callback), phone, null);
Sarah Chin2ec39f62022-08-31 17:03:26 -070011839 }
11840
11841 /**
Hunsuk Choi3b742d62021-10-25 19:48:34 +000011842 * Register an IMS connection state callback
11843 */
11844 @Override
Hunsuk Choi89bd22c2021-11-01 13:04:54 +000011845 public void registerImsStateCallback(int subId, int feature, IImsStateCallback cb,
11846 String callingPackage) {
Hunsuk Choi3b742d62021-10-25 19:48:34 +000011847 if (feature == ImsFeature.FEATURE_MMTEL) {
11848 // ImsMmTelManager
11849 // The following also checks READ_PRIVILEGED_PHONE_STATE.
11850 TelephonyPermissions
11851 .enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
11852 mApp, subId, "registerImsStateCallback");
11853 } else if (feature == ImsFeature.FEATURE_RCS) {
11854 // ImsRcsManager or SipDelegateManager
11855 TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
11856 Binder.getCallingUid(), "registerImsStateCallback",
11857 Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
11858 Manifest.permission.READ_PRECISE_PHONE_STATE,
11859 Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE,
11860 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION);
11861 }
11862
11863 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
11864 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
11865 "IMS not available on device.");
11866 }
11867
11868 if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
11869 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
11870 }
11871
11872 ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
11873 if (controller == null) {
11874 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
11875 "IMS not available on device.");
11876 }
11877
Hunsuk Choi89bd22c2021-11-01 13:04:54 +000011878 if (callingPackage == null) {
11879 callingPackage = getCurrentPackageName();
11880 }
11881
Hunsuk Choi3b742d62021-10-25 19:48:34 +000011882 final long token = Binder.clearCallingIdentity();
11883 try {
11884 int slotId = getSlotIndexOrException(subId);
Hunsuk Choi89bd22c2021-11-01 13:04:54 +000011885 controller.registerImsStateCallback(subId, feature, cb, callingPackage);
Hunsuk Choi3b742d62021-10-25 19:48:34 +000011886 } catch (ImsException e) {
11887 throw new ServiceSpecificException(e.getCode());
11888 } finally {
11889 Binder.restoreCallingIdentity(token);
11890 }
11891 }
11892
11893 /**
11894 * Unregister an IMS connection state callback
11895 */
11896 @Override
11897 public void unregisterImsStateCallback(IImsStateCallback cb) {
11898 final long token = Binder.clearCallingIdentity();
11899 ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
11900 if (controller == null) {
11901 return;
11902 }
11903 try {
11904 controller.unregisterImsStateCallback(cb);
11905 } finally {
11906 Binder.restoreCallingIdentity(token);
11907 }
11908 }
Sooraj Sasindranfae41b32021-10-26 02:10:05 -070011909
11910 /**
11911 * @return {@CellIdentity} last known cell identity {@CellIdentity}.
11912 *
11913 * Require {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and
11914 * com.android.phone.permission.ACCESS_LAST_KNOWN_CELL_ID, otherwise throws
11915 * SecurityException.
11916 * If there is current registered network this value will be same as the registered cell
11917 * identity. If the device goes out of service the previous cell identity is cached and
11918 * will be returned. If the cache age of the Cell identity is more than 24 hours
11919 * it will be cleared and null will be returned.
11920 *
11921 */
11922 @Override
11923 public @Nullable CellIdentity getLastKnownCellIdentity(int subId, String callingPackage,
11924 String callingFeatureId) {
11925 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
11926 LocationAccessPolicy.LocationPermissionResult fineLocationResult =
11927 LocationAccessPolicy.checkLocationPermission(mApp,
11928 new LocationAccessPolicy.LocationPermissionQuery.Builder()
11929 .setCallingPackage(callingPackage)
11930 .setCallingFeatureId(callingFeatureId)
11931 .setCallingPid(Binder.getCallingPid())
11932 .setCallingUid(Binder.getCallingUid())
11933 .setMethod("getLastKnownCellIdentity")
11934 .setLogAsInfo(true)
11935 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
11936 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
11937 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
11938 .build());
11939
11940 boolean hasFinePermission =
11941 fineLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
11942 if (!hasFinePermission
11943 || !TelephonyPermissions.checkLastKnownCellIdAccessPermission(mApp)) {
11944 throw new SecurityException("getLastKnownCellIdentity need ACCESS_FINE_LOCATION "
Rambo Wang918993a2022-04-27 09:08:36 -070011945 + "and ACCESS_LAST_KNOWN_CELL_ID permission.");
Sooraj Sasindranfae41b32021-10-26 02:10:05 -070011946 }
11947
11948 final long identity = Binder.clearCallingIdentity();
11949 try {
11950 Phone phone = getPhone(subId);
11951 if (phone == null) return null;
11952 ServiceStateTracker sst = phone.getServiceStateTracker();
11953 if (sst == null) return null;
11954 return sst.getLastKnownCellIdentity();
11955 } finally {
11956 Binder.restoreCallingIdentity(identity);
11957 }
11958 }
Jack Yu4c0a5502021-12-03 23:58:26 -080011959
jimsun3b9ccac2021-10-26 15:01:23 +080011960 /**
11961 * Sets the modem service class Name that Telephony will bind to.
11962 *
11963 * @param serviceName The class name of the modem service.
11964 * @return true if the operation is succeed, otherwise false.
11965 */
11966 public boolean setModemService(String serviceName) {
11967 Log.d(LOG_TAG, "setModemService - " + serviceName);
11968 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setModemService");
11969 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
11970 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
11971 "setModemService");
11972 return mPhoneConfigurationManager.setModemService(serviceName);
11973 }
11974
11975 /**
11976 * Return the class name of the currently bounded modem service.
11977 *
11978 * @return the class name of the modem service.
11979 */
11980 public String getModemService() {
11981 String result;
11982 Log.d(LOG_TAG, "getModemService");
11983 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getModemService");
11984 TelephonyPermissions
11985 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
11986 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
11987 "getModemService");
11988 result = mPhoneConfigurationManager.getModemService();
11989 Log.d(LOG_TAG, "result = " + result);
11990 return result;
11991 }
Hunter Knepshield2b076fa2022-01-19 02:26:22 -080011992
11993 @Override
11994 public void setVoiceServiceStateOverride(int subId, boolean hasService, String callingPackage) {
11995 // Only telecom (and shell, for CTS purposes) is allowed to call this method.
11996 mApp.enforceCallingOrSelfPermission(
11997 permission.BIND_TELECOM_CONNECTION_SERVICE, "setVoiceServiceStateOverride");
11998 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
11999
12000 final long identity = Binder.clearCallingIdentity();
12001 try {
12002 Phone phone = getPhone(subId);
12003 if (phone == null) return;
Grant Menke63ade122023-01-20 14:31:54 -080012004 Log.i(LOG_TAG, "setVoiceServiceStateOverride: subId=" + subId + ", phone=" + phone
12005 + ", hasService=" + hasService + ", callingPackage=" + callingPackage);
Hunter Knepshield2b076fa2022-01-19 02:26:22 -080012006 phone.setVoiceServiceStateOverride(hasService);
12007 } finally {
12008 Binder.restoreCallingIdentity(identity);
12009 }
12010 }
Muralidhar Reddy4e5a8012022-05-11 14:49:00 +000012011
12012 /**
12013 * set removable eSIM as default eUICC.
12014 *
12015 * @hide
12016 */
12017 @Override
12018 public void setRemovableEsimAsDefaultEuicc(boolean isDefault, String callingPackage) {
12019 enforceModifyPermission();
12020 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
12021
12022 final long identity = Binder.clearCallingIdentity();
12023 try {
12024 UiccController.getInstance().setRemovableEsimAsDefaultEuicc(isDefault);
12025 } finally {
12026 Binder.restoreCallingIdentity(identity);
12027 }
12028 }
12029
12030 /**
12031 * Returns whether the removable eSIM is default eUICC or not.
12032 *
12033 * @hide
12034 */
12035 @Override
12036 public boolean isRemovableEsimDefaultEuicc(String callingPackage) {
12037 enforceReadPrivilegedPermission("isRemovableEsimDefaultEuicc");
12038 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
12039
12040 final long identity = Binder.clearCallingIdentity();
12041 try {
12042 return UiccController.getInstance().isRemovableEsimDefaultEuicc();
12043 } finally {
12044 Binder.restoreCallingIdentity(identity);
12045 }
12046 }
12047
Aishwarya Mallampatifbc70d32022-11-10 20:33:02 +000012048 /**
12049 * Get the component name of the default app to direct respond-via-message intent for the
12050 * user associated with this subscription, update the cache if there is no respond-via-message
12051 * application currently configured for this user.
12052 * @return component name of the app and class to direct Respond Via Message intent to, or
12053 * {@code null} if the functionality is not supported.
12054 * @hide
12055 */
12056 @Override
12057 public @Nullable ComponentName getDefaultRespondViaMessageApplication(int subId,
12058 boolean updateIfNeeded) {
12059 enforceInteractAcrossUsersPermission("getDefaultRespondViaMessageApplication");
Muralidhar Reddy4e5a8012022-05-11 14:49:00 +000012060
Aishwarya Mallampati5e581e12023-01-17 21:57:06 +000012061 Context context = getPhoneFromSubIdOrDefault(subId).getContext();
12062
Aishwarya Mallampatifbc70d32022-11-10 20:33:02 +000012063 UserHandle userHandle = null;
12064 final long identity = Binder.clearCallingIdentity();
12065 try {
12066 userHandle = TelephonyUtils.getSubscriptionUserHandle(context, subId);
12067 } finally {
12068 Binder.restoreCallingIdentity(identity);
12069 }
12070 return SmsApplication.getDefaultRespondViaMessageApplicationAsUser(context,
12071 updateIfNeeded, userHandle);
12072 }
Jack Yuf5badd92022-12-08 00:50:53 -080012073
12074 /**
Gil Cukierman1c0eb932022-12-06 22:28:24 +000012075 * Set whether the device is able to connect with null ciphering or integrity
12076 * algorithms. This is a global setting and will apply to all active subscriptions
12077 * and all new subscriptions after this.
12078 *
12079 * @param enabled when true, null cipher and integrity algorithms are allowed.
12080 * @hide
12081 */
12082 @Override
12083 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
12084 public void setNullCipherAndIntegrityEnabled(boolean enabled) {
12085 enforceModifyPermission();
12086 checkForNullCipherAndIntegritySupport();
12087
12088 // Persist the state of our preference. Each GsmCdmaPhone instance is responsible
12089 // for listening to these preference changes and applying them immediately.
12090 SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
12091 editor.putBoolean(Phone.PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED, enabled);
12092 editor.apply();
12093
12094 for (Phone phone: PhoneFactory.getPhones()) {
12095 phone.handleNullCipherEnabledChange();
12096 }
12097 }
12098
12099
12100 /**
12101 * Get whether the device is able to connect with null ciphering or integrity
12102 * algorithms. Note that this retrieves the phone-global preference and not
12103 * the state of the radio.
12104 *
12105 * @throws SecurityException if {@link permission#MODIFY_PHONE_STATE} is not satisfied
12106 * @throws UnsupportedOperationException if the device does not support the minimum HAL
12107 * version for this feature.
12108 * @hide
12109 */
12110 @Override
12111 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
12112 public boolean isNullCipherAndIntegrityPreferenceEnabled() {
12113 enforceReadPermission();
12114 checkForNullCipherAndIntegritySupport();
12115 return getDefaultPhone().getNullCipherAndIntegrityEnabledPreference();
12116 }
12117
12118 private void checkForNullCipherAndIntegritySupport() {
12119 if (getHalVersion(HAL_SERVICE_NETWORK) < MIN_NULL_CIPHER_AND_INTEGRITY_VERSION) {
12120 throw new UnsupportedOperationException(
12121 "Null cipher and integrity operations require HAL 2.1 or above");
12122 }
Gil Cukierman92cc7db2023-01-06 19:25:53 +000012123 if (!getDefaultPhone().isNullCipherAndIntegritySupported()) {
12124 throw new UnsupportedOperationException(
12125 "Null cipher and integrity operations unsupported by modem");
12126 }
Gil Cukierman1c0eb932022-12-06 22:28:24 +000012127 }
12128
12129 /**
Jack Yuf5badd92022-12-08 00:50:53 -080012130 * Get the SIM state for the slot index.
12131 * For Remote-SIMs, this method returns {@link IccCardConstants.State#UNKNOWN}
12132 *
12133 * @return SIM state as the ordinal of {@link IccCardConstants.State}
12134 */
12135 @Override
12136 @SimState
12137 public int getSimStateForSlotIndex(int slotIndex) {
12138 IccCardConstants.State simState;
12139 if (slotIndex < 0) {
12140 simState = IccCardConstants.State.UNKNOWN;
12141 } else {
12142 Phone phone = null;
12143 try {
12144 phone = PhoneFactory.getPhone(slotIndex);
12145 } catch (IllegalStateException e) {
12146 // ignore
12147 }
12148 if (phone == null) {
12149 simState = IccCardConstants.State.UNKNOWN;
12150 } else {
12151 IccCard icc = phone.getIccCard();
12152 if (icc == null) {
12153 simState = IccCardConstants.State.UNKNOWN;
12154 } else {
12155 simState = icc.getState();
12156 }
12157 }
12158 }
12159 return simState.ordinal();
12160 }
Hui Wang9b5793a2022-12-05 14:38:06 -060012161
12162 /**
12163 * Get current cell broadcast ranges.
12164 */
12165 @Override
12166 @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS)
12167 public List<CellBroadcastIdRange> getCellBroadcastIdRanges(int subId) {
12168 mApp.enforceCallingPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS,
12169 "getCellBroadcastIdRanges");
12170 final long identity = Binder.clearCallingIdentity();
12171 try {
12172 return getPhone(subId).getCellBroadcastIdRanges();
12173 } finally {
12174 Binder.restoreCallingIdentity(identity);
12175 }
12176 }
12177
12178 /**
12179 * Set reception of cell broadcast messages with the list of the given ranges
12180 *
12181 * @param ranges the list of {@link CellBroadcastIdRange} to be enabled
12182 */
12183 @Override
12184 @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS)
12185 public void setCellBroadcastIdRanges(int subId, @NonNull List<CellBroadcastIdRange> ranges,
12186 @Nullable IIntegerConsumer callback) {
12187 mApp.enforceCallingPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS,
12188 "setCellBroadcastIdRanges");
12189 final long identity = Binder.clearCallingIdentity();
12190 try {
12191 Phone phone = getPhoneFromSubId(subId);
12192 if (DBG) {
12193 log("setCellBroadcastIdRanges for subId :" + subId + ", phone:" + phone);
12194 }
12195 phone.setCellBroadcastIdRanges(ranges, result -> {
12196 if (callback != null) {
12197 try {
12198 callback.accept(result);
12199 } catch (RemoteException e) {
12200 Log.w(LOG_TAG, "setCellBroadcastIdRanges: callback not available.");
12201 }
12202 }
12203 });
12204 } finally {
12205 Binder.restoreCallingIdentity(identity);
12206 }
12207 }
Hunsuk Choi42cc62a2022-10-16 06:03:40 +000012208
12209 /**
12210 * Returns whether the device supports the domain selection service.
12211 *
12212 * @return {@code true} if the device supports the domain selection service.
12213 */
12214 @Override
12215 public boolean isDomainSelectionSupported() {
12216 mApp.enforceCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
12217 "isDomainSelectionSupported");
12218
12219 final long identity = Binder.clearCallingIdentity();
12220 try {
12221 return DomainSelectionResolver.getInstance().isDomainSelectionSupported();
12222 } finally {
12223 Binder.restoreCallingIdentity(identity);
12224 }
12225 }
arunvoddud5c6ce02022-12-11 06:03:12 +000012226
12227 /**
Sarah Chineccfbd12023-01-20 19:00:35 -080012228 * Start receiving satellite position updates.
12229 * This can be called by the pointing UI when the user starts pointing to the satellite.
12230 * Modem should continue to report the pointing input as the device or satellite moves.
12231 *
12232 * @param subId The subId to start satellite position updates for.
12233 * @param callbackId The callback ID associating the public SatellitePositionUpdateCallback to
12234 * the internal ISatellitePositionUpdateCallback below.
12235 * @param callback The callback to notify of changes in satellite position.
12236 * @return The result of the operation.
12237 */
12238 @Override
12239 @SatelliteManager.SatelliteServiceResult public int startSatellitePositionUpdates(int subId,
12240 int callbackId, @NonNull ISatellitePositionUpdateCallback callback) {
12241 // TODO: check for SATELLITE_COMMUNICATION permission
12242 Phone phone = getPhone(subId);
12243 if (phone == null) {
12244 loge("startSatellitePositionUpdates called with invalid subId: " + subId
12245 + ". Retrying with default phone.");
12246 phone = getDefaultPhone();
12247 if (phone == null) {
12248 loge("startSatellitePositionUpdates failed with no phone object.");
12249 return SatelliteManager.SATELLITE_SERVICE_REQUEST_FAILED;
12250 }
12251 }
12252
12253 if (mSatellitePositionUpdateHandlers.containsKey(callbackId)) {
12254 log("startSatellitePositionUpdates: callback already registered: " + callbackId);
12255 return SatelliteManager.SATELLITE_SERVICE_SUCCESS;
12256 }
12257
12258 SatellitePositionUpdateHandler handler =
12259 new SatellitePositionUpdateHandler(callback, Looper.getMainLooper());
12260 phone.registerForSatellitePointingInfoChanged(handler,
12261 SatellitePositionUpdateHandler.EVENT_POSITION_UPDATE, null);
12262 phone.registerForSatelliteMessagesTransferComplete(handler,
12263 SatellitePositionUpdateHandler.EVENT_MESSAGE_TRANSFER_STATE_UPDATE, null);
12264 mSatellitePositionUpdateHandlers.put(callbackId, handler);
12265
12266 int result = (int) sendRequest(CMD_START_SATELLITE_POSITION_UPDATES, null, subId);
12267 if (DBG) log("startSatellitePositionUpdates result: " + result);
12268 return result;
12269 }
12270
12271 /**
12272 * Stop receiving satellite position updates.
12273 * This can be called by the pointing UI when the user stops pointing to the satellite.
12274 *
12275 * @param subId The subId to stop satellite position updates for.
12276 * @param callbackId The ID of the callback that was passed in {@link
12277 * #startSatellitePositionUpdates(int, int, ISatellitePositionUpdateCallback)}
12278 * @return The result of the operation.
12279 */
12280 @Override
12281 @SatelliteManager.SatelliteServiceResult public int stopSatellitePositionUpdates(int subId,
12282 int callbackId) {
12283 // TODO: check for SATELLITE_COMMUNICATION permission
12284 Phone phone = getPhone(subId);
12285 if (phone == null) {
12286 loge("stopSatellitePositionUpdates called with invalid subId: " + subId
12287 + ". Retrying with default phone.");
12288 phone = getDefaultPhone();
12289 if (phone == null) {
12290 loge("stopSatellitePositionUpdates failed with no phone object.");
12291 return SatelliteManager.SATELLITE_SERVICE_REQUEST_FAILED;
12292 }
12293 }
12294
12295 SatellitePositionUpdateHandler handler =
12296 mSatellitePositionUpdateHandlers.remove(callbackId);
12297 if (handler == null) {
12298 loge("stopSatellitePositionUpdates: No SatellitePositionArgument");
12299 return SatelliteManager.SATELLITE_SERVICE_REQUEST_FAILED;
12300 } else {
12301 phone.unregisterForSatellitePointingInfoChanged(handler);
12302 phone.unregisterForSatelliteMessagesTransferComplete(handler);
12303 }
12304
12305 if (!mSatellitePositionUpdateHandlers.isEmpty()) {
12306 log("stopSatellitePositionUpdates: other listeners still exist.");
12307 return SatelliteManager.SATELLITE_SERVICE_SUCCESS;
12308 }
12309
12310 int result = (int) sendRequest(CMD_STOP_SATELLITE_POSITION_UPDATES, null, subId);
12311 if (DBG) log("stopSatellitePositionUpdates result: " + result);
12312 return result;
12313 }
12314
12315 /**
Aishwarya Mallampati60fe1132023-01-24 19:07:21 +000012316 * Get maximum number of characters per text message on satellite.
12317 * @param subId - The subId of the subscription.
12318 * @param callback - The callback that will be used to send maximum characters limit
12319 * if operation is successful.
12320 * @return The result of the operation.
12321 *
12322 * @throws SecurityException if the caller doesn't have the required permission.
12323 */
12324 @Override
12325 public int getMaxCharactersPerSatelliteTextMessage(int subId, IIntegerConsumer callback) {
12326 enforceSatelliteCommunicationPermission("getMaxCharactersPerSatelliteTextMessage");
12327
12328 if (!isSatelliteEnabled(subId)) {
12329 return SatelliteManager.SATELLITE_SERVICE_DISABLED;
12330 }
12331
12332 Phone phone = getPhone(subId);
12333 if (phone == null) {
12334 loge("getMaxCharactersPerSatelliteTextMessage called with invalid subId: " + subId
12335 + ".Retrying with default phone.");
12336 phone = getDefaultPhone();
12337 if (phone == null) {
12338 loge("getMaxCharactersPerSatelliteTextMessage failed with no phone object.");
12339 return SatelliteManager.SATELLITE_SERVICE_TELEPHONY_INTERNAL_ERROR;
12340 }
12341 }
12342
12343 Consumer<Integer> argument = FunctionalUtils.ignoreRemoteException(callback::accept);
12344 int result = (int) sendRequest(CMD_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG, argument, subId);
12345 if (DBG) log("getMaxCharPerTextMessageOnSatellite result: " + result);
12346 return result;
12347 }
12348
12349 /**
arunvoddud5c6ce02022-12-11 06:03:12 +000012350 * Check whether the caller (or self, if not processing an IPC) can read device identifiers.
12351 *
12352 * <p>This method behaves in one of the following ways:
12353 * <ul>
12354 * <li>return true : if the calling package has the appop permission {@link
12355 * Manifest.permission#USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER} in the manifest </>
12356 * <li>return true : if any one subscription has the READ_PRIVILEGED_PHONE_STATE
12357 * permission, the calling package passes a DevicePolicyManager Device Owner / Profile
12358 * Owner device identifier access check, or the calling package has carrier privileges</>
12359 * <li>throw SecurityException: if the caller does not meet any of the requirements.
12360 * </ul>
12361 */
12362 private static boolean checkCallingOrSelfReadDeviceIdentifiersForAnySub(Context context,
12363 String callingPackage, @Nullable String callingFeatureId, String message) {
12364 for (Phone phone : PhoneFactory.getPhones()) {
12365 if (TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(context,
12366 phone.getSubId(), callingPackage, callingFeatureId, message)) {
12367 return true;
12368 }
12369 }
12370 return false;
12371 }
arunvoddud7401012022-12-15 16:08:12 +000012372
12373 /**
Aishwarya Mallampati60fe1132023-01-24 19:07:21 +000012374 * Check if satellite is enabled for a subscription.
12375 */
12376 private boolean isSatelliteEnabled(int subId) {
12377 if (mSubscriptionController != null) {
12378 String strResult = mSubscriptionController.getSubscriptionProperty(
12379 subId, SubscriptionManager.SATELLITE_ENABLED);
12380 if (strResult != null) {
12381 int intResult = Integer.parseInt(strResult);
12382 return (intResult == 1) ? true : false;
12383 }
12384 }
12385 return false;
12386 }
12387
12388 /**
arunvoddud7401012022-12-15 16:08:12 +000012389 * Class binds the consumer[callback] and carrierId.
12390 */
12391 private static class CallerCallbackInfo {
12392 private final Consumer<Integer> mConsumer;
12393 private final int mCarrierId;
12394
12395 public CallerCallbackInfo(Consumer<Integer> consumer, int carrierId) {
12396 mConsumer = consumer;
12397 mCarrierId = carrierId;
12398 }
12399
12400 public Consumer<Integer> getConsumer() {
12401 return mConsumer;
12402 }
12403
12404 public int getCarrierId() {
12405 return mCarrierId;
12406 }
12407 }
arunvoddud5c6ce02022-12-11 06:03:12 +000012408}