blob: 63af6e28aa9f051115752ce43d681d7bf618cc08 [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;
Thomas Nguyen8ee49682023-02-01 11:46:09 -080054import android.os.CancellationSignal;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070055import android.os.Handler;
yinxu504e1392017-04-12 16:03:22 -070056import android.os.IBinder;
Thomas Nguyen8ee49682023-02-01 11:46:09 -080057import android.os.ICancellationSignal;
tom hsu0b59d292022-09-29 23:49:21 +080058import android.os.LocaleList;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070059import android.os.Looper;
60import android.os.Message;
yinxu504e1392017-04-12 16:03:22 -070061import android.os.Messenger;
Hall Liua1548bd2019-12-24 14:14:12 -080062import android.os.ParcelFileDescriptor;
Malcolm Chen6ca97372019-07-01 16:28:21 -070063import android.os.ParcelUuid;
Tyler Gunn65d45c22017-06-05 11:22:26 -070064import android.os.PersistableBundle;
Shuo Qiancd19c462020-01-16 20:51:11 -080065import android.os.Process;
Brad Ebinger5f64b052017-12-14 14:26:15 -080066import android.os.RemoteException;
Adam Lesinski903a54c2016-04-11 14:49:52 -070067import android.os.ResultReceiver;
Brad Ebinger1ce9c432019-07-16 13:19:44 -070068import android.os.ServiceSpecificException;
Rambo Wang0f050d82021-02-12 11:43:36 -080069import android.os.SystemClock;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070070import android.os.UserHandle;
Stuart Scott981d8582015-04-21 14:09:50 -070071import android.os.UserManager;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070072import android.os.WorkSource;
Derek Tan97ebb422014-09-05 16:55:38 -070073import android.preference.PreferenceManager;
Naina Nallurid63128d2019-09-17 14:10:30 -070074import android.provider.DeviceConfig;
Ihab Awadf2177b72013-11-25 13:33:23 -080075import android.provider.Settings;
Amit Mahajan7dbbd822019-03-13 17:33:47 -070076import android.provider.Telephony;
arunvoddud7401012022-12-15 16:08:12 +000077import android.service.carrier.CarrierIdentifier;
Inseob Kim14bb3d02018-12-13 17:11:34 +090078import android.sysprop.TelephonyProperties;
Santos Cordon7a1885b2015-02-03 11:15:19 -080079import android.telecom.PhoneAccount;
Nancy Chen31f9ba12016-01-06 11:42:12 -080080import android.telecom.PhoneAccountHandle;
Andrew Lee9431b832015-03-09 18:46:45 -070081import android.telecom.TelecomManager;
Gary Jian3aa9a762022-01-24 16:41:19 +080082import android.telephony.AccessNetworkConstants;
83import android.telephony.ActivityStatsTechSpecificInfo;
Chen Xu227e06f2019-09-26 22:48:11 -070084import android.telephony.Annotation.ApnType;
Jack Yu0eda6842022-04-18 00:34:46 -070085import android.telephony.Annotation.DataActivityType;
Jack Nudelmanb0b87642020-11-12 15:04:39 -080086import android.telephony.Annotation.ThermalMitigationResult;
Sarah Chin2ec39f62022-08-31 17:03:26 -070087import android.telephony.AnomalyReporter;
Shuo Qian4a594052020-01-23 11:59:30 -080088import android.telephony.CallForwardingInfo;
Junda Liu12f7d802015-05-01 12:06:44 -070089import android.telephony.CarrierConfigManager;
Michele Berionne482f8202018-11-27 18:57:59 -080090import android.telephony.CarrierRestrictionRules;
Hui Wang9b5793a2022-12-05 14:38:06 -060091import android.telephony.CellBroadcastIdRange;
yincheng zhao2737e882019-09-06 17:06:54 -070092import android.telephony.CellIdentity;
Meng Wanga10e89e2019-12-09 13:13:01 -080093import android.telephony.CellIdentityCdma;
94import android.telephony.CellIdentityGsm;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070095import android.telephony.CellInfo;
Nathan Haroldf180aac2018-06-01 18:43:55 -070096import android.telephony.CellInfoGsm;
97import android.telephony.CellInfoWcdma;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070098import android.telephony.ClientRequestStats;
Jack Nudelmanb0b87642020-11-12 15:04:39 -080099import android.telephony.DataThrottlingRequest;
Hui Wang641e81c2020-10-12 12:14:23 -0700100import android.telephony.IBootstrapAuthenticationCallback;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -0700101import android.telephony.ICellInfoCallback;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700102import android.telephony.IccOpenLogicalChannelResponse;
Hall Liu1aa510f2017-11-22 17:40:08 -0800103import android.telephony.LocationAccessPolicy;
Ta-wei Yen87c49842016-05-13 21:19:52 -0700104import android.telephony.ModemActivityInfo;
Jake Hambye994d462014-02-03 13:10:13 -0800105import android.telephony.NeighboringCellInfo;
yinxu504e1392017-04-12 16:03:22 -0700106import android.telephony.NetworkScanRequest;
Michele4245e952019-02-04 11:36:23 -0800107import android.telephony.PhoneCapability;
Hall Liud892bec2018-11-30 14:51:45 -0800108import android.telephony.PhoneNumberRange;
Wink Saville5d475dd2014-10-17 15:00:58 -0700109import android.telephony.RadioAccessFamily;
Hall Liub2ac8ef2019-02-28 15:56:23 -0800110import android.telephony.RadioAccessSpecifier;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700111import android.telephony.ServiceState;
Nathan Harold46b42aa2017-03-10 19:38:22 -0800112import android.telephony.SignalStrength;
Rambo Wanga5cc9b72021-01-07 10:51:54 -0800113import android.telephony.SignalStrengthUpdateRequest;
114import android.telephony.SignalThresholdInfo;
Wink Saville0f3b5fc2014-11-11 08:40:49 -0800115import android.telephony.SubscriptionInfo;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800116import android.telephony.SubscriptionManager;
Peter Wangc035ce42020-01-08 21:00:22 -0800117import android.telephony.TelephonyFrameworkInitializer;
Sanket Padawe99ef1e32016-05-18 16:12:33 -0700118import android.telephony.TelephonyHistogram;
Ta-wei Yenb6929602016-05-24 15:48:27 -0700119import android.telephony.TelephonyManager;
Jack Yuf5badd92022-12-08 00:50:53 -0800120import android.telephony.TelephonyManager.SimState;
Hall Liub2ac8ef2019-02-28 15:56:23 -0800121import android.telephony.TelephonyScanManager;
Jack Nudelmanb0b87642020-11-12 15:04:39 -0800122import android.telephony.ThermalMitigationRequest;
Jordan Liu5aa07002018-12-18 15:44:48 -0800123import android.telephony.UiccCardInfo;
sandeepjsb6c87872021-09-27 15:34:44 +0000124import android.telephony.UiccPortInfo;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000125import android.telephony.UiccSlotInfo;
sandeepjsb6c87872021-09-27 15:34:44 +0000126import android.telephony.UiccSlotMapping;
Tyler Gunn65d45c22017-06-05 11:22:26 -0700127import android.telephony.UssdResponse;
Ta-wei Yenb6929602016-05-24 15:48:27 -0700128import android.telephony.VisualVoicemailSmsFilterSettings;
Hongbo Zeng0e18b162021-04-07 16:52:18 +0800129import android.telephony.data.NetworkSlicingConfig;
Jack Yub5d8f642018-11-26 11:20:48 -0800130import android.telephony.emergency.EmergencyNumber;
Hui Wang641e81c2020-10-12 12:14:23 -0700131import android.telephony.gba.GbaAuthRequest;
132import android.telephony.gba.UaSecurityProtocolIdentifier;
Brad Ebinger1ce9c432019-07-16 13:19:44 -0700133import android.telephony.ims.ImsException;
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800134import android.telephony.ims.ProvisioningManager;
Hui Wang761a6682020-10-31 05:12:53 +0000135import android.telephony.ims.RcsClientConfiguration;
Brad Ebinger14d467f2021-02-12 06:18:28 +0000136import android.telephony.ims.RcsContactUceCapability;
Brad Ebingera34a6c22019-10-22 17:36:18 -0700137import android.telephony.ims.RegistrationManager;
joonhunshincffb7fc2021-11-28 07:32:01 +0000138import android.telephony.ims.aidl.IFeatureProvisioningCallback;
Brad Ebinger35c841c2018-10-01 10:40:55 -0700139import android.telephony.ims.aidl.IImsCapabilityCallback;
Brad Ebinger22bc3e42018-01-16 09:39:35 -0800140import android.telephony.ims.aidl.IImsConfig;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -0700141import android.telephony.ims.aidl.IImsConfigCallback;
Brad Ebinger22bc3e42018-01-16 09:39:35 -0800142import android.telephony.ims.aidl.IImsRegistration;
Brad Ebinger35c841c2018-10-01 10:40:55 -0700143import android.telephony.ims.aidl.IImsRegistrationCallback;
Hui Wang761a6682020-10-31 05:12:53 +0000144import android.telephony.ims.aidl.IRcsConfigCallback;
Brad Ebingerbc7dd582019-10-17 17:03:22 -0700145import android.telephony.ims.feature.ImsFeature;
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800146import android.telephony.ims.stub.ImsConfigImplBase;
Brad Ebinger1f2b5082018-02-08 16:11:32 -0800147import android.telephony.ims.stub.ImsRegistrationImplBase;
Sarah Chin503828c2023-02-01 23:54:20 -0800148import android.telephony.satellite.ISatelliteCapabilitiesConsumer;
Thomas Nguyen8ee49682023-02-01 11:46:09 -0800149import android.telephony.satellite.ISatelliteStateListener;
Sarah Chineccfbd12023-01-20 19:00:35 -0800150import android.telephony.satellite.PointingInfo;
Sarah Chin503828c2023-02-01 23:54:20 -0800151import android.telephony.satellite.SatelliteCapabilities;
Sarah Chineccfbd12023-01-20 19:00:35 -0800152import android.telephony.satellite.SatelliteManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700153import android.text.TextUtils;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800154import android.util.ArraySet;
Hall Liud60acc92020-05-21 17:09:35 -0700155import android.util.EventLog;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700156import android.util.Log;
Jake Hambye994d462014-02-03 13:10:13 -0800157import android.util.Pair;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800158
Andrew Lee312e8172014-10-23 17:01:36 -0700159import com.android.ims.ImsManager;
Brad Ebinger34bef922017-11-09 10:27:08 -0800160import com.android.ims.internal.IImsServiceFeatureCallback;
James.cf Linbcdf8b32021-01-14 16:44:13 +0800161import com.android.ims.rcs.uce.eab.EabUtil;
SongFerngWangfd89b102021-05-27 22:44:54 +0800162import com.android.internal.annotations.VisibleForTesting;
Shuo Qian4a594052020-01-23 11:59:30 -0800163import com.android.internal.telephony.CallForwardInfo;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700164import com.android.internal.telephony.CallManager;
Tyler Gunn52dcf772017-04-26 11:30:31 -0700165import com.android.internal.telephony.CallStateException;
Tyler Gunnd4339262021-05-03 14:46:49 -0700166import com.android.internal.telephony.CallTracker;
Rambo Wang9c9ffdd2022-01-13 21:51:44 -0800167import com.android.internal.telephony.CarrierPrivilegesTracker;
chen xu651eec72018-11-11 19:03:44 -0800168import com.android.internal.telephony.CarrierResolver;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700169import com.android.internal.telephony.CellNetworkScanResult;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700170import com.android.internal.telephony.CommandException;
Shuo Qian4a594052020-01-23 11:59:30 -0800171import com.android.internal.telephony.CommandsInterface;
Hui Wang641e81c2020-10-12 12:14:23 -0700172import com.android.internal.telephony.GbaManager;
Shuo Qianccbaf742021-02-22 18:32:21 -0800173import com.android.internal.telephony.GsmCdmaPhone;
Nathan Harold48d6fd52019-02-06 19:01:40 -0800174import com.android.internal.telephony.HalVersion;
Hall Liu73f5d362020-01-20 13:42:00 -0800175import com.android.internal.telephony.IBooleanConsumer;
Hall Liu27d24262020-09-18 19:04:59 -0700176import com.android.internal.telephony.ICallForwardingInfoCallback;
Hunsuk Choi3b742d62021-10-25 19:48:34 +0000177import com.android.internal.telephony.IImsStateCallback;
Thomas Nguyen8ee49682023-02-01 11:46:09 -0800178import com.android.internal.telephony.IIntArrayConsumer;
Brad Ebingera63db5f2019-04-23 16:31:13 -0700179import com.android.internal.telephony.IIntegerConsumer;
Hall Liud892bec2018-11-30 14:51:45 -0800180import com.android.internal.telephony.INumberVerificationCallback;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700181import com.android.internal.telephony.ITelephony;
Jake Hambye994d462014-02-03 13:10:13 -0800182import com.android.internal.telephony.IccCard;
Jack Yuf5badd92022-12-08 00:50:53 -0800183import com.android.internal.telephony.IccCardConstants;
Rambo Wanga1782702021-11-10 20:15:19 -0800184import com.android.internal.telephony.IccLogicalChannelRequest;
Jack Yu5f7092c2018-04-13 14:05:37 -0700185import com.android.internal.telephony.LocaleTracker;
yinxub1bed742017-04-17 11:45:04 -0700186import com.android.internal.telephony.NetworkScanRequestTracker;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700187import com.android.internal.telephony.OperatorInfo;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700188import com.android.internal.telephony.Phone;
Malcolm Chen2c63d402018-08-14 16:00:53 -0700189import com.android.internal.telephony.PhoneConfigurationManager;
Nathan Harolda667c152016-12-14 11:27:20 -0800190import com.android.internal.telephony.PhoneConstantConversions;
Ta-wei Yen87c49842016-05-13 21:19:52 -0700191import com.android.internal.telephony.PhoneConstants;
Wink Saville36469e72014-06-11 15:17:00 -0700192import com.android.internal.telephony.PhoneFactory;
Wink Saville5d475dd2014-10-17 15:00:58 -0700193import com.android.internal.telephony.ProxyController;
Sanket Padawe99ef1e32016-05-18 16:12:33 -0700194import com.android.internal.telephony.RIL;
SongFerngWang8c6e82e2021-03-02 22:09:29 +0800195import com.android.internal.telephony.RILConstants;
Sarah Chineccfbd12023-01-20 19:00:35 -0800196import com.android.internal.telephony.RILUtils;
Daniel Bright94f43662021-03-01 14:43:40 -0800197import com.android.internal.telephony.RadioInterfaceCapabilityController;
Jack Yu5f7092c2018-04-13 14:05:37 -0700198import com.android.internal.telephony.ServiceStateTracker;
Aishwarya Mallampatifbc70d32022-11-10 20:33:02 +0000199import com.android.internal.telephony.SmsApplication;
Amit Mahajandccb3f12019-05-13 13:48:32 -0700200import com.android.internal.telephony.SmsController;
Brad Ebingera63db5f2019-04-23 16:31:13 -0700201import com.android.internal.telephony.SmsPermissions;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800202import com.android.internal.telephony.SubscriptionController;
Peter Wang59571be2020-01-27 12:35:15 +0800203import com.android.internal.telephony.TelephonyIntents;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800204import com.android.internal.telephony.TelephonyPermissions;
Jack Yu27422a52022-03-21 10:38:05 -0700205import com.android.internal.telephony.data.DataUtils;
Hunsuk Choi42cc62a2022-10-16 06:03:40 +0000206import com.android.internal.telephony.domainselection.DomainSelectionResolver;
sqianf4ca7ed2019-01-15 18:32:07 -0800207import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Derek Tan740e1672017-06-27 14:56:27 -0700208import com.android.internal.telephony.euicc.EuiccConnector;
Brad Ebinger9c0eb502019-01-23 15:06:19 -0800209import com.android.internal.telephony.ims.ImsResolver;
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700210import com.android.internal.telephony.imsphone.ImsPhone;
211import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
joonhunshin3e154242021-09-17 06:33:39 +0000212import com.android.internal.telephony.metrics.RcsStats;
Pengquan Meng6c2dc9f2019-02-06 11:12:53 -0800213import com.android.internal.telephony.metrics.TelephonyMetrics;
Jack Yu285100e2022-12-02 22:48:35 -0800214import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
215import com.android.internal.telephony.subscription.SubscriptionManagerService;
Meng Wangafbc5852019-09-19 17:37:13 -0700216import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700217import com.android.internal.telephony.uicc.IccIoResult;
218import com.android.internal.telephony.uicc.IccUtils;
Nathan Haroldb3014052017-01-25 15:57:32 -0800219import com.android.internal.telephony.uicc.SIMRecords;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700220import com.android.internal.telephony.uicc.UiccCard;
Nathan Haroldb3014052017-01-25 15:57:32 -0800221import com.android.internal.telephony.uicc.UiccCardApplication;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700222import com.android.internal.telephony.uicc.UiccController;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000223import com.android.internal.telephony.uicc.UiccPort;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800224import com.android.internal.telephony.uicc.UiccProfile;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000225import com.android.internal.telephony.uicc.UiccSlot;
zoey chenc730df82019-12-18 17:07:20 +0800226import com.android.internal.telephony.util.LocaleUtils;
Aishwarya Mallampatifbc70d32022-11-10 20:33:02 +0000227import com.android.internal.telephony.util.TelephonyUtils;
fionaxu7ed723d2017-05-30 18:58:54 -0700228import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
Hall Liu27d24262020-09-18 19:04:59 -0700229import com.android.internal.util.FunctionalUtils;
Jake Hambye994d462014-02-03 13:10:13 -0800230import com.android.internal.util.HexDump;
Hall Liuaa4211e2021-01-20 15:43:39 -0800231import com.android.phone.callcomposer.CallComposerPictureManager;
232import com.android.phone.callcomposer.CallComposerPictureTransfer;
233import com.android.phone.callcomposer.ImageData;
Brad Ebingera63db5f2019-04-23 16:31:13 -0700234import com.android.phone.settings.PickSmsSubscriptionActivity;
Sarah Chin46355ba2022-11-01 23:51:16 -0700235import com.android.phone.slice.SlicePurchaseController;
arunvoddud7401012022-12-15 16:08:12 +0000236import com.android.phone.utils.CarrierAllowListInfo;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700237import com.android.phone.vvm.PhoneAccountHandleConverter;
Ta-wei Yen527a9c02017-01-06 15:29:25 -0800238import com.android.phone.vvm.RemoteVvmTaskManager;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700239import com.android.phone.vvm.VisualVoicemailSettingsUtil;
Ta-wei Yenc8905312017-03-28 11:14:45 -0700240import com.android.phone.vvm.VisualVoicemailSmsFilterConfig;
Jack Nudelmanb0b87642020-11-12 15:04:39 -0800241import com.android.services.telephony.TelecomAccountRegistry;
242import com.android.services.telephony.TelephonyConnectionService;
Peter Wang44b186e2020-01-13 23:33:09 -0800243import com.android.telephony.Rlog;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800244
Hall Liu82694d52020-12-11 18:22:04 -0800245import java.io.ByteArrayOutputStream;
Ta-wei Yenc236d6b2016-06-21 13:33:12 -0700246import java.io.FileDescriptor;
Hall Liu82694d52020-12-11 18:22:04 -0800247import java.io.IOException;
248import java.io.InputStream;
Ta-wei Yenc236d6b2016-06-21 13:33:12 -0700249import java.io.PrintWriter;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700250import java.util.ArrayList;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800251import java.util.Arrays;
Muralidhar Reddyeb809e32021-11-19 03:07:54 +0000252import java.util.Collection;
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -0800253import java.util.Collections;
sqian11b7a0e2018-12-05 18:48:28 -0800254import java.util.HashMap;
sqianf4ca7ed2019-01-15 18:32:07 -0800255import java.util.HashSet;
Jake Hambye994d462014-02-03 13:10:13 -0800256import java.util.List;
Narayan Kamath1c496c22015-04-16 14:40:19 +0100257import java.util.Locale;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800258import java.util.Map;
Nazanin Bakhshif71371d2019-04-29 17:29:44 -0700259import java.util.NoSuchElementException;
Hall Liu82694d52020-12-11 18:22:04 -0800260import java.util.Objects;
sqianf4ca7ed2019-01-15 18:32:07 -0800261import java.util.Set;
Sarah Chin2ec39f62022-08-31 17:03:26 -0700262import java.util.UUID;
Sarah Chineccfbd12023-01-20 19:00:35 -0800263import java.util.concurrent.ConcurrentHashMap;
Hall Liu82694d52020-12-11 18:22:04 -0800264import java.util.concurrent.Executors;
Peter Wangdafb9ac2020-01-15 14:13:38 -0800265import java.util.concurrent.atomic.AtomicBoolean;
Hall Liu73f5d362020-01-20 13:42:00 -0800266import java.util.function.Consumer;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700267
268/**
269 * Implementation of the ITelephony interface.
270 */
Santos Cordon117fee72014-05-16 17:56:12 -0700271public class PhoneInterfaceManager extends ITelephony.Stub {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700272 private static final String LOG_TAG = "PhoneInterfaceManager";
273 private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
274 private static final boolean DBG_LOC = false;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800275 private static final boolean DBG_MERGE = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700276
277 // Message codes used with mMainThreadHandler
278 private static final int CMD_HANDLE_PIN_MMI = 1;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700279 private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7;
280 private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700281 private static final int CMD_OPEN_CHANNEL = 9;
282 private static final int EVENT_OPEN_CHANNEL_DONE = 10;
283 private static final int CMD_CLOSE_CHANNEL = 11;
284 private static final int EVENT_CLOSE_CHANNEL_DONE = 12;
Jake Hambye994d462014-02-03 13:10:13 -0800285 private static final int CMD_NV_READ_ITEM = 13;
286 private static final int EVENT_NV_READ_ITEM_DONE = 14;
287 private static final int CMD_NV_WRITE_ITEM = 15;
288 private static final int EVENT_NV_WRITE_ITEM_DONE = 16;
289 private static final int CMD_NV_WRITE_CDMA_PRL = 17;
290 private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18;
chen xu6dac5ab2018-10-26 17:39:23 -0700291 private static final int CMD_RESET_MODEM_CONFIG = 19;
292 private static final int EVENT_RESET_MODEM_CONFIG_DONE = 20;
SongFerngWang3ef3e072020-12-21 16:41:52 +0800293 private static final int CMD_GET_ALLOWED_NETWORK_TYPES_BITMASK = 21;
294 private static final int EVENT_GET_ALLOWED_NETWORK_TYPES_BITMASK_DONE = 22;
Sailesh Nepal35b59452014-03-06 09:26:56 -0800295 private static final int CMD_SEND_ENVELOPE = 25;
296 private static final int EVENT_SEND_ENVELOPE_DONE = 26;
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000297 private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27;
298 private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28;
Derek Tan6b088ee2014-09-05 14:15:18 -0700299 private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29;
300 private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30;
301 private static final int CMD_EXCHANGE_SIM_IO = 31;
302 private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800303 private static final int CMD_SET_VOICEMAIL_NUMBER = 33;
304 private static final int EVENT_SET_VOICEMAIL_NUMBER_DONE = 34;
Stuart Scott54788802015-03-30 13:18:01 -0700305 private static final int CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC = 35;
306 private static final int EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE = 36;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700307 private static final int CMD_GET_MODEM_ACTIVITY_INFO = 37;
308 private static final int EVENT_GET_MODEM_ACTIVITY_INFO_DONE = 38;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700309 private static final int CMD_PERFORM_NETWORK_SCAN = 39;
310 private static final int EVENT_PERFORM_NETWORK_SCAN_DONE = 40;
311 private static final int CMD_SET_NETWORK_SELECTION_MODE_MANUAL = 41;
312 private static final int EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE = 42;
Meng Wang1a7c35a2016-05-05 20:56:15 -0700313 private static final int CMD_SET_ALLOWED_CARRIERS = 43;
314 private static final int EVENT_SET_ALLOWED_CARRIERS_DONE = 44;
315 private static final int CMD_GET_ALLOWED_CARRIERS = 45;
316 private static final int EVENT_GET_ALLOWED_CARRIERS_DONE = 46;
pkanwar32d516d2016-10-14 19:37:38 -0700317 private static final int CMD_HANDLE_USSD_REQUEST = 47;
Nathan Haroldb3014052017-01-25 15:57:32 -0800318 private static final int CMD_GET_FORBIDDEN_PLMNS = 48;
319 private static final int EVENT_GET_FORBIDDEN_PLMNS_DONE = 49;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000320 private static final int CMD_SWITCH_SLOTS = 50;
321 private static final int EVENT_SWITCH_SLOTS_DONE = 51;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700322 private static final int CMD_GET_NETWORK_SELECTION_MODE = 52;
323 private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 53;
324 private static final int CMD_GET_CDMA_ROAMING_MODE = 54;
325 private static final int EVENT_GET_CDMA_ROAMING_MODE_DONE = 55;
326 private static final int CMD_SET_CDMA_ROAMING_MODE = 56;
327 private static final int EVENT_SET_CDMA_ROAMING_MODE_DONE = 57;
328 private static final int CMD_SET_CDMA_SUBSCRIPTION_MODE = 58;
329 private static final int EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE = 59;
Nathan Harold3ff88932018-08-14 10:19:49 -0700330 private static final int CMD_GET_ALL_CELL_INFO = 60;
331 private static final int EVENT_GET_ALL_CELL_INFO_DONE = 61;
332 private static final int CMD_GET_CELL_LOCATION = 62;
333 private static final int EVENT_GET_CELL_LOCATION_DONE = 63;
chen xu6dac5ab2018-10-26 17:39:23 -0700334 private static final int CMD_MODEM_REBOOT = 64;
335 private static final int EVENT_CMD_MODEM_REBOOT_DONE = 65;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -0700336 private static final int CMD_REQUEST_CELL_INFO_UPDATE = 66;
337 private static final int EVENT_REQUEST_CELL_INFO_UPDATE_DONE = 67;
Malcolm Chen8e4ed912019-01-15 20:22:16 -0800338 private static final int CMD_REQUEST_ENABLE_MODEM = 68;
339 private static final int EVENT_ENABLE_MODEM_DONE = 69;
Nazanin Bakhshif71371d2019-04-29 17:29:44 -0700340 private static final int CMD_GET_MODEM_STATUS = 70;
341 private static final int EVENT_GET_MODEM_STATUS_DONE = 71;
yincheng zhao2737e882019-09-06 17:06:54 -0700342 private static final int CMD_SET_FORBIDDEN_PLMNS = 72;
343 private static final int EVENT_SET_FORBIDDEN_PLMNS_DONE = 73;
Naina Nallurid63128d2019-09-17 14:10:30 -0700344 private static final int CMD_ERASE_MODEM_CONFIG = 74;
345 private static final int EVENT_ERASE_MODEM_CONFIG_DONE = 75;
zoey chene02881a2019-12-30 16:11:23 +0800346 private static final int CMD_CHANGE_ICC_LOCK_PASSWORD = 76;
347 private static final int EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE = 77;
348 private static final int CMD_SET_ICC_LOCK_ENABLED = 78;
349 private static final int EVENT_SET_ICC_LOCK_ENABLED_DONE = 79;
Hall Liu73f5d362020-01-20 13:42:00 -0800350 private static final int CMD_SET_SYSTEM_SELECTION_CHANNELS = 80;
351 private static final int EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE = 81;
Peter Wangdafb9ac2020-01-15 14:13:38 -0800352 private static final int MSG_NOTIFY_USER_ACTIVITY = 82;
Shuo Qian4a594052020-01-23 11:59:30 -0800353 private static final int CMD_GET_CALL_FORWARDING = 83;
354 private static final int EVENT_GET_CALL_FORWARDING_DONE = 84;
355 private static final int CMD_SET_CALL_FORWARDING = 85;
356 private static final int EVENT_SET_CALL_FORWARDING_DONE = 86;
357 private static final int CMD_GET_CALL_WAITING = 87;
358 private static final int EVENT_GET_CALL_WAITING_DONE = 88;
359 private static final int CMD_SET_CALL_WAITING = 89;
360 private static final int EVENT_SET_CALL_WAITING_DONE = 90;
Sooraj Sasindran37444802020-08-11 10:40:43 -0700361 private static final int CMD_ENABLE_NR_DUAL_CONNECTIVITY = 91;
362 private static final int EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE = 92;
363 private static final int CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED = 93;
364 private static final int EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE = 94;
Sarah Chinbaab1432020-10-28 13:46:24 -0700365 private static final int CMD_GET_CDMA_SUBSCRIPTION_MODE = 95;
366 private static final int EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE = 96;
Sarah Chin679c08a2020-11-18 13:39:35 -0800367 private static final int CMD_GET_SYSTEM_SELECTION_CHANNELS = 97;
368 private static final int EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE = 98;
Jack Nudelmanb0b87642020-11-12 15:04:39 -0800369 private static final int CMD_SET_DATA_THROTTLING = 99;
370 private static final int EVENT_SET_DATA_THROTTLING_DONE = 100;
Jordan Liu109698e2020-11-24 14:50:34 -0800371 private static final int CMD_SET_SIM_POWER = 101;
372 private static final int EVENT_SET_SIM_POWER_DONE = 102;
Rambo Wanga5cc9b72021-01-07 10:51:54 -0800373 private static final int CMD_SET_SIGNAL_STRENGTH_UPDATE_REQUEST = 103;
374 private static final int EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE = 104;
375 private static final int CMD_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST = 105;
376 private static final int EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE = 106;
SongFerngWang3ef3e072020-12-21 16:41:52 +0800377 private static final int CMD_SET_ALLOWED_NETWORK_TYPES_FOR_REASON = 107;
378 private static final int EVENT_SET_ALLOWED_NETWORK_TYPES_FOR_REASON_DONE = 108;
Michele Berionne5e411512020-11-13 02:36:59 +0000379 private static final int CMD_PREPARE_UNATTENDED_REBOOT = 109;
Hongbo Zeng156aa4a2021-02-08 21:50:28 +0800380 private static final int CMD_GET_SLICING_CONFIG = 110;
381 private static final int EVENT_GET_SLICING_CONFIG_DONE = 111;
Kai Shif70f46f2021-03-03 13:59:46 -0800382 private static final int CMD_ERASE_DATA_SHARED_PREFERENCES = 112;
Sooraj Sasindrandaf060f2021-06-15 14:52:55 -0700383 private static final int CMD_ENABLE_VONR = 113;
384 private static final int EVENT_ENABLE_VONR_DONE = 114;
385 private static final int CMD_IS_VONR_ENABLED = 115;
386 private static final int EVENT_IS_VONR_ENABLED_DONE = 116;
Sarah Chin2ec39f62022-08-31 17:03:26 -0700387 private static final int CMD_PURCHASE_PREMIUM_CAPABILITY = 117;
388 private static final int EVENT_PURCHASE_PREMIUM_CAPABILITY_DONE = 118;
Sarah Chineccfbd12023-01-20 19:00:35 -0800389 private static final int CMD_START_SATELLITE_POSITION_UPDATES = 119;
390 private static final int EVENT_START_SATELLITE_POSITION_UPDATES_DONE = 120;
391 private static final int CMD_STOP_SATELLITE_POSITION_UPDATES = 121;
392 private static final int EVENT_STOP_SATELLITE_POSITION_UPDATES_DONE = 122;
Aishwarya Mallampati60fe1132023-01-24 19:07:21 +0000393 private static final int CMD_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG = 123;
394 private static final int EVENT_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG_DONE = 124;
Thomas Nguyen8ee49682023-02-01 11:46:09 -0800395 private static final int CMD_PROVISION_SATELLITE_SERVICE = 125;
396 private static final int EVENT_PROVISION_SATELLITE_SERVICE_DONE = 126;
397 private static final int CMD_CANCEL_PROVISION_SATELLITE_SERVICE = 127;
398 private static final int EVENT_CANCEL_PROVISION_SATELLITE_SERVICE_DONE = 128;
399 private static final int CMD_GET_PROVISIONED_SATELLITE_FEATURES = 129;
400 private static final int EVENT_GET_PROVISIONED_SATELLITE_FEATURES_DONE = 130;
Sarah Chin503828c2023-02-01 23:54:20 -0800401 private static final int CMD_SET_SATELLITE_POWER = 131;
402 private static final int EVENT_SET_SATELLITE_POWER_DONE = 132;
403 private static final int CMD_IS_SATELLITE_POWER_ON = 133;
404 private static final int EVENT_IS_SATELLITE_POWER_ON_DONE = 134;
405 private static final int CMD_IS_SATELLITE_SUPPORTED = 135;
406 private static final int EVENT_IS_SATELLITE_SUPPORTED_DONE = 136;
407 private static final int CMD_GET_SATELLITE_CAPABILITIES = 137;
408 private static final int EVENT_GET_SATELLITE_CAPABILITIES_DONE = 138;
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -0800409 // Parameters of select command.
410 private static final int SELECT_COMMAND = 0xA4;
411 private static final int SELECT_P1 = 0x04;
412 private static final int SELECT_P2 = 0;
413 private static final int SELECT_P3 = 0x10;
414
Gil Cukierman1c0eb932022-12-06 22:28:24 +0000415 // Toggling null cipher and integrity support was added in IRadioNetwork 2.1
416 private static final int MIN_NULL_CIPHER_AND_INTEGRITY_VERSION = 201;
417
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700418 /** The singleton instance. */
419 private static PhoneInterfaceManager sInstance;
Jack Nudelman644b91a2021-03-12 14:09:48 -0800420 private static List<String> sThermalMitigationAllowlistedPackages = new ArrayList<>();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700421
Wink Saville3ab207e2014-11-20 13:07:20 -0800422 private PhoneGlobals mApp;
Wink Saville3ab207e2014-11-20 13:07:20 -0800423 private CallManager mCM;
Brad Ebinger24c29992019-12-05 13:03:21 -0800424 private ImsResolver mImsResolver;
Stuart Scott981d8582015-04-21 14:09:50 -0700425 private UserManager mUserManager;
Wink Saville3ab207e2014-11-20 13:07:20 -0800426 private AppOpsManager mAppOps;
Grace Jia0ddb3612021-04-22 13:35:26 -0700427 private PackageManager mPm;
Wink Saville3ab207e2014-11-20 13:07:20 -0800428 private MainThreadHandler mMainThreadHandler;
Jack Yue37dd262022-12-16 11:53:37 -0800429 private final SubscriptionController mSubscriptionController;
Wink Saville3ab207e2014-11-20 13:07:20 -0800430 private SharedPreferences mTelephonySharedPreferences;
Malcolm Chen2c63d402018-08-14 16:00:53 -0700431 private PhoneConfigurationManager mPhoneConfigurationManager;
Daniel Bright94f43662021-03-01 14:43:40 -0800432 private final RadioInterfaceCapabilityController mRadioInterfaceCapabilities;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700433
Peter Wangdafb9ac2020-01-15 14:13:38 -0800434 /** User Activity */
435 private AtomicBoolean mNotifyUserActivity;
Peter Wangdafb9ac2020-01-15 14:13:38 -0800436 private static final int USER_ACTIVITY_NOTIFICATION_DELAY = 200;
437
Jeff Davidson8ab02b22020-03-28 12:24:40 -0700438 private Set<Integer> mCarrierPrivilegeTestOverrideSubIds = new ArraySet<>();
Thomas Nguyen8ee49682023-02-01 11:46:09 -0800439 private ConcurrentHashMap<IBinder, SatellitePositionUpdateHandler>
440 mSatellitePositionUpdateHandlers = new ConcurrentHashMap<>();
441 /**
442 * Map key: subId, value: callback to get error code of the provision request.
443 */
444 private ConcurrentHashMap<Integer, IIntegerConsumer> mSatelliteProvisionCallbacks =
Sarah Chineccfbd12023-01-20 19:00:35 -0800445 new ConcurrentHashMap<>();
Jeff Davidson8ab02b22020-03-28 12:24:40 -0700446
Thomas Nguyen8ee49682023-02-01 11:46:09 -0800447 /**
448 * Map key: subId, value: SatelliteProvisionStateChangedHandler to notify registrants.
449 */
450 private ConcurrentHashMap<Integer, SatelliteProvisionStateChangedHandler>
451 mSatelliteProvisionStateChangedHandlers = new ConcurrentHashMap<>();
452
Thomas Nguyene77de6d2023-02-10 17:42:43 -0800453 private Boolean mIsSatelliteSupported = null;
454 private final Object mIsSatelliteSupportedLock = new Object();
455
Derek Tan97ebb422014-09-05 16:55:38 -0700456 private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
457 private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
Jeff Sharkey85190e62014-12-05 09:40:12 -0800458 private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800459 private static final String PREF_PROVISION_IMS_MMTEL_PREFIX = "provision_ims_mmtel_";
Derek Tan89e89d42014-07-08 17:00:10 -0700460
Michelecea4cf22018-12-21 15:00:11 -0800461 // String to store multi SIM allowed
462 private static final String PREF_MULTI_SIM_RESTRICTED = "multisim_restricted";
463
Derek Tan740e1672017-06-27 14:56:27 -0700464 // The AID of ISD-R.
465 private static final String ISDR_AID = "A0000005591010FFFFFFFF8900000100";
466
yinxub1bed742017-04-17 11:45:04 -0700467 private NetworkScanRequestTracker mNetworkScanRequestTracker;
468
David Kelly5e06a7f2018-03-12 14:10:59 +0000469 private static final int TYPE_ALLOCATION_CODE_LENGTH = 8;
470 private static final int MANUFACTURER_CODE_LENGTH = 8;
471
Jack Nudelmanb0b87642020-11-12 15:04:39 -0800472 private static final int SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS = -1;
Jack Nudelman5d6a98b2021-03-04 14:26:25 -0800473 private static final int MODEM_DOES_NOT_SUPPORT_DATA_THROTTLING_ERROR_CODE = -2;
Jack Nudelmanb0b87642020-11-12 15:04:39 -0800474
Sarah Chin2ec39f62022-08-31 17:03:26 -0700475 private static final String PURCHASE_PREMIUM_CAPABILITY_ERROR_UUID =
476 "24bf97a6-e8a6-44d8-a6a4-255d7548733c";
477
Derek Tan89e89d42014-07-08 17:00:10 -0700478 /**
Naina Nallurid63128d2019-09-17 14:10:30 -0700479 * Experiment flag to enable erase modem config on reset network, default value is false
480 */
481 public static final String RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED =
482 "reset_network_erase_modem_config_enabled";
483
Rambo Wang0f050d82021-02-12 11:43:36 -0800484 private static final int SET_NETWORK_SELECTION_MODE_AUTOMATIC_TIMEOUT_MS = 2000; // 2 seconds
Chen Xu540470b2021-12-14 17:15:47 -0800485
Gary Jian76280a42022-12-07 16:18:33 +0800486 private static final int MODEM_ACTIVITY_TIME_OFFSET_CORRECTION_MS = 50;
487
sandeepjsb6c87872021-09-27 15:34:44 +0000488 /**
489 * With support for MEP(multiple enabled profile) in Android T, a SIM card can have more than
490 * one ICCID active at the same time.
491 * Apps should use below API signatures if targeting SDK is T and beyond.
492 *
493 * @hide
494 */
495 @ChangeId
496 @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
497 public static final long GET_API_SIGNATURES_FROM_UICC_PORT_INFO = 202110963L;
Rambo Wang0f050d82021-02-12 11:43:36 -0800498
Naina Nallurid63128d2019-09-17 14:10:30 -0700499 /**
Chen Xu540470b2021-12-14 17:15:47 -0800500 * Apps targeting on Android T and beyond will get exception whenever icc close channel
501 * operation fails.
502 */
503 @ChangeId
504 @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
505 public static final long ICC_CLOSE_CHANNEL_EXCEPTION_ON_FAILURE = 208739934L;
506
507 /**
Shishir Agrawal566b7612013-10-28 14:41:00 -0700508 * A request object to use for transmitting data to an ICC.
509 */
510 private static final class IccAPDUArgument {
511 public int channel, cla, command, p1, p2, p3;
512 public String data;
513
514 public IccAPDUArgument(int channel, int cla, int command,
515 int p1, int p2, int p3, String data) {
516 this.channel = channel;
517 this.cla = cla;
518 this.command = command;
519 this.p1 = p1;
520 this.p2 = p2;
521 this.p3 = p3;
522 this.data = data;
523 }
524 }
525
526 /**
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700527 * A request object to use for transmitting data to an ICC.
528 */
529 private static final class ManualNetworkSelectionArgument {
530 public OperatorInfo operatorInfo;
531 public boolean persistSelection;
532
533 public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) {
534 this.operatorInfo = operatorInfo;
535 this.persistSelection = persistSelection;
536 }
537 }
538
Sarah Chin71b3a852022-09-28 15:54:19 -0700539 private static final class PurchasePremiumCapabilityArgument {
540 public @TelephonyManager.PremiumCapability int capability;
Sarah Chin71b3a852022-09-28 15:54:19 -0700541 public @NonNull IIntegerConsumer callback;
542
543 PurchasePremiumCapabilityArgument(@TelephonyManager.PremiumCapability int capability,
Sarah Chinb8218c22023-01-04 13:35:29 -0800544 @NonNull IIntegerConsumer callback) {
Sarah Chin71b3a852022-09-28 15:54:19 -0700545 this.capability = capability;
Sarah Chin71b3a852022-09-28 15:54:19 -0700546 this.callback = callback;
547 }
548 }
549
Thomas Nguyen8ee49682023-02-01 11:46:09 -0800550 private static final class ProvisionSatelliteServiceArgument {
551 public @NonNull int[] features;
552 public @NonNull IIntegerConsumer callback;
553 public int subId;
554
555 ProvisionSatelliteServiceArgument(int[] features, IIntegerConsumer callback, int subId) {
556 this.features = features;
557 this.callback = callback;
558 this.subId = subId;
559 }
560 }
561
Sarah Chineccfbd12023-01-20 19:00:35 -0800562 private static final class SatellitePositionUpdateHandler extends Handler {
563 public static final int EVENT_POSITION_UPDATE = 1;
564 public static final int EVENT_MESSAGE_TRANSFER_STATE_UPDATE = 2;
565
Thomas Nguyen8ee49682023-02-01 11:46:09 -0800566 private final ISatelliteStateListener mCallback;
Sarah Chineccfbd12023-01-20 19:00:35 -0800567
Thomas Nguyen8ee49682023-02-01 11:46:09 -0800568 SatellitePositionUpdateHandler(ISatelliteStateListener callback, Looper looper) {
Sarah Chineccfbd12023-01-20 19:00:35 -0800569 super(looper);
570 mCallback = callback;
571 }
572
573 @Override
574 public void handleMessage(@NonNull Message msg) {
575 switch (msg.what) {
576 case EVENT_POSITION_UPDATE: {
577 AsyncResult ar = (AsyncResult) msg.obj;
578 PointingInfo pointingInfo = (PointingInfo) ar.result;
579 try {
580 mCallback.onSatellitePositionUpdate(pointingInfo);
581 } catch (RemoteException e) {
582 loge("EVENT_POSITION_UPDATE RemoteException: " + e);
583 }
584 break;
585 }
586 case EVENT_MESSAGE_TRANSFER_STATE_UPDATE: {
587 AsyncResult ar = (AsyncResult) msg.obj;
588 int state = (int) ar.result;
589 try {
590 mCallback.onMessageTransferStateUpdate(state);
591 } catch (RemoteException e) {
592 loge("EVENT_MESSAGE_TRANSFER_STATE_UPDATE RemoteException: " + e);
593 }
594 break;
595 }
596 default:
597 loge("SatellitePositionUpdateHandler unknown event: " + msg.what);
598 }
599 }
600 }
601
Thomas Nguyen8ee49682023-02-01 11:46:09 -0800602 private static final class SatelliteProvisionStateChangedHandler extends Handler {
603 public static final int EVENT_PROVISION_STATE_CHANGED = 1;
604
605 private ConcurrentHashMap<IBinder, ISatelliteStateListener> mListeners;
606 private final int mSubId;
607
608 SatelliteProvisionStateChangedHandler(Looper looper, int subId) {
609 super(looper);
610 mListeners = new ConcurrentHashMap<>();
611 mSubId = subId;
612 }
613
614 public void addListener(ISatelliteStateListener listener) {
615 mListeners.put(listener.asBinder(), listener);
616 }
617
618 public boolean removeListener(ISatelliteStateListener listener) {
619 return (mListeners.remove(listener.asBinder()) != null);
620 }
621
622 @Override
623 public void handleMessage(@NonNull Message msg) {
624 switch (msg.what) {
625 case EVENT_PROVISION_STATE_CHANGED: {
626 AsyncResult ar = (AsyncResult) msg.obj;
627 boolean provisioned = (boolean) ar.userObj;
628 int[] features = (int[]) ar.result;
629 log("Received EVENT_PROVISION_STATE_CHANGED for subId=" + mSubId
630 + ", features=" + Arrays.toString(features)
631 + ", provisioned=" + provisioned);
632 mListeners.values().forEach(listener -> {
633 try {
634 listener.onSatelliteProvisionStateChanged(features, provisioned);
635 } catch (RemoteException e) {
636 log("EVENT_PROVISION_STATE_CHANGED RemoteException: " + e);
637 }
638 });
639
Thomas Nguyene77de6d2023-02-10 17:42:43 -0800640 setSatelliteProvisioned(provisioned);
Thomas Nguyen8ee49682023-02-01 11:46:09 -0800641 /**
642 * TODO: Take bugreport if provisioned is true and user did not initiate the
643 * provision procedure for the corresponding subscription.
644 */
645 break;
646 }
647 default:
648 loge("SatelliteProvisionStateChangedHandler unknown event: " + msg.what);
649 }
650 }
651
Thomas Nguyene77de6d2023-02-10 17:42:43 -0800652 private void setSatelliteProvisioned(boolean isProvisioned) {
Thomas Nguyen8ee49682023-02-01 11:46:09 -0800653 if (mSubId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
654 SubscriptionManager.setSubscriptionProperty(
Thomas Nguyene77de6d2023-02-10 17:42:43 -0800655 mSubId, SubscriptionManager.SATELLITE_ENABLED, isProvisioned ? "1" : "0");
Thomas Nguyen8ee49682023-02-01 11:46:09 -0800656 } else {
Thomas Nguyene77de6d2023-02-10 17:42:43 -0800657 //TODO (b/267826133): set via SatelliteController.
Thomas Nguyen8ee49682023-02-01 11:46:09 -0800658 }
659 }
660 }
661
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700662 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700663 * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
664 * request after sending. The main thread will notify the request when it is complete.
665 */
666 private static final class MainThreadRequest {
667 /** The argument to use for the request */
668 public Object argument;
669 /** The result of the request that is run on the main thread */
670 public Object result;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800671 // The subscriber id that this request applies to. Defaults to
672 // SubscriptionManager.INVALID_SUBSCRIPTION_ID
673 public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700674
Nathan Harold92bed182018-10-12 18:16:49 -0700675 // In cases where subId is unavailable, the caller needs to specify the phone.
676 public Phone phone;
677
vagdeviaf9a5b92018-08-15 16:01:53 -0700678 public WorkSource workSource;
679
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700680 public MainThreadRequest(Object argument) {
681 this.argument = argument;
682 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800683
Nathan Harold92bed182018-10-12 18:16:49 -0700684 MainThreadRequest(Object argument, Phone phone, WorkSource workSource) {
685 this.argument = argument;
686 if (phone != null) {
687 this.phone = phone;
688 }
689 this.workSource = workSource;
690 }
691
vagdeviaf9a5b92018-08-15 16:01:53 -0700692 MainThreadRequest(Object argument, Integer subId, WorkSource workSource) {
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800693 this.argument = argument;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800694 if (subId != null) {
695 this.subId = subId;
696 }
vagdeviaf9a5b92018-08-15 16:01:53 -0700697 this.workSource = workSource;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800698 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700699 }
700
Sailesh Nepalcc0375f2013-11-13 09:15:18 -0800701 private static final class IncomingThirdPartyCallArgs {
702 public final ComponentName component;
703 public final String callId;
704 public final String callerDisplayName;
705
706 public IncomingThirdPartyCallArgs(ComponentName component, String callId,
707 String callerDisplayName) {
708 this.component = component;
709 this.callId = callId;
710 this.callerDisplayName = callerDisplayName;
711 }
712 }
713
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700714 /**
715 * A handler that processes messages on the main thread in the phone process. Since many
716 * of the Phone calls are not thread safe this is needed to shuttle the requests from the
717 * inbound binder threads to the main thread in the phone process. The Binder thread
718 * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
719 * on, which will be notified when the operation completes and will contain the result of the
720 * request.
721 *
722 * <p>If a MainThreadRequest object is provided in the msg.obj field,
723 * note that request.result must be set to something non-null for the calling thread to
724 * unblock.
725 */
726 private final class MainThreadHandler extends Handler {
727 @Override
728 public void handleMessage(Message msg) {
729 MainThreadRequest request;
730 Message onCompleted;
731 AsyncResult ar;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000732 UiccPort uiccPort;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700733 IccAPDUArgument iccArgument;
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800734 final Phone defaultPhone = getDefaultPhone();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700735
736 switch (msg.what) {
Pengquan Menga1bb6272018-09-06 09:59:22 -0700737 case CMD_HANDLE_USSD_REQUEST: {
738 request = (MainThreadRequest) msg.obj;
739 final Phone phone = getPhoneFromRequest(request);
740 Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
Chen Xue9d737e2022-01-01 23:41:31 -0800741 String ussdRequest = ussdObject.first;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700742 ResultReceiver wrappedCallback = ussdObject.second;
Tyler Gunn65d45c22017-06-05 11:22:26 -0700743
Pengquan Menga1bb6272018-09-06 09:59:22 -0700744 if (!isUssdApiAllowed(request.subId)) {
745 // Carrier does not support use of this API, return failure.
746 Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
747 UssdResponse response = new UssdResponse(ussdRequest, null);
748 Bundle returnData = new Bundle();
749 returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
750 wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
Tyler Gunn65d45c22017-06-05 11:22:26 -0700751
Pengquan Menga1bb6272018-09-06 09:59:22 -0700752 request.result = true;
753 notifyRequester(request);
754 return;
755 }
Tyler Gunn65d45c22017-06-05 11:22:26 -0700756
Pengquan Menga1bb6272018-09-06 09:59:22 -0700757 try {
758 request.result = phone != null
759 ? phone.handleUssdRequest(ussdRequest, wrappedCallback) : false;
760 } catch (CallStateException cse) {
761 request.result = false;
762 }
763 // Wake up the requesting thread
764 notifyRequester(request);
765 break;
pkanwar32d516d2016-10-14 19:37:38 -0700766 }
767
Yorke Lee716f67e2015-06-17 15:39:16 -0700768 case CMD_HANDLE_PIN_MMI: {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700769 request = (MainThreadRequest) msg.obj;
Yorke Lee716f67e2015-06-17 15:39:16 -0700770 final Phone phone = getPhoneFromRequest(request);
771 request.result = phone != null ?
772 getPhoneFromRequest(request).handlePinMmi((String) request.argument)
773 : false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700774 // Wake up the requesting thread
Pengquan Menga1bb6272018-09-06 09:59:22 -0700775 notifyRequester(request);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700776 break;
Yorke Lee716f67e2015-06-17 15:39:16 -0700777 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700778
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700779 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700780 request = (MainThreadRequest) msg.obj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700781 iccArgument = (IccAPDUArgument) request.argument;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000782 uiccPort = getUiccPortFromRequest(request);
783 if (uiccPort == null) {
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700784 loge("iccTransmitApduLogicalChannel: No UICC");
Chen Xue9d737e2022-01-01 23:41:31 -0800785 request.result = new IccIoResult(0x6F, 0, (byte[]) null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700786 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700787 } else {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700788 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
Chen Xue9d737e2022-01-01 23:41:31 -0800789 request);
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000790 uiccPort.iccTransmitApduLogicalChannel(
Chen Xue9d737e2022-01-01 23:41:31 -0800791 iccArgument.channel, iccArgument.cla, iccArgument.command,
792 iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data,
793 onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700794 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700795 break;
796
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700797 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700798 ar = (AsyncResult) msg.obj;
799 request = (MainThreadRequest) ar.userObj;
800 if (ar.exception == null && ar.result != null) {
801 request.result = ar.result;
802 } else {
Chen Xue9d737e2022-01-01 23:41:31 -0800803 request.result = new IccIoResult(0x6F, 0, (byte[]) null);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700804 if (ar.result == null) {
805 loge("iccTransmitApduLogicalChannel: Empty response");
Jake Hambye994d462014-02-03 13:10:13 -0800806 } else if (ar.exception instanceof CommandException) {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700807 loge("iccTransmitApduLogicalChannel: CommandException: " +
Jake Hambye994d462014-02-03 13:10:13 -0800808 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700809 } else {
810 loge("iccTransmitApduLogicalChannel: Unknown exception");
811 }
812 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700813 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700814 break;
815
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700816 case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
817 request = (MainThreadRequest) msg.obj;
818 iccArgument = (IccAPDUArgument) request.argument;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000819 uiccPort = getUiccPortFromRequest(request);
820 if (uiccPort == null) {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700821 loge("iccTransmitApduBasicChannel: No UICC");
Chen Xue9d737e2022-01-01 23:41:31 -0800822 request.result = new IccIoResult(0x6F, 0, (byte[]) null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700823 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700824 } else {
825 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
Chen Xue9d737e2022-01-01 23:41:31 -0800826 request);
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000827 uiccPort.iccTransmitApduBasicChannel(
Chen Xue9d737e2022-01-01 23:41:31 -0800828 iccArgument.cla, iccArgument.command, iccArgument.p1,
829 iccArgument.p2,
830 iccArgument.p3, iccArgument.data, onCompleted);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700831 }
832 break;
833
834 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
835 ar = (AsyncResult) msg.obj;
836 request = (MainThreadRequest) ar.userObj;
837 if (ar.exception == null && ar.result != null) {
838 request.result = ar.result;
839 } else {
Chen Xue9d737e2022-01-01 23:41:31 -0800840 request.result = new IccIoResult(0x6F, 0, (byte[]) null);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700841 if (ar.result == null) {
842 loge("iccTransmitApduBasicChannel: Empty response");
843 } else if (ar.exception instanceof CommandException) {
844 loge("iccTransmitApduBasicChannel: CommandException: " +
845 ar.exception);
846 } else {
847 loge("iccTransmitApduBasicChannel: Unknown exception");
848 }
849 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700850 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700851 break;
852
853 case CMD_EXCHANGE_SIM_IO:
854 request = (MainThreadRequest) msg.obj;
855 iccArgument = (IccAPDUArgument) request.argument;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000856 uiccPort = getUiccPortFromRequest(request);
857 if (uiccPort == null) {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700858 loge("iccExchangeSimIO: No UICC");
Chen Xue9d737e2022-01-01 23:41:31 -0800859 request.result = new IccIoResult(0x6F, 0, (byte[]) null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700860 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700861 } else {
862 onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
863 request);
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000864 uiccPort.iccExchangeSimIO(iccArgument.cla, /* fileID */
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700865 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3,
866 iccArgument.data, onCompleted);
867 }
868 break;
869
870 case EVENT_EXCHANGE_SIM_IO_DONE:
871 ar = (AsyncResult) msg.obj;
872 request = (MainThreadRequest) ar.userObj;
873 if (ar.exception == null && ar.result != null) {
874 request.result = ar.result;
875 } else {
Chen Xue9d737e2022-01-01 23:41:31 -0800876 request.result = new IccIoResult(0x6f, 0, (byte[]) null);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700877 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700878 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700879 break;
880
Derek Tan4d5e5c12014-02-04 11:54:58 -0800881 case CMD_SEND_ENVELOPE:
882 request = (MainThreadRequest) msg.obj;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000883 uiccPort = getUiccPortFromRequest(request);
884 if (uiccPort == null) {
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700885 loge("sendEnvelopeWithStatus: No UICC");
Chen Xue9d737e2022-01-01 23:41:31 -0800886 request.result = new IccIoResult(0x6F, 0, (byte[]) null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700887 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700888 } else {
889 onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
Chen Xue9d737e2022-01-01 23:41:31 -0800890 uiccPort.sendEnvelopeWithStatus((String) request.argument, onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700891 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800892 break;
893
894 case EVENT_SEND_ENVELOPE_DONE:
895 ar = (AsyncResult) msg.obj;
896 request = (MainThreadRequest) ar.userObj;
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700897 if (ar.exception == null && ar.result != null) {
898 request.result = ar.result;
Derek Tan4d5e5c12014-02-04 11:54:58 -0800899 } else {
Chen Xue9d737e2022-01-01 23:41:31 -0800900 request.result = new IccIoResult(0x6F, 0, (byte[]) null);
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700901 if (ar.result == null) {
902 loge("sendEnvelopeWithStatus: Empty response");
903 } else if (ar.exception instanceof CommandException) {
904 loge("sendEnvelopeWithStatus: CommandException: " +
905 ar.exception);
906 } else {
907 loge("sendEnvelopeWithStatus: exception:" + ar.exception);
908 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800909 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700910 notifyRequester(request);
Derek Tan4d5e5c12014-02-04 11:54:58 -0800911 break;
912
Shishir Agrawal566b7612013-10-28 14:41:00 -0700913 case CMD_OPEN_CHANNEL:
914 request = (MainThreadRequest) msg.obj;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000915 uiccPort = getUiccPortFromRequest(request);
Rambo Wanga1782702021-11-10 20:15:19 -0800916 IccLogicalChannelRequest openChannelRequest =
917 (IccLogicalChannelRequest) request.argument;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000918 if (uiccPort == null) {
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700919 loge("iccOpenLogicalChannel: No UICC");
Shishir Agrawalfc0492a2016-02-17 11:15:33 -0800920 request.result = new IccOpenLogicalChannelResponse(-1,
Chen Xue9d737e2022-01-01 23:41:31 -0800921 IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700922 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700923 } else {
924 onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
Rambo Wanga1782702021-11-10 20:15:19 -0800925 uiccPort.iccOpenLogicalChannel(openChannelRequest.aid,
926 openChannelRequest.p2, onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700927 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700928 break;
929
930 case EVENT_OPEN_CHANNEL_DONE:
931 ar = (AsyncResult) msg.obj;
932 request = (MainThreadRequest) ar.userObj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700933 IccOpenLogicalChannelResponse openChannelResp;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700934 if (ar.exception == null && ar.result != null) {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700935 int[] result = (int[]) ar.result;
936 int channelId = result[0];
937 byte[] selectResponse = null;
938 if (result.length > 1) {
939 selectResponse = new byte[result.length - 1];
940 for (int i = 1; i < result.length; ++i) {
941 selectResponse[i - 1] = (byte) result[i];
942 }
943 }
944 openChannelResp = new IccOpenLogicalChannelResponse(channelId,
Chen Xue9d737e2022-01-01 23:41:31 -0800945 IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse);
Rambo Wang3b77c4c2021-11-10 20:15:19 -0800946
947 uiccPort = getUiccPortFromRequest(request);
Rambo Wange53e07d2022-05-10 13:01:13 -0700948 if (uiccPort == null) {
949 loge("EVENT_OPEN_CHANNEL_DONE: UiccPort is null");
950 } else {
951 IccLogicalChannelRequest channelRequest =
952 (IccLogicalChannelRequest) request.argument;
953 channelRequest.channel = channelId;
954 uiccPort.onLogicalChannelOpened(channelRequest);
955 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700956 } else {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700957 if (ar.result == null) {
958 loge("iccOpenLogicalChannel: Empty response");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700959 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700960 if (ar.exception != null) {
961 loge("iccOpenLogicalChannel: Exception: " + ar.exception);
962 }
963
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700964 int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR;
Junda Liua754ba12015-05-20 01:17:52 -0700965 if (ar.exception instanceof CommandException) {
966 CommandException.Error error =
Chen Xue9d737e2022-01-01 23:41:31 -0800967 ((CommandException) (ar.exception)).getCommandError();
Junda Liua754ba12015-05-20 01:17:52 -0700968 if (error == CommandException.Error.MISSING_RESOURCE) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700969 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE;
Junda Liua754ba12015-05-20 01:17:52 -0700970 } else if (error == CommandException.Error.NO_SUCH_ELEMENT) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700971 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700972 }
973 }
974 openChannelResp = new IccOpenLogicalChannelResponse(
Chen Xue9d737e2022-01-01 23:41:31 -0800975 IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700976 }
Shishir Agrawal82c8a462014-07-31 18:13:17 -0700977 request.result = openChannelResp;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700978 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700979 break;
980
981 case CMD_CLOSE_CHANNEL:
982 request = (MainThreadRequest) msg.obj;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000983 uiccPort = getUiccPortFromRequest(request);
984 if (uiccPort == null) {
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700985 loge("iccCloseLogicalChannel: No UICC");
Chen Xua8f0dff2022-02-12 00:34:15 -0800986 request.result = new IllegalArgumentException(
Thomas Nguyen8ee49682023-02-01 11:46:09 -0800987 "iccCloseLogicalChannel: No UICC");
Chen Xue9d737e2022-01-01 23:41:31 -0800988 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700989 } else {
990 onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000991 uiccPort.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700992 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700993 break;
994
995 case EVENT_CLOSE_CHANNEL_DONE:
Chen Xu540470b2021-12-14 17:15:47 -0800996 ar = (AsyncResult) msg.obj;
997 request = (MainThreadRequest) ar.userObj;
998 if (ar.exception == null) {
999 request.result = true;
Rambo Wang3b77c4c2021-11-10 20:15:19 -08001000 uiccPort = getUiccPortFromRequest(request);
Rambo Wange53e07d2022-05-10 13:01:13 -07001001 if (uiccPort == null) {
1002 loge("EVENT_CLOSE_CHANNEL_DONE: UiccPort is null");
1003 } else {
1004 final int channelId = (Integer) request.argument;
1005 uiccPort.onLogicalChannelClosed(channelId);
1006 }
Chen Xu540470b2021-12-14 17:15:47 -08001007 } else {
1008 request.result = false;
Chen Xue9d737e2022-01-01 23:41:31 -08001009 Exception exception = null;
Chen Xu540470b2021-12-14 17:15:47 -08001010 if (ar.exception instanceof CommandException) {
1011 loge("iccCloseLogicalChannel: CommandException: " + ar.exception);
1012 CommandException.Error error =
1013 ((CommandException) (ar.exception)).getCommandError();
Chen Xue9d737e2022-01-01 23:41:31 -08001014 if (error == CommandException.Error.INVALID_ARGUMENTS) {
1015 // should only throw exceptions from the binder threads.
1016 exception = new IllegalArgumentException(
Chen Xu540470b2021-12-14 17:15:47 -08001017 "iccCloseLogicalChannel: invalid argument ");
1018 }
1019 } else {
1020 loge("iccCloseLogicalChannel: Unknown exception");
1021 }
Chen Xua8f0dff2022-02-12 00:34:15 -08001022 request.result = (exception != null) ? exception :
1023 new IllegalStateException(
1024 "exception from modem to close iccLogical Channel");
Chen Xu540470b2021-12-14 17:15:47 -08001025 }
1026 notifyRequester(request);
Jake Hambye994d462014-02-03 13:10:13 -08001027 break;
1028
1029 case CMD_NV_READ_ITEM:
1030 request = (MainThreadRequest) msg.obj;
1031 onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001032 defaultPhone.nvReadItem((Integer) request.argument, onCompleted,
1033 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -08001034 break;
1035
1036 case EVENT_NV_READ_ITEM_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -07001037 ar = (AsyncResult) msg.obj;
1038 request = (MainThreadRequest) ar.userObj;
Jake Hambye994d462014-02-03 13:10:13 -08001039 if (ar.exception == null && ar.result != null) {
1040 request.result = ar.result; // String
Shishir Agrawal566b7612013-10-28 14:41:00 -07001041 } else {
Jake Hambye994d462014-02-03 13:10:13 -08001042 request.result = "";
1043 if (ar.result == null) {
1044 loge("nvReadItem: Empty response");
1045 } else if (ar.exception instanceof CommandException) {
1046 loge("nvReadItem: CommandException: " +
1047 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -07001048 } else {
Jake Hambye994d462014-02-03 13:10:13 -08001049 loge("nvReadItem: Unknown exception");
Shishir Agrawal566b7612013-10-28 14:41:00 -07001050 }
1051 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001052 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -07001053 break;
1054
Jake Hambye994d462014-02-03 13:10:13 -08001055 case CMD_NV_WRITE_ITEM:
1056 request = (MainThreadRequest) msg.obj;
1057 onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
1058 Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001059 defaultPhone.nvWriteItem(idValue.first, idValue.second, onCompleted,
vagdeviaf9a5b92018-08-15 16:01:53 -07001060 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -08001061 break;
1062
1063 case EVENT_NV_WRITE_ITEM_DONE:
1064 handleNullReturnEvent(msg, "nvWriteItem");
1065 break;
1066
1067 case CMD_NV_WRITE_CDMA_PRL:
1068 request = (MainThreadRequest) msg.obj;
1069 onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001070 defaultPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
Jake Hambye994d462014-02-03 13:10:13 -08001071 break;
1072
1073 case EVENT_NV_WRITE_CDMA_PRL_DONE:
1074 handleNullReturnEvent(msg, "nvWriteCdmaPrl");
1075 break;
1076
chen xu6dac5ab2018-10-26 17:39:23 -07001077 case CMD_RESET_MODEM_CONFIG:
Jake Hambye994d462014-02-03 13:10:13 -08001078 request = (MainThreadRequest) msg.obj;
chen xu6dac5ab2018-10-26 17:39:23 -07001079 onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001080 defaultPhone.resetModemConfig(onCompleted);
Jake Hambye994d462014-02-03 13:10:13 -08001081 break;
1082
chen xu6dac5ab2018-10-26 17:39:23 -07001083 case EVENT_RESET_MODEM_CONFIG_DONE:
1084 handleNullReturnEvent(msg, "resetModemConfig");
Jake Hambye994d462014-02-03 13:10:13 -08001085 break;
1086
Sooraj Sasindran37444802020-08-11 10:40:43 -07001087 case CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED: {
1088 request = (MainThreadRequest) msg.obj;
1089 onCompleted = obtainMessage(EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE,
1090 request);
1091 Phone phone = getPhoneFromRequest(request);
1092 if (phone != null) {
1093 phone.isNrDualConnectivityEnabled(onCompleted, request.workSource);
1094 } else {
1095 loge("isNRDualConnectivityEnabled: No phone object");
1096 request.result = false;
1097 notifyRequester(request);
1098 }
1099 break;
1100 }
1101
1102 case EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE:
1103 ar = (AsyncResult) msg.obj;
1104 request = (MainThreadRequest) ar.userObj;
1105 if (ar.exception == null && ar.result != null) {
1106 request.result = ar.result;
1107 } else {
1108 // request.result must be set to something non-null
1109 // for the calling thread to unblock
Sooraj Sasindrandaf060f2021-06-15 14:52:55 -07001110 if (ar.result != null) {
Sooraj Sasindran37444802020-08-11 10:40:43 -07001111 request.result = ar.result;
1112 } else {
1113 request.result = false;
1114 }
1115 if (ar.result == null) {
1116 loge("isNRDualConnectivityEnabled: Empty response");
1117 } else if (ar.exception instanceof CommandException) {
1118 loge("isNRDualConnectivityEnabled: CommandException: "
1119 + ar.exception);
1120 } else {
1121 loge("isNRDualConnectivityEnabled: Unknown exception");
1122 }
1123 }
1124 notifyRequester(request);
1125 break;
1126
Sooraj Sasindrandaf060f2021-06-15 14:52:55 -07001127 case CMD_IS_VONR_ENABLED: {
1128 request = (MainThreadRequest) msg.obj;
1129 onCompleted = obtainMessage(EVENT_IS_VONR_ENABLED_DONE,
1130 request);
1131 Phone phone = getPhoneFromRequest(request);
1132 if (phone != null) {
1133 phone.isVoNrEnabled(onCompleted, request.workSource);
1134 } else {
1135 loge("isVoNrEnabled: No phone object");
1136 request.result = false;
1137 notifyRequester(request);
1138 }
1139 break;
1140 }
1141
1142 case EVENT_IS_VONR_ENABLED_DONE:
1143 ar = (AsyncResult) msg.obj;
1144 request = (MainThreadRequest) ar.userObj;
1145 if (ar.exception == null && ar.result != null) {
1146 request.result = ar.result;
1147 } else {
1148 // request.result must be set to something non-null
1149 // for the calling thread to unblock
1150 if (ar.result != null) {
1151 request.result = ar.result;
1152 } else {
1153 request.result = false;
1154 }
1155 if (ar.result == null) {
1156 loge("isVoNrEnabled: Empty response");
1157 } else if (ar.exception instanceof CommandException) {
1158 loge("isVoNrEnabled: CommandException: "
1159 + ar.exception);
1160 } else {
1161 loge("isVoNrEnabled: Unknown exception");
1162 }
1163 }
1164 notifyRequester(request);
1165 break;
1166
Sooraj Sasindran37444802020-08-11 10:40:43 -07001167 case CMD_ENABLE_NR_DUAL_CONNECTIVITY: {
1168 request = (MainThreadRequest) msg.obj;
1169 onCompleted = obtainMessage(EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE, request);
1170 Phone phone = getPhoneFromRequest(request);
1171 if (phone != null) {
1172 phone.setNrDualConnectivityState((int) request.argument, onCompleted,
1173 request.workSource);
1174 } else {
1175 loge("enableNrDualConnectivity: No phone object");
1176 request.result =
1177 TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE;
1178 notifyRequester(request);
1179 }
1180 break;
1181 }
1182
1183 case EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE: {
1184 ar = (AsyncResult) msg.obj;
1185 request = (MainThreadRequest) ar.userObj;
1186 if (ar.exception == null) {
1187 request.result =
1188 TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_SUCCESS;
1189 } else {
1190 request.result =
1191 TelephonyManager
1192 .ENABLE_NR_DUAL_CONNECTIVITY_RADIO_ERROR;
1193 if (ar.exception instanceof CommandException) {
1194 CommandException.Error error =
1195 ((CommandException) (ar.exception)).getCommandError();
1196 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1197 request.result =
1198 TelephonyManager
1199 .ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE;
Sooraj Sasindran29654162021-03-03 23:00:01 +00001200 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1201 request.result =
1202 TelephonyManager
1203 .ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED;
Sooraj Sasindran37444802020-08-11 10:40:43 -07001204 }
1205 loge("enableNrDualConnectivity" + ": CommandException: "
1206 + ar.exception);
1207 } else {
1208 loge("enableNrDualConnectivity" + ": Unknown exception");
1209 }
1210 }
1211 notifyRequester(request);
1212 break;
1213 }
1214
Sooraj Sasindrandaf060f2021-06-15 14:52:55 -07001215 case CMD_ENABLE_VONR: {
1216 request = (MainThreadRequest) msg.obj;
1217 onCompleted = obtainMessage(EVENT_ENABLE_VONR_DONE, request);
1218 Phone phone = getPhoneFromRequest(request);
1219 if (phone != null) {
1220 phone.setVoNrEnabled((boolean) request.argument, onCompleted,
1221 request.workSource);
1222 } else {
1223 loge("setVoNrEnabled: No phone object");
1224 request.result =
1225 TelephonyManager.ENABLE_VONR_RADIO_NOT_AVAILABLE;
1226 notifyRequester(request);
1227 }
1228 break;
1229 }
1230
1231 case EVENT_ENABLE_VONR_DONE: {
1232 ar = (AsyncResult) msg.obj;
1233 request = (MainThreadRequest) ar.userObj;
1234 if (ar.exception == null) {
1235 request.result = TelephonyManager.ENABLE_VONR_SUCCESS;
1236 } else {
1237 request.result = TelephonyManager.ENABLE_VONR_RADIO_ERROR;
1238 if (ar.exception instanceof CommandException) {
1239 CommandException.Error error =
1240 ((CommandException) (ar.exception)).getCommandError();
1241 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1242 request.result = TelephonyManager.ENABLE_VONR_RADIO_NOT_AVAILABLE;
1243 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1244 request.result = TelephonyManager.ENABLE_VONR_REQUEST_NOT_SUPPORTED;
1245 } else {
1246 request.result = TelephonyManager.ENABLE_VONR_RADIO_ERROR;
1247 }
1248 loge("setVoNrEnabled" + ": CommandException: "
1249 + ar.exception);
1250 } else {
1251 loge("setVoNrEnabled" + ": Unknown exception");
1252 }
1253 }
1254 notifyRequester(request);
1255 break;
1256 }
1257
SongFerngWang3ef3e072020-12-21 16:41:52 +08001258 case CMD_GET_ALLOWED_NETWORK_TYPES_BITMASK:
Jake Hamby7c27be32014-03-03 13:25:59 -08001259 request = (MainThreadRequest) msg.obj;
SongFerngWang3ef3e072020-12-21 16:41:52 +08001260 onCompleted = obtainMessage(EVENT_GET_ALLOWED_NETWORK_TYPES_BITMASK_DONE,
1261 request);
1262 getPhoneFromRequest(request).getAllowedNetworkTypesBitmask(onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -08001263 break;
1264
SongFerngWang3ef3e072020-12-21 16:41:52 +08001265 case EVENT_GET_ALLOWED_NETWORK_TYPES_BITMASK_DONE:
Jake Hamby7c27be32014-03-03 13:25:59 -08001266 ar = (AsyncResult) msg.obj;
1267 request = (MainThreadRequest) ar.userObj;
1268 if (ar.exception == null && ar.result != null) {
1269 request.result = ar.result; // Integer
1270 } else {
Nazish Tabassume8ba43a2020-07-28 14:49:25 +05301271 // request.result must be set to something non-null
1272 // for the calling thread to unblock
1273 request.result = new int[]{-1};
Jake Hamby7c27be32014-03-03 13:25:59 -08001274 if (ar.result == null) {
SongFerngWang3ef3e072020-12-21 16:41:52 +08001275 loge("getAllowedNetworkTypesBitmask: Empty response");
Jake Hamby7c27be32014-03-03 13:25:59 -08001276 } else if (ar.exception instanceof CommandException) {
SongFerngWang3ef3e072020-12-21 16:41:52 +08001277 loge("getAllowedNetworkTypesBitmask: CommandException: "
1278 + ar.exception);
Jake Hamby7c27be32014-03-03 13:25:59 -08001279 } else {
SongFerngWang3ef3e072020-12-21 16:41:52 +08001280 loge("getAllowedNetworkTypesBitmask: Unknown exception");
Jake Hamby7c27be32014-03-03 13:25:59 -08001281 }
1282 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001283 notifyRequester(request);
Jake Hamby7c27be32014-03-03 13:25:59 -08001284 break;
1285
SongFerngWang3ef3e072020-12-21 16:41:52 +08001286 case CMD_SET_ALLOWED_NETWORK_TYPES_FOR_REASON:
Jake Hamby7c27be32014-03-03 13:25:59 -08001287 request = (MainThreadRequest) msg.obj;
SongFerngWang3ef3e072020-12-21 16:41:52 +08001288 onCompleted = obtainMessage(EVENT_SET_ALLOWED_NETWORK_TYPES_FOR_REASON_DONE,
1289 request);
1290 Pair<Integer, Long> reasonWithNetworkTypes =
1291 (Pair<Integer, Long>) request.argument;
1292 getPhoneFromRequest(request).setAllowedNetworkTypes(
1293 reasonWithNetworkTypes.first,
1294 reasonWithNetworkTypes.second,
1295 onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -08001296 break;
1297
SongFerngWang3ef3e072020-12-21 16:41:52 +08001298 case EVENT_SET_ALLOWED_NETWORK_TYPES_FOR_REASON_DONE:
1299 handleNullReturnEvent(msg, "setAllowedNetworkTypesForReason");
Jake Hamby7c27be32014-03-03 13:25:59 -08001300 break;
1301
Shuo Qian850e4d6a2018-04-25 21:02:08 +00001302 case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
1303 request = (MainThreadRequest)msg.obj;
1304 onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001305 defaultPhone.invokeOemRilRequestRaw((byte[]) request.argument, onCompleted);
Shuo Qian850e4d6a2018-04-25 21:02:08 +00001306 break;
1307
1308 case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
1309 ar = (AsyncResult)msg.obj;
1310 request = (MainThreadRequest)ar.userObj;
1311 request.result = ar;
Pengquan Menga1bb6272018-09-06 09:59:22 -07001312 notifyRequester(request);
Shuo Qian850e4d6a2018-04-25 21:02:08 +00001313 break;
1314
Shishir Agrawal76d5da92014-11-09 16:17:25 -08001315 case CMD_SET_VOICEMAIL_NUMBER:
1316 request = (MainThreadRequest) msg.obj;
1317 onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
1318 Pair<String, String> tagNum = (Pair<String, String>) request.argument;
Stuart Scott584921c2015-01-15 17:10:34 -08001319 getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
1320 onCompleted);
Shishir Agrawal76d5da92014-11-09 16:17:25 -08001321 break;
1322
1323 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
1324 handleNullReturnEvent(msg, "setVoicemailNumber");
1325 break;
1326
Stuart Scott54788802015-03-30 13:18:01 -07001327 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC:
1328 request = (MainThreadRequest) msg.obj;
1329 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE,
1330 request);
1331 getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted);
1332 break;
1333
1334 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE:
1335 handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic");
1336 break;
1337
Shishir Agrawal302c8692015-06-19 13:49:39 -07001338 case CMD_PERFORM_NETWORK_SCAN:
1339 request = (MainThreadRequest) msg.obj;
1340 onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request);
1341 getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
1342 break;
1343
Hall Liu27d24262020-09-18 19:04:59 -07001344 case CMD_GET_CALL_FORWARDING: {
Shuo Qian4a594052020-01-23 11:59:30 -08001345 request = (MainThreadRequest) msg.obj;
1346 onCompleted = obtainMessage(EVENT_GET_CALL_FORWARDING_DONE, request);
Hall Liu27d24262020-09-18 19:04:59 -07001347 Pair<Integer, TelephonyManager.CallForwardingInfoCallback> args =
1348 (Pair<Integer, TelephonyManager.CallForwardingInfoCallback>)
1349 request.argument;
1350 int callForwardingReason = args.first;
1351 request.phone.getCallForwardingOption(callForwardingReason, onCompleted);
Shuo Qian4a594052020-01-23 11:59:30 -08001352 break;
Hall Liu27d24262020-09-18 19:04:59 -07001353 }
1354 case EVENT_GET_CALL_FORWARDING_DONE: {
Shuo Qian4a594052020-01-23 11:59:30 -08001355 ar = (AsyncResult) msg.obj;
1356 request = (MainThreadRequest) ar.userObj;
Hall Liu27d24262020-09-18 19:04:59 -07001357 TelephonyManager.CallForwardingInfoCallback callback =
1358 ((Pair<Integer, TelephonyManager.CallForwardingInfoCallback>)
1359 request.argument).second;
Shuo Qian4a594052020-01-23 11:59:30 -08001360 if (ar.exception == null && ar.result != null) {
Hall Liu27d24262020-09-18 19:04:59 -07001361 CallForwardingInfo callForwardingInfo = null;
Shuo Qian4a594052020-01-23 11:59:30 -08001362 CallForwardInfo[] callForwardInfos = (CallForwardInfo[]) ar.result;
1363 for (CallForwardInfo callForwardInfo : callForwardInfos) {
1364 // Service Class is a bit mask per 3gpp 27.007. Search for
1365 // any service for voice call.
1366 if ((callForwardInfo.serviceClass
1367 & CommandsInterface.SERVICE_CLASS_VOICE) > 0) {
Yuchen Dong69cc1412021-09-27 20:27:01 +08001368 callForwardingInfo = new CallForwardingInfo(
1369 callForwardInfo.status
1370 == CommandsInterface.CF_ACTION_ENABLE,
Hall Liu27d24262020-09-18 19:04:59 -07001371 callForwardInfo.reason,
1372 callForwardInfo.number,
1373 callForwardInfo.timeSeconds);
Shuo Qian4a594052020-01-23 11:59:30 -08001374 break;
1375 }
1376 }
1377 // Didn't find a call forward info for voice call.
1378 if (callForwardingInfo == null) {
Hall Liu27d24262020-09-18 19:04:59 -07001379 callForwardingInfo = new CallForwardingInfo(false /* enabled */,
1380 0 /* reason */, null /* number */, 0 /* timeout */);
Shuo Qian4a594052020-01-23 11:59:30 -08001381 }
Hall Liu27d24262020-09-18 19:04:59 -07001382 callback.onCallForwardingInfoAvailable(callForwardingInfo);
Shuo Qian4a594052020-01-23 11:59:30 -08001383 } else {
1384 if (ar.result == null) {
1385 loge("EVENT_GET_CALL_FORWARDING_DONE: Empty response");
1386 }
1387 if (ar.exception != null) {
1388 loge("EVENT_GET_CALL_FORWARDING_DONE: Exception: " + ar.exception);
1389 }
Hall Liu940c4ca2020-09-29 17:10:18 -07001390 int errorCode = TelephonyManager
1391 .CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN;
Shuo Qian4a594052020-01-23 11:59:30 -08001392 if (ar.exception instanceof CommandException) {
1393 CommandException.Error error =
1394 ((CommandException) (ar.exception)).getCommandError();
1395 if (error == CommandException.Error.FDN_CHECK_FAILURE) {
Hall Liu940c4ca2020-09-29 17:10:18 -07001396 errorCode = TelephonyManager
1397 .CallForwardingInfoCallback.RESULT_ERROR_FDN_CHECK_FAILURE;
Shuo Qian4a594052020-01-23 11:59:30 -08001398 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
Hall Liu940c4ca2020-09-29 17:10:18 -07001399 errorCode = TelephonyManager
1400 .CallForwardingInfoCallback.RESULT_ERROR_NOT_SUPPORTED;
Shuo Qian4a594052020-01-23 11:59:30 -08001401 }
1402 }
Hall Liu27d24262020-09-18 19:04:59 -07001403 callback.onError(errorCode);
Shuo Qian4a594052020-01-23 11:59:30 -08001404 }
Shuo Qian4a594052020-01-23 11:59:30 -08001405 break;
Hall Liu27d24262020-09-18 19:04:59 -07001406 }
Shuo Qian4a594052020-01-23 11:59:30 -08001407
Hall Liu27d24262020-09-18 19:04:59 -07001408 case CMD_SET_CALL_FORWARDING: {
Shuo Qian4a594052020-01-23 11:59:30 -08001409 request = (MainThreadRequest) msg.obj;
1410 onCompleted = obtainMessage(EVENT_SET_CALL_FORWARDING_DONE, request);
Hall Liu27d24262020-09-18 19:04:59 -07001411 request = (MainThreadRequest) msg.obj;
Shuo Qian4a594052020-01-23 11:59:30 -08001412 CallForwardingInfo callForwardingInfoToSet =
Hall Liu27d24262020-09-18 19:04:59 -07001413 ((Pair<CallForwardingInfo, Consumer<Integer>>)
1414 request.argument).first;
1415 request.phone.setCallForwardingOption(
1416 callForwardingInfoToSet.isEnabled()
Calvin Pan258f1f72021-07-28 21:46:56 +08001417 ? CommandsInterface.CF_ACTION_REGISTRATION
Hall Liu27d24262020-09-18 19:04:59 -07001418 : CommandsInterface.CF_ACTION_DISABLE,
Shuo Qian4a594052020-01-23 11:59:30 -08001419 callForwardingInfoToSet.getReason(),
1420 callForwardingInfoToSet.getNumber(),
1421 callForwardingInfoToSet.getTimeoutSeconds(), onCompleted);
1422 break;
Hall Liu27d24262020-09-18 19:04:59 -07001423 }
Shuo Qian4a594052020-01-23 11:59:30 -08001424
Hall Liu27d24262020-09-18 19:04:59 -07001425 case EVENT_SET_CALL_FORWARDING_DONE: {
Shuo Qian4a594052020-01-23 11:59:30 -08001426 ar = (AsyncResult) msg.obj;
1427 request = (MainThreadRequest) ar.userObj;
Hall Liu27d24262020-09-18 19:04:59 -07001428 Consumer<Integer> callback =
1429 ((Pair<CallForwardingInfo, Consumer<Integer>>)
1430 request.argument).second;
1431 if (ar.exception != null) {
Shuo Qian4a594052020-01-23 11:59:30 -08001432 loge("setCallForwarding exception: " + ar.exception);
Hall Liu940c4ca2020-09-29 17:10:18 -07001433 int errorCode = TelephonyManager.CallForwardingInfoCallback
1434 .RESULT_ERROR_UNKNOWN;
Hall Liu27d24262020-09-18 19:04:59 -07001435 if (ar.exception instanceof CommandException) {
1436 CommandException.Error error =
1437 ((CommandException) (ar.exception)).getCommandError();
1438 if (error == CommandException.Error.FDN_CHECK_FAILURE) {
Hall Liu940c4ca2020-09-29 17:10:18 -07001439 errorCode = TelephonyManager.CallForwardingInfoCallback
1440 .RESULT_ERROR_FDN_CHECK_FAILURE;
Hall Liu27d24262020-09-18 19:04:59 -07001441 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
Hall Liu940c4ca2020-09-29 17:10:18 -07001442 errorCode = TelephonyManager.CallForwardingInfoCallback
1443 .RESULT_ERROR_NOT_SUPPORTED;
Hall Liu27d24262020-09-18 19:04:59 -07001444 }
1445 }
1446 callback.accept(errorCode);
1447 } else {
Hall Liu940c4ca2020-09-29 17:10:18 -07001448 callback.accept(TelephonyManager.CallForwardingInfoCallback.RESULT_SUCCESS);
Shuo Qian4a594052020-01-23 11:59:30 -08001449 }
Shuo Qian4a594052020-01-23 11:59:30 -08001450 break;
Hall Liu27d24262020-09-18 19:04:59 -07001451 }
Shuo Qian4a594052020-01-23 11:59:30 -08001452
Hall Liu27d24262020-09-18 19:04:59 -07001453 case CMD_GET_CALL_WAITING: {
Shuo Qian4a594052020-01-23 11:59:30 -08001454 request = (MainThreadRequest) msg.obj;
1455 onCompleted = obtainMessage(EVENT_GET_CALL_WAITING_DONE, request);
1456 getPhoneFromRequest(request).getCallWaiting(onCompleted);
1457 break;
Hall Liu27d24262020-09-18 19:04:59 -07001458 }
Shuo Qian4a594052020-01-23 11:59:30 -08001459
Hall Liu27d24262020-09-18 19:04:59 -07001460 case EVENT_GET_CALL_WAITING_DONE: {
Shuo Qian4a594052020-01-23 11:59:30 -08001461 ar = (AsyncResult) msg.obj;
1462 request = (MainThreadRequest) ar.userObj;
Hall Liu27d24262020-09-18 19:04:59 -07001463 Consumer<Integer> callback = (Consumer<Integer>) request.argument;
SongFerngWangebda2c52022-01-11 15:28:38 +08001464 int callWaitingStatus = TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR;
Shuo Qian4a594052020-01-23 11:59:30 -08001465 if (ar.exception == null && ar.result != null) {
Shuo Qiand6a0dba2020-02-18 18:13:49 -08001466 int[] callForwardResults = (int[]) ar.result;
Shuo Qian4a594052020-01-23 11:59:30 -08001467 // Service Class is a bit mask per 3gpp 27.007.
1468 // Search for any service for voice call.
Shuo Qiand6a0dba2020-02-18 18:13:49 -08001469 if (callForwardResults.length > 1
1470 && ((callForwardResults[1]
Hall Liu27d24262020-09-18 19:04:59 -07001471 & CommandsInterface.SERVICE_CLASS_VOICE) > 0)) {
SongFerngWangebda2c52022-01-11 15:28:38 +08001472 callWaitingStatus = callForwardResults[0] == 0
Hall Liu27d24262020-09-18 19:04:59 -07001473 ? TelephonyManager.CALL_WAITING_STATUS_DISABLED
1474 : TelephonyManager.CALL_WAITING_STATUS_ENABLED;
Shuo Qian4a594052020-01-23 11:59:30 -08001475 } else {
SongFerngWangebda2c52022-01-11 15:28:38 +08001476 callWaitingStatus = TelephonyManager.CALL_WAITING_STATUS_DISABLED;
Shuo Qian4a594052020-01-23 11:59:30 -08001477 }
1478 } else {
1479 if (ar.result == null) {
1480 loge("EVENT_GET_CALL_WAITING_DONE: Empty response");
1481 }
1482 if (ar.exception != null) {
1483 loge("EVENT_GET_CALL_WAITING_DONE: Exception: " + ar.exception);
1484 }
1485 if (ar.exception instanceof CommandException) {
1486 CommandException.Error error =
1487 ((CommandException) (ar.exception)).getCommandError();
1488 if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
SongFerngWangebda2c52022-01-11 15:28:38 +08001489 callWaitingStatus =
Shuo Qian4a594052020-01-23 11:59:30 -08001490 TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED;
SongFerngWangebda2c52022-01-11 15:28:38 +08001491 } else if (error == CommandException.Error.FDN_CHECK_FAILURE) {
1492 callWaitingStatus =
1493 TelephonyManager.CALL_WAITING_STATUS_FDN_CHECK_FAILURE;
Shuo Qian4a594052020-01-23 11:59:30 -08001494 }
1495 }
1496 }
SongFerngWangebda2c52022-01-11 15:28:38 +08001497 callback.accept(callWaitingStatus);
Shuo Qian4a594052020-01-23 11:59:30 -08001498 break;
Hall Liu27d24262020-09-18 19:04:59 -07001499 }
Shuo Qian4a594052020-01-23 11:59:30 -08001500
Hall Liu27d24262020-09-18 19:04:59 -07001501 case CMD_SET_CALL_WAITING: {
Shuo Qian4a594052020-01-23 11:59:30 -08001502 request = (MainThreadRequest) msg.obj;
1503 onCompleted = obtainMessage(EVENT_SET_CALL_WAITING_DONE, request);
Hall Liu27d24262020-09-18 19:04:59 -07001504 boolean enable = ((Pair<Boolean, Consumer<Integer>>) request.argument).first;
1505 getPhoneFromRequest(request).setCallWaiting(enable, onCompleted);
Shuo Qian4a594052020-01-23 11:59:30 -08001506 break;
Hall Liu27d24262020-09-18 19:04:59 -07001507 }
Shuo Qian4a594052020-01-23 11:59:30 -08001508
Hall Liu27d24262020-09-18 19:04:59 -07001509 case EVENT_SET_CALL_WAITING_DONE: {
Shuo Qian4a594052020-01-23 11:59:30 -08001510 ar = (AsyncResult) msg.obj;
1511 request = (MainThreadRequest) ar.userObj;
Hall Liu27d24262020-09-18 19:04:59 -07001512 boolean enable = ((Pair<Boolean, Consumer<Integer>>) request.argument).first;
1513 Consumer<Integer> callback =
1514 ((Pair<Boolean, Consumer<Integer>>) request.argument).second;
1515 if (ar.exception != null) {
Shuo Qian4a594052020-01-23 11:59:30 -08001516 loge("setCallWaiting exception: " + ar.exception);
Hall Liu27d24262020-09-18 19:04:59 -07001517 if (ar.exception instanceof CommandException) {
1518 CommandException.Error error =
1519 ((CommandException) (ar.exception)).getCommandError();
1520 if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1521 callback.accept(TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED);
SongFerngWangebda2c52022-01-11 15:28:38 +08001522 } else if (error == CommandException.Error.FDN_CHECK_FAILURE) {
1523 callback.accept(
1524 TelephonyManager.CALL_WAITING_STATUS_FDN_CHECK_FAILURE);
Hall Liu27d24262020-09-18 19:04:59 -07001525 } else {
1526 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
1527 }
1528 } else {
1529 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
1530 }
1531 } else {
1532 callback.accept(enable ? TelephonyManager.CALL_WAITING_STATUS_ENABLED
1533 : TelephonyManager.CALL_WAITING_STATUS_DISABLED);
Shuo Qian4a594052020-01-23 11:59:30 -08001534 }
Shuo Qian4a594052020-01-23 11:59:30 -08001535 break;
Hall Liu27d24262020-09-18 19:04:59 -07001536 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07001537 case EVENT_PERFORM_NETWORK_SCAN_DONE:
1538 ar = (AsyncResult) msg.obj;
1539 request = (MainThreadRequest) ar.userObj;
1540 CellNetworkScanResult cellScanResult;
1541 if (ar.exception == null && ar.result != null) {
1542 cellScanResult = new CellNetworkScanResult(
1543 CellNetworkScanResult.STATUS_SUCCESS,
1544 (List<OperatorInfo>) ar.result);
1545 } else {
1546 if (ar.result == null) {
1547 loge("getCellNetworkScanResults: Empty response");
1548 }
1549 if (ar.exception != null) {
1550 loge("getCellNetworkScanResults: Exception: " + ar.exception);
1551 }
1552 int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR;
1553 if (ar.exception instanceof CommandException) {
1554 CommandException.Error error =
Thomas Nguyen8ee49682023-02-01 11:46:09 -08001555 ((CommandException) (ar.exception)).getCommandError();
Shishir Agrawal302c8692015-06-19 13:49:39 -07001556 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1557 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE;
1558 } else if (error == CommandException.Error.GENERIC_FAILURE) {
1559 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE;
1560 }
1561 }
1562 cellScanResult = new CellNetworkScanResult(errorCode, null);
1563 }
1564 request.result = cellScanResult;
Pengquan Menga1bb6272018-09-06 09:59:22 -07001565 notifyRequester(request);
Shishir Agrawal302c8692015-06-19 13:49:39 -07001566 break;
1567
1568 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
1569 request = (MainThreadRequest) msg.obj;
Shishir Agrawal77ba3172015-09-10 14:50:19 -07001570 ManualNetworkSelectionArgument selArg =
1571 (ManualNetworkSelectionArgument) request.argument;
Shishir Agrawal302c8692015-06-19 13:49:39 -07001572 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE,
1573 request);
Shishir Agrawal77ba3172015-09-10 14:50:19 -07001574 getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo,
1575 selArg.persistSelection, onCompleted);
Shishir Agrawal302c8692015-06-19 13:49:39 -07001576 break;
1577
1578 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
Pengquan Menge3d01e22018-09-20 15:25:35 -07001579 ar = (AsyncResult) msg.obj;
1580 request = (MainThreadRequest) ar.userObj;
1581 if (ar.exception == null) {
1582 request.result = true;
1583 } else {
1584 request.result = false;
1585 loge("setNetworkSelectionModeManual " + ar.exception);
1586 }
1587 notifyRequester(request);
1588 mApp.onNetworkSelectionChanged(request.subId);
Shishir Agrawal302c8692015-06-19 13:49:39 -07001589 break;
1590
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001591 case CMD_GET_MODEM_ACTIVITY_INFO:
1592 request = (MainThreadRequest) msg.obj;
1593 onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
James Mattisab947702019-04-03 14:18:34 -07001594 if (defaultPhone != null) {
1595 defaultPhone.getModemActivityInfo(onCompleted, request.workSource);
Shuo Qian8f4750a2020-02-20 17:12:10 -08001596 } else {
1597 ResultReceiver result = (ResultReceiver) request.argument;
1598 Bundle bundle = new Bundle();
1599 bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY,
Hall Liu49656c02020-10-09 19:00:11 -07001600 new ModemActivityInfo(0, 0, 0,
1601 new int[ModemActivityInfo.getNumTxPowerLevels()], 0));
Shuo Qian8f4750a2020-02-20 17:12:10 -08001602 result.send(0, bundle);
James Mattisab947702019-04-03 14:18:34 -07001603 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001604 break;
1605
Hall Liud0f208c2020-10-14 16:54:44 -07001606 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE: {
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001607 ar = (AsyncResult) msg.obj;
1608 request = (MainThreadRequest) ar.userObj;
Shuo Qian8f4750a2020-02-20 17:12:10 -08001609 ResultReceiver result = (ResultReceiver) request.argument;
Hall Liud0f208c2020-10-14 16:54:44 -07001610 int error = 0;
Kai Shi917fdc62022-11-28 14:01:02 -08001611 ModemActivityInfo ret = null;
Gary Jian3aa9a762022-01-24 16:41:19 +08001612 if (mLastModemActivityInfo == null) {
1613 mLastModemActivitySpecificInfo = new ActivityStatsTechSpecificInfo[1];
1614 mLastModemActivitySpecificInfo[0] =
1615 new ActivityStatsTechSpecificInfo(
1616 0,
1617 0,
1618 new int[ModemActivityInfo.getNumTxPowerLevels()],
1619 0);
1620 mLastModemActivityInfo =
1621 new ModemActivityInfo(0, 0, 0, mLastModemActivitySpecificInfo);
1622 }
1623
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001624 if (ar.exception == null && ar.result != null) {
Shuo Qian8f4750a2020-02-20 17:12:10 -08001625 // Update the last modem activity info and the result of the request.
1626 ModemActivityInfo info = (ModemActivityInfo) ar.result;
1627 if (isModemActivityInfoValid(info)) {
Gary Jian3aa9a762022-01-24 16:41:19 +08001628 mergeModemActivityInfo(info);
Gary Jian76280a42022-12-07 16:18:33 +08001629 } else {
1630 loge("queryModemActivityInfo: invalid response");
Shuo Qian8f4750a2020-02-20 17:12:10 -08001631 }
Kai Shi917fdc62022-11-28 14:01:02 -08001632 // This is needed to decouple ret from mLastModemActivityInfo
1633 // We don't want to return mLastModemActivityInfo which is updated
1634 // inside mergeModemActivityInfo()
1635 ret = new ModemActivityInfo(
1636 mLastModemActivityInfo.getTimestampMillis(),
1637 mLastModemActivityInfo.getSleepTimeMillis(),
1638 mLastModemActivityInfo.getIdleTimeMillis(),
1639 deepCopyModemActivitySpecificInfo(mLastModemActivitySpecificInfo));
Gary Jian3aa9a762022-01-24 16:41:19 +08001640
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001641 } else {
1642 if (ar.result == null) {
1643 loge("queryModemActivityInfo: Empty response");
Hall Liud0f208c2020-10-14 16:54:44 -07001644 error = TelephonyManager.ModemActivityInfoException
1645 .ERROR_INVALID_INFO_RECEIVED;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001646 } else if (ar.exception instanceof CommandException) {
Gary Jian3aa9a762022-01-24 16:41:19 +08001647 loge("queryModemActivityInfo: CommandException: " + ar.exception);
Hall Liud0f208c2020-10-14 16:54:44 -07001648 error = TelephonyManager.ModemActivityInfoException
1649 .ERROR_MODEM_RESPONSE_ERROR;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001650 } else {
1651 loge("queryModemActivityInfo: Unknown exception");
Hall Liud0f208c2020-10-14 16:54:44 -07001652 error = TelephonyManager.ModemActivityInfoException
1653 .ERROR_UNKNOWN;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001654 }
1655 }
Shuo Qian8f4750a2020-02-20 17:12:10 -08001656 Bundle bundle = new Bundle();
Kai Shi917fdc62022-11-28 14:01:02 -08001657 if (ret != null) {
Gary Jian3aa9a762022-01-24 16:41:19 +08001658 bundle.putParcelable(
1659 TelephonyManager.MODEM_ACTIVITY_RESULT_KEY,
Kai Shi917fdc62022-11-28 14:01:02 -08001660 ret);
Hall Liud0f208c2020-10-14 16:54:44 -07001661 } else {
1662 bundle.putInt(TelephonyManager.EXCEPTION_RESULT_KEY, error);
1663 }
Shuo Qian8f4750a2020-02-20 17:12:10 -08001664 result.send(0, bundle);
Pengquan Menga1bb6272018-09-06 09:59:22 -07001665 notifyRequester(request);
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001666 break;
Hall Liud0f208c2020-10-14 16:54:44 -07001667 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001668
Meng Wang1a7c35a2016-05-05 20:56:15 -07001669 case CMD_SET_ALLOWED_CARRIERS:
1670 request = (MainThreadRequest) msg.obj;
Michele Berionne482f8202018-11-27 18:57:59 -08001671 CarrierRestrictionRules argument =
1672 (CarrierRestrictionRules) request.argument;
Meng Wang1a7c35a2016-05-05 20:56:15 -07001673 onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
Michele Berionne482f8202018-11-27 18:57:59 -08001674 defaultPhone.setAllowedCarriers(argument, onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -07001675 break;
1676
1677 case EVENT_SET_ALLOWED_CARRIERS_DONE:
1678 ar = (AsyncResult) msg.obj;
1679 request = (MainThreadRequest) ar.userObj;
1680 if (ar.exception == null && ar.result != null) {
1681 request.result = ar.result;
1682 } else {
Michele Berionne482f8202018-11-27 18:57:59 -08001683 request.result = TelephonyManager.SET_CARRIER_RESTRICTION_ERROR;
1684 if (ar.exception instanceof CommandException) {
1685 loge("setAllowedCarriers: CommandException: " + ar.exception);
1686 CommandException.Error error =
1687 ((CommandException) (ar.exception)).getCommandError();
1688 if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1689 request.result =
1690 TelephonyManager.SET_CARRIER_RESTRICTION_NOT_SUPPORTED;
1691 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07001692 } else {
1693 loge("setAllowedCarriers: Unknown exception");
1694 }
1695 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001696 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -07001697 break;
1698
1699 case CMD_GET_ALLOWED_CARRIERS:
1700 request = (MainThreadRequest) msg.obj;
1701 onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001702 defaultPhone.getAllowedCarriers(onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -07001703 break;
1704
1705 case EVENT_GET_ALLOWED_CARRIERS_DONE:
1706 ar = (AsyncResult) msg.obj;
1707 request = (MainThreadRequest) ar.userObj;
1708 if (ar.exception == null && ar.result != null) {
1709 request.result = ar.result;
1710 } else {
Michele Berionne482f8202018-11-27 18:57:59 -08001711 request.result = new IllegalStateException(
Thomas Nguyen8ee49682023-02-01 11:46:09 -08001712 "Failed to get carrier restrictions");
Meng Wang1a7c35a2016-05-05 20:56:15 -07001713 if (ar.result == null) {
1714 loge("getAllowedCarriers: Empty response");
1715 } else if (ar.exception instanceof CommandException) {
1716 loge("getAllowedCarriers: CommandException: " +
1717 ar.exception);
1718 } else {
1719 loge("getAllowedCarriers: Unknown exception");
1720 }
1721 }
arunvoddud7401012022-12-15 16:08:12 +00001722 if (request.argument != null) {
1723 // This is for the implementation of carrierRestrictionStatus.
1724 CallerCallbackInfo callbackInfo = (CallerCallbackInfo) request.argument;
1725 Consumer<Integer> callback = callbackInfo.getConsumer();
1726 int callerCarrierId = callbackInfo.getCarrierId();
1727 int lockStatus = TelephonyManager.CARRIER_RESTRICTION_STATUS_UNKNOWN;
1728 if (ar.exception == null && ar.result instanceof CarrierRestrictionRules) {
1729 CarrierRestrictionRules carrierRestrictionRules =
1730 (CarrierRestrictionRules) ar.result;
1731 int carrierId = -1;
1732 try {
1733 CarrierIdentifier carrierIdentifier =
1734 carrierRestrictionRules.getAllowedCarriers().get(0);
1735 carrierId = CarrierResolver.getCarrierIdFromIdentifier(mApp,
1736 carrierIdentifier);
1737 } catch (NullPointerException | IndexOutOfBoundsException ex) {
1738 Rlog.e(LOG_TAG, "CarrierIdentifier exception = " + ex);
1739 }
1740 lockStatus = carrierRestrictionRules.getCarrierRestrictionStatus();
1741 if (carrierId != -1 && callerCarrierId == carrierId && lockStatus
1742 == TelephonyManager.CARRIER_RESTRICTION_STATUS_RESTRICTED) {
Thomas Nguyen8ee49682023-02-01 11:46:09 -08001743 lockStatus = TelephonyManager
1744 .CARRIER_RESTRICTION_STATUS_RESTRICTED_TO_CALLER;
arunvoddud7401012022-12-15 16:08:12 +00001745 }
1746 } else {
1747 Rlog.e(LOG_TAG,
1748 "getCarrierRestrictionStatus: exception ex = " + ar.exception);
1749 }
1750 callback.accept(lockStatus);
1751 } else {
1752 // This is for the implementation of getAllowedCarriers.
1753 notifyRequester(request);
1754 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07001755 break;
1756
Nathan Haroldb3014052017-01-25 15:57:32 -08001757 case EVENT_GET_FORBIDDEN_PLMNS_DONE:
1758 ar = (AsyncResult) msg.obj;
1759 request = (MainThreadRequest) ar.userObj;
1760 if (ar.exception == null && ar.result != null) {
1761 request.result = ar.result;
1762 } else {
1763 request.result = new IllegalArgumentException(
1764 "Failed to retrieve Forbidden Plmns");
1765 if (ar.result == null) {
1766 loge("getForbiddenPlmns: Empty response");
1767 } else {
1768 loge("getForbiddenPlmns: Unknown exception");
1769 }
1770 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001771 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -08001772 break;
1773
1774 case CMD_GET_FORBIDDEN_PLMNS:
1775 request = (MainThreadRequest) msg.obj;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00001776 uiccPort = getUiccPortFromRequest(request);
1777 if (uiccPort == null) {
1778 loge("getForbiddenPlmns() UiccPort is null");
Nathan Haroldb3014052017-01-25 15:57:32 -08001779 request.result = new IllegalArgumentException(
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00001780 "getForbiddenPlmns() UiccPort is null");
Pengquan Menga1bb6272018-09-06 09:59:22 -07001781 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -08001782 break;
1783 }
1784 Integer appType = (Integer) request.argument;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00001785 UiccCardApplication uiccApp = uiccPort.getApplicationByType(appType);
Nathan Haroldb3014052017-01-25 15:57:32 -08001786 if (uiccApp == null) {
1787 loge("getForbiddenPlmns() no app with specified type -- "
1788 + appType);
1789 request.result = new IllegalArgumentException("Failed to get UICC App");
Pengquan Menga1bb6272018-09-06 09:59:22 -07001790 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -08001791 break;
1792 } else {
1793 if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
1794 + " specified type -- " + appType);
1795 }
1796 onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
1797 ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
Thomas Nguyen8ee49682023-02-01 11:46:09 -08001798 onCompleted);
Nathan Haroldb3014052017-01-25 15:57:32 -08001799 break;
1800
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001801 case CMD_SWITCH_SLOTS:
1802 request = (MainThreadRequest) msg.obj;
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00001803 List<UiccSlotMapping> slotMapping = (List<UiccSlotMapping>) request.argument;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001804 onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00001805 UiccController.getInstance().switchSlots(slotMapping, onCompleted);
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001806 break;
1807
1808 case EVENT_SWITCH_SLOTS_DONE:
1809 ar = (AsyncResult) msg.obj;
1810 request = (MainThreadRequest) ar.userObj;
1811 request.result = (ar.exception == null);
Pengquan Menga1bb6272018-09-06 09:59:22 -07001812 notifyRequester(request);
1813 break;
1814 case CMD_GET_NETWORK_SELECTION_MODE:
1815 request = (MainThreadRequest) msg.obj;
1816 onCompleted = obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE, request);
1817 getPhoneFromRequest(request).getNetworkSelectionMode(onCompleted);
1818 break;
1819
1820 case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
1821 ar = (AsyncResult) msg.obj;
1822 request = (MainThreadRequest) ar.userObj;
1823 if (ar.exception != null) {
1824 request.result = TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
1825 } else {
1826 int mode = ((int[]) ar.result)[0];
1827 if (mode == 0) {
1828 request.result = TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
1829 } else {
1830 request.result = TelephonyManager.NETWORK_SELECTION_MODE_MANUAL;
1831 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001832 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001833 notifyRequester(request);
1834 break;
1835 case CMD_GET_CDMA_ROAMING_MODE:
1836 request = (MainThreadRequest) msg.obj;
1837 onCompleted = obtainMessage(EVENT_GET_CDMA_ROAMING_MODE_DONE, request);
1838 getPhoneFromRequest(request).queryCdmaRoamingPreference(onCompleted);
1839 break;
1840 case EVENT_GET_CDMA_ROAMING_MODE_DONE:
1841 ar = (AsyncResult) msg.obj;
1842 request = (MainThreadRequest) ar.userObj;
1843 if (ar.exception != null) {
1844 request.result = TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT;
1845 } else {
1846 request.result = ((int[]) ar.result)[0];
1847 }
1848 notifyRequester(request);
1849 break;
1850 case CMD_SET_CDMA_ROAMING_MODE:
1851 request = (MainThreadRequest) msg.obj;
1852 onCompleted = obtainMessage(EVENT_SET_CDMA_ROAMING_MODE_DONE, request);
1853 int mode = (int) request.argument;
1854 getPhoneFromRequest(request).setCdmaRoamingPreference(mode, onCompleted);
1855 break;
1856 case EVENT_SET_CDMA_ROAMING_MODE_DONE:
1857 ar = (AsyncResult) msg.obj;
1858 request = (MainThreadRequest) ar.userObj;
1859 request.result = ar.exception == null;
1860 notifyRequester(request);
1861 break;
Sarah Chinbaab1432020-10-28 13:46:24 -07001862 case CMD_GET_CDMA_SUBSCRIPTION_MODE:
1863 request = (MainThreadRequest) msg.obj;
1864 onCompleted = obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1865 getPhoneFromRequest(request).queryCdmaSubscriptionMode(onCompleted);
1866 break;
1867 case EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE:
1868 ar = (AsyncResult) msg.obj;
1869 request = (MainThreadRequest) ar.userObj;
1870 if (ar.exception != null) {
1871 request.result = TelephonyManager.CDMA_SUBSCRIPTION_RUIM_SIM;
1872 } else {
1873 request.result = ((int[]) ar.result)[0];
1874 }
1875 notifyRequester(request);
1876 break;
Pengquan Menga1bb6272018-09-06 09:59:22 -07001877 case CMD_SET_CDMA_SUBSCRIPTION_MODE:
1878 request = (MainThreadRequest) msg.obj;
1879 onCompleted = obtainMessage(EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1880 int subscriptionMode = (int) request.argument;
Sarah Chinbaab1432020-10-28 13:46:24 -07001881 getPhoneFromRequest(request).setCdmaSubscriptionMode(
1882 subscriptionMode, onCompleted);
Pengquan Menga1bb6272018-09-06 09:59:22 -07001883 break;
1884 case EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE:
1885 ar = (AsyncResult) msg.obj;
1886 request = (MainThreadRequest) ar.userObj;
1887 request.result = ar.exception == null;
1888 notifyRequester(request);
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001889 break;
Nathan Harold3ff88932018-08-14 10:19:49 -07001890 case CMD_GET_ALL_CELL_INFO:
1891 request = (MainThreadRequest) msg.obj;
Nathan Harold3ff88932018-08-14 10:19:49 -07001892 onCompleted = obtainMessage(EVENT_GET_ALL_CELL_INFO_DONE, request);
Nathan Harold92bed182018-10-12 18:16:49 -07001893 request.phone.requestCellInfoUpdate(request.workSource, onCompleted);
Nathan Harold3ff88932018-08-14 10:19:49 -07001894 break;
Nathan Harold3ff88932018-08-14 10:19:49 -07001895 case EVENT_GET_ALL_CELL_INFO_DONE:
1896 ar = (AsyncResult) msg.obj;
1897 request = (MainThreadRequest) ar.userObj;
Nathan Harold8d0f1742018-10-02 12:14:47 -07001898 // If a timeout occurs, the response will be null
1899 request.result = (ar.exception == null && ar.result != null)
1900 ? ar.result : new ArrayList<CellInfo>();
Nathan Harold3ff88932018-08-14 10:19:49 -07001901 synchronized (request) {
1902 request.notifyAll();
1903 }
1904 break;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001905 case CMD_REQUEST_CELL_INFO_UPDATE:
1906 request = (MainThreadRequest) msg.obj;
1907 request.phone.requestCellInfoUpdate(request.workSource,
1908 obtainMessage(EVENT_REQUEST_CELL_INFO_UPDATE_DONE, request));
1909 break;
1910 case EVENT_REQUEST_CELL_INFO_UPDATE_DONE:
1911 ar = (AsyncResult) msg.obj;
1912 request = (MainThreadRequest) ar.userObj;
1913 ICellInfoCallback cb = (ICellInfoCallback) request.argument;
1914 try {
1915 if (ar.exception != null) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001916 Log.e(LOG_TAG, "Exception retrieving CellInfo=" + ar.exception);
Meng Wangd8921f42019-09-30 17:13:54 -07001917 cb.onError(
1918 TelephonyManager.CellInfoCallback.ERROR_MODEM_ERROR,
1919 ar.exception.getClass().getName(),
1920 ar.exception.toString());
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001921 } else if (ar.result == null) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001922 Log.w(LOG_TAG, "Timeout Waiting for CellInfo!");
Meng Wangd8921f42019-09-30 17:13:54 -07001923 cb.onError(TelephonyManager.CellInfoCallback.ERROR_TIMEOUT, null, null);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001924 } else {
1925 // use the result as returned
1926 cb.onCellInfo((List<CellInfo>) ar.result);
1927 }
1928 } catch (RemoteException re) {
1929 Log.w(LOG_TAG, "Discarded CellInfo due to Callback RemoteException");
1930 }
1931 break;
Sarah Chin679c08a2020-11-18 13:39:35 -08001932 case CMD_GET_CELL_LOCATION: {
Nathan Harold3ff88932018-08-14 10:19:49 -07001933 request = (MainThreadRequest) msg.obj;
1934 WorkSource ws = (WorkSource) request.argument;
1935 Phone phone = getPhoneFromRequest(request);
Meng Wanga10e89e2019-12-09 13:13:01 -08001936 phone.getCellIdentity(ws, obtainMessage(EVENT_GET_CELL_LOCATION_DONE, request));
Nathan Harold3ff88932018-08-14 10:19:49 -07001937 break;
Sarah Chin679c08a2020-11-18 13:39:35 -08001938 }
1939 case EVENT_GET_CELL_LOCATION_DONE: {
Nathan Harold3ff88932018-08-14 10:19:49 -07001940 ar = (AsyncResult) msg.obj;
1941 request = (MainThreadRequest) ar.userObj;
1942 if (ar.exception == null) {
1943 request.result = ar.result;
1944 } else {
Sarah Chin679c08a2020-11-18 13:39:35 -08001945 Phone phone = getPhoneFromRequest(request);
Nathan Harold3ff88932018-08-14 10:19:49 -07001946 request.result = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
Meng Wanga10e89e2019-12-09 13:13:01 -08001947 ? new CellIdentityCdma() : new CellIdentityGsm();
Nathan Harold3ff88932018-08-14 10:19:49 -07001948 }
1949
1950 synchronized (request) {
1951 request.notifyAll();
1952 }
1953 break;
Sarah Chin679c08a2020-11-18 13:39:35 -08001954 }
chen xu6dac5ab2018-10-26 17:39:23 -07001955 case CMD_MODEM_REBOOT:
1956 request = (MainThreadRequest) msg.obj;
1957 onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001958 defaultPhone.rebootModem(onCompleted);
chen xu6dac5ab2018-10-26 17:39:23 -07001959 break;
chen xu6dac5ab2018-10-26 17:39:23 -07001960 case EVENT_CMD_MODEM_REBOOT_DONE:
1961 handleNullReturnEvent(msg, "rebootModem");
1962 break;
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001963 case CMD_REQUEST_ENABLE_MODEM:
1964 request = (MainThreadRequest) msg.obj;
1965 boolean enable = (boolean) request.argument;
1966 onCompleted = obtainMessage(EVENT_ENABLE_MODEM_DONE, request);
Nazanin Bakhshi33d584b2019-02-27 10:44:32 -08001967 onCompleted.arg1 = enable ? 1 : 0;
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001968 PhoneConfigurationManager.getInstance()
1969 .enablePhone(request.phone, enable, onCompleted);
1970 break;
Michele Berionne5e411512020-11-13 02:36:59 +00001971 case EVENT_ENABLE_MODEM_DONE: {
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001972 ar = (AsyncResult) msg.obj;
1973 request = (MainThreadRequest) ar.userObj;
1974 request.result = (ar.exception == null);
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07001975 int phoneId = request.phone.getPhoneId();
Nazanin Bakhshi33d584b2019-02-27 10:44:32 -08001976 //update the cache as modem status has changed
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07001977 if ((boolean) request.result) {
1978 mPhoneConfigurationManager.addToPhoneStatusCache(phoneId, msg.arg1 == 1);
1979 updateModemStateMetrics();
1980 } else {
1981 Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1982 + ar.exception);
1983 }
1984 notifyRequester(request);
1985 break;
Michele Berionne5e411512020-11-13 02:36:59 +00001986 }
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07001987 case CMD_GET_MODEM_STATUS:
1988 request = (MainThreadRequest) msg.obj;
1989 onCompleted = obtainMessage(EVENT_GET_MODEM_STATUS_DONE, request);
1990 PhoneConfigurationManager.getInstance()
1991 .getPhoneStatusFromModem(request.phone, onCompleted);
1992 break;
1993 case EVENT_GET_MODEM_STATUS_DONE:
1994 ar = (AsyncResult) msg.obj;
1995 request = (MainThreadRequest) ar.userObj;
1996 int id = request.phone.getPhoneId();
1997 if (ar.exception == null && ar.result != null) {
1998 request.result = ar.result;
1999 //update the cache as modem status has changed
2000 mPhoneConfigurationManager.addToPhoneStatusCache(id,
2001 (boolean) request.result);
2002 } else {
2003 // Return true if modem status cannot be retrieved. For most cases,
2004 // modem status is on. And for older version modems, GET_MODEM_STATUS
2005 // and disable modem are not supported. Modem is always on.
2006 // TODO: this should be fixed in R to support a third
2007 // status UNKNOWN b/131631629
2008 request.result = true;
2009 Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
2010 + ar.exception);
2011 }
Malcolm Chen8e4ed912019-01-15 20:22:16 -08002012 notifyRequester(request);
2013 break;
Hall Liu73f5d362020-01-20 13:42:00 -08002014 case CMD_SET_SYSTEM_SELECTION_CHANNELS: {
2015 request = (MainThreadRequest) msg.obj;
2016 onCompleted = obtainMessage(EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE, request);
2017 Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> args =
2018 (Pair<List<RadioAccessSpecifier>, Consumer<Boolean>>) request.argument;
2019 request.phone.setSystemSelectionChannels(args.first, onCompleted);
2020 break;
2021 }
2022 case EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE: {
2023 ar = (AsyncResult) msg.obj;
2024 request = (MainThreadRequest) ar.userObj;
2025 Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> args =
2026 (Pair<List<RadioAccessSpecifier>, Consumer<Boolean>>) request.argument;
2027 args.second.accept(ar.exception == null);
2028 notifyRequester(request);
2029 break;
2030 }
Sarah Chin679c08a2020-11-18 13:39:35 -08002031 case CMD_GET_SYSTEM_SELECTION_CHANNELS: {
2032 request = (MainThreadRequest) msg.obj;
2033 onCompleted = obtainMessage(EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE, request);
2034 Phone phone = getPhoneFromRequest(request);
2035 if (phone != null) {
2036 phone.getSystemSelectionChannels(onCompleted);
2037 } else {
2038 loge("getSystemSelectionChannels: No phone object");
2039 request.result = new ArrayList<RadioAccessSpecifier>();
2040 notifyRequester(request);
2041 }
2042 break;
2043 }
2044 case EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE:
2045 ar = (AsyncResult) msg.obj;
2046 request = (MainThreadRequest) ar.userObj;
2047 if (ar.exception == null && ar.result != null) {
2048 request.result = ar.result;
2049 } else {
Sarah Chin428d1d62021-03-13 03:17:40 -08002050 request.result = new IllegalStateException(
2051 "Failed to retrieve system selecton channels");
Sarah Chin679c08a2020-11-18 13:39:35 -08002052 if (ar.result == null) {
2053 loge("getSystemSelectionChannels: Empty response");
2054 } else {
2055 loge("getSystemSelectionChannels: Unknown exception");
2056 }
2057 }
2058 notifyRequester(request);
2059 break;
yincheng zhao2737e882019-09-06 17:06:54 -07002060 case EVENT_SET_FORBIDDEN_PLMNS_DONE:
2061 ar = (AsyncResult) msg.obj;
2062 request = (MainThreadRequest) ar.userObj;
2063 if (ar.exception == null && ar.result != null) {
2064 request.result = ar.result;
2065 } else {
2066 request.result = -1;
2067 loge("Failed to set Forbidden Plmns");
2068 if (ar.result == null) {
2069 loge("setForbidenPlmns: Empty response");
2070 } else if (ar.exception != null) {
2071 loge("setForbiddenPlmns: Exception: " + ar.exception);
2072 request.result = -1;
2073 } else {
2074 loge("setForbiddenPlmns: Unknown exception");
2075 }
2076 }
2077 notifyRequester(request);
2078 break;
2079 case CMD_SET_FORBIDDEN_PLMNS:
2080 request = (MainThreadRequest) msg.obj;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00002081 uiccPort = getUiccPortFromRequest(request);
2082 if (uiccPort == null) {
2083 loge("setForbiddenPlmns: UiccPort is null");
yincheng zhao2737e882019-09-06 17:06:54 -07002084 request.result = -1;
2085 notifyRequester(request);
2086 break;
2087 }
2088 Pair<Integer, List<String>> setFplmnsArgs =
2089 (Pair<Integer, List<String>>) request.argument;
2090 appType = setFplmnsArgs.first;
2091 List<String> fplmns = setFplmnsArgs.second;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00002092 uiccApp = uiccPort.getApplicationByType(appType);
yincheng zhao2737e882019-09-06 17:06:54 -07002093 if (uiccApp == null) {
2094 loge("setForbiddenPlmns: no app with specified type -- " + appType);
2095 request.result = -1;
2096 loge("Failed to get UICC App");
2097 notifyRequester(request);
2098 } else {
2099 onCompleted = obtainMessage(EVENT_SET_FORBIDDEN_PLMNS_DONE, request);
2100 ((SIMRecords) uiccApp.getIccRecords())
2101 .setForbiddenPlmns(onCompleted, fplmns);
2102 }
yinchengzhao4d163c02019-12-12 15:21:47 -08002103 break;
Naina Nallurid63128d2019-09-17 14:10:30 -07002104 case CMD_ERASE_MODEM_CONFIG:
2105 request = (MainThreadRequest) msg.obj;
2106 onCompleted = obtainMessage(EVENT_ERASE_MODEM_CONFIG_DONE, request);
2107 defaultPhone.eraseModemConfig(onCompleted);
2108 break;
2109 case EVENT_ERASE_MODEM_CONFIG_DONE:
2110 handleNullReturnEvent(msg, "eraseModemConfig");
yincheng zhao2737e882019-09-06 17:06:54 -07002111 break;
zoey chene02881a2019-12-30 16:11:23 +08002112
Kai Shif70f46f2021-03-03 13:59:46 -08002113 case CMD_ERASE_DATA_SHARED_PREFERENCES:
2114 request = (MainThreadRequest) msg.obj;
2115 request.result = defaultPhone.eraseDataInSharedPreferences();
2116 notifyRequester(request);
2117 break;
2118
zoey chene02881a2019-12-30 16:11:23 +08002119 case CMD_CHANGE_ICC_LOCK_PASSWORD:
2120 request = (MainThreadRequest) msg.obj;
2121 onCompleted = obtainMessage(EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE, request);
2122 Pair<String, String> changed = (Pair<String, String>) request.argument;
2123 getPhoneFromRequest(request).getIccCard().changeIccLockPassword(
2124 changed.first, changed.second, onCompleted);
2125 break;
2126 case EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE:
2127 ar = (AsyncResult) msg.obj;
2128 request = (MainThreadRequest) ar.userObj;
2129 if (ar.exception == null) {
2130 request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
Michele Berionne5e411512020-11-13 02:36:59 +00002131 // If the operation is successful, update the PIN storage
2132 Pair<String, String> passwords = (Pair<String, String>) request.argument;
2133 int phoneId = getPhoneFromRequest(request).getPhoneId();
Jon Spivack9c3bc762021-10-06 20:53:09 +00002134 UiccController.getInstance().getPinStorage()
2135 .storePin(passwords.second, phoneId);
zoey chene02881a2019-12-30 16:11:23 +08002136 } else {
2137 request.result = msg.arg1;
2138 }
2139 notifyRequester(request);
2140 break;
2141
Michele Berionne5e411512020-11-13 02:36:59 +00002142 case CMD_SET_ICC_LOCK_ENABLED: {
zoey chene02881a2019-12-30 16:11:23 +08002143 request = (MainThreadRequest) msg.obj;
2144 onCompleted = obtainMessage(EVENT_SET_ICC_LOCK_ENABLED_DONE, request);
2145 Pair<Boolean, String> enabled = (Pair<Boolean, String>) request.argument;
2146 getPhoneFromRequest(request).getIccCard().setIccLockEnabled(
2147 enabled.first, enabled.second, onCompleted);
2148 break;
Michele Berionne5e411512020-11-13 02:36:59 +00002149 }
zoey chene02881a2019-12-30 16:11:23 +08002150 case EVENT_SET_ICC_LOCK_ENABLED_DONE:
2151 ar = (AsyncResult) msg.obj;
2152 request = (MainThreadRequest) ar.userObj;
2153 if (ar.exception == null) {
2154 request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
Michele Berionne5e411512020-11-13 02:36:59 +00002155 // If the operation is successful, update the PIN storage
2156 Pair<Boolean, String> enabled = (Pair<Boolean, String>) request.argument;
2157 int phoneId = getPhoneFromRequest(request).getPhoneId();
2158 if (enabled.first) {
Jon Spivack9c3bc762021-10-06 20:53:09 +00002159 UiccController.getInstance().getPinStorage()
2160 .storePin(enabled.second, phoneId);
Michele Berionne5e411512020-11-13 02:36:59 +00002161 } else {
2162 UiccController.getInstance().getPinStorage().clearPin(phoneId);
2163 }
zoey chene02881a2019-12-30 16:11:23 +08002164 } else {
2165 request.result = msg.arg1;
2166 }
Michele Berionne5e411512020-11-13 02:36:59 +00002167
2168
zoey chene02881a2019-12-30 16:11:23 +08002169 notifyRequester(request);
2170 break;
2171
Peter Wangdafb9ac2020-01-15 14:13:38 -08002172 case MSG_NOTIFY_USER_ACTIVITY:
2173 removeMessages(MSG_NOTIFY_USER_ACTIVITY);
Peter Wang59571be2020-01-27 12:35:15 +08002174 Intent intent = new Intent(TelephonyIntents.ACTION_USER_ACTIVITY_NOTIFICATION);
Peter Wangdafb9ac2020-01-15 14:13:38 -08002175 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
2176 getDefaultPhone().getContext().sendBroadcastAsUser(
2177 intent, UserHandle.ALL, permission.USER_ACTIVITY);
2178 break;
Jack Nudelmanb0b87642020-11-12 15:04:39 -08002179
2180 case CMD_SET_DATA_THROTTLING: {
2181 request = (MainThreadRequest) msg.obj;
2182 onCompleted = obtainMessage(EVENT_SET_DATA_THROTTLING_DONE, request);
2183 DataThrottlingRequest dataThrottlingRequest =
2184 (DataThrottlingRequest) request.argument;
2185 Phone phone = getPhoneFromRequest(request);
2186 if (phone != null) {
2187 phone.setDataThrottling(onCompleted,
2188 request.workSource, dataThrottlingRequest.getDataThrottlingAction(),
2189 dataThrottlingRequest.getCompletionDurationMillis());
2190 } else {
2191 loge("setDataThrottling: No phone object");
2192 request.result =
2193 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
2194 notifyRequester(request);
2195 }
2196
2197 break;
2198 }
2199 case EVENT_SET_DATA_THROTTLING_DONE:
2200 ar = (AsyncResult) msg.obj;
2201 request = (MainThreadRequest) ar.userObj;
2202
2203 if (ar.exception == null) {
2204 request.result = TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
2205 } else if (ar.exception instanceof CommandException) {
2206 loge("setDataThrottling: CommandException: " + ar.exception);
2207 CommandException.Error error =
2208 ((CommandException) (ar.exception)).getCommandError();
2209
2210 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
2211 request.result = TelephonyManager
Thomas Nguyen8ee49682023-02-01 11:46:09 -08002212 .THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
Jack Nudelmanb0b87642020-11-12 15:04:39 -08002213 } else if (error == CommandException.Error.INVALID_ARGUMENTS) {
2214 request.result = SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS;
Jack Nudelman5d6a98b2021-03-04 14:26:25 -08002215 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
2216 request.result = MODEM_DOES_NOT_SUPPORT_DATA_THROTTLING_ERROR_CODE;
Jack Nudelmanb0b87642020-11-12 15:04:39 -08002217 } else {
2218 request.result =
2219 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
2220 }
2221 } else {
2222 request.result = TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
2223 }
2224 Log.w(LOG_TAG, "DataThrottlingResult = " + request.result);
2225 notifyRequester(request);
2226 break;
Jordan Liu109698e2020-11-24 14:50:34 -08002227
2228 case CMD_SET_SIM_POWER: {
2229 request = (MainThreadRequest) msg.obj;
2230 onCompleted = obtainMessage(EVENT_SET_SIM_POWER_DONE, request);
2231 request = (MainThreadRequest) msg.obj;
2232 int stateToSet =
2233 ((Pair<Integer, IIntegerConsumer>)
2234 request.argument).first;
2235 request.phone.setSimPowerState(stateToSet, onCompleted, request.workSource);
2236 break;
2237 }
2238 case EVENT_SET_SIM_POWER_DONE: {
2239 ar = (AsyncResult) msg.obj;
2240 request = (MainThreadRequest) ar.userObj;
2241 IIntegerConsumer callback =
2242 ((Pair<Integer, IIntegerConsumer>) request.argument).second;
2243 if (ar.exception != null) {
2244 loge("setSimPower exception: " + ar.exception);
2245 int errorCode = TelephonyManager.CallForwardingInfoCallback
2246 .RESULT_ERROR_UNKNOWN;
2247 if (ar.exception instanceof CommandException) {
2248 CommandException.Error error =
2249 ((CommandException) (ar.exception)).getCommandError();
2250 if (error == CommandException.Error.SIM_ERR) {
2251 errorCode = TelephonyManager.SET_SIM_POWER_STATE_SIM_ERROR;
2252 } else if (error == CommandException.Error.INVALID_ARGUMENTS) {
2253 errorCode = TelephonyManager.SET_SIM_POWER_STATE_ALREADY_IN_STATE;
2254 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
2255 errorCode = TelephonyManager.SET_SIM_POWER_STATE_NOT_SUPPORTED;
2256 } else {
2257 errorCode = TelephonyManager.SET_SIM_POWER_STATE_MODEM_ERROR;
2258 }
2259 }
2260 try {
2261 callback.accept(errorCode);
2262 } catch (RemoteException e) {
2263 // Ignore if the remote process is no longer available to call back.
2264 Log.w(LOG_TAG, "setSimPower: callback not available.");
2265 }
2266 } else {
2267 try {
2268 callback.accept(TelephonyManager.SET_SIM_POWER_STATE_SUCCESS);
2269 } catch (RemoteException e) {
2270 // Ignore if the remote process is no longer available to call back.
2271 Log.w(LOG_TAG, "setSimPower: callback not available.");
2272 }
2273 }
2274 break;
2275 }
Rambo Wanga5cc9b72021-01-07 10:51:54 -08002276 case CMD_SET_SIGNAL_STRENGTH_UPDATE_REQUEST: {
2277 request = (MainThreadRequest) msg.obj;
2278
2279 final Phone phone = getPhoneFromRequest(request);
2280 if (phone == null || phone.getServiceStateTracker() == null) {
2281 request.result = new IllegalStateException("Phone or SST is null");
2282 notifyRequester(request);
2283 break;
2284 }
2285
2286 Pair<Integer, SignalStrengthUpdateRequest> pair =
2287 (Pair<Integer, SignalStrengthUpdateRequest>) request.argument;
2288 onCompleted = obtainMessage(EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE,
2289 request);
Rambo Wang6568f172021-02-03 16:56:47 -08002290 phone.getSignalStrengthController().setSignalStrengthUpdateRequest(
Thomas Nguyen8ee49682023-02-01 11:46:09 -08002291 request.subId, pair.first /*callingUid*/,
2292 pair.second /*request*/, onCompleted);
Rambo Wanga5cc9b72021-01-07 10:51:54 -08002293 break;
2294 }
2295 case EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE: {
2296 ar = (AsyncResult) msg.obj;
2297 request = (MainThreadRequest) ar.userObj;
2298 // request.result will be the exception of ar if present, true otherwise.
2299 // Be cautious not to leave result null which will wait() forever
2300 request.result = ar.exception != null ? ar.exception : true;
2301 notifyRequester(request);
2302 break;
2303 }
2304 case CMD_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST: {
2305 request = (MainThreadRequest) msg.obj;
2306
2307 Phone phone = getPhoneFromRequest(request);
2308 if (phone == null || phone.getServiceStateTracker() == null) {
2309 request.result = new IllegalStateException("Phone or SST is null");
2310 notifyRequester(request);
2311 break;
2312 }
2313
2314 Pair<Integer, SignalStrengthUpdateRequest> pair =
2315 (Pair<Integer, SignalStrengthUpdateRequest>) request.argument;
2316 onCompleted = obtainMessage(EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE,
2317 request);
Rambo Wang6568f172021-02-03 16:56:47 -08002318 phone.getSignalStrengthController().clearSignalStrengthUpdateRequest(
Thomas Nguyen8ee49682023-02-01 11:46:09 -08002319 request.subId, pair.first /*callingUid*/,
2320 pair.second /*request*/, onCompleted);
Rambo Wanga5cc9b72021-01-07 10:51:54 -08002321 break;
2322 }
2323 case EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE: {
2324 ar = (AsyncResult) msg.obj;
2325 request = (MainThreadRequest) ar.userObj;
2326 request.result = ar.exception != null ? ar.exception : true;
2327 notifyRequester(request);
2328 break;
2329 }
Jordan Liu109698e2020-11-24 14:50:34 -08002330
Hongbo Zeng156aa4a2021-02-08 21:50:28 +08002331 case CMD_GET_SLICING_CONFIG: {
2332 request = (MainThreadRequest) msg.obj;
2333 onCompleted = obtainMessage(EVENT_GET_SLICING_CONFIG_DONE, request);
2334 request.phone.getSlicingConfig(onCompleted);
2335 break;
2336 }
2337 case EVENT_GET_SLICING_CONFIG_DONE: {
2338 ar = (AsyncResult) msg.obj;
2339 request = (MainThreadRequest) ar.userObj;
2340 ResultReceiver result = (ResultReceiver) request.argument;
2341
Hongbo Zeng0e18b162021-04-07 16:52:18 +08002342 NetworkSlicingConfig slicingConfig = null;
Hongbo Zeng156aa4a2021-02-08 21:50:28 +08002343 Bundle bundle = new Bundle();
2344 int resultCode = 0;
2345 if (ar.exception != null) {
2346 Log.e(LOG_TAG, "Exception retrieving slicing configuration="
2347 + ar.exception);
Hongbo Zeng0e18b162021-04-07 16:52:18 +08002348 resultCode = TelephonyManager.NetworkSlicingException.ERROR_MODEM_ERROR;
Hongbo Zeng156aa4a2021-02-08 21:50:28 +08002349 } else if (ar.result == null) {
2350 Log.w(LOG_TAG, "Timeout Waiting for slicing configuration!");
Hongbo Zeng0e18b162021-04-07 16:52:18 +08002351 resultCode = TelephonyManager.NetworkSlicingException.ERROR_TIMEOUT;
Hongbo Zeng156aa4a2021-02-08 21:50:28 +08002352 } else {
2353 // use the result as returned
Hongbo Zeng0e18b162021-04-07 16:52:18 +08002354 resultCode = TelephonyManager.NetworkSlicingException.SUCCESS;
2355 slicingConfig = (NetworkSlicingConfig) ar.result;
Hongbo Zeng156aa4a2021-02-08 21:50:28 +08002356 }
2357
2358 if (slicingConfig == null) {
Hongbo Zeng0e18b162021-04-07 16:52:18 +08002359 slicingConfig = new NetworkSlicingConfig();
Hongbo Zeng156aa4a2021-02-08 21:50:28 +08002360 }
2361 bundle.putParcelable(TelephonyManager.KEY_SLICING_CONFIG_HANDLE, slicingConfig);
2362 result.send(resultCode, bundle);
2363 notifyRequester(request);
2364 break;
2365 }
2366
Sarah Chin71b3a852022-09-28 15:54:19 -07002367 case CMD_PURCHASE_PREMIUM_CAPABILITY: {
Sarah Chin2ec39f62022-08-31 17:03:26 -07002368 request = (MainThreadRequest) msg.obj;
2369 onCompleted = obtainMessage(EVENT_PURCHASE_PREMIUM_CAPABILITY_DONE, request);
Sarah Chin71b3a852022-09-28 15:54:19 -07002370 PurchasePremiumCapabilityArgument arg =
2371 (PurchasePremiumCapabilityArgument) request.argument;
Sarah Chin46355ba2022-11-01 23:51:16 -07002372 SlicePurchaseController.getInstance(request.phone).purchasePremiumCapability(
Sarah Chinb8218c22023-01-04 13:35:29 -08002373 arg.capability, onCompleted);
Sarah Chin2ec39f62022-08-31 17:03:26 -07002374 break;
Sarah Chin71b3a852022-09-28 15:54:19 -07002375 }
Sarah Chin2ec39f62022-08-31 17:03:26 -07002376
Sarah Chin71b3a852022-09-28 15:54:19 -07002377 case EVENT_PURCHASE_PREMIUM_CAPABILITY_DONE: {
Sarah Chin2ec39f62022-08-31 17:03:26 -07002378 ar = (AsyncResult) msg.obj;
2379 request = (MainThreadRequest) ar.userObj;
Sarah Chin71b3a852022-09-28 15:54:19 -07002380 PurchasePremiumCapabilityArgument arg =
2381 (PurchasePremiumCapabilityArgument) request.argument;
Sarah Chin2ec39f62022-08-31 17:03:26 -07002382 try {
2383 int result = (int) ar.result;
Sarah Chin71b3a852022-09-28 15:54:19 -07002384 arg.callback.accept(result);
Sarah Chin2ec39f62022-08-31 17:03:26 -07002385 log("purchasePremiumCapability: capability="
Sarah Chin71b3a852022-09-28 15:54:19 -07002386 + TelephonyManager.convertPremiumCapabilityToString(arg.capability)
Sarah Chin2ec39f62022-08-31 17:03:26 -07002387 + ", result= "
2388 + TelephonyManager.convertPurchaseResultToString(result));
2389 } catch (RemoteException e) {
2390 String logStr = "Purchase premium capability "
Sarah Chin71b3a852022-09-28 15:54:19 -07002391 + TelephonyManager.convertPremiumCapabilityToString(arg.capability)
Sarah Chin2ec39f62022-08-31 17:03:26 -07002392 + " failed: " + e;
2393 if (DBG) log(logStr);
2394 AnomalyReporter.reportAnomaly(
2395 UUID.fromString(PURCHASE_PREMIUM_CAPABILITY_ERROR_UUID), logStr);
2396 }
2397 break;
Sarah Chin71b3a852022-09-28 15:54:19 -07002398 }
Sarah Chin2ec39f62022-08-31 17:03:26 -07002399
Michele Berionne5e411512020-11-13 02:36:59 +00002400 case CMD_PREPARE_UNATTENDED_REBOOT:
2401 request = (MainThreadRequest) msg.obj;
2402 request.result =
Rafael Higuera Silvad9630642021-09-20 15:32:01 +00002403 UiccController.getInstance().getPinStorage()
Thomas Nguyen8ee49682023-02-01 11:46:09 -08002404 .prepareUnattendedReboot(request.workSource);
Michele Berionne5e411512020-11-13 02:36:59 +00002405 notifyRequester(request);
2406 break;
2407
Sarah Chineccfbd12023-01-20 19:00:35 -08002408 case CMD_START_SATELLITE_POSITION_UPDATES: {
2409 request = (MainThreadRequest) msg.obj;
2410 onCompleted =
2411 obtainMessage(EVENT_START_SATELLITE_POSITION_UPDATES_DONE, request);
2412 Phone phone = getPhoneFromRequest(request);
2413 if (phone != null) {
2414 phone.startSatellitePositionUpdates(onCompleted);
2415 } else {
2416 loge("startSatellitePositionUpdates: No phone object");
Sarah Chinf75afa72023-02-01 01:32:19 -08002417 request.result =
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002418 SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
Sarah Chineccfbd12023-01-20 19:00:35 -08002419 notifyRequester(request);
2420 }
2421 break;
2422 }
2423
2424 case EVENT_START_SATELLITE_POSITION_UPDATES_DONE: {
2425 ar = (AsyncResult) msg.obj;
2426 request = (MainThreadRequest) ar.userObj;
2427 if (ar.exception == null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002428 request.result = SatelliteManager.SATELLITE_ERROR_NONE;
Sarah Chineccfbd12023-01-20 19:00:35 -08002429 } else {
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002430 request.result = SatelliteManager.SATELLITE_ERROR;
Sarah Chineccfbd12023-01-20 19:00:35 -08002431 if (ar.exception instanceof CommandException) {
2432 CommandException.Error error =
2433 ((CommandException) (ar.exception)).getCommandError();
2434 request.result = RILUtils.convertToSatelliteError(error);
2435 loge("startSatellitePositionUpdates CommandException: " + ar.exception);
2436 } else {
2437 loge("startSatellitePositionUpdates unknown exception:" + ar.exception);
2438 }
2439 }
2440 notifyRequester(request);
2441 break;
2442 }
2443
2444 case CMD_STOP_SATELLITE_POSITION_UPDATES: {
2445 request = (MainThreadRequest) msg.obj;
2446 onCompleted =
2447 obtainMessage(EVENT_STOP_SATELLITE_POSITION_UPDATES_DONE, request);
2448 Phone phone = getPhoneFromRequest(request);
2449 if (phone != null) {
2450 phone.stopSatellitePositionUpdates(onCompleted);
2451 } else {
2452 loge("stopSatellitePositionUpdates: No phone object");
Sarah Chinf75afa72023-02-01 01:32:19 -08002453 request.result =
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002454 SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
Sarah Chineccfbd12023-01-20 19:00:35 -08002455 notifyRequester(request);
2456 }
2457 break;
2458 }
2459
2460 case EVENT_STOP_SATELLITE_POSITION_UPDATES_DONE: {
2461 ar = (AsyncResult) msg.obj;
2462 request = (MainThreadRequest) ar.userObj;
2463 if (ar.exception == null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002464 request.result = SatelliteManager.SATELLITE_ERROR_NONE;
Sarah Chineccfbd12023-01-20 19:00:35 -08002465 } else {
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002466 request.result = SatelliteManager.SATELLITE_ERROR;
Sarah Chineccfbd12023-01-20 19:00:35 -08002467 if (ar.exception instanceof CommandException) {
2468 CommandException.Error error =
2469 ((CommandException) (ar.exception)).getCommandError();
2470 request.result = RILUtils.convertToSatelliteError(error);
2471 loge("stopSatellitePositionUpdates CommandException: " + ar.exception);
2472 } else {
2473 loge("stopSatellitePositionUpdates unknown exception:" + ar.exception);
2474 }
2475 }
2476 notifyRequester(request);
2477 break;
2478 }
2479
Aishwarya Mallampati60fe1132023-01-24 19:07:21 +00002480 case CMD_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG: {
2481 request = (MainThreadRequest) msg.obj;
2482 onCompleted = obtainMessage(EVENT_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG_DONE,
2483 request);
2484 Phone phone = getPhoneFromRequest(request);
2485 if (phone != null) {
2486 phone.getMaxCharactersPerSatelliteTextMessage(onCompleted);
2487 } else {
2488 loge("getMaxCharactersPerSatelliteTextMessage: No phone object");
2489 request.result = SatelliteManager
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002490 .SATELLITE_INVALID_TELEPHONY_STATE;
Aishwarya Mallampati60fe1132023-01-24 19:07:21 +00002491 notifyRequester(request);
2492 }
2493 break;
2494 }
2495
2496 case EVENT_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG_DONE: {
2497 ar = (AsyncResult) msg.obj;
2498 request = (MainThreadRequest) ar.userObj;
2499 Consumer<Integer> callback = (Consumer<Integer>) request.argument;
2500 if (ar.exception != null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002501 request.result = SatelliteManager.SATELLITE_ERROR;
Aishwarya Mallampati60fe1132023-01-24 19:07:21 +00002502 if (ar.exception instanceof CommandException) {
2503 CommandException.Error error =
2504 ((CommandException) (ar.exception)).getCommandError();
2505 request.result = RILUtils.convertToSatelliteError(error);
2506 loge("getMaxCharactersPerSatelliteTextMessage: "
2507 + "CommandException: " + ar.exception);
2508 } else {
2509 loge("getMaxCharactersPerSatelliteTextMessage: "
2510 + "unknown exception:" + ar.exception);
2511 }
2512 } else if (ar.result == null) {
2513 request.result = SatelliteManager
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002514 .SATELLITE_INVALID_TELEPHONY_STATE;
Aishwarya Mallampati60fe1132023-01-24 19:07:21 +00002515 loge("getMaxCharactersPerSatelliteTextMessage: result is null");
2516 } else {
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002517 request.result = SatelliteManager.SATELLITE_ERROR_NONE;
Aishwarya Mallampati60fe1132023-01-24 19:07:21 +00002518 int maxCharLimit = ((int[]) ar.result)[0];
Sarah Chin503828c2023-02-01 23:54:20 -08002519 if (DBG) log("getMaxCharactersPerSatelliteTextMessage: " + maxCharLimit);
Aishwarya Mallampati60fe1132023-01-24 19:07:21 +00002520 callback.accept(maxCharLimit);
2521 }
2522 notifyRequester(request);
2523 break;
2524 }
2525
Thomas Nguyen8ee49682023-02-01 11:46:09 -08002526 case CMD_PROVISION_SATELLITE_SERVICE: {
2527 request = (MainThreadRequest) msg.obj;
2528 onCompleted =
2529 obtainMessage(EVENT_PROVISION_SATELLITE_SERVICE_DONE, request);
2530 Phone phone = getPhoneFromRequest(request);
2531 if (phone != null) {
2532 handleCmdProvisionSatelliteService(
2533 (ProvisionSatelliteServiceArgument) request.argument,
2534 phone, onCompleted);
2535 } else {
2536 loge("provisionSatelliteService: No phone object");
2537 request.result =
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002538 SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
Thomas Nguyen8ee49682023-02-01 11:46:09 -08002539 notifyRequester(request);
2540 }
2541 break;
2542 }
2543
2544 case EVENT_PROVISION_SATELLITE_SERVICE_DONE: {
2545 ar = (AsyncResult) msg.obj;
2546 request = (MainThreadRequest) ar.userObj;
2547 if (ar.exception == null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002548 request.result = SatelliteManager.SATELLITE_ERROR_NONE;
Thomas Nguyen8ee49682023-02-01 11:46:09 -08002549 } else {
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002550 request.result = SatelliteManager.SATELLITE_ERROR;
Thomas Nguyen8ee49682023-02-01 11:46:09 -08002551 if (ar.exception instanceof CommandException) {
2552 CommandException.Error error =
2553 ((CommandException) (ar.exception)).getCommandError();
2554 request.result = RILUtils.convertToSatelliteError(error);
2555 loge("provisionSatelliteService CommandException: " + ar.exception);
2556 } else {
2557 loge("provisionSatelliteService unknown exception:" + ar.exception);
2558 }
2559 }
2560 handleEventProvisionSatelliteServiceDone(request);
2561 notifyRequester(request);
2562 break;
2563 }
2564
2565 case CMD_CANCEL_PROVISION_SATELLITE_SERVICE: {
2566 request = (MainThreadRequest) msg.obj;
2567 onCompleted =
2568 obtainMessage(EVENT_CANCEL_PROVISION_SATELLITE_SERVICE_DONE, request);
2569 handleCmdCancelProvisionSatelliteService((int) request.argument, onCompleted);
2570 break;
2571 }
2572
2573 case EVENT_CANCEL_PROVISION_SATELLITE_SERVICE_DONE: {
2574 ar = (AsyncResult) msg.obj;
2575 request = (MainThreadRequest) ar.userObj;
2576
2577 if (ar.exception == null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002578 request.result = SatelliteManager.SATELLITE_ERROR_NONE;
Thomas Nguyen8ee49682023-02-01 11:46:09 -08002579 log("cancelProvisionSatelliteService succeeded for subId="
2580 + (int) request.argument);
2581 } else {
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002582 request.result = SatelliteManager.SATELLITE_ERROR;
Thomas Nguyen8ee49682023-02-01 11:46:09 -08002583 if (ar.exception instanceof CommandException) {
2584 CommandException.Error error =
2585 ((CommandException) (ar.exception)).getCommandError();
2586 request.result = RILUtils.convertToSatelliteError(error);
2587 loge("cancelProvisionSatelliteService CommandException: "
2588 + ar.exception + ", error code:" + request.result);
2589 } else {
2590 loge("cancelProvisionSatelliteService unknown exception:"
2591 + ar.exception);
2592 }
2593 }
2594 notifyRequester(request);
2595 break;
2596 }
2597
2598 case CMD_GET_PROVISIONED_SATELLITE_FEATURES: {
2599 request = (MainThreadRequest) msg.obj;
2600 onCompleted = obtainMessage(EVENT_GET_PROVISIONED_SATELLITE_FEATURES_DONE,
2601 request);
2602 Phone phone = getPhoneFromRequest(request);
2603 if (phone != null) {
2604 phone.getProvisionedSatelliteFeatures(onCompleted);
2605 } else {
2606 loge("getProvisionedSatelliteFeatures: No phone object");
2607 request.result = SatelliteManager
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002608 .SATELLITE_INVALID_TELEPHONY_STATE;
Thomas Nguyen8ee49682023-02-01 11:46:09 -08002609 notifyRequester(request);
2610 }
2611 break;
2612 }
2613
2614 case EVENT_GET_PROVISIONED_SATELLITE_FEATURES_DONE: {
2615 ar = (AsyncResult) msg.obj;
2616 request = (MainThreadRequest) ar.userObj;
2617 if (ar.exception != null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002618 request.result = SatelliteManager.SATELLITE_ERROR;
Thomas Nguyen8ee49682023-02-01 11:46:09 -08002619 if (ar.exception instanceof CommandException) {
2620 CommandException.Error error =
2621 ((CommandException) (ar.exception)).getCommandError();
2622 request.result = RILUtils.convertToSatelliteError(error);
2623 loge("getProvisionedSatelliteFeatures: "
2624 + "CommandException: " + ar.exception);
2625 } else {
2626 loge("getProvisionedSatelliteFeatures: "
2627 + "unknown exception:" + ar.exception);
2628 }
2629 } else if (ar.result == null) {
2630 request.result = SatelliteManager
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002631 .SATELLITE_INVALID_TELEPHONY_STATE;
Thomas Nguyen8ee49682023-02-01 11:46:09 -08002632 loge("getProvisionedSatelliteFeatures: result is null");
2633 } else {
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002634 request.result = SatelliteManager.SATELLITE_ERROR_NONE;
Thomas Nguyen8ee49682023-02-01 11:46:09 -08002635 int[] features = ((int[]) ar.result);
2636 if (DBG) {
2637 log("getProvisionedSatelliteFeatures features:"
2638 + Arrays.toString(features));
2639 }
2640 IIntArrayConsumer callback = (IIntArrayConsumer) request.argument;
2641 if (callback != null) {
2642 try {
2643 callback.accept(features);
2644 } catch (RemoteException ex) {
2645 log("getProvisionedSatelliteFeatures: remote callback"
2646 + " not available");
2647 }
2648 } else {
2649 log("getProvisionedSatelliteFeatures: callback is null");
2650 }
2651 }
2652 notifyRequester(request);
2653 break;
2654 }
2655
Sarah Chin503828c2023-02-01 23:54:20 -08002656 case CMD_SET_SATELLITE_POWER: {
2657 request = (MainThreadRequest) msg.obj;
2658 onCompleted = obtainMessage(EVENT_SET_SATELLITE_POWER_DONE, request);
2659 Phone phone = getPhoneFromRequest(request);
2660 if (phone != null) {
2661 phone.setSatellitePower(onCompleted, (boolean) request.argument);
2662 } else {
2663 loge("setSatellitePower: No phone object");
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002664 request.result = SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
Sarah Chin503828c2023-02-01 23:54:20 -08002665 notifyRequester(request);
2666 }
2667 break;
2668 }
2669
2670 case EVENT_SET_SATELLITE_POWER_DONE: {
2671 ar = (AsyncResult) msg.obj;
2672 request = (MainThreadRequest) ar.userObj;
2673 if (ar.exception == null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002674 request.result = SatelliteManager.SATELLITE_ERROR_NONE;
Sarah Chin503828c2023-02-01 23:54:20 -08002675 } else {
2676 request.result = SatelliteManager.SATELLITE_SERVICE_ERROR;
2677 if (ar.exception instanceof CommandException) {
2678 CommandException.Error error =
2679 ((CommandException) (ar.exception)).getCommandError();
2680 request.result = RILUtils.convertToSatelliteError(error);
2681 loge("setSatellitePower CommandException: " + ar.exception);
2682 } else {
2683 loge("setSatellitePower unknown exception:" + ar.exception);
2684 }
2685 }
2686 notifyRequester(request);
2687 break;
2688 }
2689
2690 case CMD_IS_SATELLITE_POWER_ON: {
2691 request = (MainThreadRequest) msg.obj;
2692 onCompleted = obtainMessage(EVENT_IS_SATELLITE_POWER_ON_DONE, request);
2693 Phone phone = getPhoneFromRequest(request);
2694 if (phone != null) {
2695 phone.isSatellitePowerOn(onCompleted);
2696 } else {
2697 loge("isSatellitePowerOn: No phone object");
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002698 request.result = SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
Sarah Chin503828c2023-02-01 23:54:20 -08002699 notifyRequester(request);
2700 }
2701 break;
2702 }
2703
2704 case EVENT_IS_SATELLITE_POWER_ON_DONE: {
2705 ar = (AsyncResult) msg.obj;
2706 request = (MainThreadRequest) ar.userObj;
2707 Consumer<Boolean> callback = (Consumer<Boolean>) request.argument;
2708 if (ar.exception != null) {
2709 request.result = SatelliteManager.SATELLITE_SERVICE_ERROR;
2710 if (ar.exception instanceof CommandException) {
2711 CommandException.Error error =
2712 ((CommandException) (ar.exception)).getCommandError();
2713 request.result = RILUtils.convertToSatelliteError(error);
2714 loge("isSatellitePowerOn CommandException: " + ar.exception);
2715 } else {
2716 loge("isSatellitePowerOn unknown exception:" + ar.exception);
2717 }
2718 } else if (ar.result == null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002719 request.result = SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
Sarah Chin503828c2023-02-01 23:54:20 -08002720 loge("isSatellitePowerOn: result is null");
2721 } else {
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002722 request.result = SatelliteManager.SATELLITE_ERROR_NONE;
Sarah Chin503828c2023-02-01 23:54:20 -08002723 boolean powerOn = ((int[]) ar.result)[0] == 1;
2724 if (DBG) log("isSatellitePowerOn: " + powerOn);
2725 callback.accept(powerOn);
2726 }
2727 notifyRequester(request);
2728 break;
2729 }
2730
2731 case CMD_IS_SATELLITE_SUPPORTED: {
2732 request = (MainThreadRequest) msg.obj;
2733 onCompleted = obtainMessage(EVENT_IS_SATELLITE_SUPPORTED_DONE, request);
2734 Phone phone = getPhoneFromRequest(request);
2735 if (phone != null) {
2736 phone.isSatelliteSupported(onCompleted);
2737 } else {
2738 loge("isSatelliteSupported: No phone object");
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002739 request.result = SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
Sarah Chin503828c2023-02-01 23:54:20 -08002740 notifyRequester(request);
2741 }
2742 break;
2743 }
2744
2745 case EVENT_IS_SATELLITE_SUPPORTED_DONE: {
2746 ar = (AsyncResult) msg.obj;
2747 request = (MainThreadRequest) ar.userObj;
2748 Consumer<Boolean> callback = (Consumer<Boolean>) request.argument;
2749 if (ar.exception != null) {
2750 request.result = SatelliteManager.SATELLITE_SERVICE_ERROR;
2751 if (ar.exception instanceof CommandException) {
2752 CommandException.Error error =
2753 ((CommandException) (ar.exception)).getCommandError();
2754 request.result = RILUtils.convertToSatelliteError(error);
2755 loge("isSatelliteSupported CommandException: " + ar.exception);
2756 } else {
2757 loge("isSatelliteSupported unknown exception:" + ar.exception);
2758 }
2759 } else if (ar.result == null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002760 request.result = SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
Sarah Chin503828c2023-02-01 23:54:20 -08002761 loge("isSatelliteSupported: result is null");
2762 } else {
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002763 request.result = SatelliteManager.SATELLITE_ERROR_NONE;
2764 boolean isSupported = ((int[]) ar.result)[0] == 1;
2765 if (DBG) log("isSatelliteSupported: " + isSupported);
2766 if (callback != null) callback.accept(isSupported);
2767 synchronized (mIsSatelliteSupportedLock) {
2768 mIsSatelliteSupported = isSupported;
2769 }
Sarah Chin503828c2023-02-01 23:54:20 -08002770 }
2771 notifyRequester(request);
2772 break;
2773 }
2774
2775 case CMD_GET_SATELLITE_CAPABILITIES: {
2776 request = (MainThreadRequest) msg.obj;
2777 onCompleted = obtainMessage(EVENT_GET_SATELLITE_CAPABILITIES_DONE, request);
2778 Phone phone = getPhoneFromRequest(request);
2779 if (phone != null) {
2780 phone.getSatelliteCapabilities(onCompleted);
2781 } else {
2782 loge("getSatelliteCapabilities: No phone object");
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002783 request.result = SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
Sarah Chin503828c2023-02-01 23:54:20 -08002784 notifyRequester(request);
2785 }
2786 break;
2787 }
2788
2789 case EVENT_GET_SATELLITE_CAPABILITIES_DONE: {
2790 ar = (AsyncResult) msg.obj;
2791 request = (MainThreadRequest) ar.userObj;
2792 Consumer<SatelliteCapabilities> callback =
2793 (Consumer<SatelliteCapabilities>) request.argument;
2794 if (ar.exception != null) {
2795 request.result = SatelliteManager.SATELLITE_SERVICE_ERROR;
2796 if (ar.exception instanceof CommandException) {
2797 CommandException.Error error =
2798 ((CommandException) (ar.exception)).getCommandError();
2799 request.result = RILUtils.convertToSatelliteError(error);
2800 loge("getSatelliteCapabilities CommandException: " + ar.exception);
2801 } else {
2802 loge("getSatelliteCapabilities unknown exception:" + ar.exception);
2803 }
2804 } else if (ar.result == null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002805 request.result = SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
Sarah Chin503828c2023-02-01 23:54:20 -08002806 loge("getSatelliteCapabilities: result is null");
2807 } else {
Thomas Nguyene77de6d2023-02-10 17:42:43 -08002808 request.result = SatelliteManager.SATELLITE_ERROR_NONE;
Sarah Chin503828c2023-02-01 23:54:20 -08002809 SatelliteCapabilities capabilities = (SatelliteCapabilities) ar.result;
2810 if (DBG) log("getSatelliteCapabilities: " + capabilities);
2811 callback.accept(capabilities);
2812 }
2813 notifyRequester(request);
2814 break;
2815 }
2816
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002817 default:
2818 Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
2819 break;
2820 }
2821 }
Jake Hambye994d462014-02-03 13:10:13 -08002822
Pengquan Menga1bb6272018-09-06 09:59:22 -07002823 private void notifyRequester(MainThreadRequest request) {
2824 synchronized (request) {
2825 request.notifyAll();
2826 }
2827 }
2828
Jake Hambye994d462014-02-03 13:10:13 -08002829 private void handleNullReturnEvent(Message msg, String command) {
2830 AsyncResult ar = (AsyncResult) msg.obj;
2831 MainThreadRequest request = (MainThreadRequest) ar.userObj;
2832 if (ar.exception == null) {
2833 request.result = true;
2834 } else {
2835 request.result = false;
2836 if (ar.exception instanceof CommandException) {
2837 loge(command + ": CommandException: " + ar.exception);
2838 } else {
2839 loge(command + ": Unknown exception");
2840 }
2841 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07002842 notifyRequester(request);
Jake Hambye994d462014-02-03 13:10:13 -08002843 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002844 }
2845
2846 /**
2847 * Posts the specified command to be executed on the main thread,
2848 * waits for the request to complete, and returns the result.
2849 * @see #sendRequestAsync
2850 */
2851 private Object sendRequest(int command, Object argument) {
Rambo Wang0f050d82021-02-12 11:43:36 -08002852 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, null,
2853 null, -1 /*timeoutInMs*/);
vagdeviaf9a5b92018-08-15 16:01:53 -07002854 }
2855
2856 /**
2857 * Posts the specified command to be executed on the main thread,
2858 * waits for the request to complete, and returns the result.
2859 * @see #sendRequestAsync
2860 */
2861 private Object sendRequest(int command, Object argument, WorkSource workSource) {
2862 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
Rambo Wang0f050d82021-02-12 11:43:36 -08002863 null, workSource, -1 /*timeoutInMs*/);
Wink Saville36469e72014-06-11 15:17:00 -07002864 }
2865
2866 /**
2867 * Posts the specified command to be executed on the main thread,
2868 * waits for the request to complete, and returns the result.
2869 * @see #sendRequestAsync
2870 */
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002871 private Object sendRequest(int command, Object argument, Integer subId) {
Rambo Wang0f050d82021-02-12 11:43:36 -08002872 return sendRequest(command, argument, subId, null, null, -1 /*timeoutInMs*/);
2873 }
2874
2875 /**
2876 * Posts the specified command to be executed on the main thread,
2877 * waits for the request to complete for at most {@code timeoutInMs}, and returns the result
2878 * if not timeout or null otherwise.
2879 * @see #sendRequestAsync
2880 */
2881 private @Nullable Object sendRequest(int command, Object argument, Integer subId,
2882 long timeoutInMs) {
2883 return sendRequest(command, argument, subId, null, null, timeoutInMs);
vagdeviaf9a5b92018-08-15 16:01:53 -07002884 }
2885
2886 /**
2887 * Posts the specified command to be executed on the main thread,
2888 * waits for the request to complete, and returns the result.
2889 * @see #sendRequestAsync
2890 */
Nathan Harold92bed182018-10-12 18:16:49 -07002891 private Object sendRequest(int command, Object argument, int subId, WorkSource workSource) {
Rambo Wang0f050d82021-02-12 11:43:36 -08002892 return sendRequest(command, argument, subId, null, workSource, -1 /*timeoutInMs*/);
Nathan Harold92bed182018-10-12 18:16:49 -07002893 }
2894
2895 /**
2896 * Posts the specified command to be executed on the main thread,
2897 * waits for the request to complete, and returns the result.
2898 * @see #sendRequestAsync
2899 */
2900 private Object sendRequest(int command, Object argument, Phone phone, WorkSource workSource) {
Rambo Wang0f050d82021-02-12 11:43:36 -08002901 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phone,
2902 workSource, -1 /*timeoutInMs*/);
Nathan Harold92bed182018-10-12 18:16:49 -07002903 }
2904
2905 /**
Rambo Wang0f050d82021-02-12 11:43:36 -08002906 * Posts the specified command to be executed on the main thread. If {@code timeoutInMs} is
2907 * negative, waits for the request to complete, and returns the result. Otherwise, wait for
2908 * maximum of {@code timeoutInMs} milliseconds, interrupt and return null.
Nathan Harold92bed182018-10-12 18:16:49 -07002909 * @see #sendRequestAsync
2910 */
Rambo Wang0f050d82021-02-12 11:43:36 -08002911 private @Nullable Object sendRequest(int command, Object argument, Integer subId, Phone phone,
2912 WorkSource workSource, long timeoutInMs) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002913 if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
2914 throw new RuntimeException("This method will deadlock if called from the main thread.");
2915 }
2916
Nathan Harold92bed182018-10-12 18:16:49 -07002917 MainThreadRequest request = null;
2918 if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && phone != null) {
2919 throw new IllegalArgumentException("subId and phone cannot both be specified!");
2920 } else if (phone != null) {
2921 request = new MainThreadRequest(argument, phone, workSource);
2922 } else {
2923 request = new MainThreadRequest(argument, subId, workSource);
2924 }
2925
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002926 Message msg = mMainThreadHandler.obtainMessage(command, request);
2927 msg.sendToTarget();
2928
Rambo Wang0f050d82021-02-12 11:43:36 -08002929
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002930 synchronized (request) {
Rambo Wang0f050d82021-02-12 11:43:36 -08002931 if (timeoutInMs >= 0) {
2932 // Wait for at least timeoutInMs before returning null request result
2933 long now = SystemClock.elapsedRealtime();
2934 long deadline = now + timeoutInMs;
Grace Jia8a0a1e82021-05-23 22:59:52 -07002935 while (request.result == null && now < deadline) {
Rambo Wang0f050d82021-02-12 11:43:36 -08002936 try {
2937 request.wait(deadline - now);
2938 } catch (InterruptedException e) {
2939 // Do nothing, go back and check if request is completed or timeout
2940 } finally {
2941 now = SystemClock.elapsedRealtime();
2942 }
2943 }
2944 } else {
2945 // Wait for the request to complete
2946 while (request.result == null) {
2947 try {
2948 request.wait();
2949 } catch (InterruptedException e) {
2950 // Do nothing, go back and wait until the request is complete
2951 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002952 }
2953 }
2954 }
Rambo Wang0f050d82021-02-12 11:43:36 -08002955 if (request.result == null) {
2956 Log.wtf(LOG_TAG,
2957 "sendRequest: Blocking command timed out. Something has gone terribly wrong.");
2958 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002959 return request.result;
2960 }
2961
2962 /**
2963 * Asynchronous ("fire and forget") version of sendRequest():
2964 * Posts the specified command to be executed on the main thread, and
2965 * returns immediately.
2966 * @see #sendRequest
2967 */
2968 private void sendRequestAsync(int command) {
2969 mMainThreadHandler.sendEmptyMessage(command);
2970 }
2971
2972 /**
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07002973 * Same as {@link #sendRequestAsync(int)} except it takes an argument.
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002974 * @see {@link #sendRequest(int)}
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07002975 */
2976 private void sendRequestAsync(int command, Object argument) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002977 sendRequestAsync(command, argument, null, null);
2978 }
2979
2980 /**
2981 * Same as {@link #sendRequestAsync(int,Object)} except it takes a Phone and WorkSource.
2982 * @see {@link #sendRequest(int,Object)}
2983 */
2984 private void sendRequestAsync(
2985 int command, Object argument, Phone phone, WorkSource workSource) {
2986 MainThreadRequest request = new MainThreadRequest(argument, phone, workSource);
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07002987 Message msg = mMainThreadHandler.obtainMessage(command, request);
2988 msg.sendToTarget();
2989 }
2990
2991 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002992 * Initialize the singleton PhoneInterfaceManager instance.
2993 * This is only done once, at startup, from PhoneApp.onCreate().
2994 */
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002995 /* package */ static PhoneInterfaceManager init(PhoneGlobals app) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002996 synchronized (PhoneInterfaceManager.class) {
2997 if (sInstance == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002998 sInstance = new PhoneInterfaceManager(app);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002999 } else {
3000 Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
3001 }
3002 return sInstance;
3003 }
3004 }
3005
3006 /** Private constructor; @see init() */
Jordan Liu1979a042020-03-20 21:39:35 +00003007 private PhoneInterfaceManager(PhoneGlobals app) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003008 mApp = app;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003009 mCM = PhoneGlobals.getInstance().mCM;
Brad Ebingerd1947d82021-05-17 20:54:49 +00003010 mImsResolver = ImsResolver.getInstance();
Stuart Scott981d8582015-04-21 14:09:50 -07003011 mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003012 mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
Grace Jia0ddb3612021-04-22 13:35:26 -07003013 mPm = app.getSystemService(PackageManager.class);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003014 mMainThreadHandler = new MainThreadHandler();
Jack Yue37dd262022-12-16 11:53:37 -08003015 if (!PhoneFactory.isSubscriptionManagerServiceEnabled()) {
3016 mSubscriptionController = SubscriptionController.getInstance();
3017 } else {
3018 mSubscriptionController = null;
3019 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003020 mTelephonySharedPreferences =
3021 PreferenceManager.getDefaultSharedPreferences(mApp);
yinxub1bed742017-04-17 11:45:04 -07003022 mNetworkScanRequestTracker = new NetworkScanRequestTracker();
Malcolm Chen2c63d402018-08-14 16:00:53 -07003023 mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
Daniel Bright94f43662021-03-01 14:43:40 -08003024 mRadioInterfaceCapabilities = RadioInterfaceCapabilityController.getInstance();
Peter Wanga3cf4ac2020-01-27 09:39:46 +08003025 mNotifyUserActivity = new AtomicBoolean(false);
Tyler Gunn64144d92022-03-17 14:16:41 -07003026 PropertyInvalidatedCache.invalidateCache(TelephonyManager.CACHE_KEY_PHONE_ACCOUNT_TO_SUBID);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003027 publish();
arunvoddud7401012022-12-15 16:08:12 +00003028 CarrierAllowListInfo.loadInstance(mApp);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003029 }
3030
Gil Cukierman1c0eb932022-12-06 22:28:24 +00003031 @VisibleForTesting
3032 public SharedPreferences getSharedPreferences() {
3033 return mTelephonySharedPreferences;
3034 }
3035
Gil Cukierman92cc7db2023-01-06 19:25:53 +00003036 /**
3037 * Get the default phone for this device.
3038 */
3039 @VisibleForTesting
3040 public Phone getDefaultPhone() {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003041 Phone thePhone = getPhone(getDefaultSubscription());
3042 return (thePhone != null) ? thePhone : PhoneFactory.getDefaultPhone();
3043 }
3044
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003045 private void publish() {
3046 if (DBG) log("publish: " + this);
3047
Peter Wangc035ce42020-01-08 21:00:22 -08003048 TelephonyFrameworkInitializer
3049 .getTelephonyServiceManager()
3050 .getTelephonyServiceRegisterer()
3051 .register(this);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003052 }
3053
Stuart Scott584921c2015-01-15 17:10:34 -08003054 private Phone getPhoneFromRequest(MainThreadRequest request) {
Jordan Liu4c733742019-02-28 12:03:40 -08003055 if (request.phone != null) {
3056 return request.phone;
3057 } else {
3058 return getPhoneFromSubId(request.subId);
3059 }
3060 }
3061
3062 private Phone getPhoneFromSubId(int subId) {
3063 return (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
3064 ? getDefaultPhone() : getPhone(subId);
Stuart Scott584921c2015-01-15 17:10:34 -08003065 }
3066
Aishwarya Mallampati5e581e12023-01-17 21:57:06 +00003067 /**
3068 * Get phone object associated with a subscription.
3069 * Return default phone if phone object associated with subscription is null
3070 * @param subId - subscriptionId
3071 * @return phone object associated with a subscription or default phone if null.
3072 */
3073 private Phone getPhoneFromSubIdOrDefault(int subId) {
3074 Phone phone = getPhoneFromSubId(subId);
3075 if (phone == null) {
3076 phone = getDefaultPhone();
3077 }
3078 return phone;
3079 }
3080
Rambo Wange53e07d2022-05-10 13:01:13 -07003081 @Nullable
3082 private UiccPort getUiccPortFromRequest(@NonNull MainThreadRequest request) {
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003083 Phone phone = getPhoneFromRequest(request);
3084 return phone == null ? null :
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00003085 UiccController.getInstance().getUiccPort(phone.getPhoneId());
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003086 }
3087
Wink Saville36469e72014-06-11 15:17:00 -07003088 // returns phone associated with the subId.
Wink Savilleb564aae2014-10-23 10:18:09 -07003089 private Phone getPhone(int subId) {
Jack Yu285100e2022-12-02 22:48:35 -08003090 return PhoneFactory.getPhone(SubscriptionManager.getPhoneId(subId));
Wink Saville36469e72014-06-11 15:17:00 -07003091 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003092
Kai Shif70f46f2021-03-03 13:59:46 -08003093 private void sendEraseModemConfig(@NonNull Phone phone) {
3094 Boolean success = (Boolean) sendRequest(CMD_ERASE_MODEM_CONFIG, null);
3095 if (DBG) log("eraseModemConfig:" + ' ' + (success ? "ok" : "fail"));
3096 }
3097
3098 private void sendEraseDataInSharedPreferences(@NonNull Phone phone) {
3099 Boolean success = (Boolean) sendRequest(CMD_ERASE_DATA_SHARED_PREFERENCES, null);
3100 if (DBG) log("eraseDataInSharedPreferences:" + ' ' + (success ? "ok" : "fail"));
Naina Nallurid63128d2019-09-17 14:10:30 -07003101 }
3102
Peter Wang44b186e2020-01-13 23:33:09 -08003103 private boolean isImsAvailableOnDevice() {
3104 PackageManager pm = getDefaultPhone().getContext().getPackageManager();
3105 if (pm == null) {
3106 // For some reason package manger is not available.. This will fail internally anyway,
3107 // so do not throw error and allow.
3108 return true;
3109 }
3110 return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS, 0);
3111 }
3112
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003113 public void dial(String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07003114 dialForSubscriber(getPreferredVoiceSubscription(), number);
Wink Saville36469e72014-06-11 15:17:00 -07003115 }
3116
Wink Savilleb564aae2014-10-23 10:18:09 -07003117 public void dialForSubscriber(int subId, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003118 if (DBG) log("dial: " + number);
3119 // No permission check needed here: This is just a wrapper around the
3120 // ACTION_DIAL intent, which is available to any app since it puts up
3121 // the UI before it does anything.
3122
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003123 final long identity = Binder.clearCallingIdentity();
3124 try {
3125 String url = createTelUrl(number);
3126 if (url == null) {
3127 return;
3128 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003129
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003130 // PENDING: should we just silently fail if phone is offhook or ringing?
3131 PhoneConstants.State state = mCM.getState(subId);
3132 if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
3133 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
3134 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3135 mApp.startActivity(intent);
3136 }
3137 } finally {
3138 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003139 }
3140 }
3141
3142 public void call(String callingPackage, String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07003143 callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number);
Wink Saville36469e72014-06-11 15:17:00 -07003144 }
3145
Wink Savilleb564aae2014-10-23 10:18:09 -07003146 public void callForSubscriber(int subId, String callingPackage, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003147 if (DBG) log("call: " + number);
3148
3149 // This is just a wrapper around the ACTION_CALL intent, but we still
3150 // need to do a permission check since we're calling startActivity()
3151 // from the context of the phone app.
3152 enforceCallPermission();
3153
Jordan Liu1617b712019-07-10 15:06:26 -07003154 if (mAppOps.noteOp(AppOpsManager.OPSTR_CALL_PHONE, Binder.getCallingUid(), callingPackage)
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003155 != AppOpsManager.MODE_ALLOWED) {
3156 return;
3157 }
3158
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003159 final long identity = Binder.clearCallingIdentity();
3160 try {
3161 String url = createTelUrl(number);
3162 if (url == null) {
3163 return;
3164 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003165
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003166 boolean isValid = false;
3167 final List<SubscriptionInfo> slist = getActiveSubscriptionInfoListPrivileged();
3168 if (slist != null) {
3169 for (SubscriptionInfo subInfoRecord : slist) {
3170 if (subInfoRecord.getSubscriptionId() == subId) {
3171 isValid = true;
3172 break;
3173 }
Wink Saville3ab207e2014-11-20 13:07:20 -08003174 }
Wink Saville08874612014-08-31 19:19:58 -07003175 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003176 if (!isValid) {
3177 return;
3178 }
Wink Saville08874612014-08-31 19:19:58 -07003179
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003180 Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
3181 intent.putExtra(SUBSCRIPTION_KEY, subId);
3182 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3183 mApp.startActivity(intent);
3184 } finally {
3185 Binder.restoreCallingIdentity(identity);
3186 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003187 }
3188
Wink Savilleb564aae2014-10-23 10:18:09 -07003189 public boolean supplyPinForSubscriber(int subId, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07003190 int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07003191 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
3192 }
3193
Wink Savilleb564aae2014-10-23 10:18:09 -07003194 public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07003195 int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07003196 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
3197 }
3198
Wink Savilleb564aae2014-10-23 10:18:09 -07003199 public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003200 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003201
3202 final long identity = Binder.clearCallingIdentity();
3203 try {
Michele Berionne5e411512020-11-13 02:36:59 +00003204 Phone phone = getPhone(subId);
3205 final UnlockSim checkSimPin = new UnlockSim(phone.getPhoneId(), phone.getIccCard());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003206 checkSimPin.start();
3207 return checkSimPin.unlockSim(null, pin);
3208 } finally {
3209 Binder.restoreCallingIdentity(identity);
3210 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003211 }
3212
Wink Savilleb564aae2014-10-23 10:18:09 -07003213 public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003214 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003215
3216 final long identity = Binder.clearCallingIdentity();
3217 try {
Michele Berionne5e411512020-11-13 02:36:59 +00003218 Phone phone = getPhone(subId);
3219 final UnlockSim checkSimPuk = new UnlockSim(phone.getPhoneId(), phone.getIccCard());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003220 checkSimPuk.start();
3221 return checkSimPuk.unlockSim(puk, pin);
3222 } finally {
3223 Binder.restoreCallingIdentity(identity);
3224 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003225 }
3226
3227 /**
Wink Saville9de0f752013-10-22 19:04:03 -07003228 * Helper thread to turn async call to SimCard#supplyPin into
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003229 * a synchronous one.
3230 */
3231 private static class UnlockSim extends Thread {
3232
3233 private final IccCard mSimCard;
Michele Berionne5e411512020-11-13 02:36:59 +00003234 private final int mPhoneId;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003235
3236 private boolean mDone = false;
Wink Saville9de0f752013-10-22 19:04:03 -07003237 private int mResult = PhoneConstants.PIN_GENERAL_FAILURE;
3238 private int mRetryCount = -1;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003239
3240 // For replies from SimCard interface
3241 private Handler mHandler;
3242
3243 // For async handler to identify request type
3244 private static final int SUPPLY_PIN_COMPLETE = 100;
3245
Michele Berionne5e411512020-11-13 02:36:59 +00003246 UnlockSim(int phoneId, IccCard simCard) {
3247 mPhoneId = phoneId;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003248 mSimCard = simCard;
3249 }
3250
3251 @Override
3252 public void run() {
3253 Looper.prepare();
3254 synchronized (UnlockSim.this) {
3255 mHandler = new Handler() {
3256 @Override
3257 public void handleMessage(Message msg) {
3258 AsyncResult ar = (AsyncResult) msg.obj;
3259 switch (msg.what) {
3260 case SUPPLY_PIN_COMPLETE:
3261 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
3262 synchronized (UnlockSim.this) {
Wink Saville9de0f752013-10-22 19:04:03 -07003263 mRetryCount = msg.arg1;
3264 if (ar.exception != null) {
Thomas Nguyen8ee49682023-02-01 11:46:09 -08003265 CommandException.Error error = null;
3266 if (ar.exception instanceof CommandException) {
3267 error = ((CommandException) (ar.exception))
3268 .getCommandError();
3269 }
3270 if (error == CommandException.Error.PASSWORD_INCORRECT) {
Wink Saville9de0f752013-10-22 19:04:03 -07003271 mResult = PhoneConstants.PIN_PASSWORD_INCORRECT;
Thomas Nguyen8ee49682023-02-01 11:46:09 -08003272 } else if (error == CommandException.Error.ABORTED) {
3273 /* When UiccCardApp dispose, handle message and return
3274 exception */
vivi.lib5e9ada2019-09-12 16:04:24 +08003275 mResult = PhoneConstants.PIN_OPERATION_ABORTED;
Wink Saville9de0f752013-10-22 19:04:03 -07003276 } else {
3277 mResult = PhoneConstants.PIN_GENERAL_FAILURE;
3278 }
3279 } else {
3280 mResult = PhoneConstants.PIN_RESULT_SUCCESS;
3281 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003282 mDone = true;
3283 UnlockSim.this.notifyAll();
3284 }
3285 break;
3286 }
3287 }
3288 };
3289 UnlockSim.this.notifyAll();
3290 }
3291 Looper.loop();
3292 }
3293
3294 /*
3295 * Use PIN or PUK to unlock SIM card
3296 *
3297 * If PUK is null, unlock SIM card with PIN
3298 *
3299 * If PUK is not null, unlock SIM card with PUK and set PIN code
3300 */
Wink Saville9de0f752013-10-22 19:04:03 -07003301 synchronized int[] unlockSim(String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003302
3303 while (mHandler == null) {
3304 try {
3305 wait();
3306 } catch (InterruptedException e) {
3307 Thread.currentThread().interrupt();
3308 }
3309 }
3310 Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
3311
3312 if (puk == null) {
3313 mSimCard.supplyPin(pin, callback);
3314 } else {
3315 mSimCard.supplyPuk(puk, pin, callback);
3316 }
3317
3318 while (!mDone) {
3319 try {
3320 Log.d(LOG_TAG, "wait for done");
3321 wait();
3322 } catch (InterruptedException e) {
3323 // Restore the interrupted status
3324 Thread.currentThread().interrupt();
3325 }
3326 }
3327 Log.d(LOG_TAG, "done");
Wink Saville9de0f752013-10-22 19:04:03 -07003328 int[] resultArray = new int[2];
3329 resultArray[0] = mResult;
3330 resultArray[1] = mRetryCount;
Michele Berionne5e411512020-11-13 02:36:59 +00003331
3332 if (mResult == PhoneConstants.PIN_RESULT_SUCCESS && pin.length() > 0) {
Jon Spivack9c3bc762021-10-06 20:53:09 +00003333 UiccController.getInstance().getPinStorage().storePin(pin, mPhoneId);
Michele Berionne5e411512020-11-13 02:36:59 +00003334 }
3335
Wink Saville9de0f752013-10-22 19:04:03 -07003336 return resultArray;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003337 }
3338 }
3339
Nathan Harold7c8d0f12020-05-28 20:40:31 -07003340 /**
3341 * This method has been removed due to privacy and stability concerns.
3342 */
3343 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003344 public void updateServiceLocation() {
Nathan Harold7c8d0f12020-05-28 20:40:31 -07003345 Log.e(LOG_TAG, "Call to unsupported method updateServiceLocation()");
3346 return;
Wink Saville36469e72014-06-11 15:17:00 -07003347 }
3348
Nathan Harold1f889d82020-06-04 17:05:26 -07003349 @Override
3350 public void updateServiceLocationWithPackageName(String callingPackage) {
3351 mApp.getSystemService(AppOpsManager.class)
3352 .checkPackage(Binder.getCallingUid(), callingPackage);
3353
Nathan Haroldf096d982020-11-18 17:18:06 -08003354 final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
Nathan Harold1f889d82020-06-04 17:05:26 -07003355 if (targetSdk > android.os.Build.VERSION_CODES.R) {
3356 // Callers targeting S have no business invoking this method.
3357 return;
3358 }
3359
3360 LocationAccessPolicy.LocationPermissionResult locationResult =
3361 LocationAccessPolicy.checkLocationPermission(mApp,
3362 new LocationAccessPolicy.LocationPermissionQuery.Builder()
3363 .setCallingPackage(callingPackage)
3364 .setCallingFeatureId(null)
3365 .setCallingPid(Binder.getCallingPid())
3366 .setCallingUid(Binder.getCallingUid())
3367 .setMethod("updateServiceLocation")
3368 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
3369 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
3370 .build());
3371 // Apps that lack location permission have no business calling this method;
3372 // however, because no permission was declared in the public API, denials must
3373 // all be "soft".
3374 switch (locationResult) {
3375 case DENIED_HARD: /* fall through */
3376 case DENIED_SOFT:
3377 return;
3378 }
3379
3380 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003381 final long identity = Binder.clearCallingIdentity();
3382 try {
Nathan Harold1f889d82020-06-04 17:05:26 -07003383 final Phone phone = getPhone(getDefaultSubscription());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003384 if (phone != null) {
Nathan Harold1f889d82020-06-04 17:05:26 -07003385 phone.updateServiceLocation(workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003386 }
3387 } finally {
3388 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003389 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003390 }
3391
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003392 @Deprecated
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003393 @Override
3394 public boolean isRadioOn(String callingPackage) {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003395 return isRadioOnWithFeature(callingPackage, null);
3396 }
3397
3398
3399 @Override
3400 public boolean isRadioOnWithFeature(String callingPackage, String callingFeatureId) {
3401 return isRadioOnForSubscriberWithFeature(getDefaultSubscription(), callingPackage,
3402 callingFeatureId);
3403 }
3404
3405 @Deprecated
3406 @Override
3407 public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
3408 return isRadioOnForSubscriberWithFeature(subId, callingPackage, null);
Wink Saville36469e72014-06-11 15:17:00 -07003409 }
3410
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003411 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003412 public boolean isRadioOnForSubscriberWithFeature(int subId, String callingPackage,
3413 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003414 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003415 mApp, subId, callingPackage, callingFeatureId, "isRadioOnForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003416 return false;
3417 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003418
3419 final long identity = Binder.clearCallingIdentity();
3420 try {
3421 return isRadioOnForSubscriber(subId);
3422 } finally {
3423 Binder.restoreCallingIdentity(identity);
3424 }
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003425 }
3426
3427 private boolean isRadioOnForSubscriber(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003428 final long identity = Binder.clearCallingIdentity();
3429 try {
3430 final Phone phone = getPhone(subId);
3431 if (phone != null) {
3432 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
3433 } else {
3434 return false;
3435 }
3436 } finally {
3437 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003438 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003439 }
3440
3441 public void toggleRadioOnOff() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07003442 toggleRadioOnOffForSubscriber(getDefaultSubscription());
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003443 }
Wink Saville36469e72014-06-11 15:17:00 -07003444
Wink Savilleb564aae2014-10-23 10:18:09 -07003445 public void toggleRadioOnOffForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003446 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003447
3448 final long identity = Binder.clearCallingIdentity();
3449 try {
3450 final Phone phone = getPhone(subId);
3451 if (phone != null) {
3452 phone.setRadioPower(!isRadioOnForSubscriber(subId));
3453 }
3454 } finally {
3455 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003456 }
Wink Saville36469e72014-06-11 15:17:00 -07003457 }
3458
3459 public boolean setRadio(boolean turnOn) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07003460 return setRadioForSubscriber(getDefaultSubscription(), turnOn);
Wink Saville36469e72014-06-11 15:17:00 -07003461 }
3462
Wink Savilleb564aae2014-10-23 10:18:09 -07003463 public boolean setRadioForSubscriber(int subId, boolean turnOn) {
Wink Saville36469e72014-06-11 15:17:00 -07003464 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003465
3466 final long identity = Binder.clearCallingIdentity();
3467 try {
3468 final Phone phone = getPhone(subId);
3469 if (phone == null) {
3470 return false;
3471 }
3472 if ((phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF) != turnOn) {
3473 toggleRadioOnOffForSubscriber(subId);
3474 }
3475 return true;
3476 } finally {
3477 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003478 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003479 }
Wink Saville36469e72014-06-11 15:17:00 -07003480
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07003481 public boolean needMobileRadioShutdown() {
Shuo Qianfa7b6b32019-12-10 10:40:38 -08003482 enforceReadPrivilegedPermission("needMobileRadioShutdown");
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07003483 /*
3484 * If any of the Radios are available, it will need to be
3485 * shutdown. So return true if any Radio is available.
3486 */
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003487 final long identity = Binder.clearCallingIdentity();
3488 try {
3489 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
3490 Phone phone = PhoneFactory.getPhone(i);
3491 if (phone != null && phone.isRadioAvailable()) return true;
3492 }
3493 logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown.");
3494 return false;
3495 } finally {
3496 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07003497 }
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07003498 }
3499
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003500 @Override
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07003501 public void shutdownMobileRadios() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003502 enforceModifyPermission();
3503
3504 final long identity = Binder.clearCallingIdentity();
3505 try {
3506 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
3507 logv("Shutting down Phone " + i);
3508 shutdownRadioUsingPhoneId(i);
3509 }
3510 } finally {
3511 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07003512 }
3513 }
3514
3515 private void shutdownRadioUsingPhoneId(int phoneId) {
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07003516 Phone phone = PhoneFactory.getPhone(phoneId);
3517 if (phone != null && phone.isRadioAvailable()) {
3518 phone.shutdownRadio();
3519 }
3520 }
3521
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003522 public boolean setRadioPower(boolean turnOn) {
Jack Yub4e16162017-05-15 12:48:40 -07003523 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003524
Ling Ma83dc5ea2023-01-12 15:06:04 -08003525 if (!turnOn) {
3526 log("setRadioPower off: callingPackage=" + getCurrentPackageName());
3527 }
3528
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003529 final long identity = Binder.clearCallingIdentity();
3530 try {
3531 final Phone defaultPhone = PhoneFactory.getDefaultPhone();
3532 if (defaultPhone != null) {
3533 defaultPhone.setRadioPower(turnOn);
3534 return true;
3535 } else {
3536 loge("There's no default phone.");
3537 return false;
3538 }
3539 } finally {
3540 Binder.restoreCallingIdentity(identity);
Wei Liu9ae2a062016-08-08 11:09:34 -07003541 }
Wink Saville36469e72014-06-11 15:17:00 -07003542 }
3543
Wink Savilleb564aae2014-10-23 10:18:09 -07003544 public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003545 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003546
Ling Ma83dc5ea2023-01-12 15:06:04 -08003547 if (!turnOn) {
3548 log("setRadioPowerForSubscriber off: subId=" + subId
3549 + ",callingPackage=" + getCurrentPackageName());
3550 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003551 final long identity = Binder.clearCallingIdentity();
3552 try {
3553 final Phone phone = getPhone(subId);
3554 if (phone != null) {
3555 phone.setRadioPower(turnOn);
3556 return true;
3557 } else {
3558 return false;
3559 }
3560 } finally {
3561 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003562 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003563 }
3564
Thomas Nguyenfd0572f2022-07-15 22:28:49 +00003565 /**
3566 * Vote on powering off the radio for a reason. The radio will be turned on only when there is
3567 * no reason to power it off. When any of the voters want to power it off, it will be turned
3568 * off. In case of emergency, the radio will be turned on even if there are some reasons for
3569 * powering it off, and these radio off votes will be cleared.
3570 * Multiple apps can vote for the same reason and the last vote will take effect. Each app is
3571 * responsible for its vote. A powering-off vote of a reason will be maintained until it is
3572 * cleared by calling {@link clearRadioPowerOffForReason} for that reason, or an emergency call
3573 * is made, or the device is rebooted. When an app comes backup from a crash, it needs to make
3574 * sure if its vote is as expected. An app can use the API {@link getRadioPowerOffReasons} to
3575 * check its vote.
3576 *
3577 * @param subId The subscription ID.
3578 * @param reason The reason for powering off radio.
3579 * @return true on success and false on failure.
3580 */
3581 public boolean requestRadioPowerOffForReason(int subId,
3582 @TelephonyManager.RadioPowerReason int reason) {
3583 enforceModifyPermission();
3584
Ling Ma83dc5ea2023-01-12 15:06:04 -08003585 log("requestRadioPowerOffForReason: subId=" + subId
3586 + ",reason=" + reason + ",callingPackage=" + getCurrentPackageName());
Thomas Nguyenfd0572f2022-07-15 22:28:49 +00003587 final long identity = Binder.clearCallingIdentity();
3588 try {
3589 final Phone phone = getPhone(subId);
3590 if (phone != null) {
3591 phone.setRadioPowerForReason(false, reason);
3592 return true;
3593 } else {
3594 return false;
3595 }
3596 } finally {
3597 Binder.restoreCallingIdentity(identity);
3598 }
3599 }
3600
3601 /**
3602 * Remove the vote on powering off the radio for a reason, as requested by
3603 * {@link requestRadioPowerOffForReason}.
3604 *
3605 * @param subId The subscription ID.
3606 * @param reason The reason for powering off radio.
3607 * @return true on success and false on failure.
3608 */
3609 public boolean clearRadioPowerOffForReason(int subId,
3610 @TelephonyManager.RadioPowerReason int reason) {
3611 enforceModifyPermission();
3612
3613 final long identity = Binder.clearCallingIdentity();
3614 try {
3615 final Phone phone = getPhone(subId);
3616 if (phone != null) {
3617 phone.setRadioPowerForReason(true, reason);
3618 return true;
3619 } else {
3620 return false;
3621 }
3622 } finally {
3623 Binder.restoreCallingIdentity(identity);
3624 }
3625 }
3626
3627 /**
3628 * Get reasons for powering off radio, as requested by {@link requestRadioPowerOffForReason}.
3629 *
3630 * @param subId The subscription ID.
3631 * @param callingPackage The package making the call.
3632 * @param callingFeatureId The feature in the package.
3633 * @return List of reasons for powering off radio.
3634 */
3635 public List getRadioPowerOffReasons(int subId, String callingPackage, String callingFeatureId) {
3636 enforceReadPrivilegedPermission("getRadioPowerOffReasons");
3637
3638 final long identity = Binder.clearCallingIdentity();
3639 List result = new ArrayList();
3640 try {
3641 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId,
3642 callingPackage, callingFeatureId, "getRadioPowerOffReasons")) {
3643 return result;
3644 }
3645
3646 final Phone phone = getPhone(subId);
3647 if (phone != null) {
3648 result.addAll(phone.getRadioPowerOffReasons());
3649 }
3650 } finally {
3651 Binder.restoreCallingIdentity(identity);
3652 }
3653 return result;
3654 }
3655
Wink Saville36469e72014-06-11 15:17:00 -07003656 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07003657 @Override
Sarah Chinecc78c42022-03-31 21:16:48 -07003658 public boolean enableDataConnectivity(String callingPackage) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003659 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003660
3661 final long identity = Binder.clearCallingIdentity();
3662 try {
Jack Yu285100e2022-12-02 22:48:35 -08003663 int subId = SubscriptionManager.getDefaultDataSubscriptionId();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003664 final Phone phone = getPhone(subId);
3665 if (phone != null) {
Jack Yu7968c6d2022-07-31 00:43:21 -07003666 phone.getDataSettingsManager().setDataEnabled(
3667 TelephonyManager.DATA_ENABLED_REASON_USER, true, callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003668 return true;
3669 } else {
3670 return false;
3671 }
3672 } finally {
3673 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003674 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003675 }
3676
Wink Saville36469e72014-06-11 15:17:00 -07003677 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07003678 @Override
Sarah Chinecc78c42022-03-31 21:16:48 -07003679 public boolean disableDataConnectivity(String callingPackage) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003680 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003681
3682 final long identity = Binder.clearCallingIdentity();
3683 try {
Jack Yu285100e2022-12-02 22:48:35 -08003684 int subId = SubscriptionManager.getDefaultDataSubscriptionId();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003685 final Phone phone = getPhone(subId);
3686 if (phone != null) {
Jack Yu7968c6d2022-07-31 00:43:21 -07003687 phone.getDataSettingsManager().setDataEnabled(
3688 TelephonyManager.DATA_ENABLED_REASON_USER, false, callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003689 return true;
3690 } else {
3691 return false;
3692 }
3693 } finally {
3694 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003695 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003696 }
3697
Sanket Padawe356d7632015-06-22 14:03:32 -07003698 @Override
Jack Yuacf8a132017-05-01 17:00:48 -07003699 public boolean isDataConnectivityPossible(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003700 final long identity = Binder.clearCallingIdentity();
3701 try {
3702 final Phone phone = getPhone(subId);
3703 if (phone != null) {
Jack Yu59824e12022-03-23 01:42:44 -07003704 return phone.isDataAllowed();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003705 } else {
3706 return false;
3707 }
3708 } finally {
3709 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003710 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003711 }
3712
3713 public boolean handlePinMmi(String dialString) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07003714 return handlePinMmiForSubscriber(getDefaultSubscription(), dialString);
Wink Saville36469e72014-06-11 15:17:00 -07003715 }
3716
pkanwarae03a6b2016-11-06 20:37:09 -08003717 public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003718 enforceCallPermission();
3719
3720 final long identity = Binder.clearCallingIdentity();
3721 try {
3722 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3723 return;
3724 }
3725 Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback);
3726 sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId);
3727 } finally {
3728 Binder.restoreCallingIdentity(identity);
3729 }
pkanwar32d516d2016-10-14 19:37:38 -07003730 };
3731
Wink Savilleb564aae2014-10-23 10:18:09 -07003732 public boolean handlePinMmiForSubscriber(int subId, String dialString) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003733 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003734
3735 final long identity = Binder.clearCallingIdentity();
3736 try {
3737 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3738 return false;
3739 }
3740 return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
3741 } finally {
3742 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003743 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003744 }
3745
Brad Ebinger4f6208e2021-03-23 21:04:45 +00003746 /**
3747 * @deprecated This method is deprecated and is only being kept due to an UnsupportedAppUsage
3748 * tag on getCallState Binder call.
3749 */
3750 @Deprecated
3751 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003752 public int getCallState() {
Brad Ebinger4f6208e2021-03-23 21:04:45 +00003753 if (CompatChanges.isChangeEnabled(
3754 TelecomManager.ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION,
3755 Binder.getCallingUid())) {
3756 // Do not allow this API to be called on API version 31+, it should only be
3757 // called on old apps using this Binder call directly.
3758 throw new SecurityException("This method can only be used for applications "
3759 + "targeting API version 30 or less.");
3760 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003761 final long identity = Binder.clearCallingIdentity();
3762 try {
Brad Ebinger4f6208e2021-03-23 21:04:45 +00003763 Phone phone = getPhone(getDefaultSubscription());
3764 return phone == null ? TelephonyManager.CALL_STATE_IDLE :
3765 PhoneConstantConversions.convertCallState(phone.getState());
3766 } finally {
3767 Binder.restoreCallingIdentity(identity);
3768 }
3769 }
3770
3771 @Override
3772 public int getCallStateForSubscription(int subId, String callingPackage, String featureId) {
3773 if (CompatChanges.isChangeEnabled(
3774 TelecomManager.ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION,
3775 Binder.getCallingUid())) {
3776 // Check READ_PHONE_STATE for API version 31+
3777 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
3778 featureId, "getCallStateForSubscription")) {
3779 throw new SecurityException("getCallState requires READ_PHONE_STATE for apps "
3780 + "targeting API level 31+.");
3781 }
3782 }
3783 final long identity = Binder.clearCallingIdentity();
3784 try {
3785 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003786 return phone == null ? TelephonyManager.CALL_STATE_IDLE :
3787 PhoneConstantConversions.convertCallState(phone.getState());
3788 } finally {
3789 Binder.restoreCallingIdentity(identity);
3790 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003791 }
3792
Sanket Padawe356d7632015-06-22 14:03:32 -07003793 @Override
Nathan Harolde037c472019-06-26 00:41:07 +00003794 public int getDataState() {
Jack Yu285100e2022-12-02 22:48:35 -08003795 return getDataStateForSubId(SubscriptionManager.getDefaultDataSubscriptionId());
Nathan Haroldc4689b12019-06-14 16:58:30 -07003796 }
3797
3798 @Override
3799 public int getDataStateForSubId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003800 final long identity = Binder.clearCallingIdentity();
3801 try {
Nathan Haroldc4689b12019-06-14 16:58:30 -07003802 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003803 if (phone != null) {
Jack Yu7968c6d2022-07-31 00:43:21 -07003804 return phone.getDataNetworkController().getInternetDataNetworkState();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003805 } else {
3806 return PhoneConstantConversions.convertDataState(
3807 PhoneConstants.DataState.DISCONNECTED);
3808 }
3809 } finally {
3810 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003811 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003812 }
3813
Sanket Padawe356d7632015-06-22 14:03:32 -07003814 @Override
Jack Yu0eda6842022-04-18 00:34:46 -07003815 public @DataActivityType int getDataActivity() {
Jack Yu285100e2022-12-02 22:48:35 -08003816 return getDataActivityForSubId(SubscriptionManager.getDefaultDataSubscriptionId());
Nathan Haroldc4689b12019-06-14 16:58:30 -07003817 }
3818
3819 @Override
Jack Yu0eda6842022-04-18 00:34:46 -07003820 public @DataActivityType int getDataActivityForSubId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003821 final long identity = Binder.clearCallingIdentity();
3822 try {
Nathan Haroldc4689b12019-06-14 16:58:30 -07003823 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003824 if (phone != null) {
Jack Yu0eda6842022-04-18 00:34:46 -07003825 return phone.getDataActivityState();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003826 } else {
3827 return TelephonyManager.DATA_ACTIVITY_NONE;
3828 }
3829 } finally {
3830 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003831 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003832 }
3833
3834 @Override
Meng Wanga10e89e2019-12-09 13:13:01 -08003835 public CellIdentity getCellLocation(String callingPackage, String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003836 mApp.getSystemService(AppOpsManager.class)
Hall Liu1aa510f2017-11-22 17:40:08 -08003837 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08003838
3839 LocationAccessPolicy.LocationPermissionResult locationResult =
3840 LocationAccessPolicy.checkLocationPermission(mApp,
3841 new LocationAccessPolicy.LocationPermissionQuery.Builder()
3842 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003843 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08003844 .setCallingPid(Binder.getCallingPid())
3845 .setCallingUid(Binder.getCallingUid())
3846 .setMethod("getCellLocation")
Hall Liu773ba022020-01-24 18:07:12 -08003847 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
Hall Liuf19c44f2018-11-27 14:38:17 -08003848 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
3849 .build());
3850 switch (locationResult) {
3851 case DENIED_HARD:
3852 throw new SecurityException("Not allowed to access cell location");
3853 case DENIED_SOFT:
Meng Wanga10e89e2019-12-09 13:13:01 -08003854 return (getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
3855 ? new CellIdentityCdma() : new CellIdentityGsm();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003856 }
3857
Narayan Kamathf04b5a12018-01-09 11:47:15 +00003858 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003859 final long identity = Binder.clearCallingIdentity();
3860 try {
3861 if (DBG_LOC) log("getCellLocation: is active user");
Jack Yu285100e2022-12-02 22:48:35 -08003862 int subId = SubscriptionManager.getDefaultDataSubscriptionId();
Meng Wanga10e89e2019-12-09 13:13:01 -08003863 return (CellIdentity) sendRequest(CMD_GET_CELL_LOCATION, workSource, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003864 } finally {
3865 Binder.restoreCallingIdentity(identity);
3866 }
Svetoslav64fad262015-04-14 14:35:21 -07003867 }
3868
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003869 @Override
Jack Yueb1e7fe2020-02-22 19:38:58 -08003870 public String getNetworkCountryIsoForPhone(int phoneId) {
Jonathan Basseribf5362b2017-07-19 12:22:35 -07003871 // Reporting the correct network country is ambiguous when IWLAN could conflict with
3872 // registered cell info, so return a NULL country instead.
3873 final long identity = Binder.clearCallingIdentity();
3874 try {
Malcolm Chen3732c2b2018-07-18 20:15:24 -07003875 if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
3876 // Get default phone in this case.
3877 phoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
3878 }
Jack Yu285100e2022-12-02 22:48:35 -08003879 final int subId = SubscriptionManager.getSubscriptionId(phoneId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003880 Phone phone = PhoneFactory.getPhone(phoneId);
Nathan Harold532f51c2020-04-21 19:31:10 -07003881 if (phone == null) return "";
3882 ServiceStateTracker sst = phone.getServiceStateTracker();
3883 if (sst == null) return "";
3884 LocaleTracker lt = sst.getLocaleTracker();
3885 if (lt == null) return "";
Shuo Qian9418a922021-03-09 11:21:16 -08003886 return lt.getCurrentCountry();
Jonathan Basseribf5362b2017-07-19 12:22:35 -07003887 } finally {
3888 Binder.restoreCallingIdentity(identity);
3889 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07003890 }
3891
Nathan Harold7c8d0f12020-05-28 20:40:31 -07003892 /**
3893 * This method was removed due to potential issues caused by performing partial
3894 * updates of service state, and lack of a credible use case.
3895 *
3896 * This has the ability to break the telephony implementation by disabling notification of
3897 * changes in device connectivity. DO NOT USE THIS!
3898 */
Jonathan Basseribf5362b2017-07-19 12:22:35 -07003899 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003900 public void enableLocationUpdates() {
3901 mApp.enforceCallingOrSelfPermission(
3902 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003903 }
3904
Nathan Harold7c8d0f12020-05-28 20:40:31 -07003905 /**
3906 * This method was removed due to potential issues caused by performing partial
3907 * updates of service state, and lack of a credible use case.
3908 *
3909 * This has the ability to break the telephony implementation by disabling notification of
3910 * changes in device connectivity. DO NOT USE THIS!
3911 */
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003912 @Override
3913 public void disableLocationUpdates() {
3914 mApp.enforceCallingOrSelfPermission(
3915 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003916 }
3917
3918 @Override
3919 @SuppressWarnings("unchecked")
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003920 public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage,
3921 String callingFeatureId) {
Nathan Haroldb55f63b2021-07-27 11:27:38 -07003922 try {
3923 mApp.getSystemService(AppOpsManager.class)
3924 .checkPackage(Binder.getCallingUid(), callingPackage);
3925 } catch (SecurityException e) {
3926 EventLog.writeEvent(0x534e4554, "190619791", Binder.getCallingUid());
3927 throw e;
3928 }
3929
Nathan Haroldf096d982020-11-18 17:18:06 -08003930 final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
Nathan Harolddbea45a2018-08-30 14:35:07 -07003931 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
3932 throw new SecurityException(
3933 "getNeighboringCellInfo() is unavailable to callers targeting Q+ SDK levels.");
3934 }
Nathan Haroldb4d55612018-07-20 13:13:08 -07003935
Jordan Liu1617b712019-07-10 15:06:26 -07003936 if (mAppOps.noteOp(AppOpsManager.OPSTR_NEIGHBORING_CELLS, Binder.getCallingUid(),
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003937 callingPackage) != AppOpsManager.MODE_ALLOWED) {
3938 return null;
3939 }
Svetoslav64fad262015-04-14 14:35:21 -07003940
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07003941 if (DBG_LOC) log("getNeighboringCellInfo: is active user");
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003942
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003943 List<CellInfo> info = getAllCellInfo(callingPackage, callingFeatureId);
Nathan Haroldf180aac2018-06-01 18:43:55 -07003944 if (info == null) return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003945
Nathan Haroldf180aac2018-06-01 18:43:55 -07003946 List<NeighboringCellInfo> neighbors = new ArrayList<NeighboringCellInfo>();
3947 for (CellInfo ci : info) {
3948 if (ci instanceof CellInfoGsm) {
3949 neighbors.add(new NeighboringCellInfo((CellInfoGsm) ci));
3950 } else if (ci instanceof CellInfoWcdma) {
3951 neighbors.add(new NeighboringCellInfo((CellInfoWcdma) ci));
3952 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003953 }
Nathan Haroldf180aac2018-06-01 18:43:55 -07003954 return (neighbors.size()) > 0 ? neighbors : null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003955 }
3956
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07003957 private List<CellInfo> getCachedCellInfo() {
3958 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
3959 for (Phone phone : PhoneFactory.getPhones()) {
3960 List<CellInfo> info = phone.getAllCellInfo();
3961 if (info != null) cellInfos.addAll(info);
3962 }
3963 return cellInfos;
3964 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003965
3966 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003967 public List<CellInfo> getAllCellInfo(String callingPackage, String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003968 mApp.getSystemService(AppOpsManager.class)
Hall Liu1aa510f2017-11-22 17:40:08 -08003969 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08003970
3971 LocationAccessPolicy.LocationPermissionResult locationResult =
3972 LocationAccessPolicy.checkLocationPermission(mApp,
3973 new LocationAccessPolicy.LocationPermissionQuery.Builder()
3974 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003975 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08003976 .setCallingPid(Binder.getCallingPid())
3977 .setCallingUid(Binder.getCallingUid())
3978 .setMethod("getAllCellInfo")
Nathan Harold5ae50b52019-02-20 15:46:36 -08003979 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
Hall Liuf19c44f2018-11-27 14:38:17 -08003980 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
3981 .build());
3982 switch (locationResult) {
3983 case DENIED_HARD:
3984 throw new SecurityException("Not allowed to access cell info");
3985 case DENIED_SOFT:
3986 return new ArrayList<>();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003987 }
3988
Nathan Haroldf096d982020-11-18 17:18:06 -08003989 final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07003990 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
3991 return getCachedCellInfo();
3992 }
3993
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07003994 if (DBG_LOC) log("getAllCellInfo: is active user");
Narayan Kamathf04b5a12018-01-09 11:47:15 +00003995 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003996 final long identity = Binder.clearCallingIdentity();
3997 try {
3998 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
3999 for (Phone phone : PhoneFactory.getPhones()) {
Nathan Harold3ff88932018-08-14 10:19:49 -07004000 final List<CellInfo> info = (List<CellInfo>) sendRequest(
Nathan Harold92bed182018-10-12 18:16:49 -07004001 CMD_GET_ALL_CELL_INFO, null, phone, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004002 if (info != null) cellInfos.addAll(info);
4003 }
4004 return cellInfos;
4005 } finally {
4006 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004007 }
4008 }
4009
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07004010 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07004011 public void requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage,
4012 String callingFeatureId) {
4013 requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId,
4014 getWorkSource(Binder.getCallingUid()));
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07004015 }
4016
4017 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07004018 public void requestCellInfoUpdateWithWorkSource(int subId, ICellInfoCallback cb,
4019 String callingPackage, String callingFeatureId, WorkSource workSource) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07004020 enforceModifyPermission();
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07004021 requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId, workSource);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07004022 }
4023
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07004024 private void requestCellInfoUpdateInternal(int subId, ICellInfoCallback cb,
4025 String callingPackage, String callingFeatureId, WorkSource workSource) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004026 mApp.getSystemService(AppOpsManager.class)
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07004027 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08004028
4029 LocationAccessPolicy.LocationPermissionResult locationResult =
4030 LocationAccessPolicy.checkLocationPermission(mApp,
4031 new LocationAccessPolicy.LocationPermissionQuery.Builder()
4032 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07004033 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08004034 .setCallingPid(Binder.getCallingPid())
4035 .setCallingUid(Binder.getCallingUid())
4036 .setMethod("requestCellInfoUpdate")
Hall Liud60acc92020-05-21 17:09:35 -07004037 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
4038 .setMinSdkVersionForFine(Build.VERSION_CODES.BASE)
Hall Liuf19c44f2018-11-27 14:38:17 -08004039 .build());
4040 switch (locationResult) {
4041 case DENIED_HARD:
Nathan Haroldf096d982020-11-18 17:18:06 -08004042 if (TelephonyPermissions
4043 .getTargetSdk(mApp, callingPackage) < Build.VERSION_CODES.Q) {
Hall Liud60acc92020-05-21 17:09:35 -07004044 // Safetynet logging for b/154934934
4045 EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
4046 }
Hall Liuf19c44f2018-11-27 14:38:17 -08004047 throw new SecurityException("Not allowed to access cell info");
4048 case DENIED_SOFT:
Nathan Haroldf096d982020-11-18 17:18:06 -08004049 if (TelephonyPermissions
4050 .getTargetSdk(mApp, callingPackage) < Build.VERSION_CODES.Q) {
Hall Liud60acc92020-05-21 17:09:35 -07004051 // Safetynet logging for b/154934934
4052 EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
4053 }
Nathan Harold5320c422019-05-09 10:26:08 -07004054 try {
4055 cb.onCellInfo(new ArrayList<CellInfo>());
4056 } catch (RemoteException re) {
4057 // Drop without consequences
4058 }
Hall Liuf19c44f2018-11-27 14:38:17 -08004059 return;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07004060 }
4061
Nathan Harolda939a962019-05-09 10:13:47 -07004062
4063 final Phone phone = getPhoneFromSubId(subId);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07004064 if (phone == null) throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
4065
4066 sendRequestAsync(CMD_REQUEST_CELL_INFO_UPDATE, cb, phone, workSource);
4067 }
4068
4069 @Override
Aishwarya Mallampati0603fb12022-08-24 21:16:56 +00004070 public void setCellInfoListRate(int rateInMillis, int subId) {
Jack Yua8d8cb82017-01-16 10:15:34 -08004071 enforceModifyPermission();
Narayan Kamathf04b5a12018-01-09 11:47:15 +00004072 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004073
4074 final long identity = Binder.clearCallingIdentity();
4075 try {
Aishwarya Mallampati0603fb12022-08-24 21:16:56 +00004076 Phone phone = getPhone(subId);
4077 if (phone == null) {
4078 getDefaultPhone().setCellInfoListRate(rateInMillis, workSource);
4079 } else {
4080 phone.setCellInfoListRate(rateInMillis, workSource);
4081 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004082 } finally {
4083 Binder.restoreCallingIdentity(identity);
4084 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004085 }
4086
Shishir Agrawala9f32182016-04-12 12:00:16 -07004087 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004088 public String getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
Jeff Davidson913390f2018-02-23 17:11:49 -08004089 Phone phone = PhoneFactory.getPhone(slotIndex);
4090 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004091 return null;
4092 }
Jeff Davidson913390f2018-02-23 17:11:49 -08004093 int subId = phone.getSubId();
Grace Jia0ddb3612021-04-22 13:35:26 -07004094 enforceCallingPackage(callingPackage, Binder.getCallingUid(), "getImeiForSlot");
Michael Groover70af6dc2018-10-01 16:23:15 -07004095 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004096 callingPackage, callingFeatureId, "getImeiForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08004097 return null;
4098 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004099
4100 final long identity = Binder.clearCallingIdentity();
4101 try {
4102 return phone.getImei();
4103 } finally {
4104 Binder.restoreCallingIdentity(identity);
4105 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07004106 }
4107
4108 @Override
arunvoddud5c6ce02022-12-11 06:03:12 +00004109 public String getPrimaryImei(String callingPackage, String callingFeatureId) {
4110 enforceCallingPackage(callingPackage, Binder.getCallingUid(), "getPrimaryImei");
4111 if (!checkCallingOrSelfReadDeviceIdentifiersForAnySub(mApp, callingPackage,
4112 callingFeatureId, "getPrimaryImei")) {
4113 throw new SecurityException("Caller does not have permission");
4114 }
4115 final long identity = Binder.clearCallingIdentity();
4116 try {
4117 for (Phone phone : PhoneFactory.getPhones()) {
4118 if (phone.getImeiType() == Phone.IMEI_TYPE_PRIMARY) {
4119 return phone.getImei();
4120 }
4121 }
4122 throw new UnsupportedOperationException("Operation not supported");
4123 } finally {
4124 Binder.restoreCallingIdentity(identity);
4125 }
4126 }
4127
4128 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00004129 public String getTypeAllocationCodeForSlot(int slotIndex) {
4130 Phone phone = PhoneFactory.getPhone(slotIndex);
4131 String tac = null;
4132 if (phone != null) {
4133 String imei = phone.getImei();
Vala Zadehab005552021-09-21 15:54:29 -07004134 try {
4135 tac = imei == null ? null : imei.substring(0, TYPE_ALLOCATION_CODE_LENGTH);
4136 } catch (IndexOutOfBoundsException e) {
4137 Log.e(LOG_TAG, "IMEI length shorter than upper index.");
4138 return null;
4139 }
David Kelly5e06a7f2018-03-12 14:10:59 +00004140 }
4141 return tac;
4142 }
4143
4144 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004145 public String getMeidForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
Shuo Qian13d89152021-05-10 23:58:11 -07004146 try {
4147 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4148 } catch (SecurityException se) {
4149 EventLog.writeEvent(0x534e4554, "186530496", Binder.getCallingUid());
4150 throw new SecurityException("Package " + callingPackage + " does not belong to "
4151 + Binder.getCallingUid());
4152 }
Jeff Davidson913390f2018-02-23 17:11:49 -08004153 Phone phone = PhoneFactory.getPhone(slotIndex);
4154 if (phone == null) {
Jack Yu2af8d712017-03-15 17:14:14 -07004155 return null;
4156 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004157
Jeff Davidson913390f2018-02-23 17:11:49 -08004158 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07004159 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004160 callingPackage, callingFeatureId, "getMeidForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08004161 return null;
4162 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004163
4164 final long identity = Binder.clearCallingIdentity();
4165 try {
4166 return phone.getMeid();
4167 } finally {
4168 Binder.restoreCallingIdentity(identity);
4169 }
Jack Yu2af8d712017-03-15 17:14:14 -07004170 }
4171
4172 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00004173 public String getManufacturerCodeForSlot(int slotIndex) {
4174 Phone phone = PhoneFactory.getPhone(slotIndex);
4175 String manufacturerCode = null;
4176 if (phone != null) {
4177 String meid = phone.getMeid();
Vala Zadehab005552021-09-21 15:54:29 -07004178 try {
4179 manufacturerCode =
4180 meid == null ? null : meid.substring(0, MANUFACTURER_CODE_LENGTH);
4181 } catch (IndexOutOfBoundsException e) {
4182 Log.e(LOG_TAG, "MEID length shorter than upper index.");
4183 return null;
4184 }
David Kelly5e06a7f2018-03-12 14:10:59 +00004185 }
4186 return manufacturerCode;
4187 }
4188
4189 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004190 public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage,
4191 String callingFeatureId) {
Jeff Davidson913390f2018-02-23 17:11:49 -08004192 Phone phone = PhoneFactory.getPhone(slotIndex);
4193 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004194 return null;
4195 }
Jeff Davidson913390f2018-02-23 17:11:49 -08004196 int subId = phone.getSubId();
4197 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004198 mApp, subId, callingPackage, callingFeatureId,
4199 "getDeviceSoftwareVersionForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08004200 return null;
4201 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004202
4203 final long identity = Binder.clearCallingIdentity();
4204 try {
4205 return phone.getDeviceSvn();
4206 } finally {
4207 Binder.restoreCallingIdentity(identity);
4208 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07004209 }
4210
fionaxu43304da2017-11-27 22:51:16 -08004211 @Override
4212 public int getSubscriptionCarrierId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004213 final long identity = Binder.clearCallingIdentity();
4214 try {
4215 final Phone phone = getPhone(subId);
4216 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getCarrierId();
4217 } finally {
4218 Binder.restoreCallingIdentity(identity);
4219 }
fionaxu43304da2017-11-27 22:51:16 -08004220 }
4221
4222 @Override
4223 public String getSubscriptionCarrierName(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004224 final long identity = Binder.clearCallingIdentity();
4225 try {
4226 final Phone phone = getPhone(subId);
4227 return phone == null ? null : phone.getCarrierName();
4228 } finally {
4229 Binder.restoreCallingIdentity(identity);
4230 }
fionaxu43304da2017-11-27 22:51:16 -08004231 }
4232
calvinpanffe225e2018-11-01 19:43:06 +08004233 @Override
chen xu0026ca62019-03-06 15:28:50 -08004234 public int getSubscriptionSpecificCarrierId(int subId) {
chen xu25637222018-11-04 17:17:00 -08004235 final long identity = Binder.clearCallingIdentity();
4236 try {
4237 final Phone phone = getPhone(subId);
4238 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID
chen xu0026ca62019-03-06 15:28:50 -08004239 : phone.getSpecificCarrierId();
chen xu25637222018-11-04 17:17:00 -08004240 } finally {
4241 Binder.restoreCallingIdentity(identity);
4242 }
4243 }
4244
4245 @Override
chen xu0026ca62019-03-06 15:28:50 -08004246 public String getSubscriptionSpecificCarrierName(int subId) {
chen xu25637222018-11-04 17:17:00 -08004247 final long identity = Binder.clearCallingIdentity();
4248 try {
4249 final Phone phone = getPhone(subId);
chen xu0026ca62019-03-06 15:28:50 -08004250 return phone == null ? null : phone.getSpecificCarrierName();
chen xu25637222018-11-04 17:17:00 -08004251 } finally {
4252 Binder.restoreCallingIdentity(identity);
4253 }
4254 }
4255
chen xu651eec72018-11-11 19:03:44 -08004256 @Override
chen xu864e11c2018-12-06 22:10:03 -08004257 public int getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc) {
4258 if (!isSubscriptionMccMnc) {
4259 enforceReadPrivilegedPermission("getCarrierIdFromMccMnc");
4260 }
chen xu651eec72018-11-11 19:03:44 -08004261 final Phone phone = PhoneFactory.getPhone(slotIndex);
4262 if (phone == null) {
4263 return TelephonyManager.UNKNOWN_CARRIER_ID;
4264 }
4265 final long identity = Binder.clearCallingIdentity();
4266 try {
4267 return CarrierResolver.getCarrierIdFromMccMnc(phone.getContext(), mccmnc);
4268 } finally {
4269 Binder.restoreCallingIdentity(identity);
4270 }
4271 }
4272
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004273 //
4274 // Internal helper methods.
4275 //
4276
Sanket Padaweee13a9b2016-03-08 17:30:28 -08004277 /**
Grace Jia0ddb3612021-04-22 13:35:26 -07004278 * Make sure the caller is the calling package itself
4279 *
4280 * @throws SecurityException if the caller is not the calling package
4281 */
4282 private void enforceCallingPackage(String callingPackage, int callingUid, String message) {
4283 int packageUid = -1;
Grace Jiadbefca02021-04-26 15:13:31 -07004284 PackageManager pm = mApp.getBaseContext().createContextAsUser(
4285 UserHandle.getUserHandleForUid(callingUid), 0).getPackageManager();
Grace Jia0ddb3612021-04-22 13:35:26 -07004286 try {
Grace Jiadbefca02021-04-26 15:13:31 -07004287 packageUid = pm.getPackageUid(callingPackage, 0);
Grace Jia0ddb3612021-04-22 13:35:26 -07004288 } catch (PackageManager.NameNotFoundException e) {
4289 // packageUid is -1
4290 }
4291 if (packageUid != callingUid) {
4292 throw new SecurityException(message + ": Package " + callingPackage
4293 + " does not belong to " + callingUid);
4294 }
4295 }
4296
4297 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004298 * Make sure the caller has the MODIFY_PHONE_STATE permission.
4299 *
4300 * @throws SecurityException if the caller does not have the required permission
4301 */
Gil Cukierman1c0eb932022-12-06 22:28:24 +00004302 @VisibleForTesting
4303 public void enforceModifyPermission() {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004304 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
4305 }
4306
Gil Cukierman1c0eb932022-12-06 22:28:24 +00004307 /**
arunvoddud7401012022-12-15 16:08:12 +00004308 * Make sure the caller has the READ_PHONE_STATE permission.
Gil Cukierman1c0eb932022-12-06 22:28:24 +00004309 *
4310 * @throws SecurityException if the caller does not have the required permission
4311 */
4312 @VisibleForTesting
4313 public void enforceReadPermission() {
arunvoddud7401012022-12-15 16:08:12 +00004314 enforceReadPermission(null);
4315 }
4316
4317 /**
4318 * Make sure the caller has the READ_PHONE_STATE permissions.
4319 *
4320 * @throws SecurityException if the caller does not have the READ_PHONE_STATE permission.
4321 */
4322 @VisibleForTesting
4323 public void enforceReadPermission(String msg) {
4324 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE, msg);
Gil Cukierman1c0eb932022-12-06 22:28:24 +00004325 }
4326
Shuo Qian3b6ee772019-11-13 17:43:31 -08004327 private void enforceActiveEmergencySessionPermission() {
4328 mApp.enforceCallingOrSelfPermission(
4329 android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION, null);
4330 }
4331
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004332 /**
4333 * Make sure the caller has the CALL_PHONE permission.
4334 *
4335 * @throws SecurityException if the caller does not have the required permission
4336 */
4337 private void enforceCallPermission() {
4338 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
4339 }
4340
paulhu5a773602019-08-23 19:17:33 +08004341 private void enforceSettingsPermission() {
4342 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.NETWORK_SETTINGS, null);
Stuart Scott8eef64f2015-04-08 15:13:54 -07004343 }
4344
Michele Berionne5e411512020-11-13 02:36:59 +00004345 private void enforceRebootPermission() {
4346 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
4347 }
4348
Aishwarya Mallampati60fe1132023-01-24 19:07:21 +00004349 /**
4350 * Make sure the caller has SATELLITE_COMMUNICATION permission.
4351 * @param message - log message to print.
4352 * @throws SecurityException if the caller does not have the required permission
4353 */
4354 private void enforceSatelliteCommunicationPermission(String message) {
4355 mApp.enforceCallingOrSelfPermission(permission.SATELLITE_COMMUNICATION, message);
4356 }
4357
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004358 private String createTelUrl(String number) {
4359 if (TextUtils.isEmpty(number)) {
4360 return null;
4361 }
4362
Jake Hambye994d462014-02-03 13:10:13 -08004363 return "tel:" + number;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004364 }
4365
Ihab Awadf9e92732013-12-05 18:02:52 -08004366 private static void log(String msg) {
Ling Ma83dc5ea2023-01-12 15:06:04 -08004367 Log.d(LOG_TAG, msg);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004368 }
4369
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07004370 private static void logv(String msg) {
4371 Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg);
4372 }
4373
Ihab Awadf9e92732013-12-05 18:02:52 -08004374 private static void loge(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004375 Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg);
4376 }
4377
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004378 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004379 public int getActivePhoneType() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07004380 return getActivePhoneTypeForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07004381 }
4382
Sanket Padawe356d7632015-06-22 14:03:32 -07004383 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004384 public int getActivePhoneTypeForSlot(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004385 final long identity = Binder.clearCallingIdentity();
4386 try {
4387 final Phone phone = PhoneFactory.getPhone(slotIndex);
4388 if (phone == null) {
4389 return PhoneConstants.PHONE_TYPE_NONE;
4390 } else {
4391 return phone.getPhoneType();
4392 }
4393 } finally {
4394 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004395 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004396 }
4397
4398 /**
4399 * Returns the CDMA ERI icon index to display
4400 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004401 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004402 public int getCdmaEriIconIndex(String callingPackage, String callingFeatureId) {
4403 return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage,
4404 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07004405 }
4406
Sanket Padawe356d7632015-06-22 14:03:32 -07004407 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004408 public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage,
4409 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004410 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004411 mApp, subId, callingPackage, callingFeatureId,
4412 "getCdmaEriIconIndexForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004413 return -1;
4414 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004415
4416 final long identity = Binder.clearCallingIdentity();
4417 try {
4418 final Phone phone = getPhone(subId);
4419 if (phone != null) {
4420 return phone.getCdmaEriIconIndex();
4421 } else {
4422 return -1;
4423 }
4424 } finally {
4425 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004426 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004427 }
4428
4429 /**
4430 * Returns the CDMA ERI icon mode,
4431 * 0 - ON
4432 * 1 - FLASHING
4433 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004434 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004435 public int getCdmaEriIconMode(String callingPackage, String callingFeatureId) {
4436 return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage,
4437 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07004438 }
4439
Sanket Padawe356d7632015-06-22 14:03:32 -07004440 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004441 public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage,
4442 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004443 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004444 mApp, subId, callingPackage, callingFeatureId,
4445 "getCdmaEriIconModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004446 return -1;
4447 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004448
4449 final long identity = Binder.clearCallingIdentity();
4450 try {
4451 final Phone phone = getPhone(subId);
4452 if (phone != null) {
4453 return phone.getCdmaEriIconMode();
4454 } else {
4455 return -1;
4456 }
4457 } finally {
4458 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004459 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004460 }
4461
4462 /**
4463 * Returns the CDMA ERI text,
4464 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004465 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004466 public String getCdmaEriText(String callingPackage, String callingFeatureId) {
4467 return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage,
4468 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07004469 }
4470
Sanket Padawe356d7632015-06-22 14:03:32 -07004471 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004472 public String getCdmaEriTextForSubscriber(int subId, String callingPackage,
4473 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004474 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004475 mApp, subId, callingPackage, callingFeatureId,
4476 "getCdmaEriIconTextForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004477 return null;
4478 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004479
4480 final long identity = Binder.clearCallingIdentity();
4481 try {
4482 final Phone phone = getPhone(subId);
4483 if (phone != null) {
4484 return phone.getCdmaEriText();
4485 } else {
4486 return null;
4487 }
4488 } finally {
4489 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004490 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004491 }
4492
4493 /**
Junda Liuca05d5d2014-08-14 22:36:34 -07004494 * Returns the CDMA MDN.
4495 */
Sanket Padawe356d7632015-06-22 14:03:32 -07004496 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07004497 public String getCdmaMdn(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004498 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4499 mApp, subId, "getCdmaMdn");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004500
4501 final long identity = Binder.clearCallingIdentity();
4502 try {
4503 final Phone phone = getPhone(subId);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004504 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004505 return phone.getLine1Number();
4506 } else {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004507 loge("getCdmaMdn: no phone found. Invalid subId: " + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004508 return null;
4509 }
4510 } finally {
4511 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07004512 }
4513 }
4514
4515 /**
4516 * Returns the CDMA MIN.
4517 */
Sanket Padawe356d7632015-06-22 14:03:32 -07004518 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07004519 public String getCdmaMin(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004520 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4521 mApp, subId, "getCdmaMin");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004522
4523 final long identity = Binder.clearCallingIdentity();
4524 try {
4525 final Phone phone = getPhone(subId);
4526 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
4527 return phone.getCdmaMin();
4528 } else {
4529 return null;
4530 }
4531 } finally {
4532 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07004533 }
4534 }
4535
Hall Liud892bec2018-11-30 14:51:45 -08004536 @Override
4537 public void requestNumberVerification(PhoneNumberRange range, long timeoutMillis,
4538 INumberVerificationCallback callback, String callingPackage) {
4539 if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
4540 != PERMISSION_GRANTED) {
4541 throw new SecurityException("Caller must hold the MODIFY_PHONE_STATE permission");
4542 }
4543 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4544
4545 String authorizedPackage = NumberVerificationManager.getAuthorizedPackage(mApp);
4546 if (!TextUtils.equals(callingPackage, authorizedPackage)) {
Hall Liub9d8feb2021-01-13 10:28:04 -08004547 throw new SecurityException("Calling package must be configured in the device config: "
4548 + "calling package: " + callingPackage
4549 + ", configured package: " + authorizedPackage);
Hall Liud892bec2018-11-30 14:51:45 -08004550 }
4551
4552 if (range == null) {
4553 throw new NullPointerException("Range must be non-null");
4554 }
4555
4556 timeoutMillis = Math.min(timeoutMillis,
Hall Liubd069e32019-02-28 18:56:30 -08004557 TelephonyManager.getMaxNumberVerificationTimeoutMillis());
Hall Liud892bec2018-11-30 14:51:45 -08004558
4559 NumberVerificationManager.getInstance().requestVerification(range, callback, timeoutMillis);
4560 }
4561
Junda Liuca05d5d2014-08-14 22:36:34 -07004562 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004563 * Returns true if CDMA provisioning needs to run.
4564 */
4565 public boolean needsOtaServiceProvisioning() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004566 final long identity = Binder.clearCallingIdentity();
4567 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004568 return getDefaultPhone().needsOtaServiceProvisioning();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004569 } finally {
4570 Binder.restoreCallingIdentity(identity);
4571 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004572 }
4573
4574 /**
Shishir Agrawal76d5da92014-11-09 16:17:25 -08004575 * Sets the voice mail number of a given subId.
4576 */
4577 @Override
4578 public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08004579 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
4580 mApp, subId, "setVoiceMailNumber");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004581
4582 final long identity = Binder.clearCallingIdentity();
4583 try {
4584 Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
4585 new Pair<String, String>(alphaTag, number), new Integer(subId));
4586 return success;
4587 } finally {
4588 Binder.restoreCallingIdentity(identity);
4589 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08004590 }
4591
Ta-wei Yen87c49842016-05-13 21:19:52 -07004592 @Override
Ta-wei Yenc9df0432017-04-17 17:09:07 -07004593 public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
4594 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07004595 TelecomManager tm = mApp.getSystemService(TelecomManager.class);
4596 String systemDialer = tm.getSystemDialerPackage();
Ta-wei Yenc9df0432017-04-17 17:09:07 -07004597 if (!TextUtils.equals(callingPackage, systemDialer)) {
4598 throw new SecurityException("caller must be system dialer");
4599 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004600
4601 final long identity = Binder.clearCallingIdentity();
4602 try {
4603 PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
4604 if (phoneAccountHandle == null) {
4605 return null;
4606 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004607 return VisualVoicemailSettingsUtil.dump(mApp, phoneAccountHandle);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004608 } finally {
4609 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc9df0432017-04-17 17:09:07 -07004610 }
Ta-wei Yenc9df0432017-04-17 17:09:07 -07004611 }
4612
4613 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004614 public String getVisualVoicemailPackageName(String callingPackage, String callingFeatureId,
4615 int subId) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08004616 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jeff Davidson7e17e312018-02-13 18:17:36 -08004617 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004618 mApp, subId, callingPackage, callingFeatureId,
4619 "getVisualVoicemailPackageName")) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08004620 return null;
4621 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004622
Jeff Davidsona8e4e242018-03-15 17:16:18 -07004623 final long identity = Binder.clearCallingIdentity();
4624 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004625 return RemoteVvmTaskManager.getRemotePackage(mApp, subId).getPackageName();
Jeff Davidsona8e4e242018-03-15 17:16:18 -07004626 } finally {
4627 Binder.restoreCallingIdentity(identity);
4628 }
Ta-wei Yendca928f2017-01-10 16:17:08 -08004629 }
4630
4631 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07004632 public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
4633 VisualVoicemailSmsFilterSettings settings) {
4634 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004635
4636 final long identity = Binder.clearCallingIdentity();
4637 try {
4638 VisualVoicemailSmsFilterConfig.enableVisualVoicemailSmsFilter(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004639 mApp, callingPackage, subId, settings);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004640 } finally {
4641 Binder.restoreCallingIdentity(identity);
4642 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07004643 }
4644
4645 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07004646 public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
4647 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004648
4649 final long identity = Binder.clearCallingIdentity();
4650 try {
4651 VisualVoicemailSmsFilterConfig.disableVisualVoicemailSmsFilter(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004652 mApp, callingPackage, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004653 } finally {
4654 Binder.restoreCallingIdentity(identity);
4655 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07004656 }
4657
4658 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07004659 public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
4660 String callingPackage, int subId) {
4661 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004662
4663 final long identity = Binder.clearCallingIdentity();
4664 try {
4665 return VisualVoicemailSmsFilterConfig.getVisualVoicemailSmsFilterSettings(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004666 mApp, callingPackage, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004667 } finally {
4668 Binder.restoreCallingIdentity(identity);
4669 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07004670 }
4671
4672 @Override
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004673 public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07004674 enforceReadPrivilegedPermission("getActiveVisualVoicemailSmsFilterSettings");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004675
4676 final long identity = Binder.clearCallingIdentity();
4677 try {
4678 return VisualVoicemailSmsFilterConfig.getActiveVisualVoicemailSmsFilterSettings(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004679 mApp, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004680 } finally {
4681 Binder.restoreCallingIdentity(identity);
4682 }
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004683 }
4684
4685 @Override
Philip P. Moltmann2f6f8ce2020-03-18 18:17:02 -07004686 public void sendVisualVoicemailSmsForSubscriber(String callingPackage,
4687 String callingAttributionTag, int subId, String number, int port, String text,
4688 PendingIntent sentIntent) {
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004689 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Ta-wei Yen527a9c02017-01-06 15:29:25 -08004690 enforceVisualVoicemailPackage(callingPackage, subId);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004691 enforceSendSmsPermission();
Amit Mahajandccb3f12019-05-13 13:48:32 -07004692 SmsController smsController = PhoneFactory.getSmsController();
Philip P. Moltmann2f6f8ce2020-03-18 18:17:02 -07004693 smsController.sendVisualVoicemailSmsForSubscriber(callingPackage, callingAttributionTag,
4694 subId, number, port, text, sentIntent);
Ta-wei Yen87c49842016-05-13 21:19:52 -07004695 }
Amit Mahajandccb3f12019-05-13 13:48:32 -07004696
Shishir Agrawal76d5da92014-11-09 16:17:25 -08004697 /**
fionaxu0152e512016-11-14 13:36:14 -08004698 * Sets the voice activation state of a given subId.
4699 */
4700 @Override
4701 public void setVoiceActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004702 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4703 mApp, subId, "setVoiceActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004704
4705 final long identity = Binder.clearCallingIdentity();
4706 try {
4707 final Phone phone = getPhone(subId);
4708 if (phone != null) {
4709 phone.setVoiceActivationState(activationState);
4710 } else {
4711 loge("setVoiceActivationState fails with invalid subId: " + subId);
4712 }
4713 } finally {
4714 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08004715 }
4716 }
4717
4718 /**
4719 * Sets the data activation state of a given subId.
4720 */
4721 @Override
4722 public void setDataActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004723 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4724 mApp, subId, "setDataActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004725
4726 final long identity = Binder.clearCallingIdentity();
4727 try {
4728 final Phone phone = getPhone(subId);
4729 if (phone != null) {
4730 phone.setDataActivationState(activationState);
4731 } else {
Taesu Leef8fbed92019-10-07 18:47:02 +09004732 loge("setDataActivationState fails with invalid subId: " + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004733 }
4734 } finally {
4735 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08004736 }
4737 }
4738
4739 /**
4740 * Returns the voice activation state of a given subId.
4741 */
4742 @Override
4743 public int getVoiceActivationState(int subId, String callingPackage) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07004744 enforceReadPrivilegedPermission("getVoiceActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004745
fionaxu0152e512016-11-14 13:36:14 -08004746 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004747 final long identity = Binder.clearCallingIdentity();
4748 try {
4749 if (phone != null) {
4750 return phone.getVoiceActivationState();
4751 } else {
4752 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
4753 }
4754 } finally {
4755 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08004756 }
4757 }
4758
4759 /**
4760 * Returns the data activation state of a given subId.
4761 */
4762 @Override
4763 public int getDataActivationState(int subId, String callingPackage) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07004764 enforceReadPrivilegedPermission("getDataActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004765
fionaxu0152e512016-11-14 13:36:14 -08004766 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004767 final long identity = Binder.clearCallingIdentity();
4768 try {
4769 if (phone != null) {
4770 return phone.getDataActivationState();
4771 } else {
4772 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
4773 }
4774 } finally {
4775 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08004776 }
4777 }
4778
4779 /**
Wink Saville36469e72014-06-11 15:17:00 -07004780 * Returns the unread count of voicemails for a subId
4781 */
Sanket Padawe356d7632015-06-22 14:03:32 -07004782 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004783 public int getVoiceMessageCountForSubscriber(int subId, String callingPackage,
4784 String callingFeatureId) {
Brad Ebingerf7664ba2018-11-29 12:43:38 -08004785 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07004786 mApp, subId, callingPackage, callingFeatureId,
4787 "getVoiceMessageCountForSubscriber")) {
Brad Ebingerf7664ba2018-11-29 12:43:38 -08004788 return 0;
4789 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004790 final long identity = Binder.clearCallingIdentity();
4791 try {
4792 final Phone phone = getPhone(subId);
4793 if (phone != null) {
4794 return phone.getVoiceMessageCount();
4795 } else {
4796 return 0;
4797 }
4798 } finally {
4799 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004800 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07004801 }
4802
4803 /**
Thomas Nguyen8ee49682023-02-01 11:46:09 -08004804 * returns true, if the device is in a state where both voice and data
4805 * are supported simultaneously. This can change based on location or network condition.
pkanwar8a4dcfb2017-01-19 13:43:16 -08004806 */
4807 @Override
4808 public boolean isConcurrentVoiceAndDataAllowed(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004809 final long identity = Binder.clearCallingIdentity();
4810 try {
4811 final Phone phone = getPhone(subId);
4812 return (phone == null ? false : phone.isConcurrentVoiceAndDataAllowed());
4813 } finally {
4814 Binder.restoreCallingIdentity(identity);
4815 }
pkanwar8a4dcfb2017-01-19 13:43:16 -08004816 }
4817
4818 /**
fionaxu235cc5e2017-03-06 22:25:57 -08004819 * Send the dialer code if called from the current default dialer or the caller has
4820 * carrier privilege.
4821 * @param inputCode The dialer code to send
4822 */
4823 @Override
4824 public void sendDialerSpecialCode(String callingPackage, String inputCode) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004825 final Phone defaultPhone = getDefaultPhone();
fionaxu235cc5e2017-03-06 22:25:57 -08004826 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07004827 TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
4828 String defaultDialer = tm.getDefaultDialerPackage();
fionaxu235cc5e2017-03-06 22:25:57 -08004829 if (!TextUtils.equals(callingPackage, defaultDialer)) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08004830 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
Jeff Davidson7e17e312018-02-13 18:17:36 -08004831 getDefaultSubscription(), "sendDialerSpecialCode");
fionaxu235cc5e2017-03-06 22:25:57 -08004832 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004833
4834 final long identity = Binder.clearCallingIdentity();
4835 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004836 defaultPhone.sendDialerSpecialCode(inputCode);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004837 } finally {
4838 Binder.restoreCallingIdentity(identity);
4839 }
fionaxu235cc5e2017-03-06 22:25:57 -08004840 }
4841
Pengquan Menga1bb6272018-09-06 09:59:22 -07004842 @Override
4843 public int getNetworkSelectionMode(int subId) {
shilufc958392020-01-20 11:36:01 -08004844 TelephonyPermissions
Thomas Nguyen8ee49682023-02-01 11:46:09 -08004845 .enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4846 mApp, subId, "getNetworkSelectionMode");
shilufc958392020-01-20 11:36:01 -08004847 final long identity = Binder.clearCallingIdentity();
4848 try {
4849 if (!isActiveSubscription(subId)) {
4850 return TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
4851 }
4852 return (int) sendRequest(CMD_GET_NETWORK_SELECTION_MODE, null /* argument */, subId);
4853 } finally {
4854 Binder.restoreCallingIdentity(identity);
Pengquan Menge92a50d2018-09-21 15:54:48 -07004855 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07004856 }
4857
Brad Ebinger35c841c2018-10-01 10:40:55 -07004858 @Override
Brad Ebingerb2b65522019-03-15 13:48:47 -07004859 public boolean isInEmergencySmsMode() {
4860 enforceReadPrivilegedPermission("isInEmergencySmsMode");
4861 final long identity = Binder.clearCallingIdentity();
4862 try {
4863 for (Phone phone : PhoneFactory.getPhones()) {
4864 if (phone.isInEmergencySmsMode()) {
4865 return true;
4866 }
4867 }
4868 } finally {
4869 Binder.restoreCallingIdentity(identity);
4870 }
4871 return false;
4872 }
4873
shilu366312e2019-12-17 09:28:10 -08004874 /**
4875 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4876 * @param subId The subscription to use to check the configuration.
4877 * @param c The callback that will be used to send the result.
4878 */
Brad Ebingerb2b65522019-03-15 13:48:47 -07004879 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08004880 public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback c)
4881 throws RemoteException {
Nathan Harold62c68512021-04-06 11:26:02 -07004882 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004883 mApp, subId, "registerImsRegistrationCallback");
Brad Ebingera2628302022-02-18 03:44:55 +00004884
4885 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4886 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4887 "IMS not available on device.");
4888 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07004889 final long token = Binder.clearCallingIdentity();
4890 try {
Brad Ebingera2628302022-02-18 03:44:55 +00004891 int slotId = getSlotIndexOrException(subId);
4892 verifyImsMmTelConfiguredOrThrow(slotId);
joonhunshin49f0aed2022-08-05 08:33:05 +00004893
4894 ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
4895 if (controller != null) {
4896 ImsManager imsManager = controller.getImsManager(subId);
4897 if (imsManager != null) {
4898 imsManager.addRegistrationCallbackForSubscription(c, subId);
4899 } else {
4900 throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
4901 }
4902 } else {
4903 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
4904 }
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004905 } catch (ImsException e) {
4906 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004907 } finally {
4908 Binder.restoreCallingIdentity(token);
4909 }
4910 }
4911
shilu366312e2019-12-17 09:28:10 -08004912 /**
4913 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4914 * @param subId The subscription to use to check the configuration.
4915 * @param c The callback that will be used to send the result.
4916 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07004917 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08004918 public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c) {
Nathan Harold62c68512021-04-06 11:26:02 -07004919 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004920 mApp, subId, "unregisterImsRegistrationCallback");
Brad Ebinger4ae57f92019-01-09 16:51:30 -08004921 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4922 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
4923 }
Meng Wangafbc5852019-09-19 17:37:13 -07004924 final long token = Binder.clearCallingIdentity();
joonhunshin49f0aed2022-08-05 08:33:05 +00004925
Meng Wangafbc5852019-09-19 17:37:13 -07004926 try {
joonhunshin49f0aed2022-08-05 08:33:05 +00004927 ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
4928 if (controller != null) {
4929 ImsManager imsManager = controller.getImsManager(subId);
4930 if (imsManager != null) {
4931 imsManager.removeRegistrationCallbackForSubscription(c, subId);
4932 } else {
4933 Log.i(LOG_TAG, "unregisterImsRegistrationCallback: " + subId
4934 + "is inactive, ignoring unregister.");
4935 // If the ImsManager is not valid, just return, since the callback
4936 // will already have been removed internally.
4937 }
4938 }
Meng Wangafbc5852019-09-19 17:37:13 -07004939 } finally {
4940 Binder.restoreCallingIdentity(token);
4941 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07004942 }
4943
Brad Ebingera34a6c22019-10-22 17:36:18 -07004944 /**
4945 * Get the IMS service registration state for the MmTelFeature associated with this sub id.
4946 */
4947 @Override
4948 public void getImsMmTelRegistrationState(int subId, IIntegerConsumer consumer) {
4949 enforceReadPrivilegedPermission("getImsMmTelRegistrationState");
4950 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4951 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4952 "IMS not available on device.");
4953 }
4954 final long token = Binder.clearCallingIdentity();
4955 try {
4956 Phone phone = getPhone(subId);
4957 if (phone == null) {
4958 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
4959 + subId + "'");
4960 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
4961 }
4962 phone.getImsRegistrationState(regState -> {
4963 try {
4964 consumer.accept((regState == null)
4965 ? RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED : regState);
4966 } catch (RemoteException e) {
4967 // Ignore if the remote process is no longer available to call back.
4968 Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
4969 }
4970 });
4971 } finally {
4972 Binder.restoreCallingIdentity(token);
4973 }
4974 }
4975
4976 /**
4977 * Get the transport type for the IMS service registration state.
4978 */
4979 @Override
4980 public void getImsMmTelRegistrationTransportType(int subId, IIntegerConsumer consumer) {
Nathan Harold62c68512021-04-06 11:26:02 -07004981 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004982 mApp, subId, "getImsMmTelRegistrationTransportType");
Brad Ebingera34a6c22019-10-22 17:36:18 -07004983 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4984 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4985 "IMS not available on device.");
4986 }
4987 final long token = Binder.clearCallingIdentity();
4988 try {
4989 Phone phone = getPhone(subId);
4990 if (phone == null) {
4991 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
4992 + subId + "'");
4993 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
4994 }
4995 phone.getImsRegistrationTech(regTech -> {
4996 // Convert registration tech from ImsRegistrationImplBase -> RegistrationManager
4997 int regTechConverted = (regTech == null)
4998 ? ImsRegistrationImplBase.REGISTRATION_TECH_NONE : regTech;
4999 regTechConverted = RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(
5000 regTechConverted);
5001 try {
5002 consumer.accept(regTechConverted);
5003 } catch (RemoteException e) {
5004 // Ignore if the remote process is no longer available to call back.
5005 Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
5006 }
5007 });
5008 } finally {
5009 Binder.restoreCallingIdentity(token);
5010 }
5011 }
5012
shilu366312e2019-12-17 09:28:10 -08005013 /**
5014 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
5015 * @param subId The subscription to use to check the configuration.
5016 * @param c The callback that will be used to send the result.
5017 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07005018 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08005019 public void registerMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)
5020 throws RemoteException {
Nathan Harold62c68512021-04-06 11:26:02 -07005021 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08005022 mApp, subId, "registerMmTelCapabilityCallback");
Brad Ebingera2628302022-02-18 03:44:55 +00005023 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
5024 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
5025 "IMS not available on device.");
5026 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07005027 final long token = Binder.clearCallingIdentity();
5028 try {
Brad Ebingera2628302022-02-18 03:44:55 +00005029 int slotId = getSlotIndexOrException(subId);
5030 verifyImsMmTelConfiguredOrThrow(slotId);
Hwangoo Park8646b0d2023-01-13 02:42:34 +00005031
5032 ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
5033 if (controller != null) {
5034 ImsManager imsManager = controller.getImsManager(subId);
5035 if (imsManager != null) {
5036 imsManager.addCapabilitiesCallbackForSubscription(c, subId);
5037 } else {
5038 throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
5039 }
5040 } else {
5041 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
5042 }
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005043 } catch (ImsException e) {
5044 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07005045 } finally {
5046 Binder.restoreCallingIdentity(token);
5047 }
5048 }
5049
shilu366312e2019-12-17 09:28:10 -08005050 /**
5051 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
5052 * @param subId The subscription to use to check the configuration.
5053 * @param c The callback that will be used to send the result.
5054 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07005055 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08005056 public void unregisterMmTelCapabilityCallback(int subId, IImsCapabilityCallback c) {
Nathan Harold62c68512021-04-06 11:26:02 -07005057 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08005058 mApp, subId, "unregisterMmTelCapabilityCallback");
Brad Ebinger4ae57f92019-01-09 16:51:30 -08005059 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5060 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
5061 }
Meng Wangafbc5852019-09-19 17:37:13 -07005062
5063 final long token = Binder.clearCallingIdentity();
5064 try {
Hwangoo Park8646b0d2023-01-13 02:42:34 +00005065 ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
5066 if (controller != null) {
5067 ImsManager imsManager = controller.getImsManager(subId);
5068 if (imsManager != null) {
5069 imsManager.removeCapabilitiesCallbackForSubscription(c, subId);
5070 } else {
5071 Log.i(LOG_TAG, "unregisterMmTelCapabilityCallback: " + subId
5072 + " is inactive, ignoring unregister.");
5073 // If the ImsManager is not valid, just return, since the callback
5074 // will already have been removed internally.
5075 }
5076 }
Meng Wangafbc5852019-09-19 17:37:13 -07005077 } finally {
5078 Binder.restoreCallingIdentity(token);
5079 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07005080 }
5081
5082 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08005083 public boolean isCapable(int subId, int capability, int regTech) {
5084 enforceReadPrivilegedPermission("isCapable");
Brad Ebinger35c841c2018-10-01 10:40:55 -07005085 final long token = Binder.clearCallingIdentity();
5086 try {
Brad Ebingera2628302022-02-18 03:44:55 +00005087 int slotId = getSlotIndexOrException(subId);
5088 verifyImsMmTelConfiguredOrThrow(slotId);
5089 return ImsManager.getInstance(mApp, slotId).queryMmTelCapability(capability, regTech);
5090 } catch (com.android.ims.ImsException e) {
5091 Log.w(LOG_TAG, "IMS isCapable - service unavailable: " + e.getMessage());
5092 return false;
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005093 } catch (ImsException e) {
Brad Ebinger6b5ac222019-02-04 14:36:52 -08005094 Log.i(LOG_TAG, "isCapable: " + subId + " is inactive, returning false.");
5095 return false;
Brad Ebinger35c841c2018-10-01 10:40:55 -07005096 } finally {
5097 Binder.restoreCallingIdentity(token);
5098 }
5099 }
5100
5101 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08005102 public boolean isAvailable(int subId, int capability, int regTech) {
5103 enforceReadPrivilegedPermission("isAvailable");
Brad Ebinger35c841c2018-10-01 10:40:55 -07005104 final long token = Binder.clearCallingIdentity();
5105 try {
5106 Phone phone = getPhone(subId);
5107 if (phone == null) return false;
5108 return phone.isImsCapabilityAvailable(capability, regTech);
Daniel Bright5e40e4e2020-03-11 16:35:39 -07005109 } catch (com.android.ims.ImsException e) {
5110 Log.w(LOG_TAG, "IMS isAvailable - service unavailable: " + e.getMessage());
5111 return false;
Brad Ebinger35c841c2018-10-01 10:40:55 -07005112 } finally {
5113 Binder.restoreCallingIdentity(token);
5114 }
5115 }
5116
Brad Ebingerbc7dd582019-10-17 17:03:22 -07005117 /**
5118 * Determines if the MmTel feature capability is supported by the carrier configuration for this
5119 * subscription.
5120 * @param subId The subscription to use to check the configuration.
5121 * @param callback The callback that will be used to send the result.
5122 * @param capability The MmTelFeature capability that will be used to send the result.
5123 * @param transportType The transport type of the MmTelFeature capability.
5124 */
5125 @Override
5126 public void isMmTelCapabilitySupported(int subId, IIntegerConsumer callback, int capability,
5127 int transportType) {
5128 enforceReadPrivilegedPermission("isMmTelCapabilitySupported");
Brad Ebingera2628302022-02-18 03:44:55 +00005129 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
5130 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
5131 "IMS not available on device.");
5132 }
Brad Ebingerbc7dd582019-10-17 17:03:22 -07005133 final long token = Binder.clearCallingIdentity();
5134 try {
Brad Ebingera2628302022-02-18 03:44:55 +00005135 int slotId = getSlotIndex(subId);
5136 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5137 Log.w(LOG_TAG, "isMmTelCapabilitySupported: called with an inactive subscription '"
5138 + subId + "'");
5139 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
5140 }
5141 verifyImsMmTelConfiguredOrThrow(slotId);
5142 ImsManager.getInstance(mApp, slotId).isSupported(capability,
5143 transportType, aBoolean -> {
5144 try {
5145 callback.accept((aBoolean == null) ? 0 : (aBoolean ? 1 : 0));
5146 } catch (RemoteException e) {
5147 Log.w(LOG_TAG, "isMmTelCapabilitySupported: remote caller is not "
5148 + "running. Ignore");
5149 }
5150 });
Brad Ebinger919631e2021-06-02 17:46:35 -07005151 } catch (ImsException e) {
5152 throw new ServiceSpecificException(e.getCode());
Brad Ebingerbc7dd582019-10-17 17:03:22 -07005153 } finally {
5154 Binder.restoreCallingIdentity(token);
5155 }
5156 }
5157
shilu366312e2019-12-17 09:28:10 -08005158 /**
5159 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
5160 * @param subId The subscription to use to check the configuration.
5161 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07005162 @Override
5163 public boolean isAdvancedCallingSettingEnabled(int subId) {
Nathan Harold62c68512021-04-06 11:26:02 -07005164 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08005165 mApp, subId, "isAdvancedCallingSettingEnabled");
shilu366312e2019-12-17 09:28:10 -08005166
Brad Ebinger35c841c2018-10-01 10:40:55 -07005167 final long token = Binder.clearCallingIdentity();
5168 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07005169 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07005170 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07005171 return ImsManager.getInstance(mApp, slotId).isEnhanced4gLteModeSettingEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005172 } catch (ImsException e) {
5173 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07005174 } finally {
5175 Binder.restoreCallingIdentity(token);
5176 }
5177 }
5178
5179 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08005180 public void setAdvancedCallingSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005181 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08005182 "setAdvancedCallingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07005183 final long identity = Binder.clearCallingIdentity();
5184 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07005185 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07005186 // This setting doesn't require an active ImsService connection, so do not verify. The
5187 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07005188 ImsManager.getInstance(mApp, slotId).setEnhanced4gLteModeSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005189 } catch (ImsException e) {
5190 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07005191 } finally {
5192 Binder.restoreCallingIdentity(identity);
5193 }
5194 }
5195
shilu366312e2019-12-17 09:28:10 -08005196 /**
5197 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
5198 * @param subId The subscription to use to check the configuration.
5199 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07005200 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08005201 public boolean isVtSettingEnabled(int subId) {
Nathan Harold62c68512021-04-06 11:26:02 -07005202 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08005203 mApp, subId, "isVtSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07005204 final long identity = Binder.clearCallingIdentity();
5205 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07005206 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07005207 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07005208 return ImsManager.getInstance(mApp, slotId).isVtEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005209 } catch (ImsException e) {
5210 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07005211 } finally {
5212 Binder.restoreCallingIdentity(identity);
5213 }
5214 }
5215
5216 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08005217 public void setVtSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005218 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08005219 "setVtSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07005220 final long identity = Binder.clearCallingIdentity();
5221 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07005222 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07005223 // This setting doesn't require an active ImsService connection, so do not verify. The
5224 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07005225 ImsManager.getInstance(mApp, slotId).setVtSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005226 } catch (ImsException e) {
5227 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07005228 } finally {
5229 Binder.restoreCallingIdentity(identity);
5230 }
5231 }
5232
shilu366312e2019-12-17 09:28:10 -08005233 /**
5234 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
5235 * @param subId The subscription to use to check the configuration.
5236 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07005237 @Override
5238 public boolean isVoWiFiSettingEnabled(int subId) {
Nathan Harold62c68512021-04-06 11:26:02 -07005239 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08005240 mApp, subId, "isVoWiFiSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07005241 final long identity = Binder.clearCallingIdentity();
5242 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07005243 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07005244 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07005245 return ImsManager.getInstance(mApp, slotId).isWfcEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005246 } catch (ImsException e) {
5247 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07005248 } finally {
5249 Binder.restoreCallingIdentity(identity);
5250 }
5251 }
5252
5253 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08005254 public void setVoWiFiSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005255 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08005256 "setVoWiFiSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07005257 final long identity = Binder.clearCallingIdentity();
5258 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07005259 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07005260 // This setting doesn't require an active ImsService connection, so do not verify. The
5261 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07005262 ImsManager.getInstance(mApp, slotId).setWfcSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005263 } catch (ImsException e) {
5264 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07005265 } finally {
5266 Binder.restoreCallingIdentity(identity);
5267 }
5268 }
5269
shilu366312e2019-12-17 09:28:10 -08005270 /**
Sooraj Sasindrane655add2020-11-23 19:40:38 -08005271 * @return true if the user's setting for Voice over Cross SIM is enabled and false if it is not
5272 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
5273 * @param subId The subscription to use to check the configuration.
5274 */
5275 @Override
5276 public boolean isCrossSimCallingEnabledByUser(int subId) {
Nathan Harold62c68512021-04-06 11:26:02 -07005277 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Sooraj Sasindrane655add2020-11-23 19:40:38 -08005278 mApp, subId, "isCrossSimCallingEnabledByUser");
5279 final long identity = Binder.clearCallingIdentity();
5280 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07005281 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07005282 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07005283 return ImsManager.getInstance(mApp, slotId).isCrossSimCallingEnabledByUser();
Sooraj Sasindrane655add2020-11-23 19:40:38 -08005284 } catch (ImsException e) {
5285 throw new ServiceSpecificException(e.getCode());
5286 } finally {
5287 Binder.restoreCallingIdentity(identity);
5288 }
5289 }
5290
5291 /**
5292 * Sets the user's setting for whether or not Voice over Cross SIM is enabled.
5293 * Requires MODIFY_PHONE_STATE permission.
5294 * @param subId The subscription to use to check the configuration.
5295 * @param isEnabled true if the user's setting for Voice over Cross SIM is enabled,
5296 * false otherwise
5297 */
5298 @Override
5299 public void setCrossSimCallingEnabled(int subId, boolean isEnabled) {
5300 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5301 "setCrossSimCallingEnabled");
5302 final long identity = Binder.clearCallingIdentity();
5303 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07005304 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07005305 // This setting doesn't require an active ImsService connection, so do not verify. The
5306 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07005307 ImsManager.getInstance(mApp, slotId).setCrossSimCallingEnabled(isEnabled);
Sooraj Sasindrane655add2020-11-23 19:40:38 -08005308 } catch (ImsException e) {
5309 throw new ServiceSpecificException(e.getCode());
5310 } finally {
5311 Binder.restoreCallingIdentity(identity);
5312 }
5313 }
5314
5315 /**
shilu366312e2019-12-17 09:28:10 -08005316 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
5317 * @param subId The subscription to use to check the configuration.
5318 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07005319 @Override
Nathan Harold62c68512021-04-06 11:26:02 -07005320
Brad Ebinger35c841c2018-10-01 10:40:55 -07005321 public boolean isVoWiFiRoamingSettingEnabled(int subId) {
Nathan Harold62c68512021-04-06 11:26:02 -07005322 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08005323 mApp, subId, "isVoWiFiRoamingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07005324 final long identity = Binder.clearCallingIdentity();
5325 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07005326 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07005327 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07005328 return ImsManager.getInstance(mApp, slotId).isWfcRoamingEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005329 } catch (ImsException e) {
5330 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07005331 } finally {
5332 Binder.restoreCallingIdentity(identity);
5333 }
5334 }
5335
5336 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08005337 public void setVoWiFiRoamingSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005338 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08005339 "setVoWiFiRoamingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07005340 final long identity = Binder.clearCallingIdentity();
5341 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07005342 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07005343 // This setting doesn't require an active ImsService connection, so do not verify. The
5344 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07005345 ImsManager.getInstance(mApp, slotId).setWfcRoamingSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005346 } catch (ImsException e) {
5347 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07005348 } finally {
5349 Binder.restoreCallingIdentity(identity);
5350 }
5351 }
5352
5353 @Override
5354 public void setVoWiFiNonPersistent(int subId, boolean isCapable, int mode) {
5355 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5356 "setVoWiFiNonPersistent");
5357 final long identity = Binder.clearCallingIdentity();
5358 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07005359 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07005360 // This setting will be ignored if the ImsService isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07005361 ImsManager.getInstance(mApp, slotId).setWfcNonPersistent(isCapable, mode);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005362 } catch (ImsException e) {
5363 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07005364 } finally {
5365 Binder.restoreCallingIdentity(identity);
5366 }
5367 }
5368
shilu366312e2019-12-17 09:28:10 -08005369 /**
5370 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
5371 * @param subId The subscription to use to check the configuration.
5372 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07005373 @Override
5374 public int getVoWiFiModeSetting(int subId) {
Nathan Harold62c68512021-04-06 11:26:02 -07005375 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08005376 mApp, subId, "getVoWiFiModeSetting");
Brad Ebinger35c841c2018-10-01 10:40:55 -07005377 final long identity = Binder.clearCallingIdentity();
5378 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07005379 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07005380 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07005381 return ImsManager.getInstance(mApp, slotId).getWfcMode(false /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005382 } catch (ImsException e) {
5383 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07005384 } finally {
5385 Binder.restoreCallingIdentity(identity);
5386 }
5387 }
5388
5389 @Override
5390 public void setVoWiFiModeSetting(int subId, int mode) {
5391 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5392 "setVoWiFiModeSetting");
5393 final long identity = Binder.clearCallingIdentity();
5394 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07005395 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07005396 // This setting doesn't require an active ImsService connection, so do not verify. The
5397 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07005398 ImsManager.getInstance(mApp, slotId).setWfcMode(mode, false /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005399 } catch (ImsException e) {
5400 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07005401 } finally {
5402 Binder.restoreCallingIdentity(identity);
5403 }
5404 }
5405
5406 @Override
5407 public int getVoWiFiRoamingModeSetting(int subId) {
5408 enforceReadPrivilegedPermission("getVoWiFiRoamingModeSetting");
5409 final long identity = Binder.clearCallingIdentity();
5410 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07005411 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07005412 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07005413 return ImsManager.getInstance(mApp, slotId).getWfcMode(true /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005414 } catch (ImsException e) {
5415 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07005416 } finally {
5417 Binder.restoreCallingIdentity(identity);
5418 }
5419 }
5420
5421 @Override
5422 public void setVoWiFiRoamingModeSetting(int subId, int mode) {
5423 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5424 "setVoWiFiRoamingModeSetting");
5425 final long identity = Binder.clearCallingIdentity();
5426 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07005427 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07005428 // This setting doesn't require an active ImsService connection, so do not verify. The
5429 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07005430 ImsManager.getInstance(mApp, slotId).setWfcMode(mode, true /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005431 } catch (ImsException e) {
5432 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07005433 } finally {
5434 Binder.restoreCallingIdentity(identity);
5435 }
5436 }
5437
5438 @Override
5439 public void setRttCapabilitySetting(int subId, boolean isEnabled) {
5440 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5441 "setRttCapabilityEnabled");
5442 final long identity = Binder.clearCallingIdentity();
5443 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07005444 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07005445 // This setting doesn't require an active ImsService connection, so do not verify. The
5446 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07005447 ImsManager.getInstance(mApp, slotId).setRttEnabled(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005448 } catch (ImsException e) {
5449 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07005450 } finally {
5451 Binder.restoreCallingIdentity(identity);
5452 }
5453 }
5454
shilu366312e2019-12-17 09:28:10 -08005455 /**
5456 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
5457 * @param subId The subscription to use to check the configuration.
5458 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07005459 @Override
5460 public boolean isTtyOverVolteEnabled(int subId) {
Nathan Harold62c68512021-04-06 11:26:02 -07005461 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08005462 mApp, subId, "isTtyOverVolteEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07005463 final long identity = Binder.clearCallingIdentity();
5464 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07005465 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07005466 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07005467 return ImsManager.getInstance(mApp, slotId).isTtyOnVoLteCapable();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005468 } catch (ImsException e) {
5469 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07005470 } finally {
5471 Binder.restoreCallingIdentity(identity);
5472 }
5473 }
5474
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005475 @Override
5476 public void registerImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
5477 enforceReadPrivilegedPermission("registerImsProvisioningChangedCallback");
joonhunshincffb7fc2021-11-28 07:32:01 +00005478
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005479 final long identity = Binder.clearCallingIdentity();
5480 try {
Brad Ebingera2628302022-02-18 03:44:55 +00005481 if (!isImsAvailableOnDevice()) {
5482 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
5483 "IMS not available on device.");
5484 }
5485 int slotId = getSlotIndexOrException(subId);
5486 verifyImsMmTelConfiguredOrThrow(slotId);
Hwangoo Park8646b0d2023-01-13 02:42:34 +00005487
5488 ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
5489 if (controller != null) {
5490 ImsManager imsManager = controller.getImsManager(subId);
5491 if (imsManager != null) {
5492 imsManager.addProvisioningCallbackForSubscription(callback, subId);
5493 } else {
5494 throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
5495 }
5496 } else {
5497 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
5498 }
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005499 } catch (ImsException e) {
5500 throw new ServiceSpecificException(e.getCode());
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005501 } finally {
5502 Binder.restoreCallingIdentity(identity);
5503 }
5504 }
5505
5506 @Override
5507 public void unregisterImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
5508 enforceReadPrivilegedPermission("unregisterImsProvisioningChangedCallback");
joonhunshincffb7fc2021-11-28 07:32:01 +00005509
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005510 final long identity = Binder.clearCallingIdentity();
Brad Ebinger4ae57f92019-01-09 16:51:30 -08005511 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5512 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
5513 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005514 try {
Hwangoo Park8646b0d2023-01-13 02:42:34 +00005515 ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
5516 if (controller != null) {
5517 ImsManager imsManager = controller.getImsManager(subId);
5518 if (imsManager != null) {
5519 imsManager.removeProvisioningCallbackForSubscription(callback, subId);
5520 } else {
5521 Log.i(LOG_TAG, "unregisterImsProvisioningChangedCallback: " + subId
5522 + " is inactive, ignoring unregister.");
5523 // If the ImsManager is not valid, just return, since the callback will already
5524 // have been removed internally.
5525 }
5526 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005527 } finally {
5528 Binder.restoreCallingIdentity(identity);
5529 }
5530 }
5531
joonhunshincffb7fc2021-11-28 07:32:01 +00005532 @Override
5533 public void registerFeatureProvisioningChangedCallback(int subId,
5534 IFeatureProvisioningCallback callback) {
5535 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5536 mApp, subId, "registerFeatureProvisioningChangedCallback");
5537
5538 final long identity = Binder.clearCallingIdentity();
5539 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5540 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
5541 }
5542
joonhunshin91bc1952022-04-29 08:47:15 +00005543 try {
5544 ImsProvisioningController controller = ImsProvisioningController.getInstance();
5545 if (controller == null) {
5546 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
5547 "Device does not support IMS");
5548 }
5549 controller.addFeatureProvisioningChangedCallback(subId, callback);
5550 } finally {
5551 Binder.restoreCallingIdentity(identity);
5552 }
joonhunshincffb7fc2021-11-28 07:32:01 +00005553 }
5554
5555 @Override
5556 public void unregisterFeatureProvisioningChangedCallback(int subId,
5557 IFeatureProvisioningCallback callback) {
5558 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5559 mApp, subId, "unregisterFeatureProvisioningChangedCallback");
5560
5561 final long identity = Binder.clearCallingIdentity();
5562 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5563 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
5564 }
5565
joonhunshin91bc1952022-04-29 08:47:15 +00005566 try {
5567 ImsProvisioningController controller = ImsProvisioningController.getInstance();
5568 if (controller == null) {
5569 loge("unregisterFeatureProvisioningChangedCallback: Device does not support IMS");
5570 return;
5571 }
5572 controller.removeFeatureProvisioningChangedCallback(subId, callback);
5573 } finally {
5574 Binder.restoreCallingIdentity(identity);
5575 }
joonhunshincffb7fc2021-11-28 07:32:01 +00005576 }
allenwtsu99c623b2020-01-03 18:24:23 +08005577
5578 private void checkModifyPhoneStatePermission(int subId, String message) {
5579 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5580 message);
5581 }
5582
allenwtsu99c623b2020-01-03 18:24:23 +08005583 @Override
joonhunshincffb7fc2021-11-28 07:32:01 +00005584 public void setRcsProvisioningStatusForCapability(int subId, int capability, int tech,
allenwtsu99c623b2020-01-03 18:24:23 +08005585 boolean isProvisioned) {
5586 checkModifyPhoneStatePermission(subId, "setRcsProvisioningStatusForCapability");
5587
5588 final long identity = Binder.clearCallingIdentity();
5589 try {
joonhunshin91bc1952022-04-29 08:47:15 +00005590 ImsProvisioningController controller = ImsProvisioningController.getInstance();
5591 if (controller == null) {
5592 loge("setRcsProvisioningStatusForCapability: Device does not support IMS");
5593 return;
5594 }
5595 controller.setRcsProvisioningStatusForCapability(
5596 subId, capability, tech, isProvisioned);
allenwtsu99c623b2020-01-03 18:24:23 +08005597 } finally {
5598 Binder.restoreCallingIdentity(identity);
5599 }
allenwtsu99c623b2020-01-03 18:24:23 +08005600 }
5601
5602
5603 @Override
joonhunshincffb7fc2021-11-28 07:32:01 +00005604 public boolean getRcsProvisioningStatusForCapability(int subId, int capability, int tech) {
5605 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5606 mApp, subId, "getRcsProvisioningStatusForCapability");
5607
allenwtsu99c623b2020-01-03 18:24:23 +08005608 final long identity = Binder.clearCallingIdentity();
5609 try {
joonhunshin91bc1952022-04-29 08:47:15 +00005610 ImsProvisioningController controller = ImsProvisioningController.getInstance();
5611 if (controller == null) {
5612 loge("getRcsProvisioningStatusForCapability: Device does not support IMS");
5613
5614 // device does not support IMS, this method will return true always.
5615 return true;
5616 }
5617 return controller.getRcsProvisioningStatusForCapability(subId, capability, tech);
allenwtsu99c623b2020-01-03 18:24:23 +08005618 } finally {
5619 Binder.restoreCallingIdentity(identity);
5620 }
5621 }
5622
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005623 @Override
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005624 public void setImsProvisioningStatusForCapability(int subId, int capability, int tech,
5625 boolean isProvisioned) {
allenwtsu99c623b2020-01-03 18:24:23 +08005626 checkModifyPhoneStatePermission(subId, "setImsProvisioningStatusForCapability");
joonhunshincffb7fc2021-11-28 07:32:01 +00005627
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005628 final long identity = Binder.clearCallingIdentity();
5629 try {
joonhunshin91bc1952022-04-29 08:47:15 +00005630 ImsProvisioningController controller = ImsProvisioningController.getInstance();
5631 if (controller == null) {
5632 loge("setImsProvisioningStatusForCapability: Device does not support IMS");
5633 return;
5634 }
5635 controller.setImsProvisioningStatusForCapability(
5636 subId, capability, tech, isProvisioned);
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005637 } finally {
5638 Binder.restoreCallingIdentity(identity);
5639 }
5640 }
5641
5642 @Override
5643 public boolean getImsProvisioningStatusForCapability(int subId, int capability, int tech) {
joonhunshincffb7fc2021-11-28 07:32:01 +00005644 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5645 mApp, subId, "getProvisioningStatusForCapability");
5646
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005647 final long identity = Binder.clearCallingIdentity();
5648 try {
joonhunshin91bc1952022-04-29 08:47:15 +00005649 ImsProvisioningController controller = ImsProvisioningController.getInstance();
5650 if (controller == null) {
5651 loge("getImsProvisioningStatusForCapability: Device does not support IMS");
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005652
joonhunshin91bc1952022-04-29 08:47:15 +00005653 // device does not support IMS, this method will return true always.
5654 return true;
5655 }
5656 return controller.getImsProvisioningStatusForCapability(subId, capability, tech);
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005657 } finally {
5658 Binder.restoreCallingIdentity(identity);
5659 }
5660 }
5661
5662 @Override
joonhunshincffb7fc2021-11-28 07:32:01 +00005663 public boolean isProvisioningRequiredForCapability(int subId, int capability, int tech) {
5664 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5665 mApp, subId, "isProvisioningRequiredForCapability");
5666
5667 final long identity = Binder.clearCallingIdentity();
5668 try {
joonhunshin91bc1952022-04-29 08:47:15 +00005669 ImsProvisioningController controller = ImsProvisioningController.getInstance();
5670 if (controller == null) {
5671 loge("isProvisioningRequiredForCapability: Device does not support IMS");
5672
5673 // device does not support IMS, this method will return false
5674 return false;
5675 }
5676 return controller.isImsProvisioningRequiredForCapability(subId, capability, tech);
joonhunshincffb7fc2021-11-28 07:32:01 +00005677 } finally {
5678 Binder.restoreCallingIdentity(identity);
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005679 }
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005680 }
5681
5682 @Override
joonhunshincffb7fc2021-11-28 07:32:01 +00005683 public boolean isRcsProvisioningRequiredForCapability(int subId, int capability, int tech) {
5684 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5685 mApp, subId, "isProvisioningRequiredForCapability");
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005686
joonhunshincffb7fc2021-11-28 07:32:01 +00005687 final long identity = Binder.clearCallingIdentity();
5688 try {
joonhunshin91bc1952022-04-29 08:47:15 +00005689 ImsProvisioningController controller = ImsProvisioningController.getInstance();
5690 if (controller == null) {
5691 loge("isRcsProvisioningRequiredForCapability: Device does not support IMS");
5692
5693 // device does not support IMS, this method will return false
5694 return false;
5695 }
5696 return controller.isRcsProvisioningRequiredForCapability(subId, capability, tech);
joonhunshincffb7fc2021-11-28 07:32:01 +00005697 } finally {
5698 Binder.restoreCallingIdentity(identity);
5699 }
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005700 }
5701
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005702 @Override
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005703 public int getImsProvisioningInt(int subId, int key) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005704 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5705 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
5706 }
joonhunshincffb7fc2021-11-28 07:32:01 +00005707 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5708 mApp, subId, "getImsProvisioningInt");
5709
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005710 final long identity = Binder.clearCallingIdentity();
5711 try {
5712 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005713 int slotId = getSlotIndex(subId);
5714 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5715 Log.w(LOG_TAG, "getImsProvisioningInt: called with an inactive subscription '"
5716 + subId + "' for key:" + key);
5717 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
5718 }
joonhunshincffb7fc2021-11-28 07:32:01 +00005719
joonhunshin91bc1952022-04-29 08:47:15 +00005720 ImsProvisioningController controller = ImsProvisioningController.getInstance();
5721 if (controller == null) {
5722 loge("getImsProvisioningInt: Device does not support IMS");
5723
5724 // device does not support IMS, this method will return CONFIG_RESULT_UNKNOWN.
5725 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
5726 }
5727 int retVal = controller.getProvisioningValue(subId, key);
joonhunshincffb7fc2021-11-28 07:32:01 +00005728 if (retVal != ImsConfigImplBase.CONFIG_RESULT_UNKNOWN) {
5729 return retVal;
5730 }
5731
calvinpanb5a34062021-02-08 19:59:36 +08005732 return ImsManager.getInstance(mApp, slotId).getConfigInt(key);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005733 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005734 Log.w(LOG_TAG, "getImsProvisioningInt: ImsService is not available for subscription '"
5735 + subId + "' for key:" + key);
5736 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005737 } finally {
5738 Binder.restoreCallingIdentity(identity);
5739 }
5740 }
5741
5742 @Override
5743 public String getImsProvisioningString(int subId, int key) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005744 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5745 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
5746 }
joonhunshincffb7fc2021-11-28 07:32:01 +00005747 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5748 mApp, subId, "getImsProvisioningString");
5749
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005750 final long identity = Binder.clearCallingIdentity();
5751 try {
5752 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005753 int slotId = getSlotIndex(subId);
5754 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5755 Log.w(LOG_TAG, "getImsProvisioningString: called for an inactive subscription id '"
5756 + subId + "' for key:" + key);
5757 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_GENERIC;
5758 }
calvinpanb5a34062021-02-08 19:59:36 +08005759 return ImsManager.getInstance(mApp, slotId).getConfigString(key);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005760 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005761 Log.w(LOG_TAG, "getImsProvisioningString: ImsService is not available for sub '"
5762 + subId + "' for key:" + key);
5763 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_NOT_READY;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005764 } finally {
5765 Binder.restoreCallingIdentity(identity);
5766 }
5767 }
5768
5769 @Override
5770 public int setImsProvisioningInt(int subId, int key, int value) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005771 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5772 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
5773 }
Brad Ebinger3d0b34e2018-11-15 14:13:12 -08005774 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5775 "setImsProvisioningInt");
joonhunshincffb7fc2021-11-28 07:32:01 +00005776
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005777 final long identity = Binder.clearCallingIdentity();
5778 try {
5779 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005780 int slotId = getSlotIndex(subId);
5781 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5782 Log.w(LOG_TAG, "setImsProvisioningInt: called with an inactive subscription id '"
5783 + subId + "' for key:" + key);
5784 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
5785 }
joonhunshincffb7fc2021-11-28 07:32:01 +00005786
joonhunshin91bc1952022-04-29 08:47:15 +00005787 ImsProvisioningController controller = ImsProvisioningController.getInstance();
5788 if (controller == null) {
5789 loge("setImsProvisioningInt: Device does not support IMS");
5790
5791 // device does not support IMS, this method will return CONFIG_RESULT_FAILED.
5792 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
5793 }
5794 int retVal = controller.setProvisioningValue(subId, key, value);
joonhunshincffb7fc2021-11-28 07:32:01 +00005795 if (retVal != ImsConfigImplBase.CONFIG_RESULT_UNKNOWN) {
5796 return retVal;
5797 }
5798
calvinpanb5a34062021-02-08 19:59:36 +08005799 return ImsManager.getInstance(mApp, slotId).setConfig(key, value);
5800 } catch (com.android.ims.ImsException | RemoteException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005801 Log.w(LOG_TAG, "setImsProvisioningInt: ImsService unavailable for sub '" + subId
calvinpanb5a34062021-02-08 19:59:36 +08005802 + "' for key:" + key, e);
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005803 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005804 } finally {
5805 Binder.restoreCallingIdentity(identity);
5806 }
5807 }
5808
5809 @Override
5810 public int setImsProvisioningString(int subId, int key, String value) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005811 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5812 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
5813 }
Brad Ebinger3d0b34e2018-11-15 14:13:12 -08005814 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5815 "setImsProvisioningString");
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005816 final long identity = Binder.clearCallingIdentity();
5817 try {
5818 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005819 int slotId = getSlotIndex(subId);
5820 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5821 Log.w(LOG_TAG, "setImsProvisioningString: called with an inactive subscription id '"
5822 + subId + "' for key:" + key);
5823 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
5824 }
calvinpanb5a34062021-02-08 19:59:36 +08005825 return ImsManager.getInstance(mApp, slotId).setConfig(key, value);
5826 } catch (com.android.ims.ImsException | RemoteException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005827 Log.w(LOG_TAG, "setImsProvisioningString: ImsService unavailable for sub '" + subId
calvinpanb5a34062021-02-08 19:59:36 +08005828 + "' for key:" + key, e);
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005829 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005830 } finally {
5831 Binder.restoreCallingIdentity(identity);
5832 }
5833 }
5834
Brad Ebinger919631e2021-06-02 17:46:35 -07005835 /**
5836 * Throw an ImsException if the IMS resolver does not have an ImsService configured for MMTEL
5837 * for the given slot ID or no ImsResolver instance has been created.
5838 * @param slotId The slot ID that the IMS service is created for.
5839 * @throws ImsException If there is no ImsService configured for this slot.
5840 */
5841 private void verifyImsMmTelConfiguredOrThrow(int slotId) throws ImsException {
5842 if (mImsResolver == null || !mImsResolver.isImsServiceConfiguredForFeature(slotId,
5843 ImsFeature.FEATURE_MMTEL)) {
5844 throw new ImsException("This subscription does not support MMTEL over IMS",
5845 ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
5846 }
5847 }
5848
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005849 private int getSlotIndexOrException(int subId) throws ImsException {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005850 int slotId = SubscriptionManager.getSlotIndex(subId);
5851 if (!SubscriptionManager.isValidSlotIndex(slotId)) {
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005852 throw new ImsException("Invalid Subscription Id, subId=" + subId,
5853 ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
Brad Ebinger35c841c2018-10-01 10:40:55 -07005854 }
5855 return slotId;
5856 }
5857
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005858 private int getSlotIndex(int subId) {
5859 int slotId = SubscriptionManager.getSlotIndex(subId);
5860 if (!SubscriptionManager.isValidSlotIndex(slotId)) {
5861 return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
5862 }
5863 return slotId;
5864 }
5865
Wink Saville36469e72014-06-11 15:17:00 -07005866 /**
Nathan Harold9042f0b2019-05-21 15:51:27 -07005867 * Returns the data network type for a subId; does not throw SecurityException.
Wink Saville36469e72014-06-11 15:17:00 -07005868 */
5869 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005870 public int getNetworkTypeForSubscriber(int subId, String callingPackage,
5871 String callingFeatureId) {
Shuo Qian13d89152021-05-10 23:58:11 -07005872 try {
5873 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
5874 } catch (SecurityException se) {
5875 EventLog.writeEvent(0x534e4554, "186776740", Binder.getCallingUid());
5876 throw new SecurityException("Package " + callingPackage + " does not belong to "
5877 + Binder.getCallingUid());
5878 }
Nathan Haroldf096d982020-11-18 17:18:06 -08005879 final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
Nathan Haroldef60dba2019-05-22 13:55:14 -07005880 if (targetSdk > android.os.Build.VERSION_CODES.Q) {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005881 return getDataNetworkTypeForSubscriber(subId, callingPackage, callingFeatureId);
Nathan Haroldef60dba2019-05-22 13:55:14 -07005882 } else if (targetSdk == android.os.Build.VERSION_CODES.Q
Nathan Harold9042f0b2019-05-21 15:51:27 -07005883 && !TelephonyPermissions.checkCallingOrSelfReadPhoneStateNoThrow(
Thomas Nguyen8ee49682023-02-01 11:46:09 -08005884 mApp, subId, callingPackage, callingFeatureId,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005885 "getNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07005886 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5887 }
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07005888
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005889 final long identity = Binder.clearCallingIdentity();
5890 try {
5891 final Phone phone = getPhone(subId);
5892 if (phone != null) {
5893 return phone.getServiceState().getDataNetworkType();
5894 } else {
5895 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5896 }
5897 } finally {
5898 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07005899 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005900 }
5901
5902 /**
5903 * Returns the data network type
5904 */
5905 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005906 public int getDataNetworkType(String callingPackage, String callingFeatureId) {
Jack Yu285100e2022-12-02 22:48:35 -08005907 return getDataNetworkTypeForSubscriber(SubscriptionManager.getDefaultDataSubscriptionId(),
Zoey Chenfd61f7f2021-04-21 13:42:10 +08005908 callingPackage, callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07005909 }
5910
5911 /**
5912 * Returns the data network type for a subId
5913 */
5914 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005915 public int getDataNetworkTypeForSubscriber(int subId, String callingPackage,
5916 String callingFeatureId) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07005917 String functionName = "getDataNetworkTypeForSubscriber";
5918 if (!TelephonyPermissions.checkCallingOrSelfReadNonDangerousPhoneStateNoThrow(
5919 mApp, functionName)) {
5920 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5921 mApp, subId, callingPackage, callingFeatureId, functionName)) {
5922 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5923 }
Robert Greenwalt36b23af2015-07-06 17:59:14 -07005924 }
5925
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005926 final long identity = Binder.clearCallingIdentity();
5927 try {
5928 final Phone phone = getPhone(subId);
5929 if (phone != null) {
5930 return phone.getServiceState().getDataNetworkType();
5931 } else {
5932 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5933 }
5934 } finally {
5935 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07005936 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005937 }
5938
5939 /**
Wink Saville36469e72014-06-11 15:17:00 -07005940 * Returns the Voice network type for a subId
5941 */
5942 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005943 public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage,
5944 String callingFeatureId) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07005945 String functionName = "getVoiceNetworkTypeForSubscriber";
5946 if (!TelephonyPermissions.checkCallingOrSelfReadNonDangerousPhoneStateNoThrow(
5947 mApp, functionName)) {
5948 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5949 mApp, subId, callingPackage, callingFeatureId, functionName)) {
5950 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5951 }
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07005952 }
5953
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005954 final long identity = Binder.clearCallingIdentity();
5955 try {
5956 final Phone phone = getPhone(subId);
5957 if (phone != null) {
5958 return phone.getServiceState().getVoiceNetworkType();
5959 } else {
5960 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5961 }
5962 } finally {
5963 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07005964 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005965 }
5966
5967 /**
5968 * @return true if a ICC card is present
5969 */
5970 public boolean hasIccCard() {
Wink Saville36469e72014-06-11 15:17:00 -07005971 // FIXME Make changes to pass defaultSimId of type int
Jack Yu285100e2022-12-02 22:48:35 -08005972 return hasIccCardUsingSlotIndex(SubscriptionManager.getSlotIndex(
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005973 getDefaultSubscription()));
Wink Saville36469e72014-06-11 15:17:00 -07005974 }
5975
5976 /**
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005977 * @return true if a ICC card is present for a slotIndex
Wink Saville36469e72014-06-11 15:17:00 -07005978 */
Sanket Padawe356d7632015-06-22 14:03:32 -07005979 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005980 public boolean hasIccCardUsingSlotIndex(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005981 final long identity = Binder.clearCallingIdentity();
5982 try {
5983 final Phone phone = PhoneFactory.getPhone(slotIndex);
5984 if (phone != null) {
5985 return phone.getIccCard().hasIccCard();
5986 } else {
5987 return false;
5988 }
5989 } finally {
5990 Binder.restoreCallingIdentity(identity);
Amit Mahajana6fc2a82015-01-06 11:53:51 -08005991 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005992 }
5993
5994 /**
5995 * Return if the current radio is LTE on CDMA. This
5996 * is a tri-state return value as for a period of time
5997 * the mode may be unknown.
5998 *
Robert Greenwalt36b23af2015-07-06 17:59:14 -07005999 * @param callingPackage the name of the package making the call.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07006000 * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
Jake Hambye994d462014-02-03 13:10:13 -08006001 * or {@link Phone#LTE_ON_CDMA_TRUE}
Santos Cordon7d4ddf62013-07-10 11:58:08 -07006002 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07006003 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006004 public int getLteOnCdmaMode(String callingPackage, String callingFeatureId) {
6005 return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage,
6006 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07006007 }
6008
Sanket Padawe356d7632015-06-22 14:03:32 -07006009 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006010 public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage,
6011 String callingFeatureId) {
Sarah Chin790d2922020-01-16 12:17:23 -08006012 try {
6013 enforceReadPrivilegedPermission("getLteOnCdmaModeForSubscriber");
6014 } catch (SecurityException e) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07006015 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
6016 }
6017
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006018 final long identity = Binder.clearCallingIdentity();
6019 try {
6020 final Phone phone = getPhone(subId);
6021 if (phone == null) {
6022 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
6023 } else {
Nathan Harold05ad6332020-07-10 11:54:36 -07006024 return TelephonyProperties.lte_on_cdma_device()
6025 .orElse(PhoneConstants.LTE_ON_CDMA_FALSE);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006026 }
6027 } finally {
6028 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07006029 }
Wink Saville36469e72014-06-11 15:17:00 -07006030 }
6031
Wink Saville36469e72014-06-11 15:17:00 -07006032 /**
6033 * {@hide}
6034 * Returns Default subId, 0 in the case of single standby.
6035 */
Wink Savilleb564aae2014-10-23 10:18:09 -07006036 private int getDefaultSubscription() {
Jack Yu285100e2022-12-02 22:48:35 -08006037 return SubscriptionManager.getDefaultSubscriptionId();
Wink Saville36469e72014-06-11 15:17:00 -07006038 }
6039
Shishir Agrawala9f32182016-04-12 12:00:16 -07006040 private int getSlotForDefaultSubscription() {
Jack Yu285100e2022-12-02 22:48:35 -08006041 return SubscriptionManager.getPhoneId(getDefaultSubscription());
Shishir Agrawala9f32182016-04-12 12:00:16 -07006042 }
6043
Wink Savilleb564aae2014-10-23 10:18:09 -07006044 private int getPreferredVoiceSubscription() {
Jack Yu285100e2022-12-02 22:48:35 -08006045 return SubscriptionManager.getDefaultVoiceSubscriptionId();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07006046 }
Ihab Awadf2177b72013-11-25 13:33:23 -08006047
Pengquan Menge92a50d2018-09-21 15:54:48 -07006048 private boolean isActiveSubscription(int subId) {
Jack Yu285100e2022-12-02 22:48:35 -08006049 if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
Jack Yufa8ed012023-02-11 15:42:28 -08006050 return getSubscriptionManagerService().isActiveSubId(subId,
Jack Yu285100e2022-12-02 22:48:35 -08006051 mApp.getOpPackageName(), mApp.getFeatureId());
6052 }
Pengquan Menge92a50d2018-09-21 15:54:48 -07006053 return mSubscriptionController.isActiveSubId(subId);
6054 }
6055
Ihab Awadf2177b72013-11-25 13:33:23 -08006056 /**
6057 * @see android.telephony.TelephonyManager.WifiCallingChoices
6058 */
6059 public int getWhenToMakeWifiCalls() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006060 final long identity = Binder.clearCallingIdentity();
6061 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006062 return Settings.System.getInt(mApp.getContentResolver(),
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006063 Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
6064 getWhenToMakeWifiCallsDefaultPreference());
6065 } finally {
6066 Binder.restoreCallingIdentity(identity);
6067 }
Ihab Awadf2177b72013-11-25 13:33:23 -08006068 }
6069
6070 /**
6071 * @see android.telephony.TelephonyManager.WifiCallingChoices
6072 */
6073 public void setWhenToMakeWifiCalls(int preference) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006074 final long identity = Binder.clearCallingIdentity();
6075 try {
6076 if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006077 Settings.System.putInt(mApp.getContentResolver(),
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006078 Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference);
6079 } finally {
6080 Binder.restoreCallingIdentity(identity);
6081 }
Ihab Awadf9e92732013-12-05 18:02:52 -08006082 }
6083
Sailesh Nepald1e68152013-12-12 19:08:02 -08006084 private static int getWhenToMakeWifiCallsDefaultPreference() {
Santos Cordonda120f42014-08-06 04:44:34 -07006085 // TODO: Use a build property to choose this value.
Evan Charlton9829e882013-12-19 15:30:38 -08006086 return TelephonyManager.WifiCallingChoices.ALWAYS_USE;
Ihab Awadf2177b72013-11-25 13:33:23 -08006087 }
Shishir Agrawal69f68122013-12-16 17:25:49 -08006088
Muralidhar Reddybd38d952021-12-02 21:04:16 +00006089 private Phone getPhoneFromSlotPortIndexOrThrowException(int slotIndex, int portIndex) {
6090 int phoneId = UiccController.getInstance().getPhoneIdFromSlotPortIndex(slotIndex,
6091 portIndex);
Jordan Liu4c733742019-02-28 12:03:40 -08006092 if (phoneId == -1) {
Muralidhar Reddybd38d952021-12-02 21:04:16 +00006093 throw new IllegalArgumentException("Given slot index: " + slotIndex + " port index: "
Thomas Nguyen8ee49682023-02-01 11:46:09 -08006094 + portIndex + " does not correspond to an active phone");
Jordan Liu4c733742019-02-28 12:03:40 -08006095 }
6096 return PhoneFactory.getPhone(phoneId);
6097 }
6098
Shishir Agrawal566b7612013-10-28 14:41:00 -07006099 @Override
Derek Tan740e1672017-06-27 14:56:27 -07006100 public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
Rambo Wanga1782702021-11-10 20:15:19 -08006101 @NonNull IccLogicalChannelRequest request) {
6102 Phone phone = getPhoneFromValidIccLogicalChannelRequest(request,
6103 /*message=*/ "iccOpenLogicalChannel");
6104
6105 if (DBG) log("iccOpenLogicalChannel: request=" + request);
6106 // Verify that the callingPackage in the request belongs to the calling UID
6107 mAppOps.checkPackage(Binder.getCallingUid(), request.callingPackage);
6108
6109 return iccOpenLogicalChannelWithPermission(phone, request);
Jordan Liu4c733742019-02-28 12:03:40 -08006110 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07006111
Rambo Wanga1782702021-11-10 20:15:19 -08006112 private Phone getPhoneFromValidIccLogicalChannelRequest(
6113 @NonNull IccLogicalChannelRequest request, String message) {
6114 Phone phone;
6115 if (request.subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
6116 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6117 mApp, request.subId, message);
6118 phone = getPhoneFromSubId(request.subId);
6119 } else if (request.slotIndex != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
6120 enforceModifyPermission();
6121 phone = getPhoneFromSlotPortIndexOrThrowException(request.slotIndex, request.portIndex);
6122 } else {
6123 throw new IllegalArgumentException("Both subId and slotIndex in request are invalid.");
Jordan Liu4c733742019-02-28 12:03:40 -08006124 }
Rambo Wanga1782702021-11-10 20:15:19 -08006125 return phone;
Jordan Liu4c733742019-02-28 12:03:40 -08006126 }
6127
6128 private IccOpenLogicalChannelResponse iccOpenLogicalChannelWithPermission(Phone phone,
Rambo Wanga1782702021-11-10 20:15:19 -08006129 IccLogicalChannelRequest channelRequest) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006130 final long identity = Binder.clearCallingIdentity();
6131 try {
Rambo Wanga1782702021-11-10 20:15:19 -08006132 if (TextUtils.equals(ISDR_AID, channelRequest.aid)) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006133 // Only allows LPA to open logical channel to ISD-R.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006134 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
6135 .getContext().getPackageManager());
Rambo Wanga1782702021-11-10 20:15:19 -08006136 if (bestComponent == null || !TextUtils.equals(channelRequest.callingPackage,
6137 bestComponent.packageName)) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006138 loge("The calling package is not allowed to access ISD-R.");
6139 throw new SecurityException(
6140 "The calling package is not allowed to access ISD-R.");
6141 }
Derek Tan740e1672017-06-27 14:56:27 -07006142 }
Derek Tan740e1672017-06-27 14:56:27 -07006143
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006144 IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse) sendRequest(
Rambo Wanga1782702021-11-10 20:15:19 -08006145 CMD_OPEN_CHANNEL, channelRequest, phone, null /* workSource */);
6146 if (DBG) log("iccOpenLogicalChannelWithPermission: response=" + response);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006147 return response;
6148 } finally {
6149 Binder.restoreCallingIdentity(identity);
6150 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07006151 }
6152
6153 @Override
Rambo Wanga1782702021-11-10 20:15:19 -08006154 public boolean iccCloseLogicalChannel(@NonNull IccLogicalChannelRequest request) {
6155 Phone phone = getPhoneFromValidIccLogicalChannelRequest(request,
6156 /*message=*/"iccCloseLogicalChannel");
6157
6158 if (DBG) log("iccCloseLogicalChannel: request=" + request);
6159
6160 return iccCloseLogicalChannelWithPermission(phone, request);
Jordan Liu4c733742019-02-28 12:03:40 -08006161 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07006162
Rambo Wanga1782702021-11-10 20:15:19 -08006163 private boolean iccCloseLogicalChannelWithPermission(Phone phone,
6164 IccLogicalChannelRequest request) {
Chen Xua8f0dff2022-02-12 00:34:15 -08006165 // before this feature is enabled, this API should only return false if
6166 // the operation fails instead of throwing runtime exception for
6167 // backward-compatibility.
6168 final boolean shouldThrowExceptionOnFailure = CompatChanges.isChangeEnabled(
6169 ICC_CLOSE_CHANNEL_EXCEPTION_ON_FAILURE, Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006170 final long identity = Binder.clearCallingIdentity();
6171 try {
Rambo Wanga1782702021-11-10 20:15:19 -08006172 if (request.channel < 0) {
Chen Xu540470b2021-12-14 17:15:47 -08006173 throw new IllegalArgumentException("request.channel is less than 0");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006174 }
Chen Xue9d737e2022-01-01 23:41:31 -08006175 Object result = sendRequest(CMD_CLOSE_CHANNEL, request.channel, phone,
Jordan Liu4c733742019-02-28 12:03:40 -08006176 null /* workSource */);
Chen Xue9d737e2022-01-01 23:41:31 -08006177 Boolean success = false;
6178 if (result instanceof RuntimeException) {
6179 // if there is an exception returned, throw from the binder thread here.
Chen Xua8f0dff2022-02-12 00:34:15 -08006180 if (shouldThrowExceptionOnFailure) {
6181 throw (RuntimeException) result;
6182 } else {
6183 return false;
6184 }
Chen Xue9d737e2022-01-01 23:41:31 -08006185 } else if (result instanceof Boolean) {
6186 success = (Boolean) result;
6187 } else {
6188 loge("iccCloseLogicalChannelWithPermission: supported return type " + result);
6189 }
Rambo Wanga1782702021-11-10 20:15:19 -08006190 if (DBG) log("iccCloseLogicalChannelWithPermission: success=" + success);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006191 return success;
6192 } finally {
6193 Binder.restoreCallingIdentity(identity);
Shishir Agrawal566b7612013-10-28 14:41:00 -07006194 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07006195 }
6196
6197 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08006198 public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
Shishir Agrawal566b7612013-10-28 14:41:00 -07006199 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006200 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6201 mApp, subId, "iccTransmitApduLogicalChannel");
Jordan Liu4c733742019-02-28 12:03:40 -08006202 if (DBG) {
6203 log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel
6204 + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
6205 + p3 + " data=" + data);
6206 }
6207 return iccTransmitApduLogicalChannelWithPermission(getPhoneFromSubId(subId), channel, cla,
6208 command, p1, p2, p3, data);
6209 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07006210
Jordan Liu4c733742019-02-28 12:03:40 -08006211 @Override
Muralidhar Reddybd38d952021-12-02 21:04:16 +00006212 public String iccTransmitApduLogicalChannelByPort(int slotIndex, int portIndex, int channel,
Thomas Nguyen8ee49682023-02-01 11:46:09 -08006213 int cla, int command, int p1, int p2, int p3, String data) {
Jordan Liu4c733742019-02-28 12:03:40 -08006214 enforceModifyPermission();
6215 if (DBG) {
Muralidhar Reddybd38d952021-12-02 21:04:16 +00006216 log("iccTransmitApduLogicalChannelByPort: slotIndex=" + slotIndex + " portIndex="
Thomas Nguyen8ee49682023-02-01 11:46:09 -08006217 + portIndex + " chnl=" + channel + " cla=" + cla + " cmd=" + command + " p1="
6218 + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
Jordan Liu4c733742019-02-28 12:03:40 -08006219 }
6220 return iccTransmitApduLogicalChannelWithPermission(
Muralidhar Reddybd38d952021-12-02 21:04:16 +00006221 getPhoneFromSlotPortIndexOrThrowException(slotIndex, portIndex), channel, cla,
6222 command, p1, p2, p3, data);
Jordan Liu4c733742019-02-28 12:03:40 -08006223 }
6224
6225 private String iccTransmitApduLogicalChannelWithPermission(Phone phone, int channel, int cla,
6226 int command, int p1, int p2, int p3, String data) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006227 final long identity = Binder.clearCallingIdentity();
6228 try {
Hall Liu4fd771b2019-05-02 09:16:29 -07006229 if (channel <= 0) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006230 return "";
6231 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07006232
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006233 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL,
Jordan Liu4c733742019-02-28 12:03:40 -08006234 new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), phone,
6235 null /* workSource */);
6236 if (DBG) log("iccTransmitApduLogicalChannelWithPermission: " + response);
Shishir Agrawal566b7612013-10-28 14:41:00 -07006237
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006238 // Append the returned status code to the end of the response payload.
6239 String s = Integer.toHexString(
6240 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
6241 if (response.payload != null) {
6242 s = IccUtils.bytesToHexString(response.payload) + s;
6243 }
6244 return s;
6245 } finally {
6246 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07006247 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07006248 }
Jake Hambye994d462014-02-03 13:10:13 -08006249
Evan Charltonc66da362014-05-16 14:06:40 -07006250 @Override
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08006251 public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
6252 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006253 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6254 mApp, subId, "iccTransmitApduBasicChannel");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006255 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jordan Liu4c733742019-02-28 12:03:40 -08006256 if (DBG) {
6257 log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd="
6258 + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
6259 }
6260 return iccTransmitApduBasicChannelWithPermission(getPhoneFromSubId(subId), callingPackage,
6261 cla, command, p1, p2, p3, data);
6262 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07006263
Jordan Liu4c733742019-02-28 12:03:40 -08006264 @Override
Muralidhar Reddybd38d952021-12-02 21:04:16 +00006265 public String iccTransmitApduBasicChannelByPort(int slotIndex, int portIndex,
Thomas Nguyen8ee49682023-02-01 11:46:09 -08006266 String callingPackage, int cla, int command, int p1, int p2, int p3, String data) {
Jordan Liu4c733742019-02-28 12:03:40 -08006267 enforceModifyPermission();
6268 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
6269 if (DBG) {
Muralidhar Reddybd38d952021-12-02 21:04:16 +00006270 log("iccTransmitApduBasicChannelByPort: slotIndex=" + slotIndex + " portIndex="
Thomas Nguyen8ee49682023-02-01 11:46:09 -08006271 + portIndex + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2="
6272 + p2 + " p3=" + p3 + " data=" + data);
Jordan Liu4c733742019-02-28 12:03:40 -08006273 }
6274
6275 return iccTransmitApduBasicChannelWithPermission(
Muralidhar Reddybd38d952021-12-02 21:04:16 +00006276 getPhoneFromSlotPortIndexOrThrowException(slotIndex, portIndex), callingPackage,
6277 cla, command, p1, p2, p3, data);
Jordan Liu4c733742019-02-28 12:03:40 -08006278 }
6279
6280 // open APDU basic channel assuming the caller has sufficient permissions
6281 private String iccTransmitApduBasicChannelWithPermission(Phone phone, String callingPackage,
6282 int cla, int command, int p1, int p2, int p3, String data) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006283 final long identity = Binder.clearCallingIdentity();
6284 try {
6285 if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
6286 && TextUtils.equals(ISDR_AID, data)) {
6287 // Only allows LPA to select ISD-R.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08006288 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
6289 .getContext().getPackageManager());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006290 if (bestComponent == null
6291 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
6292 loge("The calling package is not allowed to select ISD-R.");
6293 throw new SecurityException(
6294 "The calling package is not allowed to select ISD-R.");
6295 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08006296 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08006297
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006298 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL,
Jordan Liu4c733742019-02-28 12:03:40 -08006299 new IccAPDUArgument(0, cla, command, p1, p2, p3, data), phone,
6300 null /* workSource */);
6301 if (DBG) log("iccTransmitApduBasicChannelWithPermission: " + response);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07006302
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006303 // Append the returned status code to the end of the response payload.
6304 String s = Integer.toHexString(
6305 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
6306 if (response.payload != null) {
6307 s = IccUtils.bytesToHexString(response.payload) + s;
6308 }
6309 return s;
6310 } finally {
6311 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07006312 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07006313 }
6314
6315 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08006316 public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07006317 String filePath) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006318 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6319 mApp, subId, "iccExchangeSimIO");
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07006320
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006321 final long identity = Binder.clearCallingIdentity();
6322 try {
6323 if (DBG) {
6324 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " "
6325 + p1 + " " + p2 + " " + p3 + ":" + filePath);
6326 }
6327
6328 IccIoResult response =
6329 (IccIoResult) sendRequest(CMD_EXCHANGE_SIM_IO,
6330 new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath),
6331 subId);
6332
6333 if (DBG) {
6334 log("Exchange SIM_IO [R]" + response);
6335 }
6336
6337 byte[] result = null;
6338 int length = 2;
6339 if (response.payload != null) {
6340 length = 2 + response.payload.length;
6341 result = new byte[length];
6342 System.arraycopy(response.payload, 0, result, 0, response.payload.length);
6343 } else {
6344 result = new byte[length];
6345 }
6346
6347 result[length - 1] = (byte) response.sw2;
6348 result[length - 2] = (byte) response.sw1;
6349 return result;
6350 } finally {
6351 Binder.restoreCallingIdentity(identity);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07006352 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07006353 }
6354
Nathan Haroldb3014052017-01-25 15:57:32 -08006355 /**
6356 * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
6357 * on a particular subscription
6358 */
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006359 public String[] getForbiddenPlmns(int subId, int appType, String callingPackage,
6360 String callingFeatureId) {
sqianb6e41952018-03-12 14:54:01 -07006361 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006362 mApp, subId, callingPackage, callingFeatureId, "getForbiddenPlmns")) {
sqianb6e41952018-03-12 14:54:01 -07006363 return null;
6364 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006365
6366 final long identity = Binder.clearCallingIdentity();
6367 try {
6368 if (appType != TelephonyManager.APPTYPE_USIM
6369 && appType != TelephonyManager.APPTYPE_SIM) {
6370 loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
6371 return null;
6372 }
6373 Object response = sendRequest(
6374 CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
6375 if (response instanceof String[]) {
6376 return (String[]) response;
6377 }
yincheng zhao2737e882019-09-06 17:06:54 -07006378 // Response is an Exception of some kind
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006379 // which is signalled to the user as a NULL retval
Nathan Haroldb3014052017-01-25 15:57:32 -08006380 return null;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006381 } finally {
6382 Binder.restoreCallingIdentity(identity);
Nathan Haroldb3014052017-01-25 15:57:32 -08006383 }
Nathan Haroldb3014052017-01-25 15:57:32 -08006384 }
6385
yincheng zhao2737e882019-09-06 17:06:54 -07006386 /**
6387 * Set the forbidden PLMN list from the given app type (ex APPTYPE_USIM) on a particular
6388 * subscription.
6389 *
6390 * @param subId the id of the subscription.
6391 * @param appType the uicc app type, must be USIM or SIM.
6392 * @param fplmns the Forbiden plmns list that needed to be written to the SIM.
6393 * @param callingPackage the op Package name.
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006394 * @param callingFeatureId the feature in the package.
yincheng zhao2737e882019-09-06 17:06:54 -07006395 * @return number of fplmns that is successfully written to the SIM.
6396 */
Philip P. Moltmann700a9592019-10-03 11:53:50 -07006397 public int setForbiddenPlmns(int subId, int appType, List<String> fplmns, String callingPackage,
6398 String callingFeatureId) {
Jayachandran C5b0d75a2021-10-21 22:15:27 -07006399 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6400 mApp, subId, "setForbiddenPlmns");
6401
yincheng zhao2737e882019-09-06 17:06:54 -07006402 if (appType != TelephonyManager.APPTYPE_USIM && appType != TelephonyManager.APPTYPE_SIM) {
6403 loge("setForbiddenPlmnList(): App Type must be USIM or SIM");
6404 throw new IllegalArgumentException("Invalid appType: App Type must be USIM or SIM");
6405 }
6406 if (fplmns == null) {
6407 throw new IllegalArgumentException("Fplmn List provided is null");
6408 }
6409 for (String fplmn : fplmns) {
6410 if (!CellIdentity.isValidPlmn(fplmn)) {
6411 throw new IllegalArgumentException("Invalid fplmn provided: " + fplmn);
6412 }
6413 }
6414 final long identity = Binder.clearCallingIdentity();
6415 try {
6416 Object response = sendRequest(
6417 CMD_SET_FORBIDDEN_PLMNS,
6418 new Pair<Integer, List<String>>(new Integer(appType), fplmns),
6419 subId);
6420 return (int) response;
6421 } finally {
6422 Binder.restoreCallingIdentity(identity);
6423 }
6424 }
6425
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07006426 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08006427 public String sendEnvelopeWithStatus(int subId, String content) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006428 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6429 mApp, subId, "sendEnvelopeWithStatus");
Evan Charltonc66da362014-05-16 14:06:40 -07006430
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006431 final long identity = Binder.clearCallingIdentity();
6432 try {
6433 IccIoResult response = (IccIoResult) sendRequest(CMD_SEND_ENVELOPE, content, subId);
6434 if (response.payload == null) {
6435 return "";
6436 }
Evan Charltonc66da362014-05-16 14:06:40 -07006437
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006438 // Append the returned status code to the end of the response payload.
6439 String s = Integer.toHexString(
6440 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
6441 s = IccUtils.bytesToHexString(response.payload) + s;
6442 return s;
6443 } finally {
6444 Binder.restoreCallingIdentity(identity);
6445 }
Evan Charltonc66da362014-05-16 14:06:40 -07006446 }
6447
Jake Hambye994d462014-02-03 13:10:13 -08006448 /**
6449 * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
6450 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
6451 *
6452 * @param itemID the ID of the item to read
6453 * @return the NV item as a String, or null on error.
6454 */
6455 @Override
6456 public String nvReadItem(int itemID) {
vagdeviaf9a5b92018-08-15 16:01:53 -07006457 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08006458 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6459 mApp, getDefaultSubscription(), "nvReadItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006460
6461 final long identity = Binder.clearCallingIdentity();
6462 try {
6463 if (DBG) log("nvReadItem: item " + itemID);
vagdeviaf9a5b92018-08-15 16:01:53 -07006464 String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006465 if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
6466 return value;
6467 } finally {
6468 Binder.restoreCallingIdentity(identity);
6469 }
Jake Hambye994d462014-02-03 13:10:13 -08006470 }
6471
6472 /**
6473 * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
6474 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
6475 *
6476 * @param itemID the ID of the item to read
6477 * @param itemValue the value to write, as a String
6478 * @return true on success; false on any failure
6479 */
6480 @Override
6481 public boolean nvWriteItem(int itemID, String itemValue) {
vagdeviaf9a5b92018-08-15 16:01:53 -07006482 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08006483 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6484 mApp, getDefaultSubscription(), "nvWriteItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006485
6486 final long identity = Binder.clearCallingIdentity();
6487 try {
6488 if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
6489 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
vagdeviaf9a5b92018-08-15 16:01:53 -07006490 new Pair<Integer, String>(itemID, itemValue), workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006491 if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
6492 return success;
6493 } finally {
6494 Binder.restoreCallingIdentity(identity);
6495 }
Jake Hambye994d462014-02-03 13:10:13 -08006496 }
6497
6498 /**
6499 * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
6500 * Used for device configuration by some CDMA operators.
6501 *
6502 * @param preferredRoamingList byte array containing the new PRL
6503 * @return true on success; false on any failure
6504 */
6505 @Override
6506 public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006507 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6508 mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006509
6510 final long identity = Binder.clearCallingIdentity();
6511 try {
6512 if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
6513 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
6514 if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
6515 return success;
6516 } finally {
6517 Binder.restoreCallingIdentity(identity);
6518 }
Jake Hambye994d462014-02-03 13:10:13 -08006519 }
6520
6521 /**
chen xu6dac5ab2018-10-26 17:39:23 -07006522 * Rollback modem configurations to factory default except some config which are in whitelist.
Jake Hambye994d462014-02-03 13:10:13 -08006523 * Used for device configuration by some CDMA operators.
6524 *
chen xu6dac5ab2018-10-26 17:39:23 -07006525 * @param slotIndex - device slot.
6526 *
Jake Hambye994d462014-02-03 13:10:13 -08006527 * @return true on success; false on any failure
6528 */
6529 @Override
chen xu6dac5ab2018-10-26 17:39:23 -07006530 public boolean resetModemConfig(int slotIndex) {
6531 Phone phone = PhoneFactory.getPhone(slotIndex);
6532 if (phone != null) {
6533 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6534 mApp, phone.getSubId(), "resetModemConfig");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006535
chen xu6dac5ab2018-10-26 17:39:23 -07006536 final long identity = Binder.clearCallingIdentity();
6537 try {
6538 Boolean success = (Boolean) sendRequest(CMD_RESET_MODEM_CONFIG, null);
6539 if (DBG) log("resetModemConfig:" + ' ' + (success ? "ok" : "fail"));
6540 return success;
6541 } finally {
6542 Binder.restoreCallingIdentity(identity);
6543 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006544 }
chen xu6dac5ab2018-10-26 17:39:23 -07006545 return false;
6546 }
6547
6548 /**
6549 * Generate a radio modem reset. Used for device configuration by some CDMA operators.
6550 *
6551 * @param slotIndex - device slot.
6552 *
6553 * @return true on success; false on any failure
6554 */
6555 @Override
6556 public boolean rebootModem(int slotIndex) {
6557 Phone phone = PhoneFactory.getPhone(slotIndex);
6558 if (phone != null) {
6559 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6560 mApp, phone.getSubId(), "rebootModem");
6561
6562 final long identity = Binder.clearCallingIdentity();
6563 try {
6564 Boolean success = (Boolean) sendRequest(CMD_MODEM_REBOOT, null);
6565 if (DBG) log("rebootModem:" + ' ' + (success ? "ok" : "fail"));
6566 return success;
6567 } finally {
6568 Binder.restoreCallingIdentity(identity);
6569 }
6570 }
6571 return false;
Jake Hambye994d462014-02-03 13:10:13 -08006572 }
Jake Hamby7c27be32014-03-03 13:25:59 -08006573
Brad Ebinger51f743a2017-01-23 13:50:20 -08006574 /**
Grace Jiaaa2eb6b2020-01-09 16:26:08 -08006575 * Toggle IMS disable and enable for the framework to reset it. See {@link #enableIms(int)} and
6576 * {@link #disableIms(int)}.
6577 * @param slotIndex device slot.
6578 */
6579 public void resetIms(int slotIndex) {
6580 enforceModifyPermission();
6581
6582 final long identity = Binder.clearCallingIdentity();
6583 try {
6584 if (mImsResolver == null) {
6585 // may happen if the does not support IMS.
6586 return;
6587 }
Hyunhoa17ac7c2022-08-30 12:03:04 +00006588 mImsResolver.resetIms(slotIndex);
Grace Jiaaa2eb6b2020-01-09 16:26:08 -08006589 } finally {
6590 Binder.restoreCallingIdentity(identity);
6591 }
6592 }
6593
6594 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08006595 * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
6596 * status updates, if not already enabled.
Brad Ebinger51f743a2017-01-23 13:50:20 -08006597 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08006598 public void enableIms(int slotId) {
Brad Ebinger51f743a2017-01-23 13:50:20 -08006599 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006600
6601 final long identity = Binder.clearCallingIdentity();
6602 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08006603 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08006604 // may happen if the device does not support IMS.
6605 return;
6606 }
Brad Ebinger24c29992019-12-05 13:03:21 -08006607 mImsResolver.enableIms(slotId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006608 } finally {
6609 Binder.restoreCallingIdentity(identity);
6610 }
Brad Ebinger34bef922017-11-09 10:27:08 -08006611 }
6612
6613 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08006614 * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
6615 * status updates to disabled.
Brad Ebinger34bef922017-11-09 10:27:08 -08006616 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08006617 public void disableIms(int slotId) {
6618 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006619
6620 final long identity = Binder.clearCallingIdentity();
6621 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08006622 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08006623 // may happen if the device does not support IMS.
6624 return;
6625 }
Brad Ebinger24c29992019-12-05 13:03:21 -08006626 mImsResolver.disableIms(slotId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006627 } finally {
6628 Binder.restoreCallingIdentity(identity);
6629 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08006630 }
6631
6632 /**
Brad Ebinger67b3e042020-09-11 12:45:11 -07006633 * Registers for updates to the MmTelFeature connection through the IImsServiceFeatureCallback
6634 * callback.
Brad Ebinger22bc3e42018-01-16 09:39:35 -08006635 */
Brad Ebinger67b3e042020-09-11 12:45:11 -07006636 @Override
Brad Ebingerf6aca002020-10-01 13:51:05 -07006637 public void registerMmTelFeatureCallback(int slotId, IImsServiceFeatureCallback callback) {
Brad Ebinger34bef922017-11-09 10:27:08 -08006638 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006639
6640 final long identity = Binder.clearCallingIdentity();
6641 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08006642 if (mImsResolver == null) {
Brad Ebinger67b3e042020-09-11 12:45:11 -07006643 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
6644 "Device does not support IMS");
Brad Ebinger9c0eb502019-01-23 15:06:19 -08006645 }
Brad Ebingerf6aca002020-10-01 13:51:05 -07006646 mImsResolver.listenForFeature(slotId, ImsFeature.FEATURE_MMTEL, callback);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006647 } finally {
6648 Binder.restoreCallingIdentity(identity);
6649 }
Brad Ebinger34bef922017-11-09 10:27:08 -08006650 }
Brad Ebinger5f64b052017-12-14 14:26:15 -08006651 /**
Brad Ebinger075ff3a2020-05-18 17:52:58 -07006652 * Unregister a previously registered IImsServiceFeatureCallback associated with an ImsFeature.
6653 */
Brad Ebinger67b3e042020-09-11 12:45:11 -07006654 @Override
6655 public void unregisterImsFeatureCallback(IImsServiceFeatureCallback callback) {
Brad Ebinger075ff3a2020-05-18 17:52:58 -07006656 enforceModifyPermission();
6657
6658 final long identity = Binder.clearCallingIdentity();
6659 try {
6660 if (mImsResolver == null) return;
Brad Ebinger67b3e042020-09-11 12:45:11 -07006661 mImsResolver.unregisterImsFeatureCallback(callback);
Brad Ebinger075ff3a2020-05-18 17:52:58 -07006662 } finally {
6663 Binder.restoreCallingIdentity(identity);
6664 }
6665 }
6666
6667 /**
Brad Ebinger5f64b052017-12-14 14:26:15 -08006668 * Returns the {@link IImsRegistration} structure associated with the slotId and feature
Brad Ebinger9c0eb502019-01-23 15:06:19 -08006669 * specified or null if IMS is not supported on the slot specified.
Brad Ebinger5f64b052017-12-14 14:26:15 -08006670 */
6671 public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
6672 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006673
6674 final long identity = Binder.clearCallingIdentity();
6675 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08006676 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08006677 // may happen if the device does not support IMS.
6678 return null;
6679 }
Brad Ebinger24c29992019-12-05 13:03:21 -08006680 return mImsResolver.getImsRegistration(slotId, feature);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006681 } finally {
6682 Binder.restoreCallingIdentity(identity);
6683 }
Brad Ebinger5f64b052017-12-14 14:26:15 -08006684 }
6685
Brad Ebinger22bc3e42018-01-16 09:39:35 -08006686 /**
6687 * Returns the {@link IImsConfig} structure associated with the slotId and feature
Brad Ebinger9c0eb502019-01-23 15:06:19 -08006688 * specified or null if IMS is not supported on the slot specified.
Brad Ebinger22bc3e42018-01-16 09:39:35 -08006689 */
6690 public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
6691 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006692
6693 final long identity = Binder.clearCallingIdentity();
6694 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08006695 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08006696 // may happen if the device does not support IMS.
6697 return null;
6698 }
Brad Ebinger24c29992019-12-05 13:03:21 -08006699 return mImsResolver.getImsConfig(slotId, feature);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006700 } finally {
6701 Binder.restoreCallingIdentity(identity);
6702 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08006703 }
6704
Brad Ebinger884c07b2018-02-15 16:17:40 -08006705 /**
Brad Ebingerdac2f002018-04-03 15:17:52 -07006706 * Sets the ImsService Package Name that Telephony will bind to.
6707 *
Brad Ebinger24c29992019-12-05 13:03:21 -08006708 * @param slotIndex the slot ID that the ImsService should bind for.
6709 * @param isCarrierService true if the ImsService is the carrier override, false if the
Brad Ebingerdac2f002018-04-03 15:17:52 -07006710 * ImsService is the device default ImsService.
Brad Ebinger24c29992019-12-05 13:03:21 -08006711 * @param featureTypes An integer array of feature types associated with a packageName.
6712 * @param packageName The name of the package that the current configuration will be replaced
6713 * with.
Brad Ebingerdac2f002018-04-03 15:17:52 -07006714 * @return true if setting the ImsService to bind to succeeded, false if it did not.
Brad Ebingerdac2f002018-04-03 15:17:52 -07006715 */
Brad Ebinger24c29992019-12-05 13:03:21 -08006716 public boolean setBoundImsServiceOverride(int slotIndex, boolean isCarrierService,
6717 int[] featureTypes, String packageName) {
Brad Ebinger24c29992019-12-05 13:03:21 -08006718 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setBoundImsServiceOverride");
Brad Ebingerde696de2018-04-06 09:56:40 -07006719 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
Jack Yu00ece8c2022-11-19 22:29:12 -08006720 SubscriptionManager.getSubscriptionId(slotIndex), "setBoundImsServiceOverride");
Brad Ebingerde696de2018-04-06 09:56:40 -07006721
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006722 final long identity = Binder.clearCallingIdentity();
6723 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08006724 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08006725 // may happen if the device does not support IMS.
6726 return false;
6727 }
Brad Ebinger24c29992019-12-05 13:03:21 -08006728 Map<Integer, String> featureConfig = new HashMap<>();
6729 for (int featureType : featureTypes) {
6730 featureConfig.put(featureType, packageName);
6731 }
6732 return mImsResolver.overrideImsServiceConfiguration(slotIndex, isCarrierService,
6733 featureConfig);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006734 } finally {
6735 Binder.restoreCallingIdentity(identity);
6736 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07006737 }
6738
6739 /**
Brad Ebinger999d3302020-11-25 14:31:39 -08006740 * Clears any carrier ImsService overrides for the slot index specified that were previously
6741 * set with {@link #setBoundImsServiceOverride(int, boolean, int[], String)}.
6742 *
6743 * This should only be used for testing.
6744 *
6745 * @param slotIndex the slot ID that the ImsService should bind for.
6746 * @return true if clearing the carrier ImsService override succeeded or false if it did not.
6747 */
6748 @Override
6749 public boolean clearCarrierImsServiceOverride(int slotIndex) {
Brad Ebinger999d3302020-11-25 14:31:39 -08006750 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
6751 "clearCarrierImsServiceOverride");
6752 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
Jack Yu00ece8c2022-11-19 22:29:12 -08006753 SubscriptionManager.getSubscriptionId(slotIndex), "clearCarrierImsServiceOverride");
Brad Ebinger999d3302020-11-25 14:31:39 -08006754
6755 final long identity = Binder.clearCallingIdentity();
6756 try {
6757 if (mImsResolver == null) {
6758 // may happen if the device does not support IMS.
6759 return false;
6760 }
6761 return mImsResolver.clearCarrierImsServiceConfiguration(slotIndex);
6762 } finally {
6763 Binder.restoreCallingIdentity(identity);
6764 }
6765 }
6766
6767 /**
Brad Ebinger24c29992019-12-05 13:03:21 -08006768 * Return the package name of the currently bound ImsService.
Brad Ebingerdac2f002018-04-03 15:17:52 -07006769 *
6770 * @param slotId The slot that the ImsService is associated with.
6771 * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
6772 * the device default.
Brad Ebinger24c29992019-12-05 13:03:21 -08006773 * @param featureType The feature associated with the queried configuration.
Brad Ebingerdac2f002018-04-03 15:17:52 -07006774 * @return the package name of the ImsService configuration.
6775 */
Brad Ebinger24c29992019-12-05 13:03:21 -08006776 public String getBoundImsServicePackage(int slotId, boolean isCarrierImsService,
6777 @ImsFeature.FeatureType int featureType) {
Brad Ebinger24c29992019-12-05 13:03:21 -08006778 TelephonyPermissions
Jack Yu00ece8c2022-11-19 22:29:12 -08006779 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(mApp,
6780 SubscriptionManager.getSubscriptionId(slotId), "getBoundImsServicePackage");
Brad Ebingerde696de2018-04-06 09:56:40 -07006781
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006782 final long identity = Binder.clearCallingIdentity();
6783 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08006784 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08006785 // may happen if the device does not support IMS.
6786 return "";
6787 }
Brad Ebingera80c3312019-12-02 10:59:39 -08006788 // TODO: change API to query RCS separately.
Brad Ebinger24c29992019-12-05 13:03:21 -08006789 return mImsResolver.getImsServiceConfiguration(slotId, isCarrierImsService,
6790 featureType);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006791 } finally {
6792 Binder.restoreCallingIdentity(identity);
6793 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07006794 }
6795
Brad Ebingerbc7dd582019-10-17 17:03:22 -07006796 /**
6797 * Get the MmTelFeature state associated with the requested subscription id.
6798 * @param subId The subscription that the MmTelFeature is associated with.
6799 * @param callback A callback with an integer containing the
6800 * {@link android.telephony.ims.feature.ImsFeature.ImsState} associated with the MmTelFeature.
6801 */
6802 @Override
6803 public void getImsMmTelFeatureState(int subId, IIntegerConsumer callback) {
6804 enforceReadPrivilegedPermission("getImsMmTelFeatureState");
Brad Ebingera2628302022-02-18 03:44:55 +00006805 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
6806 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
6807 "IMS not available on device.");
6808 }
Brad Ebingerbc7dd582019-10-17 17:03:22 -07006809 final long token = Binder.clearCallingIdentity();
6810 try {
Brad Ebingera2628302022-02-18 03:44:55 +00006811 int slotId = getSlotIndex(subId);
6812 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
6813 Log.w(LOG_TAG, "getImsMmTelFeatureState: called with an inactive subscription '"
6814 + subId + "'");
6815 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
6816 }
6817 verifyImsMmTelConfiguredOrThrow(slotId);
6818 ImsManager.getInstance(mApp, slotId).getImsServiceState(anInteger -> {
6819 try {
6820 callback.accept(anInteger == null ? ImsFeature.STATE_UNAVAILABLE : anInteger);
6821 } catch (RemoteException e) {
6822 Log.w(LOG_TAG, "getImsMmTelFeatureState: remote caller is no longer running. "
6823 + "Ignore");
6824 }
Brad Ebingerbc7dd582019-10-17 17:03:22 -07006825 });
Brad Ebinger919631e2021-06-02 17:46:35 -07006826 } catch (ImsException e) {
6827 throw new ServiceSpecificException(e.getCode());
Brad Ebingerbc7dd582019-10-17 17:03:22 -07006828 } finally {
6829 Binder.restoreCallingIdentity(token);
6830 }
6831 }
6832
Daniel Brightbb5840b2021-01-12 15:48:18 -08006833 /**
6834 * Sets the ims registration state on all valid {@link Phone}s.
6835 */
6836 public void setImsRegistrationState(final boolean registered) {
Wink Saville36469e72014-06-11 15:17:00 -07006837 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006838
6839 final long identity = Binder.clearCallingIdentity();
6840 try {
Daniel Brightbb5840b2021-01-12 15:48:18 -08006841 // NOTE: Before S, this method only set the default phone.
6842 for (final Phone phone : PhoneFactory.getPhones()) {
6843 if (SubscriptionManager.isValidSubscriptionId(phone.getSubId())) {
6844 phone.setImsRegistrationState(registered);
6845 }
6846 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006847 } finally {
6848 Binder.restoreCallingIdentity(identity);
6849 }
Wink Saville36469e72014-06-11 15:17:00 -07006850 }
6851
6852 /**
Stuart Scott54788802015-03-30 13:18:01 -07006853 * Set the network selection mode to automatic.
6854 *
6855 */
6856 @Override
6857 public void setNetworkSelectionModeAutomatic(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006858 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6859 mApp, subId, "setNetworkSelectionModeAutomatic");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006860
6861 final long identity = Binder.clearCallingIdentity();
6862 try {
shilufc958392020-01-20 11:36:01 -08006863 if (!isActiveSubscription(subId)) {
6864 return;
6865 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006866 if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
Rambo Wang0f050d82021-02-12 11:43:36 -08006867 sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId,
6868 SET_NETWORK_SELECTION_MODE_AUTOMATIC_TIMEOUT_MS);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006869 } finally {
6870 Binder.restoreCallingIdentity(identity);
6871 }
Stuart Scott54788802015-03-30 13:18:01 -07006872 }
6873
Jack Yud10cdd42020-09-28 20:28:01 -07006874 /**
Pengquan Mengea84e042018-09-20 14:57:26 -07006875 * Ask the radio to connect to the input network and change selection mode to manual.
6876 *
6877 * @param subId the id of the subscription.
6878 * @param operatorInfo the operator information, included the PLMN, long name and short name of
6879 * the operator to attach to.
6880 * @param persistSelection whether the selection will persist until reboot. If true, only allows
6881 * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
6882 * normal network selection next time.
6883 * @return {@code true} on success; {@code true} on any failure.
Shishir Agrawal302c8692015-06-19 13:49:39 -07006884 */
6885 @Override
Pengquan Mengea84e042018-09-20 14:57:26 -07006886 public boolean setNetworkSelectionModeManual(
6887 int subId, OperatorInfo operatorInfo, boolean persistSelection) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006888 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6889 mApp, subId, "setNetworkSelectionModeManual");
Pengquan Menge92a50d2018-09-21 15:54:48 -07006890
Jack Yu285100e2022-12-02 22:48:35 -08006891 final long identity = Binder.clearCallingIdentity();
Pengquan Menge92a50d2018-09-21 15:54:48 -07006892 if (!isActiveSubscription(subId)) {
6893 return false;
6894 }
6895
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006896 try {
Pengquan Mengea84e042018-09-20 14:57:26 -07006897 ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operatorInfo,
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006898 persistSelection);
Pengquan Mengea84e042018-09-20 14:57:26 -07006899 if (DBG) {
6900 log("setNetworkSelectionModeManual: subId: " + subId
6901 + " operator: " + operatorInfo);
6902 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006903 return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
6904 } finally {
6905 Binder.restoreCallingIdentity(identity);
6906 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07006907 }
Thomas Nguyen8ee49682023-02-01 11:46:09 -08006908 /**
shilu84f6e8b2019-12-19 13:58:01 -08006909 * Get the manual network selection
6910 *
6911 * @param subId the id of the subscription.
6912 *
6913 * @return the previously saved user selected PLMN
6914 */
6915 @Override
6916 public String getManualNetworkSelectionPlmn(int subId) {
6917 TelephonyPermissions
Thomas Nguyen8ee49682023-02-01 11:46:09 -08006918 .enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
6919 mApp, subId, "getManualNetworkSelectionPlmn");
shilu84f6e8b2019-12-19 13:58:01 -08006920
6921 final long identity = Binder.clearCallingIdentity();
6922 try {
6923 if (!isActiveSubscription(subId)) {
shilufa1c2592020-03-10 10:59:43 -07006924 throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
shilu84f6e8b2019-12-19 13:58:01 -08006925 }
6926
6927 final Phone phone = getPhone(subId);
6928 if (phone == null) {
shilufa1c2592020-03-10 10:59:43 -07006929 throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
shilu84f6e8b2019-12-19 13:58:01 -08006930 }
6931 OperatorInfo networkSelection = phone.getSavedNetworkSelection();
6932 return TextUtils.isEmpty(networkSelection.getOperatorNumeric())
Thomas Nguyen8ee49682023-02-01 11:46:09 -08006933 ? phone.getManualNetworkSelectionPlmn() : networkSelection.getOperatorNumeric();
shilu84f6e8b2019-12-19 13:58:01 -08006934 } finally {
6935 Binder.restoreCallingIdentity(identity);
6936 }
6937 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07006938
6939 /**
6940 * Scans for available networks.
6941 */
6942 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07006943 public CellNetworkScanResult getCellNetworkScanResults(int subId, String callingPackage,
6944 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006945 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6946 mApp, subId, "getCellNetworkScanResults");
Hall Liuf19c44f2018-11-27 14:38:17 -08006947 LocationAccessPolicy.LocationPermissionResult locationResult =
6948 LocationAccessPolicy.checkLocationPermission(mApp,
6949 new LocationAccessPolicy.LocationPermissionQuery.Builder()
6950 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07006951 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08006952 .setCallingPid(Binder.getCallingPid())
6953 .setCallingUid(Binder.getCallingUid())
6954 .setMethod("getCellNetworkScanResults")
6955 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
Hall Liuc4a3e422020-05-26 17:18:03 -07006956 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
6957 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
Hall Liuf19c44f2018-11-27 14:38:17 -08006958 .build());
6959 switch (locationResult) {
6960 case DENIED_HARD:
6961 throw new SecurityException("Not allowed to access scan results -- location");
6962 case DENIED_SOFT:
6963 return null;
6964 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006965
Pengquan Menga1bb6272018-09-06 09:59:22 -07006966 long identity = Binder.clearCallingIdentity();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006967 try {
6968 if (DBG) log("getCellNetworkScanResults: subId " + subId);
Pengquan Menga1bb6272018-09-06 09:59:22 -07006969 return (CellNetworkScanResult) sendRequest(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006970 CMD_PERFORM_NETWORK_SCAN, null, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006971 } finally {
6972 Binder.restoreCallingIdentity(identity);
6973 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07006974 }
6975
6976 /**
Shuo Qian4a594052020-01-23 11:59:30 -08006977 * Get the call forwarding info, given the call forwarding reason.
6978 */
6979 @Override
Hall Liu27d24262020-09-18 19:04:59 -07006980 public void getCallForwarding(int subId, int callForwardingReason,
6981 ICallForwardingInfoCallback callback) {
Shuo Qian4a594052020-01-23 11:59:30 -08006982 enforceReadPrivilegedPermission("getCallForwarding");
6983 long identity = Binder.clearCallingIdentity();
6984 try {
6985 if (DBG) {
6986 log("getCallForwarding: subId " + subId
6987 + " callForwardingReason" + callForwardingReason);
6988 }
Hall Liu27d24262020-09-18 19:04:59 -07006989
6990 Phone phone = getPhone(subId);
6991 if (phone == null) {
6992 try {
Hall Liu940c4ca2020-09-29 17:10:18 -07006993 callback.onError(
6994 TelephonyManager.CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN);
Hall Liu27d24262020-09-18 19:04:59 -07006995 } catch (RemoteException e) {
6996 // ignore
6997 }
6998 return;
6999 }
7000
7001 Pair<Integer, TelephonyManager.CallForwardingInfoCallback> argument = Pair.create(
7002 callForwardingReason, new TelephonyManager.CallForwardingInfoCallback() {
7003 @Override
7004 public void onCallForwardingInfoAvailable(CallForwardingInfo info) {
7005 try {
7006 callback.onCallForwardingInfoAvailable(info);
7007 } catch (RemoteException e) {
7008 // ignore
7009 }
7010 }
7011
7012 @Override
7013 public void onError(int error) {
7014 try {
7015 callback.onError(error);
7016 } catch (RemoteException e) {
7017 // ignore
7018 }
7019 }
7020 });
7021 sendRequestAsync(CMD_GET_CALL_FORWARDING, argument, phone, null);
Shuo Qian4a594052020-01-23 11:59:30 -08007022 } finally {
7023 Binder.restoreCallingIdentity(identity);
7024 }
7025 }
7026
7027 /**
7028 * Sets the voice call forwarding info including status (enable/disable), call forwarding
7029 * reason, the number to forward, and the timeout before the forwarding is attempted.
7030 */
7031 @Override
Hall Liu27d24262020-09-18 19:04:59 -07007032 public void setCallForwarding(int subId, CallForwardingInfo callForwardingInfo,
7033 IIntegerConsumer callback) {
Shuo Qian4a594052020-01-23 11:59:30 -08007034 enforceModifyPermission();
7035 long identity = Binder.clearCallingIdentity();
7036 try {
7037 if (DBG) {
7038 log("setCallForwarding: subId " + subId
7039 + " callForwardingInfo" + callForwardingInfo);
7040 }
Hall Liu27d24262020-09-18 19:04:59 -07007041
7042 Phone phone = getPhone(subId);
7043 if (phone == null) {
7044 try {
Hall Liu940c4ca2020-09-29 17:10:18 -07007045 callback.accept(
7046 TelephonyManager.CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN);
Hall Liu27d24262020-09-18 19:04:59 -07007047 } catch (RemoteException e) {
7048 // ignore
7049 }
7050 return;
7051 }
7052
7053 Pair<CallForwardingInfo, Consumer<Integer>> arguments = Pair.create(callForwardingInfo,
7054 FunctionalUtils.ignoreRemoteException(callback::accept));
7055
7056 sendRequestAsync(CMD_SET_CALL_FORWARDING, arguments, phone, null);
Shuo Qian4a594052020-01-23 11:59:30 -08007057 } finally {
7058 Binder.restoreCallingIdentity(identity);
7059 }
7060 }
7061
7062 /**
Hall Liu27d24262020-09-18 19:04:59 -07007063 * Get the call waiting status for a subId.
Shuo Qian4a594052020-01-23 11:59:30 -08007064 */
7065 @Override
Hall Liu27d24262020-09-18 19:04:59 -07007066 public void getCallWaitingStatus(int subId, IIntegerConsumer callback) {
SongFerngWang0e767992021-03-31 22:08:45 +08007067 enforceReadPrivilegedPermission("getCallWaitingStatus");
Shuo Qian4a594052020-01-23 11:59:30 -08007068 long identity = Binder.clearCallingIdentity();
7069 try {
Hall Liu27d24262020-09-18 19:04:59 -07007070 Phone phone = getPhone(subId);
7071 if (phone == null) {
7072 try {
7073 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
7074 } catch (RemoteException e) {
7075 // ignore
7076 }
7077 return;
7078 }
SongFerngWang0e767992021-03-31 22:08:45 +08007079 CarrierConfigManager configManager = new CarrierConfigManager(phone.getContext());
7080 PersistableBundle c = configManager.getConfigForSubId(subId);
7081 boolean requireUssd = c.getBoolean(
7082 CarrierConfigManager.KEY_USE_CALL_WAITING_USSD_BOOL, false);
Hall Liu27d24262020-09-18 19:04:59 -07007083
Shuo Qian4a594052020-01-23 11:59:30 -08007084 if (DBG) log("getCallWaitingStatus: subId " + subId);
SongFerngWang0e767992021-03-31 22:08:45 +08007085 if (requireUssd) {
7086 CarrierXmlParser carrierXmlParser = new CarrierXmlParser(phone.getContext(),
7087 getSubscriptionCarrierId(subId));
7088 String newUssdCommand = "";
7089 try {
7090 newUssdCommand = carrierXmlParser.getFeature(
Thomas Nguyen8ee49682023-02-01 11:46:09 -08007091 CarrierXmlParser.FEATURE_CALL_WAITING)
SongFerngWang0e767992021-03-31 22:08:45 +08007092 .makeCommand(CarrierXmlParser.SsEntry.SSAction.QUERY, null);
7093 } catch (NullPointerException e) {
7094 loge("Failed to generate USSD number" + e);
7095 }
7096 ResultReceiver wrappedCallback = new CallWaitingUssdResultReceiver(
7097 mMainThreadHandler, callback, carrierXmlParser,
7098 CarrierXmlParser.SsEntry.SSAction.QUERY);
7099 final String ussdCommand = newUssdCommand;
7100 Executors.newSingleThreadExecutor().execute(() -> {
7101 handleUssdRequest(subId, ussdCommand, wrappedCallback);
7102 });
7103 } else {
7104 Consumer<Integer> argument = FunctionalUtils.ignoreRemoteException(
7105 callback::accept);
7106 sendRequestAsync(CMD_GET_CALL_WAITING, argument, phone, null);
7107 }
Shuo Qian4a594052020-01-23 11:59:30 -08007108 } finally {
7109 Binder.restoreCallingIdentity(identity);
7110 }
7111 }
7112
7113 /**
Hall Liu27d24262020-09-18 19:04:59 -07007114 * Sets whether call waiting is enabled for a given subId.
Shuo Qian4a594052020-01-23 11:59:30 -08007115 */
7116 @Override
Hall Liu27d24262020-09-18 19:04:59 -07007117 public void setCallWaitingStatus(int subId, boolean enable, IIntegerConsumer callback) {
Shuo Qian4a594052020-01-23 11:59:30 -08007118 enforceModifyPermission();
7119 long identity = Binder.clearCallingIdentity();
7120 try {
Hall Liu27d24262020-09-18 19:04:59 -07007121 if (DBG) log("setCallWaitingStatus: subId " + subId + " enable: " + enable);
7122
7123 Phone phone = getPhone(subId);
7124 if (phone == null) {
7125 try {
7126 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
7127 } catch (RemoteException e) {
7128 // ignore
7129 }
7130 return;
7131 }
7132
SongFerngWang0e767992021-03-31 22:08:45 +08007133 CarrierConfigManager configManager = new CarrierConfigManager(phone.getContext());
7134 PersistableBundle c = configManager.getConfigForSubId(subId);
7135 boolean requireUssd = c.getBoolean(
7136 CarrierConfigManager.KEY_USE_CALL_WAITING_USSD_BOOL, false);
Hall Liu27d24262020-09-18 19:04:59 -07007137
SongFerngWang0e767992021-03-31 22:08:45 +08007138 if (DBG) log("getCallWaitingStatus: subId " + subId);
7139 if (requireUssd) {
7140 CarrierXmlParser carrierXmlParser = new CarrierXmlParser(phone.getContext(),
7141 getSubscriptionCarrierId(subId));
7142 CarrierXmlParser.SsEntry.SSAction ssAction =
7143 enable ? CarrierXmlParser.SsEntry.SSAction.UPDATE_ACTIVATE
7144 : CarrierXmlParser.SsEntry.SSAction.UPDATE_DEACTIVATE;
7145 String newUssdCommand = "";
7146 try {
7147 newUssdCommand = carrierXmlParser.getFeature(
Thomas Nguyen8ee49682023-02-01 11:46:09 -08007148 CarrierXmlParser.FEATURE_CALL_WAITING)
SongFerngWang0e767992021-03-31 22:08:45 +08007149 .makeCommand(ssAction, null);
7150 } catch (NullPointerException e) {
7151 loge("Failed to generate USSD number" + e);
7152 }
7153 ResultReceiver wrappedCallback = new CallWaitingUssdResultReceiver(
7154 mMainThreadHandler, callback, carrierXmlParser, ssAction);
7155 final String ussdCommand = newUssdCommand;
7156 Executors.newSingleThreadExecutor().execute(() -> {
7157 handleUssdRequest(subId, ussdCommand, wrappedCallback);
7158 });
7159 } else {
7160 Pair<Boolean, Consumer<Integer>> arguments = Pair.create(enable,
7161 FunctionalUtils.ignoreRemoteException(callback::accept));
7162
7163 sendRequestAsync(CMD_SET_CALL_WAITING, arguments, phone, null);
7164 }
Shuo Qian4a594052020-01-23 11:59:30 -08007165 } finally {
7166 Binder.restoreCallingIdentity(identity);
7167 }
7168 }
7169
7170 /**
yinxub1bed742017-04-17 11:45:04 -07007171 * Starts a new network scan and returns the id of this scan.
yinxu504e1392017-04-12 16:03:22 -07007172 *
yinxub1bed742017-04-17 11:45:04 -07007173 * @param subId id of the subscription
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08007174 * @param renounceFineLocationAccess Set this to true if the caller would not like to receive
7175 * location related information which will be sent if the caller already possess
7176 * {@android.Manifest.permission.ACCESS_FINE_LOCATION} and do not renounce the permission
yinxub1bed742017-04-17 11:45:04 -07007177 * @param request contains the radio access networks with bands/channels to scan
7178 * @param messenger callback messenger for scan results or errors
7179 * @param binder for the purpose of auto clean when the user thread crashes
yinxu504e1392017-04-12 16:03:22 -07007180 * @return the id of the requested scan which can be used to stop the scan.
7181 */
7182 @Override
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08007183 public int requestNetworkScan(int subId, boolean renounceFineLocationAccess,
7184 NetworkScanRequest request, Messenger messenger,
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07007185 IBinder binder, String callingPackage, String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08007186 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7187 mApp, subId, "requestNetworkScan");
Hall Liuf19c44f2018-11-27 14:38:17 -08007188 LocationAccessPolicy.LocationPermissionResult locationResult =
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08007189 LocationAccessPolicy.LocationPermissionResult.DENIED_HARD;
7190 if (!renounceFineLocationAccess) {
7191 locationResult = LocationAccessPolicy.checkLocationPermission(mApp,
Thomas Nguyen8ee49682023-02-01 11:46:09 -08007192 new LocationAccessPolicy.LocationPermissionQuery.Builder()
7193 .setCallingPackage(callingPackage)
7194 .setCallingFeatureId(callingFeatureId)
7195 .setCallingPid(Binder.getCallingPid())
7196 .setCallingUid(Binder.getCallingUid())
7197 .setMethod("requestNetworkScan")
7198 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
7199 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
7200 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
7201 .build());
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08007202 }
Hall Liub2ac8ef2019-02-28 15:56:23 -08007203 if (locationResult != LocationAccessPolicy.LocationPermissionResult.ALLOWED) {
Nathan Harold1c11dba2020-09-22 17:54:53 -07007204 SecurityException e = checkNetworkRequestForSanitizedLocationAccess(
7205 request, subId, callingPackage);
Hall Liub2ac8ef2019-02-28 15:56:23 -08007206 if (e != null) {
7207 if (locationResult == LocationAccessPolicy.LocationPermissionResult.DENIED_HARD) {
7208 throw e;
7209 } else {
Hall Liu0e5abaf2019-04-04 01:25:30 -07007210 loge(e.getMessage());
Hall Liub2ac8ef2019-02-28 15:56:23 -08007211 return TelephonyScanManager.INVALID_SCAN_ID;
7212 }
7213 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007214 }
Hall Liu912dfd32019-04-25 14:02:26 -07007215 int callingUid = Binder.getCallingUid();
7216 int callingPid = Binder.getCallingPid();
Ying Xu94a46582019-04-18 17:14:56 -07007217 final long identity = Binder.clearCallingIdentity();
7218 try {
7219 return mNetworkScanRequestTracker.startNetworkScan(
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08007220 renounceFineLocationAccess, request, messenger, binder, getPhone(subId),
Hall Liu912dfd32019-04-25 14:02:26 -07007221 callingUid, callingPid, callingPackage);
Ying Xu94a46582019-04-18 17:14:56 -07007222 } finally {
7223 Binder.restoreCallingIdentity(identity);
7224 }
yinxu504e1392017-04-12 16:03:22 -07007225 }
7226
Hall Liub2ac8ef2019-02-28 15:56:23 -08007227 private SecurityException checkNetworkRequestForSanitizedLocationAccess(
Nathan Harold1c11dba2020-09-22 17:54:53 -07007228 NetworkScanRequest request, int subId, String callingPackage) {
Rambo Wang3dee30a2022-10-20 16:52:29 +00007229 boolean hasCarrierPriv;
7230 final long identity = Binder.clearCallingIdentity();
7231 try {
7232 hasCarrierPriv = checkCarrierPrivilegesForPackage(subId, callingPackage)
7233 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
7234 } finally {
7235 Binder.restoreCallingIdentity(identity);
7236 }
Hall Liu558027f2019-05-15 19:14:05 -07007237 boolean hasNetworkScanPermission =
7238 mApp.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_SCAN)
Thomas Nguyen8ee49682023-02-01 11:46:09 -08007239 == PERMISSION_GRANTED;
Hall Liu558027f2019-05-15 19:14:05 -07007240
7241 if (!hasCarrierPriv && !hasNetworkScanPermission) {
7242 return new SecurityException("permission.NETWORK_SCAN or carrier privileges is needed"
7243 + " for network scans without location access.");
Hall Liub2ac8ef2019-02-28 15:56:23 -08007244 }
7245
7246 if (request.getSpecifiers() != null && request.getSpecifiers().length > 0) {
7247 for (RadioAccessSpecifier ras : request.getSpecifiers()) {
Hall Liub2ac8ef2019-02-28 15:56:23 -08007248 if (ras.getChannels() != null && ras.getChannels().length > 0) {
7249 return new SecurityException("Specific channels must not be"
7250 + " scanned without location access.");
7251 }
7252 }
7253 }
7254
Hall Liub2ac8ef2019-02-28 15:56:23 -08007255 return null;
7256 }
7257
yinxu504e1392017-04-12 16:03:22 -07007258 /**
7259 * Stops an existing network scan with the given scanId.
yinxub1bed742017-04-17 11:45:04 -07007260 *
7261 * @param subId id of the subscription
7262 * @param scanId id of the scan that needs to be stopped
yinxu504e1392017-04-12 16:03:22 -07007263 */
7264 @Override
7265 public void stopNetworkScan(int subId, int scanId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08007266 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7267 mApp, subId, "stopNetworkScan");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007268
Hall Liu912dfd32019-04-25 14:02:26 -07007269 int callingUid = Binder.getCallingUid();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007270 final long identity = Binder.clearCallingIdentity();
7271 try {
Hall Liu912dfd32019-04-25 14:02:26 -07007272 mNetworkScanRequestTracker.stopNetworkScan(scanId, callingUid);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007273 } finally {
7274 Binder.restoreCallingIdentity(identity);
7275 }
yinxu504e1392017-04-12 16:03:22 -07007276 }
7277
7278 /**
SongFerngWang3ef3e072020-12-21 16:41:52 +08007279 * Get the allowed network types bitmask.
Junda Liu84d15a22014-07-02 11:21:04 -07007280 *
SongFerngWang3ef3e072020-12-21 16:41:52 +08007281 * @return the allowed network types bitmask, defined in RILConstants.java.
Junda Liu84d15a22014-07-02 11:21:04 -07007282 */
7283 @Override
SongFerngWang3ef3e072020-12-21 16:41:52 +08007284 public int getAllowedNetworkTypesBitmask(int subId) {
Pengquan Menga4009cb2018-12-20 11:00:24 -08007285 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07007286 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
SongFerngWang3ef3e072020-12-21 16:41:52 +08007287 mApp, subId, "getAllowedNetworkTypesBitmask");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007288
7289 final long identity = Binder.clearCallingIdentity();
7290 try {
SongFerngWang3ef3e072020-12-21 16:41:52 +08007291 if (DBG) log("getAllowedNetworkTypesBitmask");
7292 int[] result = (int[]) sendRequest(CMD_GET_ALLOWED_NETWORK_TYPES_BITMASK, null, subId);
7293 int networkTypesBitmask = (result != null ? result[0] : -1);
7294 if (DBG) log("getAllowedNetworkTypesBitmask: " + networkTypesBitmask);
7295 return networkTypesBitmask;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007296 } finally {
7297 Binder.restoreCallingIdentity(identity);
7298 }
Jake Hamby7c27be32014-03-03 13:25:59 -08007299 }
7300
7301 /**
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07007302 * Get the allowed network types for certain reason.
7303 *
7304 * @param subId the id of the subscription.
7305 * @param reason the reason the allowed network type change is taking place
7306 * @return the allowed network types.
7307 */
7308 @Override
7309 public long getAllowedNetworkTypesForReason(int subId,
7310 @TelephonyManager.AllowedNetworkTypesReason int reason) {
Nathan Harold62c68512021-04-06 11:26:02 -07007311 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
SongFerngWang8c6e82e2021-03-02 22:09:29 +08007312 mApp, subId, "getAllowedNetworkTypesForReason");
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07007313 final long identity = Binder.clearCallingIdentity();
7314 try {
7315 return getPhoneFromSubId(subId).getAllowedNetworkTypes(reason);
7316 } finally {
7317 Binder.restoreCallingIdentity(identity);
7318 }
7319 }
7320
7321 /**
Sooraj Sasindran37444802020-08-11 10:40:43 -07007322 * Enable/Disable E-UTRA-NR Dual Connectivity
7323 * @param subId subscription id of the sim card
7324 * @param nrDualConnectivityState expected NR dual connectivity state
7325 * This can be passed following states
7326 * <ol>
7327 * <li>Enable NR dual connectivity {@link TelephonyManager#NR_DUAL_CONNECTIVITY_ENABLE}
7328 * <li>Disable NR dual connectivity {@link TelephonyManager#NR_DUAL_CONNECTIVITY_DISABLE}
7329 * <li>Disable NR dual connectivity and force secondary cell to be released
7330 * {@link TelephonyManager#NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE}
7331 * </ol>
7332 * @return operation result.
7333 */
7334 @Override
7335 public int setNrDualConnectivityState(int subId,
7336 @TelephonyManager.NrDualConnectivityState int nrDualConnectivityState) {
7337 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7338 mApp, subId, "enableNRDualConnectivity");
Sooraj Sasindran0e4e00a2021-03-16 18:02:32 -07007339 if (!isRadioInterfaceCapabilitySupported(
Sooraj Sasindrandfd595b2021-03-11 17:38:13 -08007340 TelephonyManager.CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE)) {
7341 return TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED;
7342 }
7343
Sooraj Sasindran37444802020-08-11 10:40:43 -07007344 WorkSource workSource = getWorkSource(Binder.getCallingUid());
7345 final long identity = Binder.clearCallingIdentity();
7346 try {
7347 int result = (int) sendRequest(CMD_ENABLE_NR_DUAL_CONNECTIVITY,
7348 nrDualConnectivityState, subId,
7349 workSource);
7350 if (DBG) log("enableNRDualConnectivity result: " + result);
7351 return result;
7352 } finally {
7353 Binder.restoreCallingIdentity(identity);
7354 }
7355 }
7356
7357 /**
7358 * Is E-UTRA-NR Dual Connectivity enabled
7359 * @return true if dual connectivity is enabled else false
7360 */
7361 @Override
7362 public boolean isNrDualConnectivityEnabled(int subId) {
7363 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07007364 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Sooraj Sasindran37444802020-08-11 10:40:43 -07007365 mApp, subId, "isNRDualConnectivityEnabled");
Sooraj Sasindran0e4e00a2021-03-16 18:02:32 -07007366 if (!isRadioInterfaceCapabilitySupported(
Sooraj Sasindrandfd595b2021-03-11 17:38:13 -08007367 TelephonyManager.CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE)) {
7368 return false;
7369 }
Sooraj Sasindran37444802020-08-11 10:40:43 -07007370 WorkSource workSource = getWorkSource(Binder.getCallingUid());
7371 final long identity = Binder.clearCallingIdentity();
7372 try {
7373 boolean isEnabled = (boolean) sendRequest(CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED,
7374 null, subId, workSource);
7375 if (DBG) log("isNRDualConnectivityEnabled: " + isEnabled);
7376 return isEnabled;
7377 } finally {
7378 Binder.restoreCallingIdentity(identity);
7379 }
7380 }
7381
7382 /**
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07007383 * Set the allowed network types of the device and
7384 * provide the reason triggering the allowed network change.
7385 *
7386 * @param subId the id of the subscription.
7387 * @param reason the reason the allowed network type change is taking place
7388 * @param allowedNetworkTypes the allowed network types.
7389 * @return true on success; false on any failure.
7390 */
7391 @Override
7392 public boolean setAllowedNetworkTypesForReason(int subId,
SongFerngWang3ef3e072020-12-21 16:41:52 +08007393 @TelephonyManager.AllowedNetworkTypesReason int reason,
7394 @TelephonyManager.NetworkTypeBitMask long allowedNetworkTypes) {
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07007395 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7396 mApp, subId, "setAllowedNetworkTypesForReason");
Gil Cukierman1d3d3752022-10-03 21:31:33 +00007397 // If the caller only has carrier privileges, then they should not be able to override
7398 // any network types which were set for security reasons.
7399 if (mApp.checkCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE)
7400 != PERMISSION_GRANTED
Gil Cukierman2a8f48b2023-01-26 20:26:20 +00007401 && reason == TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G) {
Gil Cukierman1d3d3752022-10-03 21:31:33 +00007402 throw new SecurityException(
7403 "setAllowedNetworkTypesForReason cannot be called with carrier privileges for"
Gil Cukierman2a8f48b2023-01-26 20:26:20 +00007404 + " reason " + reason);
Gil Cukierman1d3d3752022-10-03 21:31:33 +00007405 }
SongFerngWang3ef3e072020-12-21 16:41:52 +08007406 if (!TelephonyManager.isValidAllowedNetworkTypesReason(reason)) {
Jack Yu5b494332023-01-23 18:18:04 +00007407 loge("setAllowedNetworkTypesForReason: Invalid allowed network type reason: " + reason);
SongFerngWang7ffc2732021-04-15 19:46:33 +08007408 return false;
7409 }
7410 if (!SubscriptionManager.isUsableSubscriptionId(subId)) {
7411 loge("setAllowedNetworkTypesForReason: Invalid subscriptionId:" + subId);
SongFerngWang3ef3e072020-12-21 16:41:52 +08007412 return false;
7413 }
7414
Jack Yu5b494332023-01-23 18:18:04 +00007415 log("setAllowedNetworkTypesForReason: subId=" + subId + ", reason=" + reason + " value: "
7416 + TelephonyManager.convertNetworkTypeBitmaskToString(allowedNetworkTypes));
SongFerngWang8c6e82e2021-03-02 22:09:29 +08007417
Jack Yue37dd262022-12-16 11:53:37 -08007418 Phone phone = getPhone(subId);
7419 if (phone == null) {
7420 return false;
7421 }
SongFerngWang8c6e82e2021-03-02 22:09:29 +08007422
Jack Yue37dd262022-12-16 11:53:37 -08007423 if (allowedNetworkTypes == phone.getAllowedNetworkTypes(reason)) {
Jack Yu5b494332023-01-23 18:18:04 +00007424 log("setAllowedNetworkTypesForReason: " + reason + "does not change value");
SongFerngWang8c6e82e2021-03-02 22:09:29 +08007425 return true;
SongFerngWang3ef3e072020-12-21 16:41:52 +08007426 }
SongFerngWang8c6e82e2021-03-02 22:09:29 +08007427
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07007428 final long identity = Binder.clearCallingIdentity();
7429 try {
SongFerngWang3ef3e072020-12-21 16:41:52 +08007430 Boolean success = (Boolean) sendRequest(
7431 CMD_SET_ALLOWED_NETWORK_TYPES_FOR_REASON,
7432 new Pair<Integer, Long>(reason, allowedNetworkTypes), subId);
7433
7434 if (DBG) log("setAllowedNetworkTypesForReason: " + (success ? "ok" : "fail"));
7435 return success;
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07007436 } finally {
7437 Binder.restoreCallingIdentity(identity);
7438 }
7439 }
7440
7441 /**
Miaoa84611c2019-03-15 09:21:10 +08007442 * Check whether DUN APN is required for tethering with subId.
Junda Liu475951f2014-11-07 16:45:03 -08007443 *
Miaoa84611c2019-03-15 09:21:10 +08007444 * @param subId the id of the subscription to require tethering.
Amit Mahajanfe58cdf2017-07-11 12:01:53 -07007445 * @return {@code true} if DUN APN is required for tethering.
Junda Liu475951f2014-11-07 16:45:03 -08007446 * @hide
7447 */
7448 @Override
SongFerngWangf08d8122019-11-15 14:58:44 +08007449 public boolean isTetheringApnRequiredForSubscriber(int subId) {
Shishir Agrawalc04d9752016-02-19 10:41:00 -08007450 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007451 final long identity = Binder.clearCallingIdentity();
Miaoa84611c2019-03-15 09:21:10 +08007452 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007453 try {
Miaoa84611c2019-03-15 09:21:10 +08007454 if (phone != null) {
7455 return phone.hasMatchedTetherApnSetting();
7456 } else {
7457 return false;
7458 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007459 } finally {
7460 Binder.restoreCallingIdentity(identity);
Junda Liu475951f2014-11-07 16:45:03 -08007461 }
Junda Liu475951f2014-11-07 16:45:03 -08007462 }
7463
7464 /**
Malcolm Chen964682d2017-11-28 16:20:07 -08007465 * Get the user enabled state of Mobile Data.
7466 *
7467 * TODO: remove and use isUserDataEnabled.
7468 * This can't be removed now because some vendor codes
7469 * calls through ITelephony directly while they should
7470 * use TelephonyManager.
7471 *
7472 * @return true on enabled
7473 */
7474 @Override
7475 public boolean getDataEnabled(int subId) {
7476 return isUserDataEnabled(subId);
7477 }
7478
7479 /**
7480 * Get whether mobile data is enabled per user setting.
7481 *
7482 * There are other factors deciding whether mobile data is actually enabled, but they are
7483 * not considered here. See {@link #isDataEnabled(int)} for more details.
Robert Greenwalt646120a2014-05-23 11:54:03 -07007484 *
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007485 * Accepts either READ_BASIC_PHONE_STATE, ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE
7486 * or carrier privileges.
Robert Greenwalted86e582014-05-21 20:03:20 -07007487 *
7488 * @return {@code true} if data is enabled else {@code false}
7489 */
7490 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08007491 public boolean isUserDataEnabled(int subId) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007492 String functionName = "isUserDataEnabled";
Robert Greenwalt646120a2014-05-23 11:54:03 -07007493 try {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007494 try {
7495 mApp.enforceCallingOrSelfPermission(permission.READ_BASIC_PHONE_STATE,
7496 functionName);
Sooraj Sasindran12545cc2022-08-22 14:30:25 -07007497 } catch (SecurityException e) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007498 mApp.enforceCallingOrSelfPermission(permission.ACCESS_NETWORK_STATE, functionName);
7499 }
Sooraj Sasindran12545cc2022-08-22 14:30:25 -07007500 } catch (SecurityException e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08007501 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007502 mApp, subId, functionName);
7503
Robert Greenwalt646120a2014-05-23 11:54:03 -07007504 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007505
7506 final long identity = Binder.clearCallingIdentity();
7507 try {
Jack Yu285100e2022-12-02 22:48:35 -08007508 int phoneId = SubscriptionManager.getPhoneId(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007509 if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
7510 Phone phone = PhoneFactory.getPhone(phoneId);
7511 if (phone != null) {
7512 boolean retVal = phone.isUserDataEnabled();
7513 if (DBG) log("isUserDataEnabled: subId=" + subId + " retVal=" + retVal);
7514 return retVal;
7515 } else {
7516 if (DBG) loge("isUserDataEnabled: no phone subId=" + subId + " retVal=false");
7517 return false;
7518 }
7519 } finally {
7520 Binder.restoreCallingIdentity(identity);
Malcolm Chen964682d2017-11-28 16:20:07 -08007521 }
7522 }
7523
7524 /**
Shuo Qian8ee4e882020-01-08 14:30:06 -08007525 * Checks if the device is capable of mobile data by considering whether whether the
7526 * user has enabled mobile data, whether the carrier has enabled mobile data, and
7527 * whether the network policy allows data connections.
Malcolm Chen964682d2017-11-28 16:20:07 -08007528 *
Shuo Qian8ee4e882020-01-08 14:30:06 -08007529 * @return {@code true} if the overall data connection is capable; {@code false} if not.
Malcolm Chen964682d2017-11-28 16:20:07 -08007530 */
7531 @Override
7532 public boolean isDataEnabled(int subId) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007533 String functionName = "isDataEnabled";
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07007534 try {
7535 try {
7536 mApp.enforceCallingOrSelfPermission(
7537 android.Manifest.permission.ACCESS_NETWORK_STATE,
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007538 functionName);
Sooraj Sasindran12545cc2022-08-22 14:30:25 -07007539 } catch (SecurityException e) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007540 try {
7541 mApp.enforceCallingOrSelfPermission(
7542 android.Manifest.permission.READ_PHONE_STATE,
7543 functionName);
Sooraj Sasindran12545cc2022-08-22 14:30:25 -07007544 } catch (SecurityException e2) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007545 mApp.enforceCallingOrSelfPermission(
7546 permission.READ_BASIC_PHONE_STATE, functionName);
7547 }
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07007548 }
Sooraj Sasindran12545cc2022-08-22 14:30:25 -07007549 } catch (SecurityException e) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007550 enforceReadPrivilegedPermission(functionName);
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07007551 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007552
7553 final long identity = Binder.clearCallingIdentity();
7554 try {
Jack Yu285100e2022-12-02 22:48:35 -08007555 int phoneId = SubscriptionManager.getPhoneId(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007556 Phone phone = PhoneFactory.getPhone(phoneId);
7557 if (phone != null) {
Sarah Chine04784a2022-10-31 20:32:34 -07007558 boolean retVal = phone.getDataSettingsManager().isDataEnabled();
Jack Yu4ad64e52021-12-03 14:23:53 -08007559 if (DBG) log("isDataEnabled: " + retVal + ", subId=" + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007560 return retVal;
7561 } else {
7562 if (DBG) loge("isDataEnabled: no phone subId=" + subId + " retVal=false");
7563 return false;
7564 }
7565 } finally {
7566 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08007567 }
Robert Greenwalted86e582014-05-21 20:03:20 -07007568 }
Shishir Agrawal60f9c952014-06-23 12:00:43 -07007569
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007570 /**
7571 * Check if data is enabled for a specific reason
7572 * @param subId Subscription index
7573 * @param reason the reason the data enable change is taking place
7574 * @return {@code true} if the overall data is enabled; {@code false} if not.
7575 */
7576 @Override
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07007577 public boolean isDataEnabledForReason(int subId,
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007578 @TelephonyManager.DataEnabledReason int reason) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007579 String functionName = "isDataEnabledForReason";
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007580 try {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007581 try {
7582 mApp.enforceCallingOrSelfPermission(
7583 android.Manifest.permission.ACCESS_NETWORK_STATE,
7584 functionName);
Sooraj Sasindran12545cc2022-08-22 14:30:25 -07007585 } catch (SecurityException e) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007586 mApp.enforceCallingOrSelfPermission(permission.READ_BASIC_PHONE_STATE,
7587 functionName);
7588 }
Sooraj Sasindran12545cc2022-08-22 14:30:25 -07007589 } catch (SecurityException e) {
Sooraj Sasindran0d909a02021-11-08 12:01:16 -08007590 try {
7591 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE,
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007592 functionName);
Sooraj Sasindran12545cc2022-08-22 14:30:25 -07007593 } catch (SecurityException e2) {
Sooraj Sasindran0d909a02021-11-08 12:01:16 -08007594 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07007595 mApp, subId, functionName);
Sooraj Sasindran0d909a02021-11-08 12:01:16 -08007596 }
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007597 }
7598
7599
7600 final long identity = Binder.clearCallingIdentity();
7601 try {
Jack Yu285100e2022-12-02 22:48:35 -08007602 int phoneId = SubscriptionManager.getPhoneId(subId);
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007603 if (DBG) {
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07007604 log("isDataEnabledForReason: subId=" + subId + " phoneId=" + phoneId
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007605 + " reason=" + reason);
7606 }
7607 Phone phone = PhoneFactory.getPhone(phoneId);
7608 if (phone != null) {
7609 boolean retVal;
Jack Yu7968c6d2022-07-31 00:43:21 -07007610 retVal = phone.getDataSettingsManager().isDataEnabledForReason(reason);
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07007611 if (DBG) log("isDataEnabledForReason: retVal=" + retVal);
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007612 return retVal;
7613 } else {
7614 if (DBG) {
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07007615 loge("isDataEnabledForReason: no phone subId="
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007616 + subId + " retVal=false");
7617 }
7618 return false;
7619 }
7620 } finally {
7621 Binder.restoreCallingIdentity(identity);
7622 }
7623 }
7624
Shishir Agrawal60f9c952014-06-23 12:00:43 -07007625 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08007626 public int getCarrierPrivilegeStatus(int subId) {
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007627 // No permission needed; this only lets the caller inspect their own status.
7628 return getCarrierPrivilegeStatusForUidWithPermission(subId, Binder.getCallingUid());
Shishir Agrawal60f9c952014-06-23 12:00:43 -07007629 }
Junda Liu29340342014-07-10 15:23:27 -07007630
7631 @Override
Jeff Davidson7e17e312018-02-13 18:17:36 -08007632 public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08007633 enforceReadPrivilegedPermission("getCarrierPrivilegeStatusForUid");
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007634 return getCarrierPrivilegeStatusForUidWithPermission(subId, uid);
7635 }
7636
7637 private int getCarrierPrivilegeStatusForUidWithPermission(int subId, int uid) {
7638 Phone phone = getPhone(subId);
Jeff Davidson7e17e312018-02-13 18:17:36 -08007639 if (phone == null) {
Taesu Leef8fbed92019-10-07 18:47:02 +09007640 loge("getCarrierPrivilegeStatusForUid: Invalid subId");
Jeff Davidson7e17e312018-02-13 18:17:36 -08007641 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
7642 }
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007643 CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7644 if (cpt == null) {
7645 loge("getCarrierPrivilegeStatusForUid: No CarrierPrivilegesTracker");
Jeff Davidson7e17e312018-02-13 18:17:36 -08007646 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
7647 }
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007648 return cpt.getCarrierPrivilegeStatusForUid(uid);
Jeff Davidson7e17e312018-02-13 18:17:36 -08007649 }
7650
7651 @Override
chen xuf7e9fe82019-05-09 19:31:02 -07007652 public int checkCarrierPrivilegesForPackage(int subId, String pkgName) {
Nazanin1adf4562021-03-29 15:35:30 -07007653 enforceReadPrivilegedPermission("checkCarrierPrivilegesForPackage");
chen xuf7e9fe82019-05-09 19:31:02 -07007654 if (TextUtils.isEmpty(pkgName)) {
Junda Liu317d70b2016-03-08 09:33:53 -08007655 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
chen xuf7e9fe82019-05-09 19:31:02 -07007656 }
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007657 Phone phone = getPhone(subId);
7658 if (phone == null) {
7659 loge("checkCarrierPrivilegesForPackage: Invalid subId");
7660 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
7661 }
7662 CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7663 if (cpt == null) {
7664 loge("checkCarrierPrivilegesForPackage: No CarrierPrivilegesTracker");
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07007665 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
7666 }
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007667 return cpt.getCarrierPrivilegeStatusForPackage(pkgName);
Zach Johnson50ecba32015-05-19 00:24:21 -07007668 }
7669
7670 @Override
7671 public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007672 enforceReadPrivilegedPermission("checkCarrierPrivilegesForPackageAnyPhone");
Rambo Wange7209ce2022-02-23 13:41:02 -08007673 return checkCarrierPrivilegesForPackageAnyPhoneWithPermission(pkgName);
7674 }
7675
7676 private int checkCarrierPrivilegesForPackageAnyPhoneWithPermission(String pkgName) {
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007677 if (TextUtils.isEmpty(pkgName)) {
Junda Liu317d70b2016-03-08 09:33:53 -08007678 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007679 }
Zach Johnson50ecba32015-05-19 00:24:21 -07007680 int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007681 for (int phoneId = 0; phoneId < TelephonyManager.getDefault().getPhoneCount(); phoneId++) {
7682 Phone phone = PhoneFactory.getPhone(phoneId);
7683 if (phone == null) {
7684 continue;
Zach Johnson50ecba32015-05-19 00:24:21 -07007685 }
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007686 CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7687 if (cpt == null) {
7688 continue;
7689 }
7690 result = cpt.getCarrierPrivilegeStatusForPackage(pkgName);
Zach Johnson50ecba32015-05-19 00:24:21 -07007691 if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
7692 break;
7693 }
7694 }
Zach Johnson50ecba32015-05-19 00:24:21 -07007695 return result;
Junda Liu29340342014-07-10 15:23:27 -07007696 }
Derek Tan89e89d42014-07-08 17:00:10 -07007697
7698 @Override
Junda Liue64de782015-04-16 17:19:16 -07007699 public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
Nazanin1adf4562021-03-29 15:35:30 -07007700 enforceReadPrivilegedPermission("getCarrierPackageNamesForIntentAndPhone");
Rambo Wang8a247eb2022-02-08 21:11:18 +00007701 Phone phone = PhoneFactory.getPhone(phoneId);
7702 if (phone == null) {
7703 return Collections.emptyList();
Junda Liue64de782015-04-16 17:19:16 -07007704 }
Rambo Wang8a247eb2022-02-08 21:11:18 +00007705 CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7706 if (cpt == null) {
7707 return Collections.emptyList();
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07007708 }
Rambo Wang8a247eb2022-02-08 21:11:18 +00007709 return cpt.getCarrierPackageNamesForIntent(intent);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07007710 }
7711
Amith Yamasani6e118872016-02-19 12:53:51 -08007712 @Override
chen xuf7e9fe82019-05-09 19:31:02 -07007713 public List<String> getPackagesWithCarrierPrivileges(int phoneId) {
Nazanin1adf4562021-03-29 15:35:30 -07007714 enforceReadPrivilegedPermission("getPackagesWithCarrierPrivileges");
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007715 Phone phone = PhoneFactory.getPhone(phoneId);
7716 if (phone == null) {
7717 return Collections.emptyList();
Amith Yamasani6e118872016-02-19 12:53:51 -08007718 }
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007719 CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7720 if (cpt == null) {
7721 return Collections.emptyList();
7722 }
7723 return new ArrayList<>(cpt.getPackagesWithCarrierPrivileges());
Amith Yamasani6e118872016-02-19 12:53:51 -08007724 }
7725
chen xuf7e9fe82019-05-09 19:31:02 -07007726 @Override
7727 public List<String> getPackagesWithCarrierPrivilegesForAllPhones() {
Shuo Qian067a06d2019-12-03 23:40:18 +00007728 enforceReadPrivilegedPermission("getPackagesWithCarrierPrivilegesForAllPhones");
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007729 Set<String> privilegedPackages = new ArraySet<>();
Shuo Qian067a06d2019-12-03 23:40:18 +00007730 final long identity = Binder.clearCallingIdentity();
Shuo Qian067a06d2019-12-03 23:40:18 +00007731 try {
7732 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
7733 privilegedPackages.addAll(getPackagesWithCarrierPrivileges(i));
7734 }
7735 } finally {
7736 Binder.restoreCallingIdentity(identity);
chen xuf7e9fe82019-05-09 19:31:02 -07007737 }
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08007738 return new ArrayList<>(privilegedPackages);
chen xuf7e9fe82019-05-09 19:31:02 -07007739 }
7740
Rambo Wang6812ffb2022-03-15 16:54:17 -07007741 @Override
7742 public @Nullable String getCarrierServicePackageNameForLogicalSlot(int logicalSlotIndex) {
7743 enforceReadPrivilegedPermission("getCarrierServicePackageNameForLogicalSlot");
7744
7745 final Phone phone = PhoneFactory.getPhone(logicalSlotIndex);
7746 if (phone == null) {
7747 return null;
7748 }
7749 final CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7750 if (cpt == null) {
7751 return null;
7752 }
7753 return cpt.getCarrierServicePackageName();
7754 }
7755
Wink Savilleb564aae2014-10-23 10:18:09 -07007756 private String getIccId(int subId) {
Sanket Padawe356d7632015-06-22 14:03:32 -07007757 final Phone phone = getPhone(subId);
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00007758 UiccPort port = phone == null ? null : phone.getUiccPort();
7759 if (port == null) {
Derek Tan97ebb422014-09-05 16:55:38 -07007760 return null;
7761 }
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00007762 String iccId = port.getIccId();
Derek Tan97ebb422014-09-05 16:55:38 -07007763 if (TextUtils.isEmpty(iccId)) {
Derek Tan97ebb422014-09-05 16:55:38 -07007764 return null;
7765 }
7766 return iccId;
7767 }
7768
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07007769 @Override
Shuo Qiane4e11672020-12-15 22:15:33 -08007770 public void setCallComposerStatus(int subId, int status) {
7771 enforceModifyPermission();
7772
7773 final long identity = Binder.clearCallingIdentity();
7774 try {
7775 Phone phone = getPhone(subId);
7776 if (phone != null) {
7777 Phone defaultPhone = phone.getImsPhone();
7778 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
7779 ImsPhone imsPhone = (ImsPhone) defaultPhone;
7780 imsPhone.setCallComposerStatus(status);
Shuo Qian284ae752020-12-22 19:10:14 -08007781 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
7782 .updateImsServiceConfig();
Shuo Qiane4e11672020-12-15 22:15:33 -08007783 }
7784 }
Shuo Qian284ae752020-12-22 19:10:14 -08007785 } catch (ImsException e) {
7786 throw new ServiceSpecificException(e.getCode());
7787 } finally {
Shuo Qiane4e11672020-12-15 22:15:33 -08007788 Binder.restoreCallingIdentity(identity);
7789 }
7790 }
7791
7792 @Override
7793 public int getCallComposerStatus(int subId) {
7794 enforceReadPrivilegedPermission("getCallComposerStatus");
7795
7796 final long identity = Binder.clearCallingIdentity();
7797 try {
7798 Phone phone = getPhone(subId);
7799 if (phone != null) {
7800 Phone defaultPhone = phone.getImsPhone();
7801 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
7802 ImsPhone imsPhone = (ImsPhone) defaultPhone;
7803 return imsPhone.getCallComposerStatus();
7804 }
7805 }
7806 } finally {
7807 Binder.restoreCallingIdentity(identity);
7808 }
7809 return TelephonyManager.CALL_COMPOSER_STATUS_OFF;
7810 }
7811
7812 @Override
Jeff Sharkey85190e62014-12-05 09:40:12 -08007813 public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
7814 String number) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08007815 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
Jeff Davidson7e17e312018-02-13 18:17:36 -08007816 subId, "setLine1NumberForDisplayForSubscriber");
Derek Tan97ebb422014-09-05 16:55:38 -07007817
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007818 final long identity = Binder.clearCallingIdentity();
7819 try {
7820 final String iccId = getIccId(subId);
7821 final Phone phone = getPhone(subId);
7822 if (phone == null) {
7823 return false;
7824 }
7825 final String subscriberId = phone.getSubscriberId();
7826
7827 if (DBG_MERGE) {
Amit Mahajanb8f13202020-01-27 18:16:07 -08007828 Rlog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId="
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007829 + subscriberId + " to " + number);
7830 }
7831
7832 if (TextUtils.isEmpty(iccId)) {
7833 return false;
7834 }
7835
7836 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
7837
7838 final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
7839 if (alphaTag == null) {
7840 editor.remove(alphaTagPrefKey);
7841 } else {
7842 editor.putString(alphaTagPrefKey, alphaTag);
7843 }
7844
7845 // Record both the line number and IMSI for this ICCID, since we need to
7846 // track all merged IMSIs based on line number
7847 final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
7848 final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
7849 if (number == null) {
7850 editor.remove(numberPrefKey);
7851 editor.remove(subscriberPrefKey);
7852 } else {
7853 editor.putString(numberPrefKey, number);
7854 editor.putString(subscriberPrefKey, subscriberId);
7855 }
7856
7857 editor.commit();
7858 return true;
7859 } finally {
7860 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07007861 }
Derek Tan7226c842014-07-02 17:42:23 -07007862 }
7863
7864 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007865 public String getLine1NumberForDisplay(int subId, String callingPackage,
7866 String callingFeatureId) {
Makoto Onukifee69342015-06-29 14:44:50 -07007867 // This is open to apps with WRITE_SMS.
Jeff Davidson7e17e312018-02-13 18:17:36 -08007868 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007869 mApp, subId, callingPackage, callingFeatureId, "getLine1NumberForDisplay")) {
Amit Mahajan9cf11512015-11-09 11:40:48 -08007870 if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
Svet Ganovb320e182015-04-16 12:30:10 -07007871 return null;
7872 }
Derek Tan97ebb422014-09-05 16:55:38 -07007873
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007874 final long identity = Binder.clearCallingIdentity();
7875 try {
7876 String iccId = getIccId(subId);
7877 if (iccId != null) {
7878 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
7879 if (DBG_MERGE) {
7880 log("getLine1NumberForDisplay returning "
7881 + mTelephonySharedPreferences.getString(numberPrefKey, null));
7882 }
7883 return mTelephonySharedPreferences.getString(numberPrefKey, null);
Amit Mahajan9cf11512015-11-09 11:40:48 -08007884 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007885 if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null");
7886 return null;
7887 } finally {
7888 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07007889 }
Derek Tan7226c842014-07-02 17:42:23 -07007890 }
7891
7892 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007893 public String getLine1AlphaTagForDisplay(int subId, String callingPackage,
7894 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08007895 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007896 mApp, subId, callingPackage, callingFeatureId, "getLine1AlphaTagForDisplay")) {
Svet Ganovb320e182015-04-16 12:30:10 -07007897 return null;
7898 }
Derek Tan97ebb422014-09-05 16:55:38 -07007899
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007900 final long identity = Binder.clearCallingIdentity();
7901 try {
7902 String iccId = getIccId(subId);
7903 if (iccId != null) {
7904 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
7905 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null);
7906 }
7907 return null;
7908 } finally {
7909 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07007910 }
Derek Tan7226c842014-07-02 17:42:23 -07007911 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07007912
7913 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007914 public String[] getMergedSubscriberIds(int subId, String callingPackage,
7915 String callingFeatureId) {
Jeff Davidson913390f2018-02-23 17:11:49 -08007916 // This API isn't public, so no need to provide a valid subscription ID - we're not worried
7917 // about carrier-privileged callers not having access.
Jeff Davidson7e17e312018-02-13 18:17:36 -08007918 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08007919 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007920 callingFeatureId, "getMergedSubscriberIds")) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07007921 return null;
7922 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08007923
Jordan Liub49b04b2019-05-06 14:45:15 -07007924 // Clear calling identity, when calling TelephonyManager, because callerUid must be
7925 // the process, where TelephonyManager was instantiated.
7926 // Otherwise AppOps check will fail.
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07007927 final long identity = Binder.clearCallingIdentity();
7928 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007929 final Context context = mApp;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007930 final TelephonyManager tele = TelephonyManager.from(context);
7931 final SubscriptionManager sub = SubscriptionManager.from(context);
7932
7933 // Figure out what subscribers are currently active
7934 final ArraySet<String> activeSubscriberIds = new ArraySet<>();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007935
Jordan Liub49b04b2019-05-06 14:45:15 -07007936 // Only consider subs which match the current subId
7937 // This logic can be simplified. See b/131189269 for progress.
7938 if (isActiveSubscription(subId)) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07007939 activeSubscriberIds.add(tele.getSubscriberId(subId));
7940 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007941
7942 // First pass, find a number override for an active subscriber
7943 String mergeNumber = null;
7944 final Map<String, ?> prefs = mTelephonySharedPreferences.getAll();
7945 for (String key : prefs.keySet()) {
7946 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) {
7947 final String subscriberId = (String) prefs.get(key);
7948 if (activeSubscriberIds.contains(subscriberId)) {
7949 final String iccId = key.substring(
7950 PREF_CARRIERS_SUBSCRIBER_PREFIX.length());
7951 final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
7952 mergeNumber = (String) prefs.get(numberKey);
7953 if (DBG_MERGE) {
Amit Mahajanb8f13202020-01-27 18:16:07 -08007954 Rlog.d(LOG_TAG, "Found line number " + mergeNumber
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007955 + " for active subscriber " + subscriberId);
7956 }
7957 if (!TextUtils.isEmpty(mergeNumber)) {
7958 break;
7959 }
7960 }
7961 }
7962 }
7963
7964 // Shortcut when no active merged subscribers
7965 if (TextUtils.isEmpty(mergeNumber)) {
7966 return null;
7967 }
7968
7969 // Second pass, find all subscribers under that line override
7970 final ArraySet<String> result = new ArraySet<>();
7971 for (String key : prefs.keySet()) {
7972 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) {
7973 final String number = (String) prefs.get(key);
7974 if (mergeNumber.equals(number)) {
7975 final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length());
7976 final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
7977 final String subscriberId = (String) prefs.get(subscriberKey);
7978 if (!TextUtils.isEmpty(subscriberId)) {
7979 result.add(subscriberId);
7980 }
7981 }
7982 }
7983 }
7984
7985 final String[] resultArray = result.toArray(new String[result.size()]);
7986 Arrays.sort(resultArray);
7987 if (DBG_MERGE) {
Amit Mahajanb8f13202020-01-27 18:16:07 -08007988 Rlog.d(LOG_TAG,
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007989 "Found subscribers " + Arrays.toString(resultArray) + " after merge");
7990 }
7991 return resultArray;
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07007992 } finally {
7993 Binder.restoreCallingIdentity(identity);
Jeff Sharkey85190e62014-12-05 09:40:12 -08007994 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08007995 }
7996
7997 @Override
zoey chen38003472019-12-13 17:16:31 +08007998 public String[] getMergedImsisFromGroup(int subId, String callingPackage) {
7999 enforceReadPrivilegedPermission("getMergedImsisFromGroup");
Malcolm Chen6ca97372019-07-01 16:28:21 -07008000
8001 final long identity = Binder.clearCallingIdentity();
8002 try {
8003 final TelephonyManager telephonyManager = mApp.getSystemService(
8004 TelephonyManager.class);
8005 String subscriberId = telephonyManager.getSubscriberId(subId);
8006 if (subscriberId == null) {
8007 if (DBG) {
zoey chen38003472019-12-13 17:16:31 +08008008 log("getMergedImsisFromGroup can't find subscriberId for subId "
Malcolm Chen6ca97372019-07-01 16:28:21 -07008009 + subId);
8010 }
8011 return null;
8012 }
8013
Jack Yu285100e2022-12-02 22:48:35 -08008014 ParcelUuid groupUuid;
8015 if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
Jack Yufa8ed012023-02-11 15:42:28 -08008016 final SubscriptionInfo info = getSubscriptionManagerService()
Jack Yu285100e2022-12-02 22:48:35 -08008017 .getSubscriptionInfo(subId);
8018 groupUuid = info.getGroupUuid();
8019 } else {
8020 final SubscriptionInfo info = mSubscriptionController
8021 .getSubscriptionInfo(subId);
8022 groupUuid = info.getGroupUuid();
8023 }
Malcolm Chen6ca97372019-07-01 16:28:21 -07008024 // If it doesn't belong to any group, return just subscriberId of itself.
8025 if (groupUuid == null) {
8026 return new String[]{subscriberId};
8027 }
8028
8029 // Get all subscriberIds from the group.
8030 final List<String> mergedSubscriberIds = new ArrayList<>();
Jack Yu285100e2022-12-02 22:48:35 -08008031 List<SubscriptionInfo> groupInfos;
8032 if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
Jack Yufa8ed012023-02-11 15:42:28 -08008033 groupInfos = getSubscriptionManagerService()
Jack Yu285100e2022-12-02 22:48:35 -08008034 .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName(),
8035 mApp.getAttributionTag());
8036 } else {
8037 groupInfos = mSubscriptionController
8038 .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName(),
8039 mApp.getAttributionTag());
8040 }
Malcolm Chen6ca97372019-07-01 16:28:21 -07008041 for (SubscriptionInfo subInfo : groupInfos) {
8042 subscriberId = telephonyManager.getSubscriberId(subInfo.getSubscriptionId());
8043 if (subscriberId != null) {
8044 mergedSubscriberIds.add(subscriberId);
8045 }
8046 }
8047
8048 return mergedSubscriberIds.toArray(new String[mergedSubscriberIds.size()]);
8049 } finally {
8050 Binder.restoreCallingIdentity(identity);
8051
8052 }
8053 }
8054
8055 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08008056 public boolean setOperatorBrandOverride(int subId, String brand) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08008057 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
Jeff Davidson7e17e312018-02-13 18:17:36 -08008058 subId, "setOperatorBrandOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008059
8060 final long identity = Binder.clearCallingIdentity();
8061 try {
8062 final Phone phone = getPhone(subId);
8063 return phone == null ? false : phone.setOperatorBrandOverride(brand);
8064 } finally {
8065 Binder.restoreCallingIdentity(identity);
8066 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07008067 }
Steven Liu4bf01bc2014-07-17 11:05:29 -05008068
8069 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08008070 public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
Shishir Agrawal621a47c2014-12-01 10:25:09 -08008071 List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
8072 List<String> cdmaNonRoamingList) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08008073 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
8074 mApp, subId, "setRoamingOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008075
8076 final long identity = Binder.clearCallingIdentity();
8077 try {
8078 final Phone phone = getPhone(subId);
8079 if (phone == null) {
8080 return false;
8081 }
8082 return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList,
8083 cdmaNonRoamingList);
8084 } finally {
8085 Binder.restoreCallingIdentity(identity);
Shishir Agrawalc04d9752016-02-19 10:41:00 -08008086 }
Shishir Agrawal621a47c2014-12-01 10:25:09 -08008087 }
8088
8089 @Override
Shuo Qian850e4d6a2018-04-25 21:02:08 +00008090 @Deprecated
8091 public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
8092 enforceModifyPermission();
8093
8094 int returnValue = 0;
8095 try {
vagdeviaf9a5b92018-08-15 16:01:53 -07008096 AsyncResult result = (AsyncResult) sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
Shuo Qian850e4d6a2018-04-25 21:02:08 +00008097 if(result.exception == null) {
8098 if (result.result != null) {
8099 byte[] responseData = (byte[])(result.result);
8100 if(responseData.length > oemResp.length) {
8101 Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +
8102 responseData.length + "bytes. Buffer Size is " +
8103 oemResp.length + "bytes.");
8104 }
8105 System.arraycopy(responseData, 0, oemResp, 0, responseData.length);
8106 returnValue = responseData.length;
8107 }
8108 } else {
8109 CommandException ex = (CommandException) result.exception;
8110 returnValue = ex.getCommandError().ordinal();
8111 if(returnValue > 0) returnValue *= -1;
8112 }
8113 } catch (RuntimeException e) {
8114 Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");
8115 returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());
8116 if(returnValue > 0) returnValue *= -1;
8117 }
8118
8119 return returnValue;
8120 }
8121
8122 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07008123 public int getRadioAccessFamily(int phoneId, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08008124 Phone phone = PhoneFactory.getPhone(phoneId);
Shuo Qiandee53402020-05-29 14:08:15 -07008125 try {
8126 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07008127 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Shuo Qiandee53402020-05-29 14:08:15 -07008128 mApp, phone.getSubId(), "getRadioAccessFamily");
8129 } catch (SecurityException e) {
8130 EventLog.writeEvent(0x534e4554, "150857259", -1, "Missing Permission");
8131 throw e;
8132 }
chen xub97461a2018-10-26 14:17:57 -07008133 int raf = RadioAccessFamily.RAF_UNKNOWN;
Jeff Davidson913390f2018-02-23 17:11:49 -08008134 if (phone == null) {
chen xub97461a2018-10-26 14:17:57 -07008135 return raf;
Jeff Davidson913390f2018-02-23 17:11:49 -08008136 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008137 final long identity = Binder.clearCallingIdentity();
8138 try {
chen xub97461a2018-10-26 14:17:57 -07008139 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07008140 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
chen xub97461a2018-10-26 14:17:57 -07008141 mApp, phone.getSubId(), "getRadioAccessFamily");
8142 raf = ProxyController.getInstance().getRadioAccessFamily(phoneId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008143 } finally {
8144 Binder.restoreCallingIdentity(identity);
8145 }
chen xub97461a2018-10-26 14:17:57 -07008146 return raf;
Wink Saville5d475dd2014-10-17 15:00:58 -07008147 }
Andrew Leedf14ead2014-10-17 14:22:52 -07008148
8149 @Override
Hall Liu82694d52020-12-11 18:22:04 -08008150 public void uploadCallComposerPicture(int subscriptionId, String callingPackage,
Hall Liue31bac62020-12-23 19:16:10 -08008151 String contentType, ParcelFileDescriptor fd, ResultReceiver callback) {
Hall Liu82694d52020-12-11 18:22:04 -08008152 try {
8153 if (!Objects.equals(mApp.getPackageManager().getPackageUid(callingPackage, 0),
8154 Binder.getCallingUid())) {
Tyler Gunnb87925a2021-06-10 14:54:27 -07008155 throw new SecurityException("Invalid package:" + callingPackage);
Hall Liu82694d52020-12-11 18:22:04 -08008156 }
8157 } catch (PackageManager.NameNotFoundException e) {
Tyler Gunnb87925a2021-06-10 14:54:27 -07008158 throw new SecurityException("Invalid package:" + callingPackage);
Hall Liu82694d52020-12-11 18:22:04 -08008159 }
8160 RoleManager rm = mApp.getSystemService(RoleManager.class);
8161 List<String> dialerRoleHolders = rm.getRoleHolders(RoleManager.ROLE_DIALER);
8162 if (!dialerRoleHolders.contains(callingPackage)) {
8163 throw new SecurityException("App must be the dialer role holder to"
8164 + " upload a call composer pic");
8165 }
8166
8167 Executors.newSingleThreadExecutor().execute(() -> {
8168 ByteArrayOutputStream output = new ByteArrayOutputStream(
8169 (int) TelephonyManager.getMaximumCallComposerPictureSize());
8170 InputStream input = new ParcelFileDescriptor.AutoCloseInputStream(fd);
8171 boolean readUntilEnd = false;
8172 int totalBytesRead = 0;
8173 byte[] buffer = new byte[16 * 1024];
8174 while (true) {
8175 int numRead;
8176 try {
8177 numRead = input.read(buffer);
8178 } catch (IOException e) {
8179 try {
8180 fd.checkError();
8181 callback.send(TelephonyManager.CallComposerException.ERROR_INPUT_CLOSED,
8182 null);
8183 } catch (IOException e1) {
8184 // This means that the other side closed explicitly with an error. If this
8185 // happens, log and ignore.
8186 loge("Remote end of call composer picture pipe closed: " + e1);
8187 }
8188 break;
8189 }
8190 if (numRead == -1) {
8191 readUntilEnd = true;
8192 break;
8193 }
8194 totalBytesRead += numRead;
8195 if (totalBytesRead > TelephonyManager.getMaximumCallComposerPictureSize()) {
8196 loge("Too many bytes read for call composer picture: " + totalBytesRead);
8197 try {
8198 input.close();
8199 } catch (IOException e) {
8200 // ignore
8201 }
8202 break;
8203 }
8204 output.write(buffer, 0, numRead);
8205 }
8206 // Generally, the remote end will close the file descriptors. The only case where we
8207 // close is above, where the picture size is too big.
8208
8209 try {
8210 fd.checkError();
8211 } catch (IOException e) {
8212 loge("Remote end for call composer closed with an error: " + e);
8213 return;
8214 }
8215
Hall Liuaa4211e2021-01-20 15:43:39 -08008216 if (!readUntilEnd) {
8217 loge("Did not finish reading entire image; aborting");
8218 return;
8219 }
Hall Liu82694d52020-12-11 18:22:04 -08008220
Hall Liuaa4211e2021-01-20 15:43:39 -08008221 ImageData imageData = new ImageData(output.toByteArray(), contentType, null);
8222 CallComposerPictureManager.getInstance(mApp, subscriptionId).handleUploadToServer(
8223 new CallComposerPictureTransfer.Factory() {},
8224 imageData,
8225 (result) -> {
8226 if (result.first != null) {
8227 ParcelUuid parcelUuid = new ParcelUuid(result.first);
8228 Bundle outputResult = new Bundle();
8229 outputResult.putParcelable(
8230 TelephonyManager.KEY_CALL_COMPOSER_PICTURE_HANDLE, parcelUuid);
8231 callback.send(TelephonyManager.CallComposerException.SUCCESS,
8232 outputResult);
8233 } else {
8234 callback.send(result.second, null);
8235 }
8236 }
8237 );
Hall Liu82694d52020-12-11 18:22:04 -08008238 });
8239 }
8240
8241 @Override
Andrew Leedf14ead2014-10-17 14:22:52 -07008242 public void enableVideoCalling(boolean enable) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008243 final Phone defaultPhone = getDefaultPhone();
Andrew Leedf14ead2014-10-17 14:22:52 -07008244 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008245
8246 final long identity = Binder.clearCallingIdentity();
8247 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008248 ImsManager.getInstance(defaultPhone.getContext(),
8249 defaultPhone.getPhoneId()).setVtSetting(enable);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008250 } finally {
8251 Binder.restoreCallingIdentity(identity);
8252 }
Andrew Leedf14ead2014-10-17 14:22:52 -07008253 }
8254
8255 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008256 public boolean isVideoCallingEnabled(String callingPackage, String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008257 final Phone defaultPhone = getDefaultPhone();
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008258 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
8259 callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
Amit Mahajan578e53d2018-03-20 16:18:38 +00008260 return false;
8261 }
Svet Ganovb320e182015-04-16 12:30:10 -07008262
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008263 final long identity = Binder.clearCallingIdentity();
8264 try {
8265 // Check the user preference and the system-level IMS setting. Even if the user has
8266 // enabled video calling, if IMS is disabled we aren't able to support video calling.
8267 // In the long run, we may instead need to check if there exists a connection service
8268 // which can support video calling.
8269 ImsManager imsManager =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008270 ImsManager.getInstance(defaultPhone.getContext(), defaultPhone.getPhoneId());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008271 return imsManager.isVtEnabledByPlatform()
8272 && imsManager.isEnhanced4gLteModeSettingEnabledByUser()
8273 && imsManager.isVtEnabledByUser();
8274 } finally {
8275 Binder.restoreCallingIdentity(identity);
8276 }
Andrew Leedf14ead2014-10-17 14:22:52 -07008277 }
Libin.Tang@motorola.comafe82642014-12-18 13:27:53 -06008278
Andrew Leea1239f22015-03-02 17:44:07 -08008279 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008280 public boolean canChangeDtmfToneLength(int subId, String callingPackage,
8281 String callingFeatureId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008282 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008283 mApp, subId, callingPackage, callingFeatureId,
8284 "isVideoCallingEnabled")) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008285 return false;
8286 }
8287
8288 final long identity = Binder.clearCallingIdentity();
8289 try {
8290 CarrierConfigManager configManager =
8291 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008292 return configManager.getConfigForSubId(subId)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008293 .getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL);
8294 } finally {
8295 Binder.restoreCallingIdentity(identity);
8296 }
Andrew Leea1239f22015-03-02 17:44:07 -08008297 }
8298
8299 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008300 public boolean isWorldPhone(int subId, String callingPackage, String callingFeatureId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008301 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008302 mApp, subId, callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008303 return false;
8304 }
8305
8306 final long identity = Binder.clearCallingIdentity();
8307 try {
8308 CarrierConfigManager configManager =
8309 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008310 return configManager.getConfigForSubId(subId)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008311 .getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL);
8312 } finally {
8313 Binder.restoreCallingIdentity(identity);
8314 }
Andrew Leea1239f22015-03-02 17:44:07 -08008315 }
8316
Andrew Lee9431b832015-03-09 18:46:45 -07008317 @Override
8318 public boolean isTtyModeSupported() {
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07008319 TelecomManager telecomManager = mApp.getSystemService(TelecomManager.class);
Wooki Wu1f82f7a2016-02-15 15:59:58 +08008320 return telecomManager.isTtySupported();
Andrew Lee9431b832015-03-09 18:46:45 -07008321 }
8322
8323 @Override
8324 public boolean isHearingAidCompatibilitySupported() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008325 final long identity = Binder.clearCallingIdentity();
8326 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008327 return mApp.getResources().getBoolean(R.bool.hac_enabled);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008328 } finally {
8329 Binder.restoreCallingIdentity(identity);
8330 }
Andrew Lee9431b832015-03-09 18:46:45 -07008331 }
8332
Hall Liuf6668912018-10-31 17:05:23 -07008333 /**
8334 * Determines whether the device currently supports RTT (Real-time text). Based both on carrier
8335 * support for the feature and device firmware support.
8336 *
8337 * @return {@code true} if the device and carrier both support RTT, {@code false} otherwise.
8338 */
8339 @Override
8340 public boolean isRttSupported(int subscriptionId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008341 final long identity = Binder.clearCallingIdentity();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008342 final Phone phone = getPhone(subscriptionId);
8343 if (phone == null) {
8344 loge("isRttSupported: no Phone found. Invalid subId:" + subscriptionId);
8345 return false;
8346 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008347 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008348 boolean isCarrierSupported = mApp.getCarrierConfigForSubId(subscriptionId).getBoolean(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008349 CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
8350 boolean isDeviceSupported =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008351 phone.getContext().getResources().getBoolean(R.bool.config_support_rtt);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008352 return isCarrierSupported && isDeviceSupported;
8353 } finally {
8354 Binder.restoreCallingIdentity(identity);
8355 }
Hall Liu98187582018-01-22 19:15:32 -08008356 }
8357
Hall Liuf6668912018-10-31 17:05:23 -07008358 /**
Hall Liuf2daa022019-07-23 18:39:00 -07008359 * Determines whether the user has turned on RTT. If the carrier wants to ignore the user-set
8360 * RTT setting, will return true if the device and carrier both support RTT.
8361 * Otherwise. only returns true if the device and carrier both also support RTT.
Hall Liuf6668912018-10-31 17:05:23 -07008362 */
8363 public boolean isRttEnabled(int subscriptionId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008364 final long identity = Binder.clearCallingIdentity();
8365 try {
Hall Liu5bab75c2019-12-11 23:58:20 +00008366 boolean isRttSupported = isRttSupported(subscriptionId);
8367 boolean isUserRttSettingOn = Settings.Secure.getInt(
8368 mApp.getContentResolver(), Settings.Secure.RTT_CALLING_MODE, 0) != 0;
8369 boolean shouldIgnoreUserRttSetting = mApp.getCarrierConfigForSubId(subscriptionId)
8370 .getBoolean(CarrierConfigManager.KEY_IGNORE_RTT_MODE_SETTING_BOOL);
8371 return isRttSupported && (isUserRttSettingOn || shouldIgnoreUserRttSetting);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008372 } finally {
8373 Binder.restoreCallingIdentity(identity);
8374 }
Hall Liu3ad5f012018-04-06 16:23:39 -07008375 }
8376
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008377 @Deprecated
8378 @Override
8379 public String getDeviceId(String callingPackage) {
8380 return getDeviceIdWithFeature(callingPackage, null);
8381 }
8382
Sanket Padawe7310cc72015-01-14 09:53:20 -08008383 /**
8384 * Returns the unique device ID of phone, for example, the IMEI for
8385 * GSM and the MEID for CDMA phones. Return null if device ID is not available.
8386 *
8387 * <p>Requires Permission:
8388 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
8389 */
8390 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008391 public String getDeviceIdWithFeature(String callingPackage, String callingFeatureId) {
Shuo Qian13d89152021-05-10 23:58:11 -07008392 try {
8393 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
8394 } catch (SecurityException se) {
8395 EventLog.writeEvent(0x534e4554, "186530889", Binder.getCallingUid());
8396 throw new SecurityException("Package " + callingPackage + " does not belong to "
8397 + Binder.getCallingUid());
8398 }
Sanket Padawe7310cc72015-01-14 09:53:20 -08008399 final Phone phone = PhoneFactory.getPhone(0);
Jeff Davidson913390f2018-02-23 17:11:49 -08008400 if (phone == null) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08008401 return null;
8402 }
Jeff Davidson913390f2018-02-23 17:11:49 -08008403 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07008404 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008405 callingPackage, callingFeatureId, "getDeviceId")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08008406 return null;
8407 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008408
8409 final long identity = Binder.clearCallingIdentity();
8410 try {
8411 return phone.getDeviceId();
8412 } finally {
8413 Binder.restoreCallingIdentity(identity);
8414 }
Sanket Padawe7310cc72015-01-14 09:53:20 -08008415 }
8416
Ping Sunc67b7c22016-03-02 19:16:45 +08008417 /**
8418 * {@hide}
8419 * Returns the IMS Registration Status on a particular subid
8420 *
8421 * @param subId
8422 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08008423 public boolean isImsRegistered(int subId) {
Ping Sunc67b7c22016-03-02 19:16:45 +08008424 Phone phone = getPhone(subId);
8425 if (phone != null) {
8426 return phone.isImsRegistered();
8427 } else {
8428 return false;
8429 }
8430 }
8431
Santos Cordon7a1885b2015-02-03 11:15:19 -08008432 @Override
Shuo Qian6e6137d2019-10-30 16:33:31 -07008433 public int getSubIdForPhoneAccountHandle(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008434 PhoneAccountHandle phoneAccountHandle, String callingPackage, String callingFeatureId) {
Shuo Qian6e6137d2019-10-30 16:33:31 -07008435 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, getDefaultSubscription(),
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008436 callingPackage, callingFeatureId, "getSubIdForPhoneAccountHandle")) {
Shuo Qian6e6137d2019-10-30 16:33:31 -07008437 throw new SecurityException("Requires READ_PHONE_STATE permission.");
8438 }
8439 final long identity = Binder.clearCallingIdentity();
8440 try {
8441 return PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle);
8442 } finally {
8443 Binder.restoreCallingIdentity(identity);
8444 }
8445 }
8446
8447 @Override
Tyler Gunnf70ed162019-04-03 15:28:53 -07008448 public @Nullable PhoneAccountHandle getPhoneAccountHandleForSubscriptionId(int subscriptionId) {
Alireza Forouzan4ac4f982021-03-16 22:18:52 -07008449 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07008450 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Thomas Nguyen8ee49682023-02-01 11:46:09 -08008451 mApp,
8452 subscriptionId,
8453 "getPhoneAccountHandleForSubscriptionId, " + "subscriptionId: "
8454 + subscriptionId);
Tyler Gunnf70ed162019-04-03 15:28:53 -07008455 final long identity = Binder.clearCallingIdentity();
8456 try {
8457 Phone phone = getPhone(subscriptionId);
8458 if (phone == null) {
8459 return null;
8460 }
8461 return PhoneUtils.makePstnPhoneAccountHandle(phone);
8462 } finally {
8463 Binder.restoreCallingIdentity(identity);
8464 }
8465 }
8466
Brad Ebinger1f2b5082018-02-08 16:11:32 -08008467 /**
8468 * @return the VoWiFi calling availability.
Nathan Haroldc55097a2015-03-11 18:14:50 -07008469 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08008470 public boolean isWifiCallingAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008471 final long identity = Binder.clearCallingIdentity();
8472 try {
8473 Phone phone = getPhone(subId);
8474 if (phone != null) {
8475 return phone.isWifiCallingEnabled();
8476 } else {
8477 return false;
8478 }
8479 } finally {
8480 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08008481 }
Nathan Haroldc55097a2015-03-11 18:14:50 -07008482 }
8483
Brad Ebinger1f2b5082018-02-08 16:11:32 -08008484 /**
Brad Ebinger1f2b5082018-02-08 16:11:32 -08008485 * @return the VT calling availability.
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07008486 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08008487 public boolean isVideoTelephonyAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008488 final long identity = Binder.clearCallingIdentity();
8489 try {
8490 Phone phone = getPhone(subId);
8491 if (phone != null) {
8492 return phone.isVideoEnabled();
8493 } else {
8494 return false;
8495 }
8496 } finally {
8497 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08008498 }
8499 }
8500
8501 /**
8502 * @return the IMS registration technology for the MMTEL feature. Valid return values are
8503 * defined in {@link ImsRegistrationImplBase}.
8504 */
8505 public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008506 final long identity = Binder.clearCallingIdentity();
8507 try {
8508 Phone phone = getPhone(subId);
8509 if (phone != null) {
8510 return phone.getImsRegistrationTech();
8511 } else {
8512 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
8513 }
8514 } finally {
8515 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08008516 }
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07008517 }
8518
Stuart Scott8eef64f2015-04-08 15:13:54 -07008519 @Override
Sarah Chinecc78c42022-03-31 21:16:48 -07008520 public void factoryReset(int subId, String callingPackage) {
paulhu5a773602019-08-23 19:17:33 +08008521 enforceSettingsPermission();
Stuart Scott981d8582015-04-21 14:09:50 -07008522 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
8523 return;
8524 }
Kai Shif70f46f2021-03-03 13:59:46 -08008525 Phone defaultPhone = getDefaultPhone();
8526 if (defaultPhone != null) {
8527 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8528 mApp, getDefaultPhone().getSubId(), "factoryReset");
8529 }
Svet Ganovcc087f82015-05-12 20:35:54 -07008530 final long identity = Binder.clearCallingIdentity();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008531
Svet Ganovcc087f82015-05-12 20:35:54 -07008532 try {
Stuart Scott981d8582015-04-21 14:09:50 -07008533 if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
8534 UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07008535 setDataEnabledForReason(subId, TelephonyManager.DATA_ENABLED_REASON_USER,
Sarah Chinecc78c42022-03-31 21:16:48 -07008536 getDefaultDataEnabled(), callingPackage);
Svet Ganovcc087f82015-05-12 20:35:54 -07008537 setNetworkSelectionModeAutomatic(subId);
SongFerngWang8c6e82e2021-03-02 22:09:29 +08008538 Phone phone = getPhone(subId);
SongFerngWangfd89b102021-05-27 22:44:54 +08008539 cleanUpAllowedNetworkTypes(phone, subId);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008540 setDataRoamingEnabled(subId, getDefaultDataRoamingEnabled(subId));
Jordan Liu857e73a2021-03-05 16:24:04 -08008541 getPhone(subId).resetCarrierKeysForImsiEncryption();
Svet Ganovcc087f82015-05-12 20:35:54 -07008542 }
Amit Mahajan7dbbd822019-03-13 17:33:47 -07008543 // There has been issues when Sms raw table somehow stores orphan
8544 // fragments. They lead to garbled message when new fragments come
8545 // in and combined with those stale ones. In case this happens again,
8546 // user can reset all network settings which will clean up this table.
8547 cleanUpSmsRawTable(getDefaultPhone().getContext());
Brad Ebingerbc7dd582019-10-17 17:03:22 -07008548 // Clean up IMS settings as well here.
8549 int slotId = getSlotIndex(subId);
8550 if (slotId > SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
8551 ImsManager.getInstance(mApp, slotId).factoryReset();
8552 }
Naina Nallurid63128d2019-09-17 14:10:30 -07008553
Kai Shif70f46f2021-03-03 13:59:46 -08008554 if (defaultPhone == null) {
8555 return;
8556 }
Naina Nallurid63128d2019-09-17 14:10:30 -07008557 // Erase modem config if erase modem on network setting is enabled.
8558 String configValue = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_TELEPHONY,
8559 RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED);
8560 if (configValue != null && Boolean.parseBoolean(configValue)) {
Kai Shif70f46f2021-03-03 13:59:46 -08008561 sendEraseModemConfig(defaultPhone);
Naina Nallurid63128d2019-09-17 14:10:30 -07008562 }
Kai Shif70f46f2021-03-03 13:59:46 -08008563
8564 sendEraseDataInSharedPreferences(defaultPhone);
Svet Ganovcc087f82015-05-12 20:35:54 -07008565 } finally {
8566 Binder.restoreCallingIdentity(identity);
Stuart Scott8eef64f2015-04-08 15:13:54 -07008567 }
8568 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01008569
SongFerngWangfd89b102021-05-27 22:44:54 +08008570 @VisibleForTesting
8571 void cleanUpAllowedNetworkTypes(Phone phone, int subId) {
8572 if (phone == null || !SubscriptionManager.isUsableSubscriptionId(subId)) {
8573 return;
8574 }
8575 long defaultNetworkType = RadioAccessFamily.getRafFromNetworkType(
8576 RILConstants.PREFERRED_NETWORK_MODE);
8577 SubscriptionManager.setSubscriptionProperty(subId,
8578 SubscriptionManager.ALLOWED_NETWORK_TYPES,
8579 "user=" + defaultNetworkType);
8580 phone.loadAllowedNetworksFromSubscriptionDatabase();
8581 phone.setAllowedNetworkTypes(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER,
8582 defaultNetworkType, null);
8583 }
8584
Amit Mahajan7dbbd822019-03-13 17:33:47 -07008585 private void cleanUpSmsRawTable(Context context) {
8586 ContentResolver resolver = context.getContentResolver();
8587 Uri uri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete");
8588 resolver.delete(uri, null, null);
8589 }
8590
Narayan Kamath1c496c22015-04-16 14:40:19 +01008591 @Override
chen xu5d3637b2019-01-21 23:31:38 -08008592 public String getSimLocaleForSubscriber(int subId) {
8593 enforceReadPrivilegedPermission("getSimLocaleForSubscriber, subId: " + subId);
8594 final Phone phone = getPhone(subId);
8595 if (phone == null) {
8596 log("getSimLocaleForSubscriber, invalid subId");
chen xu2bb91e42019-01-24 14:35:54 -08008597 return null;
chen xu5d3637b2019-01-21 23:31:38 -08008598 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008599 final long identity = Binder.clearCallingIdentity();
8600 try {
Jack Yu285100e2022-12-02 22:48:35 -08008601 SubscriptionInfo info;
8602 if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
Jack Yufa8ed012023-02-11 15:42:28 -08008603 info = getSubscriptionManagerService().getActiveSubscriptionInfo(subId,
Jack Yu285100e2022-12-02 22:48:35 -08008604 phone.getContext().getOpPackageName(),
8605 phone.getContext().getAttributionTag());
8606 if (info == null) {
8607 log("getSimLocaleForSubscriber, inactive subId: " + subId);
8608 return null;
8609 }
8610 } else {
8611 info = mSubscriptionController.getActiveSubscriptionInfo(subId,
8612 phone.getContext().getOpPackageName(),
8613 phone.getContext().getAttributionTag());
8614 if (info == null) {
8615 log("getSimLocaleForSubscriber, inactive subId: " + subId);
8616 return null;
8617 }
chen xu6291c472019-02-04 12:55:53 -08008618 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008619 // Try and fetch the locale from the carrier properties or from the SIM language
8620 // preferences (EF-PL and EF-LI)...
8621 final int mcc = info.getMcc();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008622 String simLanguage = null;
chen xu5d3637b2019-01-21 23:31:38 -08008623 final Locale localeFromDefaultSim = phone.getLocaleFromSimAndCarrierPrefs();
8624 if (localeFromDefaultSim != null) {
8625 if (!localeFromDefaultSim.getCountry().isEmpty()) {
8626 if (DBG) log("Using locale from subId: " + subId + " locale: "
8627 + localeFromDefaultSim);
tom hsu60a8dc52022-10-27 00:10:04 +08008628 return matchLocaleFromSupportedLocaleList(phone, localeFromDefaultSim);
chen xu5d3637b2019-01-21 23:31:38 -08008629 } else {
8630 simLanguage = localeFromDefaultSim.getLanguage();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008631 }
8632 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01008633
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008634 // The SIM language preferences only store a language (e.g. fr = French), not an
8635 // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
8636 // the SIM and carrier preferences does not include a country we add the country
8637 // determined from the SIM MCC to provide an exact locale.
zoey chenc730df82019-12-18 17:07:20 +08008638 final Locale mccLocale = LocaleUtils.getLocaleFromMcc(mApp, mcc, simLanguage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008639 if (mccLocale != null) {
chen xu5d3637b2019-01-21 23:31:38 -08008640 if (DBG) log("No locale from SIM, using mcc locale:" + mccLocale);
tom hsu60a8dc52022-10-27 00:10:04 +08008641 return matchLocaleFromSupportedLocaleList(phone, mccLocale);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008642 }
8643
8644 if (DBG) log("No locale found - returning null");
8645 return null;
8646 } finally {
8647 Binder.restoreCallingIdentity(identity);
8648 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01008649 }
8650
tom hsu0b59d292022-09-29 23:49:21 +08008651 @VisibleForTesting
tom hsu60a8dc52022-10-27 00:10:04 +08008652 String matchLocaleFromSupportedLocaleList(Phone phone, @NonNull Locale inputLocale) {
tom hsu0b59d292022-09-29 23:49:21 +08008653 String[] supportedLocale = com.android.internal.app.LocalePicker.getSupportedLocales(
tom hsu60a8dc52022-10-27 00:10:04 +08008654 phone.getContext());
tom hsu0b59d292022-09-29 23:49:21 +08008655 for (String localeTag : supportedLocale) {
tom hsu60a8dc52022-10-27 00:10:04 +08008656 if (LocaleList.matchesLanguageAndScript(inputLocale, Locale.forLanguageTag(localeTag))
8657 && TextUtils.equals(inputLocale.getCountry(),
tom hsu0b59d292022-09-29 23:49:21 +08008658 Locale.forLanguageTag(localeTag).getCountry())) {
8659 return localeTag;
8660 }
8661 }
8662 return inputLocale.toLanguageTag();
8663 }
8664
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008665 /**
8666 * NOTE: this method assumes permission checks are done and caller identity has been cleared.
8667 */
8668 private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
Jack Yu285100e2022-12-02 22:48:35 -08008669 if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
Jack Yufa8ed012023-02-11 15:42:28 -08008670 return getSubscriptionManagerService().getActiveSubscriptionInfoList(
Jack Yu285100e2022-12-02 22:48:35 -08008671 mApp.getOpPackageName(), mApp.getAttributionTag());
8672 }
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008673 return mSubscriptionController.getActiveSubscriptionInfoList(mApp.getOpPackageName(),
Philip P. Moltmann8d34f0c2020-03-05 16:24:02 -08008674 mApp.getAttributionTag());
Narayan Kamath1c496c22015-04-16 14:40:19 +01008675 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07008676
Gary Jian3aa9a762022-01-24 16:41:19 +08008677 private ActivityStatsTechSpecificInfo[] mLastModemActivitySpecificInfo = null;
8678 private ModemActivityInfo mLastModemActivityInfo = null;
Chenjie Yu1ba97252018-01-11 18:16:20 -08008679
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07008680 /**
Adam Lesinski903a54c2016-04-11 14:49:52 -07008681 * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
8682 * representing the state of the modem.
8683 *
Chenjie Yu1ba97252018-01-11 18:16:20 -08008684 * NOTE: The underlying implementation clears the modem state, so there should only ever be one
8685 * caller to it. Everyone should call this class to get cumulative data.
Adam Lesinski903a54c2016-04-11 14:49:52 -07008686 * @hide
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07008687 */
8688 @Override
Adam Lesinski903a54c2016-04-11 14:49:52 -07008689 public void requestModemActivityInfo(ResultReceiver result) {
8690 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07008691 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008692
8693 final long identity = Binder.clearCallingIdentity();
8694 try {
Shuo Qian8f4750a2020-02-20 17:12:10 -08008695 sendRequestAsync(CMD_GET_MODEM_ACTIVITY_INFO, result, null, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008696 } finally {
8697 Binder.restoreCallingIdentity(identity);
Chenjie Yu1ba97252018-01-11 18:16:20 -08008698 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07008699 }
Jack Yu85bd38a2015-11-09 11:34:32 -08008700
Gary Jian76280a42022-12-07 16:18:33 +08008701 // Checks that ModemActivityInfo is valid. Sleep time and Idle time should be
Siddharth Rayb8114062018-06-17 15:02:38 -07008702 // less than total activity duration.
8703 private boolean isModemActivityInfoValid(ModemActivityInfo info) {
8704 if (info == null) {
8705 return false;
8706 }
8707 int activityDurationMs =
Hall Liu49656c02020-10-09 19:00:11 -07008708 (int) (info.getTimestampMillis() - mLastModemActivityInfo.getTimestampMillis());
Gary Jian76280a42022-12-07 16:18:33 +08008709 activityDurationMs += MODEM_ACTIVITY_TIME_OFFSET_CORRECTION_MS;
8710
Hall Liu49656c02020-10-09 19:00:11 -07008711 int totalTxTimeMs = Arrays.stream(info.getTransmitTimeMillis()).sum();
8712
Siddharth Rayb8114062018-06-17 15:02:38 -07008713 return (info.isValid()
Thomas Nguyen8ee49682023-02-01 11:46:09 -08008714 && (info.getSleepTimeMillis() <= activityDurationMs)
8715 && (info.getIdleTimeMillis() <= activityDurationMs));
Siddharth Rayb8114062018-06-17 15:02:38 -07008716 }
8717
Gary Jian3aa9a762022-01-24 16:41:19 +08008718 private void updateLastModemActivityInfo(ModemActivityInfo info, int rat, int freq) {
8719 int[] mergedTxTimeMs = new int [ModemActivityInfo.getNumTxPowerLevels()];
8720 int[] txTimeMs = info.getTransmitTimeMillis(rat, freq);
8721 int[] lastModemTxTimeMs = mLastModemActivityInfo.getTransmitTimeMillis(rat, freq);
8722
8723 for (int lvl = 0; lvl < mergedTxTimeMs.length; lvl++) {
8724 mergedTxTimeMs[lvl] = txTimeMs[lvl] + lastModemTxTimeMs[lvl];
8725 }
8726
8727 mLastModemActivityInfo.setTransmitTimeMillis(rat, freq, mergedTxTimeMs);
8728 mLastModemActivityInfo.setReceiveTimeMillis(
8729 rat,
8730 freq,
8731 info.getReceiveTimeMillis(rat, freq)
8732 + mLastModemActivityInfo.getReceiveTimeMillis(rat, freq));
8733 }
8734
8735 private void updateLastModemActivityInfo(ModemActivityInfo info, int rat) {
8736 int[] mergedTxTimeMs = new int [ModemActivityInfo.getNumTxPowerLevels()];
8737 int[] txTimeMs = info.getTransmitTimeMillis(rat);
8738 int[] lastModemTxTimeMs = mLastModemActivityInfo.getTransmitTimeMillis(rat);
8739
8740 for (int lvl = 0; lvl < mergedTxTimeMs.length; lvl++) {
8741 mergedTxTimeMs[lvl] = txTimeMs[lvl] + lastModemTxTimeMs[lvl];
8742 }
8743 mLastModemActivityInfo.setTransmitTimeMillis(rat, mergedTxTimeMs);
8744 mLastModemActivityInfo.setReceiveTimeMillis(
8745 rat,
8746 info.getReceiveTimeMillis(rat) + mLastModemActivityInfo.getReceiveTimeMillis(rat));
8747 }
8748
Thomas Nguyen8ee49682023-02-01 11:46:09 -08008749 /**
8750 * Merge this ModemActivityInfo with mLastModemActivitySpecificInfo
8751 * @param info recent ModemActivityInfo
8752 */
Gary Jian3aa9a762022-01-24 16:41:19 +08008753 private void mergeModemActivityInfo(ModemActivityInfo info) {
8754 List<ActivityStatsTechSpecificInfo> merged = new ArrayList<>();
Kai Shi917fdc62022-11-28 14:01:02 -08008755 ActivityStatsTechSpecificInfo deltaSpecificInfo;
Gary Jian3aa9a762022-01-24 16:41:19 +08008756 boolean matched;
8757 for (int i = 0; i < info.getSpecificInfoLength(); i++) {
8758 matched = false;
8759 int rat = info.getSpecificInfoRat(i);
8760 int freq = info.getSpecificInfoFrequencyRange(i);
8761 //Check each ActivityStatsTechSpecificInfo in this ModemActivityInfo for new rat returns
8762 //Add a new ActivityStatsTechSpecificInfo if is a new rat, and merge with the original
8763 //if it already exists
8764 for (int j = 0; j < mLastModemActivitySpecificInfo.length; j++) {
8765 if (rat == mLastModemActivityInfo.getSpecificInfoRat(j) && !matched) {
8766 //Merged based on frequency range (MMWAVE vs SUB6) for 5G
8767 if (rat == AccessNetworkConstants.AccessNetworkType.NGRAN) {
8768 if (freq == mLastModemActivityInfo.getSpecificInfoFrequencyRange(j)) {
8769 updateLastModemActivityInfo(info, rat, freq);
8770 matched = true;
8771 }
8772 } else {
8773 updateLastModemActivityInfo(info, rat);
8774 matched = true;
8775 }
8776 }
8777 }
8778
8779 if (!matched) {
Kai Shi917fdc62022-11-28 14:01:02 -08008780 deltaSpecificInfo =
Gary Jian3aa9a762022-01-24 16:41:19 +08008781 new ActivityStatsTechSpecificInfo(
8782 rat,
8783 freq,
8784 info.getTransmitTimeMillis(rat, freq),
8785 (int) info.getReceiveTimeMillis(rat, freq));
Kai Shi917fdc62022-11-28 14:01:02 -08008786 merged.addAll(Arrays.asList(deltaSpecificInfo));
Gary Jian3aa9a762022-01-24 16:41:19 +08008787 }
8788 }
8789 merged.addAll(Arrays.asList(mLastModemActivitySpecificInfo));
8790 mLastModemActivitySpecificInfo =
8791 new ActivityStatsTechSpecificInfo[merged.size()];
8792 merged.toArray(mLastModemActivitySpecificInfo);
8793
8794 mLastModemActivityInfo.setTimestamp(info.getTimestampMillis());
8795 mLastModemActivityInfo.setSleepTimeMillis(
8796 info.getSleepTimeMillis()
Thomas Nguyen8ee49682023-02-01 11:46:09 -08008797 + mLastModemActivityInfo.getSleepTimeMillis());
Gary Jian3aa9a762022-01-24 16:41:19 +08008798 mLastModemActivityInfo.setIdleTimeMillis(
8799 info.getIdleTimeMillis()
Thomas Nguyen8ee49682023-02-01 11:46:09 -08008800 + mLastModemActivityInfo.getIdleTimeMillis());
Kai Shi917fdc62022-11-28 14:01:02 -08008801
8802 mLastModemActivityInfo =
Thomas Nguyen8ee49682023-02-01 11:46:09 -08008803 new ModemActivityInfo(
8804 mLastModemActivityInfo.getTimestampMillis(),
8805 mLastModemActivityInfo.getSleepTimeMillis(),
8806 mLastModemActivityInfo.getIdleTimeMillis(),
8807 mLastModemActivitySpecificInfo);
Kai Shi917fdc62022-11-28 14:01:02 -08008808 }
8809
8810 private ActivityStatsTechSpecificInfo[] deepCopyModemActivitySpecificInfo(
8811 ActivityStatsTechSpecificInfo[] info) {
8812 int infoSize = info.length;
8813 ActivityStatsTechSpecificInfo[] ret = new ActivityStatsTechSpecificInfo[infoSize];
8814 for (int i = 0; i < infoSize; i++) {
8815 ret[i] = new ActivityStatsTechSpecificInfo(
8816 info[i].getRat(), info[i].getFrequencyRange(),
8817 info[i].getTransmitTimeMillis(),
8818 (int) info[i].getReceiveTimeMillis());
8819 }
8820 return ret;
Gary Jian3aa9a762022-01-24 16:41:19 +08008821 }
8822
Jack Yu85bd38a2015-11-09 11:34:32 -08008823 /**
Jack Yu85bd38a2015-11-09 11:34:32 -08008824 * Returns the service state information on specified subscription.
8825 */
8826 @Override
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08008827 public ServiceState getServiceStateForSubscriber(int subId,
8828 boolean renounceFineLocationAccess, boolean renounceCoarseLocationAccess,
8829 String callingPackage, String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08008830 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008831 mApp, subId, callingPackage, callingFeatureId, "getServiceStateForSubscriber")) {
Jack Yu85bd38a2015-11-09 11:34:32 -08008832 return null;
8833 }
8834
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08008835 boolean hasFinePermission = false;
8836 boolean hasCoarsePermission = false;
8837 if (!renounceFineLocationAccess) {
8838 LocationAccessPolicy.LocationPermissionResult fineLocationResult =
8839 LocationAccessPolicy.checkLocationPermission(mApp,
8840 new LocationAccessPolicy.LocationPermissionQuery.Builder()
8841 .setCallingPackage(callingPackage)
8842 .setCallingFeatureId(callingFeatureId)
8843 .setCallingPid(Binder.getCallingPid())
8844 .setCallingUid(Binder.getCallingUid())
8845 .setMethod("getServiceStateForSubscriber")
8846 .setLogAsInfo(true)
8847 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
8848 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
8849 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
8850 .build());
8851 hasFinePermission =
8852 fineLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
8853 }
Hall Liuf19c44f2018-11-27 14:38:17 -08008854
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08008855 if (!renounceCoarseLocationAccess) {
8856 LocationAccessPolicy.LocationPermissionResult coarseLocationResult =
8857 LocationAccessPolicy.checkLocationPermission(mApp,
8858 new LocationAccessPolicy.LocationPermissionQuery.Builder()
8859 .setCallingPackage(callingPackage)
8860 .setCallingFeatureId(callingFeatureId)
8861 .setCallingPid(Binder.getCallingPid())
8862 .setCallingUid(Binder.getCallingUid())
8863 .setMethod("getServiceStateForSubscriber")
8864 .setLogAsInfo(true)
8865 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
8866 .setMinSdkVersionForFine(Integer.MAX_VALUE)
8867 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
8868 .build());
8869 hasCoarsePermission =
8870 coarseLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
8871 }
Hall Liuf19c44f2018-11-27 14:38:17 -08008872
Jack Yu479f40e2020-10-27 21:29:25 -07008873 final Phone phone = getPhone(subId);
8874 if (phone == null) {
8875 return null;
8876 }
8877
Jordan Liu0f2bc442020-11-18 16:47:37 -08008878 final long identity = Binder.clearCallingIdentity();
8879
Jack Yu479f40e2020-10-27 21:29:25 -07008880 boolean isCallingPackageDataService = phone.getDataServicePackages()
8881 .contains(callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008882 try {
Jordan Liuc437b192020-08-17 10:59:12 -07008883 // isActiveSubId requires READ_PHONE_STATE, which we already check for above
Jack Yu285100e2022-12-02 22:48:35 -08008884 if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
Jack Yufa8ed012023-02-11 15:42:28 -08008885 SubscriptionInfoInternal subInfo = getSubscriptionManagerService()
Jack Yu285100e2022-12-02 22:48:35 -08008886 .getSubscriptionInfoInternal(subId);
8887 if (subInfo == null || !subInfo.isActive()) {
8888 Rlog.d(LOG_TAG, "getServiceStateForSubscriber returning null for inactive "
8889 + "subId=" + subId);
8890 return null;
8891 }
8892 } else {
8893 if (!mSubscriptionController.isActiveSubId(subId, callingPackage,
8894 callingFeatureId)) {
8895 Rlog.d(LOG_TAG, "getServiceStateForSubscriber returning null for inactive "
8896 + "subId=" + subId);
8897 return null;
8898 }
Jordan Liuc437b192020-08-17 10:59:12 -07008899 }
8900
Hall Liuf19c44f2018-11-27 14:38:17 -08008901 ServiceState ss = phone.getServiceState();
8902
8903 // Scrub out the location info in ServiceState depending on what level of access
8904 // the caller has.
Jack Yu479f40e2020-10-27 21:29:25 -07008905 if (hasFinePermission || isCallingPackageDataService) return ss;
Malcolm Chen5052de62019-12-30 13:56:38 -08008906 if (hasCoarsePermission) return ss.createLocationInfoSanitizedCopy(false);
8907 return ss.createLocationInfoSanitizedCopy(true);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008908 } finally {
8909 Binder.restoreCallingIdentity(identity);
8910 }
Jack Yu85bd38a2015-11-09 11:34:32 -08008911 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08008912
8913 /**
8914 * Returns the URI for the per-account voicemail ringtone set in Phone settings.
8915 *
8916 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
8917 * voicemail ringtone.
8918 * @return The URI for the ringtone to play when receiving a voicemail from a specific
8919 * PhoneAccount.
8920 */
8921 @Override
8922 public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008923 final long identity = Binder.clearCallingIdentity();
8924 try {
8925 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
8926 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008927 phone = getDefaultPhone();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008928 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08008929
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008930 return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext());
8931 } finally {
8932 Binder.restoreCallingIdentity(identity);
8933 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08008934 }
8935
8936 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008937 * Sets the per-account voicemail ringtone.
8938 *
8939 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
8940 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
8941 *
8942 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
8943 * voicemail ringtone.
8944 * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
8945 * PhoneAccount.
8946 */
8947 @Override
8948 public void setVoicemailRingtoneUri(String callingPackage,
8949 PhoneAccountHandle phoneAccountHandle, Uri uri) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008950 final Phone defaultPhone = getDefaultPhone();
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008951 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07008952 TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
8953 if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08008954 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8955 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
8956 "setVoicemailRingtoneUri");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008957 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008958
8959 final long identity = Binder.clearCallingIdentity();
8960 try {
8961 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
8962 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008963 phone = defaultPhone;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008964 }
8965 VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri);
8966 } finally {
8967 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008968 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008969 }
8970
8971 /**
Nancy Chen31f9ba12016-01-06 11:42:12 -08008972 * Returns whether vibration is set for voicemail notification in Phone settings.
8973 *
8974 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
8975 * voicemail vibration setting.
8976 * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
8977 */
8978 @Override
8979 public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008980 final long identity = Binder.clearCallingIdentity();
8981 try {
8982 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
8983 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008984 phone = getDefaultPhone();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008985 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08008986
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008987 return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext());
8988 } finally {
8989 Binder.restoreCallingIdentity(identity);
8990 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08008991 }
8992
Youhan Wange64578a2016-05-02 15:32:42 -07008993 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008994 * Sets the per-account voicemail vibration.
8995 *
8996 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
8997 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
8998 *
8999 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
9000 * voicemail vibration setting.
9001 * @param enabled Whether to enable or disable vibration for voicemail notifications from a
9002 * specific PhoneAccount.
9003 */
9004 @Override
9005 public void setVoicemailVibrationEnabled(String callingPackage,
9006 PhoneAccountHandle phoneAccountHandle, boolean enabled) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08009007 final Phone defaultPhone = getDefaultPhone();
Ta-wei Yenc33877d2017-01-23 18:11:21 -08009008 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07009009 TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
9010 if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08009011 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
9012 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
9013 "setVoicemailVibrationEnabled");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08009014 }
9015
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009016 final long identity = Binder.clearCallingIdentity();
9017 try {
9018 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
9019 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08009020 phone = defaultPhone;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009021 }
9022 VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled);
9023 } finally {
9024 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08009025 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08009026 }
9027
9028 /**
Youhan Wange64578a2016-05-02 15:32:42 -07009029 * Make sure either called from same process as self (phone) or IPC caller has read privilege.
9030 *
9031 * @throws SecurityException if the caller does not have the required permission
9032 */
arunvoddud7401012022-12-15 16:08:12 +00009033 @VisibleForTesting
9034 public void enforceReadPrivilegedPermission(String message) {
Youhan Wange64578a2016-05-02 15:32:42 -07009035 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
Brad Ebinger35c841c2018-10-01 10:40:55 -07009036 message);
Youhan Wange64578a2016-05-02 15:32:42 -07009037 }
9038
9039 /**
Ta-wei Yen30a69c82016-12-27 14:52:32 -08009040 * Make sure either called from same process as self (phone) or IPC caller has send SMS
9041 * permission.
9042 *
9043 * @throws SecurityException if the caller does not have the required permission
9044 */
9045 private void enforceSendSmsPermission() {
9046 mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null);
9047 }
9048
9049 /**
Aishwarya Mallampatifbc70d32022-11-10 20:33:02 +00009050 * Make sure either called from same process as self (phone) or IPC caller has interact across
9051 * users permission.
9052 *
9053 * @throws SecurityException if the caller does not have the required permission
9054 */
9055 private void enforceInteractAcrossUsersPermission(String message) {
9056 mApp.enforceCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS, message);
9057 }
9058
9059 /**
Ta-wei Yen527a9c02017-01-06 15:29:25 -08009060 * Make sure called from the package in charge of visual voicemail.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08009061 *
Ta-wei Yen527a9c02017-01-06 15:29:25 -08009062 * @throws SecurityException if the caller is not the visual voicemail package.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08009063 */
Ta-wei Yen527a9c02017-01-06 15:29:25 -08009064 private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009065 final long identity = Binder.clearCallingIdentity();
9066 try {
9067 ComponentName componentName =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08009068 RemoteVvmTaskManager.getRemotePackage(mApp, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009069 if (componentName == null) {
9070 throw new SecurityException(
9071 "Caller not current active visual voicemail package[null]");
9072 }
9073 String vvmPackage = componentName.getPackageName();
9074 if (!callingPackage.equals(vvmPackage)) {
Hui Wang7f657552022-08-16 16:58:25 +00009075 throw new SecurityException("Caller not current active visual voicemail package");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009076 }
9077 } finally {
9078 Binder.restoreCallingIdentity(identity);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08009079 }
9080 }
9081
9082 /**
Youhan Wange64578a2016-05-02 15:32:42 -07009083 * Return the application ID for the app type.
9084 *
9085 * @param subId the subscription ID that this request applies to.
9086 * @param appType the uicc app type.
9087 * @return Application ID for specificied app type, or null if no uicc.
9088 */
9089 @Override
9090 public String getAidForAppType(int subId, int appType) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07009091 enforceReadPrivilegedPermission("getAidForAppType");
Youhan Wange64578a2016-05-02 15:32:42 -07009092 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009093
9094 final long identity = Binder.clearCallingIdentity();
Youhan Wange64578a2016-05-02 15:32:42 -07009095 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009096 if (phone == null) {
9097 return null;
9098 }
9099 String aid = null;
9100 try {
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00009101 aid = UiccController.getInstance().getUiccPort(phone.getPhoneId())
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009102 .getApplicationByType(appType).getAid();
9103 } catch (Exception e) {
9104 Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e);
9105 }
9106 return aid;
9107 } finally {
9108 Binder.restoreCallingIdentity(identity);
Youhan Wange64578a2016-05-02 15:32:42 -07009109 }
Youhan Wange64578a2016-05-02 15:32:42 -07009110 }
9111
Youhan Wang4001d252016-05-11 10:29:41 -07009112 /**
9113 * Return the Electronic Serial Number.
9114 *
9115 * @param subId the subscription ID that this request applies to.
9116 * @return ESN or null if error.
9117 */
9118 @Override
9119 public String getEsn(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07009120 enforceReadPrivilegedPermission("getEsn");
Youhan Wang4001d252016-05-11 10:29:41 -07009121 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009122
9123 final long identity = Binder.clearCallingIdentity();
Youhan Wang4001d252016-05-11 10:29:41 -07009124 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009125 if (phone == null) {
9126 return null;
9127 }
9128 String esn = null;
9129 try {
9130 esn = phone.getEsn();
9131 } catch (Exception e) {
9132 Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e);
9133 }
9134 return esn;
9135 } finally {
9136 Binder.restoreCallingIdentity(identity);
Youhan Wang4001d252016-05-11 10:29:41 -07009137 }
Youhan Wang4001d252016-05-11 10:29:41 -07009138 }
9139
Sanket Padawe99ef1e32016-05-18 16:12:33 -07009140 /**
Youhan Wang66ad5d72016-07-18 17:56:58 -07009141 * Return the Preferred Roaming List Version.
9142 *
9143 * @param subId the subscription ID that this request applies to.
9144 * @return PRLVersion or null if error.
9145 */
9146 @Override
9147 public String getCdmaPrlVersion(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07009148 enforceReadPrivilegedPermission("getCdmaPrlVersion");
Youhan Wang66ad5d72016-07-18 17:56:58 -07009149 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009150
9151 final long identity = Binder.clearCallingIdentity();
Youhan Wang66ad5d72016-07-18 17:56:58 -07009152 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009153 if (phone == null) {
9154 return null;
9155 }
9156 String cdmaPrlVersion = null;
9157 try {
9158 cdmaPrlVersion = phone.getCdmaPrlVersion();
9159 } catch (Exception e) {
9160 Log.e(LOG_TAG, "Not getting PRLVersion", e);
9161 }
9162 return cdmaPrlVersion;
9163 } finally {
9164 Binder.restoreCallingIdentity(identity);
Youhan Wang66ad5d72016-07-18 17:56:58 -07009165 }
Youhan Wang66ad5d72016-07-18 17:56:58 -07009166 }
9167
9168 /**
Sanket Padawe99ef1e32016-05-18 16:12:33 -07009169 * Get snapshot of Telephony histograms
9170 * @return List of Telephony histograms
9171 * @hide
9172 */
9173 @Override
9174 public List<TelephonyHistogram> getTelephonyHistograms() {
Jeff Davidson7e17e312018-02-13 18:17:36 -08009175 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
9176 mApp, getDefaultSubscription(), "getTelephonyHistograms");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009177
9178 final long identity = Binder.clearCallingIdentity();
9179 try {
9180 return RIL.getTelephonyRILTimingHistograms();
9181 } finally {
9182 Binder.restoreCallingIdentity(identity);
9183 }
Sanket Padawe99ef1e32016-05-18 16:12:33 -07009184 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07009185
9186 /**
9187 * {@hide}
Michele Berionne482f8202018-11-27 18:57:59 -08009188 * Set the allowed carrier list and the excluded carrier list, indicating the priority between
9189 * the two lists.
Meng Wang1a7c35a2016-05-05 20:56:15 -07009190 * Require system privileges. In the future we may add this to carrier APIs.
9191 *
Michele Berionne482f8202018-11-27 18:57:59 -08009192 * @return Integer with the result of the operation, as defined in {@link TelephonyManager}.
Meng Wang1a7c35a2016-05-05 20:56:15 -07009193 */
9194 @Override
Michele Berionne482f8202018-11-27 18:57:59 -08009195 @TelephonyManager.SetCarrierRestrictionResult
9196 public int setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules) {
Meng Wang1a7c35a2016-05-05 20:56:15 -07009197 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07009198 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Sanket Padawe13bac7b2017-03-20 15:04:47 -07009199
Michele Berionne482f8202018-11-27 18:57:59 -08009200 if (carrierRestrictionRules == null) {
9201 throw new NullPointerException("carrier restriction cannot be null");
Meng Wang9b7c4e92017-02-17 11:41:27 -08009202 }
Sanket Padawe13bac7b2017-03-20 15:04:47 -07009203
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009204 final long identity = Binder.clearCallingIdentity();
9205 try {
Michele Berionne482f8202018-11-27 18:57:59 -08009206 return (int) sendRequest(CMD_SET_ALLOWED_CARRIERS, carrierRestrictionRules,
vagdeviaf9a5b92018-08-15 16:01:53 -07009207 workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009208 } finally {
9209 Binder.restoreCallingIdentity(identity);
9210 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07009211 }
9212
9213 /**
9214 * {@hide}
Michele Berionne482f8202018-11-27 18:57:59 -08009215 * Get the allowed carrier list and the excluded carrier list, including the priority between
9216 * the two lists.
Meng Wang1a7c35a2016-05-05 20:56:15 -07009217 * Require system privileges. In the future we may add this to carrier APIs.
9218 *
Michele Berionne482f8202018-11-27 18:57:59 -08009219 * @return {@link android.telephony.CarrierRestrictionRules}
Meng Wang1a7c35a2016-05-05 20:56:15 -07009220 */
9221 @Override
Michele Berionne482f8202018-11-27 18:57:59 -08009222 public CarrierRestrictionRules getAllowedCarriers() {
Brad Ebinger35c841c2018-10-01 10:40:55 -07009223 enforceReadPrivilegedPermission("getAllowedCarriers");
vagdeviaf9a5b92018-08-15 16:01:53 -07009224 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009225
9226 final long identity = Binder.clearCallingIdentity();
9227 try {
Michele Berionne482f8202018-11-27 18:57:59 -08009228 Object response = sendRequest(CMD_GET_ALLOWED_CARRIERS, null, workSource);
9229 if (response instanceof CarrierRestrictionRules) {
9230 return (CarrierRestrictionRules) response;
9231 }
9232 // Response is an Exception of some kind,
9233 // which is signalled to the user as a NULL retval
9234 return null;
9235 } catch (Exception e) {
9236 Log.e(LOG_TAG, "getAllowedCarriers. Exception ex=" + e);
9237 return null;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009238 } finally {
9239 Binder.restoreCallingIdentity(identity);
9240 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07009241 }
9242
fionaxu59545b42016-05-25 15:53:37 -07009243 /**
arunvoddud7401012022-12-15 16:08:12 +00009244 * Fetches the carrier restriction status of the device and sends the status to the caller
9245 * through the callback.
9246 *
9247 * @param callback The callback that will be used to send the result.
9248 * @throws SecurityException if the caller does not have the required permission/privileges or
9249 * the caller is not allowlisted.
9250 */
9251 @Override
9252 public void getCarrierRestrictionStatus(IIntegerConsumer callback, String packageName) {
9253 enforceReadPermission("getCarrierRestrictionStatus");
9254 int carrierId = validateCallerAndGetCarrierId(packageName);
9255 if (carrierId == CarrierAllowListInfo.INVALID_CARRIER_ID) {
9256 Rlog.e(LOG_TAG, "getCarrierRestrictionStatus: caller is not registered");
9257 throw new SecurityException("Not an authorized caller");
9258 }
9259 final long identity = Binder.clearCallingIdentity();
9260 try {
9261 Consumer<Integer> consumer = FunctionalUtils.ignoreRemoteException(callback::accept);
9262 CallerCallbackInfo callbackInfo = new CallerCallbackInfo(consumer, carrierId);
9263 sendRequestAsync(CMD_GET_ALLOWED_CARRIERS, callbackInfo);
9264 } finally {
9265 Binder.restoreCallingIdentity(identity);
9266 }
9267 }
9268
9269 @VisibleForTesting
9270 public int validateCallerAndGetCarrierId(String packageName) {
9271 CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mApp);
9272 return allowListInfo.validateCallerAndGetCarrierId(packageName);
9273 }
9274
9275 /**
fionaxu59545b42016-05-25 15:53:37 -07009276 * Action set from carrier signalling broadcast receivers to enable/disable radio
9277 * @param subId the subscription ID that this action applies to.
9278 * @param enabled control enable or disable radio.
9279 * {@hide}
9280 */
9281 @Override
9282 public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
9283 enforceModifyPermission();
9284 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009285
9286 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07009287 if (phone == null) {
9288 loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
9289 return;
9290 }
9291 try {
9292 phone.carrierActionSetRadioEnabled(enabled);
9293 } catch (Exception e) {
9294 Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009295 } finally {
9296 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07009297 }
9298 }
9299
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07009300 /**
Sooraj Sasindrandaf060f2021-06-15 14:52:55 -07009301 * Enable or disable Voice over NR (VoNR)
9302 * @param subId the subscription ID that this action applies to.
9303 * @param enabled enable or disable VoNR.
9304 * @return operation result.
9305 */
9306 @Override
9307 public int setVoNrEnabled(int subId, boolean enabled) {
9308 enforceModifyPermission();
9309 final Phone phone = getPhone(subId);
9310
9311 final long identity = Binder.clearCallingIdentity();
9312 if (phone == null) {
9313 loge("setVoNrEnabled fails with no phone object for subId: " + subId);
9314 return TelephonyManager.ENABLE_VONR_RADIO_NOT_AVAILABLE;
9315 }
9316
9317 WorkSource workSource = getWorkSource(Binder.getCallingUid());
9318 try {
9319 int result = (int) sendRequest(CMD_ENABLE_VONR, enabled, subId,
9320 workSource);
9321 if (DBG) log("setVoNrEnabled result: " + result);
Gary Jian8dd305f2021-10-14 16:31:35 +08009322
9323 if (result == TelephonyManager.ENABLE_VONR_SUCCESS) {
9324 if (DBG) {
9325 log("Set VoNR settings in siminfo db; subId=" + subId + ", value:" + enabled);
9326 }
9327 SubscriptionManager.setSubscriptionProperty(
9328 subId, SubscriptionManager.NR_ADVANCED_CALLING_ENABLED,
9329 (enabled ? "1" : "0"));
9330 }
9331
Sooraj Sasindrandaf060f2021-06-15 14:52:55 -07009332 return result;
9333 } finally {
9334 Binder.restoreCallingIdentity(identity);
9335 }
9336 }
9337
9338 /**
9339 * Is voice over NR enabled
9340 * @return true if VoNR is enabled else false
9341 */
9342 @Override
9343 public boolean isVoNrEnabled(int subId) {
9344 enforceReadPrivilegedPermission("isVoNrEnabled");
9345 WorkSource workSource = getWorkSource(Binder.getCallingUid());
9346 final long identity = Binder.clearCallingIdentity();
9347 try {
9348 boolean isEnabled = (boolean) sendRequest(CMD_IS_VONR_ENABLED,
9349 null, subId, workSource);
9350 if (DBG) log("isVoNrEnabled: " + isEnabled);
9351 return isEnabled;
9352 } finally {
9353 Binder.restoreCallingIdentity(identity);
9354 }
9355 }
9356
9357 /**
fionaxu8da9cb12017-05-23 15:02:46 -07009358 * Action set from carrier signalling broadcast receivers to start/stop reporting the default
9359 * network status based on which carrier apps could apply actions accordingly,
9360 * enable/disable default url handler for example.
9361 *
9362 * @param subId the subscription ID that this action applies to.
9363 * @param report control start/stop reporting the default network status.
9364 * {@hide}
9365 */
9366 @Override
9367 public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
9368 enforceModifyPermission();
9369 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009370
9371 final long identity = Binder.clearCallingIdentity();
fionaxu8da9cb12017-05-23 15:02:46 -07009372 if (phone == null) {
9373 loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId);
9374 return;
9375 }
9376 try {
9377 phone.carrierActionReportDefaultNetworkStatus(report);
9378 } catch (Exception e) {
9379 Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009380 } finally {
9381 Binder.restoreCallingIdentity(identity);
fionaxu8da9cb12017-05-23 15:02:46 -07009382 }
9383 }
9384
9385 /**
fionaxud9622282017-07-17 17:51:30 -07009386 * Action set from carrier signalling broadcast receivers to reset all carrier actions
9387 * @param subId the subscription ID that this action applies to.
9388 * {@hide}
9389 */
9390 @Override
9391 public void carrierActionResetAll(int subId) {
9392 enforceModifyPermission();
9393 final Phone phone = getPhone(subId);
9394 if (phone == null) {
9395 loge("carrierAction: ResetAll fails with invalid sibId: " + subId);
9396 return;
9397 }
9398 try {
9399 phone.carrierActionResetAll();
9400 } catch (Exception e) {
9401 Log.e(LOG_TAG, "carrierAction: ResetAll fails. Exception ex=" + e);
9402 }
9403 }
9404
9405 /**
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07009406 * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a
9407 * bug report is being generated.
9408 */
9409 @Override
Ta-wei Yen99282e02016-06-21 18:19:35 -07009410 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08009411 if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
9412 != PackageManager.PERMISSION_GRANTED) {
dcashman22b950d2016-06-27 11:39:02 -07009413 writer.println("Permission Denial: can't dump Phone from pid="
9414 + Binder.getCallingPid()
9415 + ", uid=" + Binder.getCallingUid()
9416 + "without permission "
9417 + android.Manifest.permission.DUMP);
9418 return;
9419 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08009420 DumpsysHandler.dump(mApp, fd, writer, args);
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07009421 }
Jack Yueb89b242016-06-22 13:27:47 -07009422
Brad Ebingerdac2f002018-04-03 15:17:52 -07009423 @Override
Hall Liua1548bd2019-12-24 14:14:12 -08009424 public int handleShellCommand(@NonNull ParcelFileDescriptor in,
9425 @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
9426 @NonNull String[] args) {
9427 return new TelephonyShellCommand(this, getDefaultPhone().getContext()).exec(
9428 this, in.getFileDescriptor(), out.getFileDescriptor(),
Thomas Nguyen8ee49682023-02-01 11:46:09 -08009429 err.getFileDescriptor(), args);
Brad Ebingerdac2f002018-04-03 15:17:52 -07009430 }
9431
Jack Yueb89b242016-06-22 13:27:47 -07009432 /**
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00009433 * Policy control of data connection with reason {@@TelephonyManager.DataEnabledReason}
Greg Kaiser17f41752020-05-05 16:47:47 +00009434 * @param subId Subscription index
Sarah Chinecc78c42022-03-31 21:16:48 -07009435 * @param reason The reason the data enable change is taking place.
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00009436 * @param enabled True if enabling the data, otherwise disabling.
Sarah Chinecc78c42022-03-31 21:16:48 -07009437 * @param callingPackage The package that changed the data enabled state.
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00009438 * @hide
Jack Yu75ab2952016-07-08 14:29:33 -07009439 */
9440 @Override
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07009441 public void setDataEnabledForReason(int subId, @TelephonyManager.DataEnabledReason int reason,
Sarah Chinecc78c42022-03-31 21:16:48 -07009442 boolean enabled, String callingPackage) {
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00009443 if (reason == TelephonyManager.DATA_ENABLED_REASON_USER
9444 || reason == TelephonyManager.DATA_ENABLED_REASON_CARRIER) {
9445 try {
9446 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07009447 mApp, subId, "setDataEnabledForReason");
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00009448 } catch (SecurityException se) {
9449 enforceModifyPermission();
9450 }
9451 } else {
9452 enforceModifyPermission();
9453 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009454
9455 final long identity = Binder.clearCallingIdentity();
9456 try {
9457 Phone phone = getPhone(subId);
9458 if (phone != null) {
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00009459 if (reason == TelephonyManager.DATA_ENABLED_REASON_CARRIER) {
9460 phone.carrierActionSetMeteredApnsEnabled(enabled);
9461 } else {
Jack Yu7968c6d2022-07-31 00:43:21 -07009462 phone.getDataSettingsManager().setDataEnabled(
9463 reason, enabled, callingPackage);
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00009464 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009465 }
9466 } finally {
9467 Binder.restoreCallingIdentity(identity);
Jack Yu75ab2952016-07-08 14:29:33 -07009468 }
9469 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07009470
9471 /**
9472 * Get Client request stats
9473 * @return List of Client Request Stats
9474 * @hide
9475 */
9476 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009477 public List<ClientRequestStats> getClientRequestStats(String callingPackage,
9478 String callingFeatureId, int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08009479 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009480 mApp, subId, callingPackage, callingFeatureId, "getClientRequestStats")) {
Sooraj Sasindran9a909312016-07-18 11:57:25 -07009481 return null;
9482 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07009483 Phone phone = getPhone(subId);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07009484
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009485 final long identity = Binder.clearCallingIdentity();
9486 try {
9487 if (phone != null) {
9488 return phone.getClientRequestStats();
9489 }
9490
9491 return null;
9492 } finally {
9493 Binder.restoreCallingIdentity(identity);
9494 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07009495 }
9496
Narayan Kamathf04b5a12018-01-09 11:47:15 +00009497 private WorkSource getWorkSource(int uid) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08009498 String packageName = mApp.getPackageManager().getNameForUid(uid);
Hunter Knepshieldd03383b2022-03-29 22:47:54 +00009499 if (uid == Process.ROOT_UID && packageName == null) {
9500 // Downstream WorkSource attribution inside the RIL requires both a UID and package name
9501 // to be set for wakelock tracking, otherwise RIL requests fail with a runtime
9502 // exception. ROOT_UID seems not to have a valid package name returned by
9503 // PackageManager, so just fake it here to avoid issues when running telephony shell
9504 // commands that plumb through the RIL as root, like so:
9505 // $ adb root
9506 // $ adb shell cmd phone ...
9507 packageName = "root";
9508 }
Narayan Kamathf04b5a12018-01-09 11:47:15 +00009509 return new WorkSource(uid, packageName);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07009510 }
Jack Yueb4124c2017-02-16 15:32:43 -08009511
9512 /**
Grace Chen70990072017-03-24 17:21:30 -07009513 * Set SIM card power state.
Jack Yueb4124c2017-02-16 15:32:43 -08009514 *
Sanket Padawe13bac7b2017-03-20 15:04:47 -07009515 * @param slotIndex SIM slot id.
Grace Chen70990072017-03-24 17:21:30 -07009516 * @param state State of SIM (power down, power up, pass through)
9517 * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
9518 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
9519 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
Jack Yueb4124c2017-02-16 15:32:43 -08009520 *
9521 **/
9522 @Override
Grace Chen70990072017-03-24 17:21:30 -07009523 public void setSimPowerStateForSlot(int slotIndex, int state) {
Jack Yueb4124c2017-02-16 15:32:43 -08009524 enforceModifyPermission();
Sanket Padawe13bac7b2017-03-20 15:04:47 -07009525 Phone phone = PhoneFactory.getPhone(slotIndex);
9526
vagdeviaf9a5b92018-08-15 16:01:53 -07009527 WorkSource workSource = getWorkSource(Binder.getCallingUid());
9528
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009529 final long identity = Binder.clearCallingIdentity();
9530 try {
9531 if (phone != null) {
Jordan Liu109698e2020-11-24 14:50:34 -08009532 phone.setSimPowerState(state, null, workSource);
9533 }
9534 } finally {
9535 Binder.restoreCallingIdentity(identity);
9536 }
9537 }
9538
9539 /**
9540 * Set SIM card power state.
9541 *
9542 * @param slotIndex SIM slot id.
9543 * @param state State of SIM (power down, power up, pass through)
9544 * @param callback callback to trigger after success or failure
9545 * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
9546 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
9547 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
9548 *
9549 **/
9550 @Override
9551 public void setSimPowerStateForSlotWithCallback(int slotIndex, int state,
9552 IIntegerConsumer callback) {
9553 enforceModifyPermission();
9554 Phone phone = PhoneFactory.getPhone(slotIndex);
9555
9556 WorkSource workSource = getWorkSource(Binder.getCallingUid());
9557
9558 final long identity = Binder.clearCallingIdentity();
9559 try {
9560 if (phone != null) {
9561 Pair<Integer, IIntegerConsumer> arguments = Pair.create(state, callback);
9562 sendRequestAsync(CMD_SET_SIM_POWER, arguments, phone, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009563 }
9564 } finally {
9565 Binder.restoreCallingIdentity(identity);
Jack Yueb4124c2017-02-16 15:32:43 -08009566 }
9567 }
Shuo Qiandd210312017-04-12 22:11:33 +00009568
Tyler Gunn65d45c22017-06-05 11:22:26 -07009569 private boolean isUssdApiAllowed(int subId) {
9570 CarrierConfigManager configManager =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08009571 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Tyler Gunn65d45c22017-06-05 11:22:26 -07009572 if (configManager == null) {
9573 return false;
9574 }
9575 PersistableBundle pb = configManager.getConfigForSubId(subId);
9576 if (pb == null) {
9577 return false;
9578 }
9579 return pb.getBoolean(
9580 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL);
9581 }
9582
Shuo Qiandd210312017-04-12 22:11:33 +00009583 /**
9584 * Check if phone is in emergency callback mode
9585 * @return true if phone is in emergency callback mode
9586 * @param subId sub id
9587 */
goneil9c5f4872017-12-05 14:07:56 -08009588 @Override
Shuo Qiandd210312017-04-12 22:11:33 +00009589 public boolean getEmergencyCallbackMode(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07009590 enforceReadPrivilegedPermission("getEmergencyCallbackMode");
Shuo Qiandd210312017-04-12 22:11:33 +00009591 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009592
9593 final long identity = Binder.clearCallingIdentity();
9594 try {
9595 if (phone != null) {
9596 return phone.isInEcm();
9597 } else {
9598 return false;
9599 }
9600 } finally {
9601 Binder.restoreCallingIdentity(identity);
Shuo Qiandd210312017-04-12 22:11:33 +00009602 }
9603 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08009604
9605 /**
9606 * Get the current signal strength information for the given subscription.
9607 * Because this information is not updated when the device is in a low power state
9608 * it should not be relied-upon to be current.
9609 * @param subId Subscription index
9610 * @return the most recent cached signal strength info from the modem
9611 */
9612 @Override
9613 public SignalStrength getSignalStrength(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009614 final long identity = Binder.clearCallingIdentity();
9615 try {
9616 Phone p = getPhone(subId);
9617 if (p == null) {
9618 return null;
9619 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08009620
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009621 return p.getSignalStrength();
9622 } finally {
9623 Binder.restoreCallingIdentity(identity);
9624 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08009625 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00009626
Pengquan Meng77b7f132018-08-22 14:49:57 -07009627 /**
Chen Xuf792fd62018-10-17 17:54:36 +00009628 * Get the current modem radio state for the given slot.
9629 * @param slotIndex slot index.
9630 * @param callingPackage the name of the package making the call.
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009631 * @param callingFeatureId The feature in the package.
Chen Xuf792fd62018-10-17 17:54:36 +00009632 * @return the current radio power state from the modem
9633 */
9634 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009635 public int getRadioPowerState(int slotIndex, String callingPackage, String callingFeatureId) {
Chen Xuf792fd62018-10-17 17:54:36 +00009636 Phone phone = PhoneFactory.getPhone(slotIndex);
9637 if (phone != null) {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009638 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, phone.getSubId(),
9639 callingPackage, callingFeatureId, "getRadioPowerState")) {
Chen Xuf792fd62018-10-17 17:54:36 +00009640 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
9641 }
9642
9643 final long identity = Binder.clearCallingIdentity();
9644 try {
9645 return phone.getRadioPowerState();
9646 } finally {
9647 Binder.restoreCallingIdentity(identity);
9648 }
9649 }
9650 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
9651 }
9652
9653 /**
Pengquan Meng77b7f132018-08-22 14:49:57 -07009654 * Checks if data roaming is enabled on the subscription with id {@code subId}.
9655 *
9656 * <p>Requires one of the following permissions:
9657 * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07009658 * {@link android.Manifest.permission#READ_BASIC_PHONE_STATE},
Pengquan Meng77b7f132018-08-22 14:49:57 -07009659 * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
9660 * privileges.
9661 *
9662 * @param subId subscription id
9663 * @return {@code true} if data roaming is enabled on this subscription, otherwise return
9664 * {@code false}.
9665 */
9666 @Override
9667 public boolean isDataRoamingEnabled(int subId) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07009668 String functionName = "isDataRoamingEnabled";
Shuo Qian093013d2020-08-13 15:42:55 -07009669 try {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07009670 try {
9671 mApp.enforceCallingOrSelfPermission(
9672 android.Manifest.permission.ACCESS_NETWORK_STATE,
9673 functionName);
Sooraj Sasindran12545cc2022-08-22 14:30:25 -07009674 } catch (SecurityException e) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07009675 mApp.enforceCallingOrSelfPermission(
9676 permission.READ_BASIC_PHONE_STATE, functionName);
9677 }
Sooraj Sasindran12545cc2022-08-22 14:30:25 -07009678 } catch (SecurityException e) {
Nathan Harold62c68512021-04-06 11:26:02 -07009679 TelephonyPermissions.enforceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07009680 mApp, subId, functionName);
Shuo Qian093013d2020-08-13 15:42:55 -07009681 }
Pengquan Meng44e66f12019-04-01 10:48:20 -07009682
Pengquan Menga1bb6272018-09-06 09:59:22 -07009683 boolean isEnabled = false;
9684 final long identity = Binder.clearCallingIdentity();
Pengquan Meng77b7f132018-08-22 14:49:57 -07009685 try {
Pengquan Menga1bb6272018-09-06 09:59:22 -07009686 Phone phone = getPhone(subId);
9687 isEnabled = phone != null ? phone.getDataRoamingEnabled() : false;
Pengquan Menga1bb6272018-09-06 09:59:22 -07009688 } finally {
9689 Binder.restoreCallingIdentity(identity);
Pengquan Meng77b7f132018-08-22 14:49:57 -07009690 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07009691 return isEnabled;
Pengquan Meng77b7f132018-08-22 14:49:57 -07009692 }
9693
9694
9695 /**
9696 * Enables/Disables the data roaming on the subscription with id {@code subId}.
9697 *
9698 * <p> Requires permission:
9699 * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier
9700 * privileges.
9701 *
9702 * @param subId subscription id
9703 * @param isEnabled {@code true} means enable, {@code false} means disable.
9704 */
9705 @Override
9706 public void setDataRoamingEnabled(int subId, boolean isEnabled) {
Pengquan Meng44e66f12019-04-01 10:48:20 -07009707 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
9708 mApp, subId, "setDataRoamingEnabled");
9709
Pengquan Menga1bb6272018-09-06 09:59:22 -07009710 final long identity = Binder.clearCallingIdentity();
9711 try {
Pengquan Menga1bb6272018-09-06 09:59:22 -07009712 Phone phone = getPhone(subId);
9713 if (phone != null) {
9714 phone.setDataRoamingEnabled(isEnabled);
9715 }
9716 } finally {
9717 Binder.restoreCallingIdentity(identity);
Pengquan Meng77b7f132018-08-22 14:49:57 -07009718 }
9719 }
9720
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00009721 @Override
Pengquan Meng6884a2c2018-10-03 12:19:13 -07009722 public boolean isManualNetworkSelectionAllowed(int subId) {
tom hsuc91afc72020-01-06 23:46:07 +08009723 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07009724 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Thomas Nguyen8ee49682023-02-01 11:46:09 -08009725 mApp, subId, "isManualNetworkSelectionAllowed");
Pengquan Meng44e66f12019-04-01 10:48:20 -07009726
Pengquan Meng6884a2c2018-10-03 12:19:13 -07009727 boolean isAllowed = true;
9728 final long identity = Binder.clearCallingIdentity();
9729 try {
Pengquan Meng6884a2c2018-10-03 12:19:13 -07009730 Phone phone = getPhone(subId);
9731 if (phone != null) {
9732 isAllowed = phone.isCspPlmnEnabled();
9733 }
9734 } finally {
9735 Binder.restoreCallingIdentity(identity);
9736 }
9737 return isAllowed;
9738 }
9739
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009740 private boolean haveCarrierPrivilegeAccess(UiccPort port, String callingPackage) {
9741 UiccProfile profile = port.getUiccProfile();
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08009742 if (profile == null) {
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009743 return false;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00009744 }
Hunter Knepshieldcad7f0b2021-12-13 15:08:35 -08009745 Phone phone = PhoneFactory.getPhone(profile.getPhoneId());
9746 if (phone == null) {
9747 return false;
9748 }
9749 CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
9750 return cpt != null && cpt.getCarrierPrivilegeStatusForPackage(callingPackage)
9751 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00009752 }
9753
Pengquan Meng6884a2c2018-10-03 12:19:13 -07009754 @Override
Jordan Liu75f43ea2019-01-17 16:56:37 -08009755 public List<UiccCardInfo> getUiccCardsInfo(String callingPackage) {
sandeepjsa208e3b2021-11-17 04:05:58 +00009756 // Verify that the callingPackage belongs to the calling UID
Jordan Liu4cda4552020-03-23 11:55:07 -07009757 mApp.getSystemService(AppOpsManager.class)
9758 .checkPackage(Binder.getCallingUid(), callingPackage);
9759
Jordan Liu1e142fc2019-04-22 15:10:43 -07009760 boolean hasReadPermission = false;
sandeepjsb6c87872021-09-27 15:34:44 +00009761 boolean isIccIdAccessRestricted = false;
Jordan Liuc65bc952019-02-12 17:54:02 -08009762 try {
9763 enforceReadPrivilegedPermission("getUiccCardsInfo");
Jordan Liu1e142fc2019-04-22 15:10:43 -07009764 hasReadPermission = true;
Jordan Liuc65bc952019-02-12 17:54:02 -08009765 } catch (SecurityException e) {
9766 // even without READ_PRIVILEGED_PHONE_STATE, we allow the call to continue if the caller
9767 // has carrier privileges on an active UICC
Rambo Wange7209ce2022-02-23 13:41:02 -08009768 if (checkCarrierPrivilegesForPackageAnyPhoneWithPermission(callingPackage)
Thomas Nguyen8ee49682023-02-01 11:46:09 -08009769 != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
Jordan Liu1e142fc2019-04-22 15:10:43 -07009770 throw new SecurityException("Caller does not have permission.");
Jordan Liuc65bc952019-02-12 17:54:02 -08009771 }
Jordan Liu75f43ea2019-01-17 16:56:37 -08009772 }
sandeepjsb6c87872021-09-27 15:34:44 +00009773 // checking compatibility, if calling app's target SDK is T and beyond.
9774 if (CompatChanges.isChangeEnabled(GET_API_SIGNATURES_FROM_UICC_PORT_INFO,
9775 Binder.getCallingUid())) {
9776 isIccIdAccessRestricted = true;
9777 }
Jordan Liu5aa07002018-12-18 15:44:48 -08009778 final long identity = Binder.clearCallingIdentity();
9779 try {
Jordan Liu75f43ea2019-01-17 16:56:37 -08009780 UiccController uiccController = UiccController.getInstance();
9781 ArrayList<UiccCardInfo> cardInfos = uiccController.getAllUiccCardInfos();
Jordan Liu1e142fc2019-04-22 15:10:43 -07009782 if (hasReadPermission) {
9783 return cardInfos;
Jordan Liu75f43ea2019-01-17 16:56:37 -08009784 }
Jordan Liu1e142fc2019-04-22 15:10:43 -07009785
9786 // Remove private info if the caller doesn't have access
9787 ArrayList<UiccCardInfo> filteredInfos = new ArrayList<>();
9788 for (UiccCardInfo cardInfo : cardInfos) {
sandeepjsb6c87872021-09-27 15:34:44 +00009789 //setting the value after compatibility check
9790 cardInfo.setIccIdAccessRestricted(isIccIdAccessRestricted);
Jordan Liu1e142fc2019-04-22 15:10:43 -07009791 // For an inactive eUICC, the UiccCard will be null even though the UiccCardInfo
9792 // is available
sandeepjsb6c87872021-09-27 15:34:44 +00009793 UiccCard card = uiccController.getUiccCardForSlot(cardInfo.getPhysicalSlotIndex());
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009794 if (card == null) {
9795 // assume no access if the card is unavailable
sandeepjsb6c87872021-09-27 15:34:44 +00009796 filteredInfos.add(getUiccCardInfoUnPrivileged(cardInfo));
Jordan Liu1e142fc2019-04-22 15:10:43 -07009797 continue;
9798 }
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009799 Collection<UiccPortInfo> portInfos = cardInfo.getPorts();
9800 if (portInfos.isEmpty()) {
sandeepjsb6c87872021-09-27 15:34:44 +00009801 filteredInfos.add(getUiccCardInfoUnPrivileged(cardInfo));
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009802 continue;
Jordan Liu1e142fc2019-04-22 15:10:43 -07009803 }
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009804 List<UiccPortInfo> uiccPortInfos = new ArrayList<>();
9805 for (UiccPortInfo portInfo : portInfos) {
9806 UiccPort port = uiccController.getUiccPortForSlot(
9807 cardInfo.getPhysicalSlotIndex(), portInfo.getPortIndex());
9808 if (port == null) {
9809 // assume no access if port is null
9810 uiccPortInfos.add(getUiccPortInfoUnPrivileged(portInfo));
9811 continue;
9812 }
9813 if (haveCarrierPrivilegeAccess(port, callingPackage)) {
9814 uiccPortInfos.add(portInfo);
9815 } else {
9816 uiccPortInfos.add(getUiccPortInfoUnPrivileged(portInfo));
9817 }
9818 }
9819 filteredInfos.add(new UiccCardInfo(
9820 cardInfo.isEuicc(),
9821 cardInfo.getCardId(),
9822 null,
9823 cardInfo.getPhysicalSlotIndex(),
9824 cardInfo.isRemovable(),
9825 cardInfo.isMultipleEnabledProfilesSupported(),
9826 uiccPortInfos));
Jordan Liu1e142fc2019-04-22 15:10:43 -07009827 }
9828 return filteredInfos;
Jordan Liu5aa07002018-12-18 15:44:48 -08009829 } finally {
9830 Binder.restoreCallingIdentity(identity);
9831 }
9832 }
9833
sandeepjsb6c87872021-09-27 15:34:44 +00009834 /**
9835 * Returns a copy of the UiccCardinfo with the EID and ICCID set to null. These values are
9836 * generally private and require carrier privileges to view.
9837 *
9838 * @hide
9839 */
9840 @NonNull
9841 public UiccCardInfo getUiccCardInfoUnPrivileged(UiccCardInfo cardInfo) {
9842 List<UiccPortInfo> portinfo = new ArrayList<>();
9843 for (UiccPortInfo portinfos : cardInfo.getPorts()) {
9844 portinfo.add(getUiccPortInfoUnPrivileged(portinfos));
9845 }
9846 return new UiccCardInfo(
9847 cardInfo.isEuicc(),
9848 cardInfo.getCardId(),
9849 null,
9850 cardInfo.getPhysicalSlotIndex(),
9851 cardInfo.isRemovable(),
9852 cardInfo.isMultipleEnabledProfilesSupported(),
9853 portinfo
9854 );
9855 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00009856
sandeepjsb6c87872021-09-27 15:34:44 +00009857 /**
9858 * @hide
9859 * @return a copy of the UiccPortInfo with ICCID set to {@link UiccPortInfo#ICCID_REDACTED}.
9860 * These values are generally private and require carrier privileges to view.
9861 */
9862 @NonNull
9863 public UiccPortInfo getUiccPortInfoUnPrivileged(UiccPortInfo portInfo) {
9864 return new UiccPortInfo(
9865 UiccPortInfo.ICCID_REDACTED,
9866 portInfo.getPortIndex(),
9867 portInfo.getLogicalSlotIndex(),
9868 portInfo.isActive()
9869 );
9870 }
9871 @Override
9872 public UiccSlotInfo[] getUiccSlotsInfo(String callingPackage) {
sandeepjsa208e3b2021-11-17 04:05:58 +00009873 // Verify that the callingPackage belongs to the calling UID
sandeepjsb6c87872021-09-27 15:34:44 +00009874 mApp.getSystemService(AppOpsManager.class)
9875 .checkPackage(Binder.getCallingUid(), callingPackage);
9876
sandeepjsb6c87872021-09-27 15:34:44 +00009877 boolean isLogicalSlotAccessRestricted = false;
sandeepjsb6c87872021-09-27 15:34:44 +00009878
Aman Guptaf3c90b32022-03-17 04:54:16 +00009879 // This will make sure caller has the READ_PRIVILEGED_PHONE_STATE. Do not remove this as
9880 // we are reading iccId which is PII data.
9881 enforceReadPrivilegedPermission("getUiccSlotsInfo");
sandeepjsb6c87872021-09-27 15:34:44 +00009882
9883 // checking compatibility, if calling app's target SDK is T and beyond.
9884 if (CompatChanges.isChangeEnabled(GET_API_SIGNATURES_FROM_UICC_PORT_INFO,
9885 Binder.getCallingUid())) {
9886 isLogicalSlotAccessRestricted = true;
9887 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009888 final long identity = Binder.clearCallingIdentity();
9889 try {
9890 UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
Muralidhar Reddyd196bbf2022-01-17 17:56:30 +00009891 if (slots == null || slots.length == 0) {
9892 Rlog.i(LOG_TAG, "slots is null or empty.");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009893 return null;
9894 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009895 UiccSlotInfo[] infos = new UiccSlotInfo[slots.length];
9896 for (int i = 0; i < slots.length; i++) {
9897 UiccSlot slot = slots[i];
9898 if (slot == null) {
9899 continue;
9900 }
9901
Jordan Liu7be7e652019-05-06 18:55:02 +00009902 String cardId;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009903 UiccCard card = slot.getUiccCard();
9904 if (card != null) {
9905 cardId = card.getCardId();
Jordan Liu7be7e652019-05-06 18:55:02 +00009906 } else {
Jordan Liu01bd00d2019-09-12 16:19:43 -07009907 cardId = slot.getEid();
9908 if (TextUtils.isEmpty(cardId)) {
Aman Guptaf3c90b32022-03-17 04:54:16 +00009909 // If cardId is null, use iccId of default port as cardId.
9910 cardId = slot.getIccId(TelephonyManager.DEFAULT_PORT_INDEX);
Jordan Liu01bd00d2019-09-12 16:19:43 -07009911 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009912 }
9913
Jordan Liu857451f2019-05-09 16:35:35 -07009914 if (cardId != null) {
9915 // if cardId is an ICCID, strip off trailing Fs before exposing to user
9916 // if cardId is an EID, it's all digits so this is fine
9917 cardId = IccUtils.stripTrailingFs(cardId);
9918 }
9919
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009920 int cardState = 0;
9921 switch (slot.getCardState()) {
9922 case CARDSTATE_ABSENT:
9923 cardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
9924 break;
9925 case CARDSTATE_PRESENT:
9926 cardState = UiccSlotInfo.CARD_STATE_INFO_PRESENT;
9927 break;
9928 case CARDSTATE_ERROR:
9929 cardState = UiccSlotInfo.CARD_STATE_INFO_ERROR;
9930 break;
9931 case CARDSTATE_RESTRICTED:
9932 cardState = UiccSlotInfo.CARD_STATE_INFO_RESTRICTED;
9933 break;
9934 default:
9935 break;
9936
9937 }
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009938 List<UiccPortInfo> portInfos = new ArrayList<>();
9939 int[] portIndexes = slot.getPortList();
9940 for (int portIdx : portIndexes) {
9941 String iccId = IccUtils.stripTrailingFs(getIccId(slot, portIdx,
Aman Guptaf3c90b32022-03-17 04:54:16 +00009942 callingPackage, /* hasReadPermission= */ true));
Muralidhar Reddyfbcff0c2022-01-19 13:07:57 +00009943 portInfos.add(new UiccPortInfo(iccId, portIdx,
9944 slot.getPhoneIdFromPortIndex(portIdx), slot.isPortActive(portIdx)));
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009945 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009946 infos[i] = new UiccSlotInfo(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009947 slot.isEuicc(),
9948 cardId,
9949 cardState,
Jordan Liua2619582019-02-14 12:56:40 -08009950 slot.isExtendedApduSupported(),
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009951 slot.isRemovable(), portInfos);
sandeepjsb6c87872021-09-27 15:34:44 +00009952 //setting the value after compatibility check
9953 infos[i].setLogicalSlotAccessRestricted(isLogicalSlotAccessRestricted);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009954 }
9955 return infos;
9956 } finally {
9957 Binder.restoreCallingIdentity(identity);
Holly Jiuyu Sun1d957c52018-04-04 13:52:42 -07009958 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00009959 }
9960
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009961 /* Returns null if doesn't have read permission or carrier privilege access. */
9962 private String getIccId(UiccSlot slot, int portIndex, String callingPackage,
9963 boolean hasReadPermission) {
9964 String iccId = slot.getIccId(portIndex);
9965 if (hasReadPermission) { // if has read permission
9966 return iccId;
9967 } else {
9968 if (slot.getUiccCard() != null && slot.getUiccCard().getUiccPort(portIndex) != null) {
9969 UiccPort port = slot.getUiccCard().getUiccPort(portIndex);
9970 // if no read permission, checking carrier privilege access
9971 if (haveCarrierPrivilegeAccess(port, callingPackage)) {
9972 return iccId;
9973 }
9974 }
9975 }
9976 // No read permission or carrier privilege access.
9977 return UiccPortInfo.ICCID_REDACTED;
9978 }
9979
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00009980 @Override
sandeepjsb6c87872021-09-27 15:34:44 +00009981 @Deprecated
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00009982 public boolean switchSlots(int[] physicalSlots) {
9983 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009984
9985 final long identity = Binder.clearCallingIdentity();
9986 try {
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009987 List<UiccSlotMapping> slotMappings = new ArrayList<>();
9988 for (int i = 0; i < physicalSlots.length; i++) {
9989 // Deprecated API, hence MEP is not supported. Adding default portIndex 0.
9990 slotMappings.add(new UiccSlotMapping(TelephonyManager.DEFAULT_PORT_INDEX,
9991 physicalSlots[i], i));
9992 }
9993 return (Boolean) sendRequest(CMD_SWITCH_SLOTS, slotMappings);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009994 } finally {
9995 Binder.restoreCallingIdentity(identity);
9996 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00009997 }
Jack Yu4c988042018-02-27 15:30:01 -08009998
9999 @Override
sandeepjsb6c87872021-09-27 15:34:44 +000010000 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
10001 public boolean setSimSlotMapping(@NonNull List<UiccSlotMapping> slotMapping) {
10002 enforceModifyPermission();
10003
10004 final long identity = Binder.clearCallingIdentity();
10005 try {
Muralidhar Reddyeb809e32021-11-19 03:07:54 +000010006 return (Boolean) sendRequest(CMD_SWITCH_SLOTS, slotMapping);
sandeepjsb6c87872021-09-27 15:34:44 +000010007 } finally {
10008 Binder.restoreCallingIdentity(identity);
10009 }
10010 }
10011
10012 @Override
Jordan Liu7de49fa2018-12-06 14:48:49 -080010013 public int getCardIdForDefaultEuicc(int subId, String callingPackage) {
Jordan Liu7de49fa2018-12-06 14:48:49 -080010014 final long identity = Binder.clearCallingIdentity();
10015 try {
10016 return UiccController.getInstance().getCardIdForDefaultEuicc();
10017 } finally {
10018 Binder.restoreCallingIdentity(identity);
10019 }
10020 }
10021
Pengquan Meng85728fb2018-03-12 16:31:21 -070010022 /**
goneil47ffb6e2018-04-06 15:40:58 -070010023 * A test API to reload the UICC profile.
10024 *
10025 * <p>Requires that the calling app has permission
10026 * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
10027 * @hide
10028 */
10029 @Override
10030 public void refreshUiccProfile(int subId) {
10031 enforceModifyPermission();
10032
10033 final long identity = Binder.clearCallingIdentity();
10034 try {
10035 Phone phone = getPhone(subId);
10036 if (phone == null) {
10037 return;
10038 }
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +000010039 UiccPort uiccPort = phone.getUiccPort();
10040 if (uiccPort == null) {
goneil47ffb6e2018-04-06 15:40:58 -070010041 return;
10042 }
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +000010043 UiccProfile uiccProfile = uiccPort.getUiccProfile();
goneil47ffb6e2018-04-06 15:40:58 -070010044 if (uiccProfile == null) {
10045 return;
10046 }
10047 uiccProfile.refresh();
10048 } finally {
10049 Binder.restoreCallingIdentity(identity);
10050 }
10051 }
10052
10053 /**
Pengquan Meng85728fb2018-03-12 16:31:21 -070010054 * Returns false if the mobile data is disabled by default, otherwise return true.
10055 */
10056 private boolean getDefaultDataEnabled() {
Inseob Kim14bb3d02018-12-13 17:11:34 +090010057 return TelephonyProperties.mobile_data().orElse(true);
Pengquan Meng85728fb2018-03-12 16:31:21 -070010058 }
10059
10060 /**
10061 * Returns true if the data roaming is enabled by default, i.e the system property
10062 * of {@link #DEFAULT_DATA_ROAMING_PROPERTY_NAME} is true or the config of
10063 * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} is true.
10064 */
10065 private boolean getDefaultDataRoamingEnabled(int subId) {
10066 final CarrierConfigManager configMgr = (CarrierConfigManager)
Nazanin Bakhshif782e562018-12-11 15:15:39 -080010067 mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Shuo Qian1d84a0e2020-07-15 12:36:44 -070010068 boolean isDataRoamingEnabled = TelephonyProperties.data_roaming().orElse(false);
Pengquan Meng85728fb2018-03-12 16:31:21 -070010069 isDataRoamingEnabled |= configMgr.getConfigForSubId(subId).getBoolean(
10070 CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
10071 return isDataRoamingEnabled;
10072 }
10073
10074 /**
10075 * Returns the default network type for the given {@code subId}, if the default network type is
10076 * not set, return {@link Phone#PREFERRED_NT_MODE}.
10077 */
10078 private int getDefaultNetworkType(int subId) {
Inseob Kim14bb3d02018-12-13 17:11:34 +090010079 List<Integer> list = TelephonyProperties.default_network();
Jack Yu285100e2022-12-02 22:48:35 -080010080 int phoneId = SubscriptionManager.getPhoneId(subId);
Inseob Kim14bb3d02018-12-13 17:11:34 +090010081 if (phoneId >= 0 && phoneId < list.size() && list.get(phoneId) != null) {
10082 return list.get(phoneId);
10083 }
10084 return Phone.PREFERRED_NT_MODE;
Pengquan Meng85728fb2018-03-12 16:31:21 -070010085 }
fionaxua13278b2018-03-21 00:08:13 -070010086
10087 @Override
10088 public void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String
chen xueaba88a2019-03-15 13:15:10 -070010089 gid1, String gid2, String plmn, String spn, String carrierPrivilegeRules, String apn) {
fionaxua13278b2018-03-21 00:08:13 -070010090 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -080010091
10092 final long identity = Binder.clearCallingIdentity();
10093 try {
10094 final Phone phone = getPhone(subId);
10095 if (phone == null) {
10096 loge("setCarrierTestOverride fails with invalid subId: " + subId);
10097 return;
10098 }
Rambo Wang9c9ffdd2022-01-13 21:51:44 -080010099 CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
10100 if (cpt != null) {
10101 cpt.setTestOverrideCarrierPrivilegeRules(carrierPrivilegeRules);
10102 }
10103 // TODO(b/211796398): remove the legacy logic below once CPT migration is done.
chen xueaba88a2019-03-15 13:15:10 -070010104 phone.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, plmn, spn,
10105 carrierPrivilegeRules, apn);
Jeff Davidson8ab02b22020-03-28 12:24:40 -070010106 if (carrierPrivilegeRules == null) {
10107 mCarrierPrivilegeTestOverrideSubIds.remove(subId);
10108 } else {
10109 mCarrierPrivilegeTestOverrideSubIds.add(subId);
10110 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -080010111 } finally {
10112 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -070010113 }
fionaxua13278b2018-03-21 00:08:13 -070010114 }
10115
10116 @Override
10117 public int getCarrierIdListVersion(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -070010118 enforceReadPrivilegedPermission("getCarrierIdListVersion");
Malcolm Chenaa4a8532018-02-28 15:00:40 -080010119
10120 final long identity = Binder.clearCallingIdentity();
10121 try {
10122 final Phone phone = getPhone(subId);
10123 if (phone == null) {
10124 loge("getCarrierIdListVersion fails with invalid subId: " + subId);
10125 return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
10126 }
10127 return phone.getCarrierIdListVersion();
10128 } finally {
10129 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -070010130 }
fionaxua13278b2018-03-21 00:08:13 -070010131 }
Malcolm Chen2c63d402018-08-14 16:00:53 -070010132
10133 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -070010134 public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage,
10135 String callingFeatureId) {
Malcolm Chen2c63d402018-08-14 16:00:53 -070010136 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -070010137 mApp, subId, callingPackage, callingFeatureId,
10138 "getNumberOfModemsWithSimultaneousDataConnections")) {
Malcolm Chen2c63d402018-08-14 16:00:53 -070010139 return -1;
10140 }
10141
10142 final long identity = Binder.clearCallingIdentity();
10143 try {
10144 return mPhoneConfigurationManager.getNumberOfModemsWithSimultaneousDataConnections();
10145 } finally {
10146 Binder.restoreCallingIdentity(identity);
10147 }
10148 }
Pengquan Menga1bb6272018-09-06 09:59:22 -070010149
10150 @Override
10151 public int getCdmaRoamingMode(int subId) {
zoey chen7e6d4e52019-12-17 18:18:59 +080010152 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -070010153 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Thomas Nguyen8ee49682023-02-01 11:46:09 -080010154 mApp, subId, "getCdmaRoamingMode");
Pengquan Menga1bb6272018-09-06 09:59:22 -070010155
10156 final long identity = Binder.clearCallingIdentity();
10157 try {
10158 return (int) sendRequest(CMD_GET_CDMA_ROAMING_MODE, null /* argument */, subId);
10159 } finally {
10160 Binder.restoreCallingIdentity(identity);
10161 }
10162 }
10163
10164 @Override
10165 public boolean setCdmaRoamingMode(int subId, int mode) {
10166 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
10167 mApp, subId, "setCdmaRoamingMode");
10168
10169 final long identity = Binder.clearCallingIdentity();
10170 try {
10171 return (boolean) sendRequest(CMD_SET_CDMA_ROAMING_MODE, mode, subId);
10172 } finally {
10173 Binder.restoreCallingIdentity(identity);
10174 }
10175 }
10176
10177 @Override
Sarah Chinbaab1432020-10-28 13:46:24 -070010178 public int getCdmaSubscriptionMode(int subId) {
10179 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -070010180 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Sarah Chinbaab1432020-10-28 13:46:24 -070010181 mApp, subId, "getCdmaSubscriptionMode");
10182
10183 final long identity = Binder.clearCallingIdentity();
10184 try {
10185 return (int) sendRequest(CMD_GET_CDMA_SUBSCRIPTION_MODE, null /* argument */, subId);
10186 } finally {
10187 Binder.restoreCallingIdentity(identity);
10188 }
10189 }
10190
10191 @Override
Pengquan Menga1bb6272018-09-06 09:59:22 -070010192 public boolean setCdmaSubscriptionMode(int subId, int mode) {
10193 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
10194 mApp, subId, "setCdmaSubscriptionMode");
10195
10196 final long identity = Binder.clearCallingIdentity();
10197 try {
10198 return (boolean) sendRequest(CMD_SET_CDMA_SUBSCRIPTION_MODE, mode, subId);
10199 } finally {
10200 Binder.restoreCallingIdentity(identity);
10201 }
10202 }
Makoto Onukida3bf792018-09-18 16:06:29 -070010203
sqianc5eccab2018-10-19 18:46:41 -070010204 @Override
sqian8c685422019-02-22 15:55:18 -080010205 public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList(
Philip P. Moltmann700a9592019-10-03 11:53:50 -070010206 String callingPackage, String callingFeatureId) {
sqian11b7a0e2018-12-05 18:48:28 -080010207 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -070010208 mApp, getDefaultSubscription(), callingPackage, callingFeatureId,
10209 "getEmergencyNumberList")) {
sqian11b7a0e2018-12-05 18:48:28 -080010210 throw new SecurityException("Requires READ_PHONE_STATE permission.");
10211 }
10212 final long identity = Binder.clearCallingIdentity();
10213 try {
sqian854d44b2018-12-12 16:48:18 -080010214 Map<Integer, List<EmergencyNumber>> emergencyNumberListInternal = new HashMap<>();
10215 for (Phone phone: PhoneFactory.getPhones()) {
10216 if (phone.getEmergencyNumberTracker() != null
10217 && phone.getEmergencyNumberTracker().getEmergencyNumberList() != null) {
10218 emergencyNumberListInternal.put(
10219 phone.getSubId(),
10220 phone.getEmergencyNumberTracker().getEmergencyNumberList());
10221 }
sqian11b7a0e2018-12-05 18:48:28 -080010222 }
sqian854d44b2018-12-12 16:48:18 -080010223 return emergencyNumberListInternal;
sqian11b7a0e2018-12-05 18:48:28 -080010224 } finally {
10225 Binder.restoreCallingIdentity(identity);
10226 }
sqianc5eccab2018-10-19 18:46:41 -070010227 }
10228
10229 @Override
sqian8c685422019-02-22 15:55:18 -080010230 public boolean isEmergencyNumber(String number, boolean exactMatch) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -080010231 final Phone defaultPhone = getDefaultPhone();
sqian11b7a0e2018-12-05 18:48:28 -080010232 if (!exactMatch) {
10233 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -070010234 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
sqian8c685422019-02-22 15:55:18 -080010235 mApp, defaultPhone.getSubId(), "isEmergencyNumber(Potential)");
sqian11b7a0e2018-12-05 18:48:28 -080010236 }
10237 final long identity = Binder.clearCallingIdentity();
10238 try {
sqian854d44b2018-12-12 16:48:18 -080010239 for (Phone phone: PhoneFactory.getPhones()) {
Chinmay Dhodapkard521bb12022-08-16 15:49:54 -070010240 //Note: we ignore passed in param exactMatch. We can remove it once
10241 // TelephonyManager#isPotentialEmergencyNumber is removed completely
sqian854d44b2018-12-12 16:48:18 -080010242 if (phone.getEmergencyNumberTracker() != null
Taesu Leee050c002020-10-13 17:19:35 +090010243 && phone.getEmergencyNumberTracker()
Thomas Nguyen8ee49682023-02-01 11:46:09 -080010244 .isEmergencyNumber(number)) {
Taesu Leee050c002020-10-13 17:19:35 +090010245 return true;
sqian11b7a0e2018-12-05 18:48:28 -080010246 }
sqian11b7a0e2018-12-05 18:48:28 -080010247 }
10248 return false;
10249 } finally {
10250 Binder.restoreCallingIdentity(identity);
10251 }
10252 }
10253
sqianf4ca7ed2019-01-15 18:32:07 -080010254 /**
Shuo Qianccbaf742021-02-22 18:32:21 -080010255 * Start emergency callback mode for GsmCdmaPhone for testing.
10256 */
10257 @Override
10258 public void startEmergencyCallbackMode() {
10259 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10260 "startEmergencyCallbackMode");
10261 enforceModifyPermission();
10262 final long identity = Binder.clearCallingIdentity();
10263 try {
10264 for (Phone phone : PhoneFactory.getPhones()) {
10265 Rlog.d(LOG_TAG, "startEmergencyCallbackMode phone type: " + phone.getPhoneType());
10266 if (phone != null && ((phone.getPhoneType() == PHONE_TYPE_GSM)
10267 || (phone.getPhoneType() == PHONE_TYPE_CDMA))) {
10268 GsmCdmaPhone gsmCdmaPhone = (GsmCdmaPhone) phone;
10269 gsmCdmaPhone.obtainMessage(
10270 GsmCdmaPhone.EVENT_EMERGENCY_CALLBACK_MODE_ENTER).sendToTarget();
10271 Rlog.d(LOG_TAG, "startEmergencyCallbackMode: triggered");
10272 }
10273 }
10274 } finally {
10275 Binder.restoreCallingIdentity(identity);
10276 }
10277 }
10278
10279 /**
sqianf4ca7ed2019-01-15 18:32:07 -080010280 * Update emergency number list for test mode.
10281 */
10282 @Override
10283 public void updateEmergencyNumberListTestMode(int action, EmergencyNumber num) {
10284 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10285 "updateEmergencyNumberListTestMode");
10286
10287 final long identity = Binder.clearCallingIdentity();
10288 try {
10289 for (Phone phone: PhoneFactory.getPhones()) {
10290 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
10291 if (tracker != null) {
10292 tracker.executeEmergencyNumberTestModeCommand(action, num);
10293 }
10294 }
10295 } finally {
10296 Binder.restoreCallingIdentity(identity);
10297 }
10298 }
10299
10300 /**
10301 * Get the full emergency number list for test mode.
10302 */
10303 @Override
10304 public List<String> getEmergencyNumberListTestMode() {
10305 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10306 "getEmergencyNumberListTestMode");
10307
10308 final long identity = Binder.clearCallingIdentity();
10309 try {
10310 Set<String> emergencyNumbers = new HashSet<>();
10311 for (Phone phone: PhoneFactory.getPhones()) {
10312 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
10313 if (tracker != null) {
10314 for (EmergencyNumber num : tracker.getEmergencyNumberList()) {
10315 emergencyNumbers.add(num.getNumber());
10316 }
10317 }
10318 }
10319 return new ArrayList<>(emergencyNumbers);
10320 } finally {
10321 Binder.restoreCallingIdentity(identity);
10322 }
10323 }
10324
chen xud6b45bd2018-10-30 22:27:10 -070010325 @Override
Shuo Qian3b6ee772019-11-13 17:43:31 -080010326 public int getEmergencyNumberDbVersion(int subId) {
10327 enforceReadPrivilegedPermission("getEmergencyNumberDbVersion");
10328
10329 final long identity = Binder.clearCallingIdentity();
10330 try {
10331 final Phone phone = getPhone(subId);
10332 if (phone == null) {
10333 loge("getEmergencyNumberDbVersion fails with invalid subId: " + subId);
10334 return TelephonyManager.INVALID_EMERGENCY_NUMBER_DB_VERSION;
10335 }
10336 return phone.getEmergencyNumberDbVersion();
10337 } finally {
10338 Binder.restoreCallingIdentity(identity);
10339 }
10340 }
10341
10342 @Override
10343 public void notifyOtaEmergencyNumberDbInstalled() {
10344 enforceModifyPermission();
10345
10346 final long identity = Binder.clearCallingIdentity();
10347 try {
10348 for (Phone phone: PhoneFactory.getPhones()) {
10349 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
10350 if (tracker != null) {
10351 tracker.updateOtaEmergencyNumberDatabase();
10352 }
10353 }
10354 } finally {
10355 Binder.restoreCallingIdentity(identity);
10356 }
10357 }
10358
10359 @Override
Shuo Qianc373f112020-03-05 17:55:34 -080010360 public void updateOtaEmergencyNumberDbFilePath(ParcelFileDescriptor otaParcelFileDescriptor) {
Shuo Qian3b6ee772019-11-13 17:43:31 -080010361 enforceActiveEmergencySessionPermission();
10362
10363 final long identity = Binder.clearCallingIdentity();
10364 try {
10365 for (Phone phone: PhoneFactory.getPhones()) {
10366 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
10367 if (tracker != null) {
Shuo Qianc373f112020-03-05 17:55:34 -080010368 tracker.updateOtaEmergencyNumberDbFilePath(otaParcelFileDescriptor);
10369 }
10370 }
10371 } finally {
10372 Binder.restoreCallingIdentity(identity);
10373 }
10374 }
10375
10376 @Override
10377 public void resetOtaEmergencyNumberDbFilePath() {
10378 enforceActiveEmergencySessionPermission();
10379
10380 final long identity = Binder.clearCallingIdentity();
10381 try {
10382 for (Phone phone: PhoneFactory.getPhones()) {
10383 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
10384 if (tracker != null) {
10385 tracker.resetOtaEmergencyNumberDbFilePath();
Shuo Qian3b6ee772019-11-13 17:43:31 -080010386 }
10387 }
10388 } finally {
10389 Binder.restoreCallingIdentity(identity);
10390 }
10391 }
10392
10393 @Override
chen xud6b45bd2018-10-30 22:27:10 -070010394 public List<String> getCertsFromCarrierPrivilegeAccessRules(int subId) {
10395 enforceReadPrivilegedPermission("getCertsFromCarrierPrivilegeAccessRules");
10396 Phone phone = getPhone(subId);
10397 if (phone == null) {
10398 return null;
10399 }
10400 final long identity = Binder.clearCallingIdentity();
10401 try {
10402 UiccProfile profile = UiccController.getInstance()
10403 .getUiccProfileForPhone(phone.getPhoneId());
10404 if (profile != null) {
10405 return profile.getCertsFromCarrierPrivilegeAccessRules();
10406 }
10407 } finally {
10408 Binder.restoreCallingIdentity(identity);
10409 }
10410 return null;
10411 }
Malcolm Chen8e4ed912019-01-15 20:22:16 -080010412
10413 /**
10414 * Enable or disable a modem stack.
10415 */
10416 @Override
10417 public boolean enableModemForSlot(int slotIndex, boolean enable) {
10418 enforceModifyPermission();
10419
10420 final long identity = Binder.clearCallingIdentity();
10421 try {
10422 Phone phone = PhoneFactory.getPhone(slotIndex);
10423 if (phone == null) {
10424 return false;
10425 } else {
10426 return (Boolean) sendRequest(CMD_REQUEST_ENABLE_MODEM, enable, phone, null);
10427 }
10428 } finally {
10429 Binder.restoreCallingIdentity(identity);
10430 }
10431 }
Michelecea4cf22018-12-21 15:00:11 -080010432
Malcolm Chen4bcd9822019-03-27 18:34:05 -070010433 /**
10434 * Whether a modem stack is enabled or not.
10435 */
10436 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -070010437 public boolean isModemEnabledForSlot(int slotIndex, String callingPackage,
10438 String callingFeatureId) {
Malcolm Chen4bcd9822019-03-27 18:34:05 -070010439 Phone phone = PhoneFactory.getPhone(slotIndex);
10440 if (phone == null) return false;
10441
10442 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -070010443 mApp, phone.getSubId(), callingPackage, callingFeatureId,
10444 "isModemEnabledForSlot")) {
Malcolm Chen4bcd9822019-03-27 18:34:05 -070010445 throw new SecurityException("Requires READ_PHONE_STATE permission.");
10446 }
10447
10448 final long identity = Binder.clearCallingIdentity();
10449 try {
Nazanin Bakhshif71371d2019-04-29 17:29:44 -070010450 try {
10451 return mPhoneConfigurationManager.getPhoneStatusFromCache(phone.getPhoneId());
10452 } catch (NoSuchElementException ex) {
10453 return (Boolean) sendRequest(CMD_GET_MODEM_STATUS, null, phone, null);
10454 }
Malcolm Chen4bcd9822019-03-27 18:34:05 -070010455 } finally {
10456 Binder.restoreCallingIdentity(identity);
10457 }
10458 }
10459
Michelecea4cf22018-12-21 15:00:11 -080010460 @Override
Michele0ea7d782019-03-19 14:58:42 -070010461 public void setMultiSimCarrierRestriction(boolean isMultiSimCarrierRestricted) {
Michelecea4cf22018-12-21 15:00:11 -080010462 enforceModifyPermission();
10463
10464 final long identity = Binder.clearCallingIdentity();
10465 try {
10466 mTelephonySharedPreferences.edit()
Michele0ea7d782019-03-19 14:58:42 -070010467 .putBoolean(PREF_MULTI_SIM_RESTRICTED, isMultiSimCarrierRestricted)
Michelecea4cf22018-12-21 15:00:11 -080010468 .commit();
10469 } finally {
10470 Binder.restoreCallingIdentity(identity);
10471 }
10472 }
10473
10474 @Override
Michele0ea7d782019-03-19 14:58:42 -070010475 @TelephonyManager.IsMultiSimSupportedResult
Philip P. Moltmann700a9592019-10-03 11:53:50 -070010476 public int isMultiSimSupported(String callingPackage, String callingFeatureId) {
Michele4245e952019-02-04 11:36:23 -080010477 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp,
Philip P. Moltmann700a9592019-10-03 11:53:50 -070010478 getDefaultPhone().getSubId(), callingPackage, callingFeatureId,
10479 "isMultiSimSupported")) {
Michele0ea7d782019-03-19 14:58:42 -070010480 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele4245e952019-02-04 11:36:23 -080010481 }
Michelecea4cf22018-12-21 15:00:11 -080010482
10483 final long identity = Binder.clearCallingIdentity();
10484 try {
Michele0ea7d782019-03-19 14:58:42 -070010485 return isMultiSimSupportedInternal();
Michelecea4cf22018-12-21 15:00:11 -080010486 } finally {
10487 Binder.restoreCallingIdentity(identity);
10488 }
10489 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -080010490
Michele0ea7d782019-03-19 14:58:42 -070010491 @TelephonyManager.IsMultiSimSupportedResult
10492 private int isMultiSimSupportedInternal() {
Michele30b57b22019-03-01 12:01:14 -080010493 // If the device has less than 2 SIM cards, indicate that multisim is restricted.
10494 int numPhysicalSlots = UiccController.getInstance().getUiccSlots().length;
10495 if (numPhysicalSlots < 2) {
Michele0ea7d782019-03-19 14:58:42 -070010496 loge("isMultiSimSupportedInternal: requires at least 2 cards");
10497 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -080010498 }
10499 // Check if the hardware supports multisim functionality. If usage of multisim is not
10500 // supported by the modem, indicate that it is restricted.
10501 PhoneCapability staticCapability =
10502 mPhoneConfigurationManager.getStaticPhoneCapability();
10503 if (staticCapability == null) {
Michele0ea7d782019-03-19 14:58:42 -070010504 loge("isMultiSimSupportedInternal: no static configuration available");
10505 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -080010506 }
SongFerngWang8236caa2021-01-17 21:51:44 +080010507 if (staticCapability.getLogicalModemList().size() < 2) {
Michele0ea7d782019-03-19 14:58:42 -070010508 loge("isMultiSimSupportedInternal: maximum number of modem is < 2");
10509 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -080010510 }
10511 // Check if support of multiple SIMs is restricted by carrier
10512 if (mTelephonySharedPreferences.getBoolean(PREF_MULTI_SIM_RESTRICTED, false)) {
Michele0ea7d782019-03-19 14:58:42 -070010513 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_CARRIER;
Michele30b57b22019-03-01 12:01:14 -080010514 }
10515
Michele0ea7d782019-03-19 14:58:42 -070010516 return TelephonyManager.MULTISIM_ALLOWED;
Michele30b57b22019-03-01 12:01:14 -080010517 }
10518
Nazanin Bakhshi628473f2019-01-29 17:37:52 -080010519 /**
10520 * Switch configs to enable multi-sim or switch back to single-sim
Nazanin Bakhshi17318782019-03-01 11:56:08 -080010521 * Note: Switch from multi-sim to single-sim is only possible with MODIFY_PHONE_STATE
10522 * permission, but the other way around is possible with either MODIFY_PHONE_STATE
10523 * or carrier privileges
Nazanin Bakhshi628473f2019-01-29 17:37:52 -080010524 * @param numOfSims number of active sims we want to switch to
10525 */
10526 @Override
10527 public void switchMultiSimConfig(int numOfSims) {
Nazanin Bakhshi17318782019-03-01 11:56:08 -080010528 if (numOfSims == 1) {
10529 enforceModifyPermission();
10530 } else {
10531 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
10532 mApp, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, "switchMultiSimConfig");
10533 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -080010534 final long identity = Binder.clearCallingIdentity();
Michele30b57b22019-03-01 12:01:14 -080010535
Nazanin Bakhshi628473f2019-01-29 17:37:52 -080010536 try {
Michele30b57b22019-03-01 12:01:14 -080010537 //only proceed if multi-sim is not restricted
Michele0ea7d782019-03-19 14:58:42 -070010538 if (isMultiSimSupportedInternal() != TelephonyManager.MULTISIM_ALLOWED) {
Michele30b57b22019-03-01 12:01:14 -080010539 loge("switchMultiSimConfig not possible. It is restricted or not supported.");
10540 return;
10541 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -080010542 mPhoneConfigurationManager.switchMultiSimConfig(numOfSims);
10543 } finally {
10544 Binder.restoreCallingIdentity(identity);
10545 }
10546 }
10547
Hyungjun Parkbb07fde2019-01-10 15:28:51 +090010548 @Override
10549 public boolean isApplicationOnUicc(int subId, int appType) {
10550 enforceReadPrivilegedPermission("isApplicationOnUicc");
10551 Phone phone = getPhone(subId);
10552 if (phone == null) {
10553 return false;
10554 }
10555 final long identity = Binder.clearCallingIdentity();
10556 try {
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +000010557 UiccPort uiccPort = phone.getUiccPort();
10558 if (uiccPort == null) {
Hyungjun Parkbb07fde2019-01-10 15:28:51 +090010559 return false;
10560 }
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +000010561 UiccProfile uiccProfile = uiccPort.getUiccProfile();
Hyungjun Parkbb07fde2019-01-10 15:28:51 +090010562 if (uiccProfile == null) {
10563 return false;
10564 }
10565 if (TelephonyManager.APPTYPE_SIM <= appType
10566 && appType <= TelephonyManager.APPTYPE_ISIM) {
10567 return uiccProfile.isApplicationOnIcc(AppType.values()[appType]);
10568 }
10569 return false;
10570 } finally {
10571 Binder.restoreCallingIdentity(identity);
10572 }
10573 }
10574
Nazanin Bakhshi628473f2019-01-29 17:37:52 -080010575 /**
chen xub4baa772019-04-03 10:23:41 -070010576 * Get whether making changes to modem configurations will trigger reboot.
10577 * Return value defaults to true.
Nazanin Bakhshi5fe5ef22019-01-30 10:52:09 -080010578 */
10579 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -070010580 public boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage,
10581 String callingFeatureId) {
chen xub4baa772019-04-03 10:23:41 -070010582 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -070010583 mApp, subId, callingPackage, callingFeatureId,
10584 "doesSwitchMultiSimConfigTriggerReboot")) {
chen xub4baa772019-04-03 10:23:41 -070010585 return false;
10586 }
Nazanin Bakhshi5fe5ef22019-01-30 10:52:09 -080010587 final long identity = Binder.clearCallingIdentity();
10588 try {
10589 return mPhoneConfigurationManager.isRebootRequiredForModemConfigChange();
10590 } finally {
10591 Binder.restoreCallingIdentity(identity);
10592 }
10593 }
10594
Nathan Harold29f5f052019-02-15 13:41:57 -080010595 private void updateModemStateMetrics() {
10596 TelephonyMetrics metrics = TelephonyMetrics.getInstance();
10597 // TODO: check the state for each modem if the api is ready.
10598 metrics.updateEnabledModemBitmap((1 << TelephonyManager.from(mApp).getPhoneCount()) - 1);
10599 }
10600
Pengquan Meng3889a572019-01-23 11:16:29 -080010601 @Override
sandeepjsa208e3b2021-11-17 04:05:58 +000010602 public List<UiccSlotMapping> getSlotsMapping(String callingPackage) {
Pengquan Meng3889a572019-01-23 11:16:29 -080010603 enforceReadPrivilegedPermission("getSlotsMapping");
sandeepjsa208e3b2021-11-17 04:05:58 +000010604 // Verify that the callingPackage belongs to the calling UID
10605 mApp.getSystemService(AppOpsManager.class)
10606 .checkPackage(Binder.getCallingUid(), callingPackage);
Pengquan Meng3889a572019-01-23 11:16:29 -080010607 final long identity = Binder.clearCallingIdentity();
sandeepjsa208e3b2021-11-17 04:05:58 +000010608 List<UiccSlotMapping> slotMap = new ArrayList<>();
Pengquan Meng3889a572019-01-23 11:16:29 -080010609 try {
sandeepjsa208e3b2021-11-17 04:05:58 +000010610 UiccSlotInfo[] slotInfos = getUiccSlotsInfo(mApp.getOpPackageName());
10611 if (slotInfos != null) {
10612 for (int i = 0; i < slotInfos.length; i++) {
10613 for (UiccPortInfo portInfo : slotInfos[i].getPorts()) {
10614 if (SubscriptionManager.isValidPhoneId(portInfo.getLogicalSlotIndex())) {
10615 slotMap.add(new UiccSlotMapping(portInfo.getPortIndex(), i,
10616 portInfo.getLogicalSlotIndex()));
10617 }
10618 }
Pengquan Meng3889a572019-01-23 11:16:29 -080010619 }
10620 }
sandeepjsa208e3b2021-11-17 04:05:58 +000010621 return slotMap;
Pengquan Meng3889a572019-01-23 11:16:29 -080010622 } finally {
10623 Binder.restoreCallingIdentity(identity);
10624 }
10625 }
Nathan Harold48d6fd52019-02-06 19:01:40 -080010626
10627 /**
10628 * Get the IRadio HAL Version
jimsunf9ec1622022-09-13 21:18:43 +080010629 * @deprecated use getHalVersion instead
Nathan Harold48d6fd52019-02-06 19:01:40 -080010630 */
jimsunf9ec1622022-09-13 21:18:43 +080010631 @Deprecated
Nathan Harold48d6fd52019-02-06 19:01:40 -080010632 @Override
10633 public int getRadioHalVersion() {
jimsunf9ec1622022-09-13 21:18:43 +080010634 return getHalVersion(HAL_SERVICE_RADIO);
10635 }
10636
10637 /**
10638 * Get the HAL Version of a specific service
10639 */
10640 @Override
10641 public int getHalVersion(int service) {
Nathan Harold48d6fd52019-02-06 19:01:40 -080010642 Phone phone = getDefaultPhone();
10643 if (phone == null) return -1;
jimsunf9ec1622022-09-13 21:18:43 +080010644 HalVersion hv = phone.getHalVersion(service);
Nathan Harold48d6fd52019-02-06 19:01:40 -080010645 if (hv.equals(HalVersion.UNKNOWN)) return -1;
10646 return hv.major * 100 + hv.minor;
10647 }
Malcolm Chendc8c10e2019-04-10 18:25:07 -070010648
10649 /**
Shuo Qianda2d6ec2020-01-14 15:18:28 -080010650 * Get the current calling package name.
10651 * @return the current calling package name
10652 */
10653 @Override
10654 public String getCurrentPackageName() {
10655 return mApp.getPackageManager().getPackagesForUid(Binder.getCallingUid())[0];
10656 }
10657
10658 /**
Malcolm Chene5ad5792019-04-18 13:51:02 -070010659 * Return whether data is enabled for certain APN type. This will tell if framework will accept
10660 * corresponding network requests on a subId.
10661 *
10662 * Data is enabled if:
Malcolm Chendc8c10e2019-04-10 18:25:07 -070010663 * 1) user data is turned on, or
Malcolm Chene5ad5792019-04-18 13:51:02 -070010664 * 2) APN is un-metered for this subscription, or
10665 * 3) APN type is whitelisted. E.g. MMS is whitelisted if
Hall Liu746e03c2020-09-25 11:13:49 -070010666 * {@link TelephonyManager#MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED} is enabled.
Malcolm Chene5ad5792019-04-18 13:51:02 -070010667 *
10668 * @return whether data is allowed for a apn type.
10669 *
10670 * @hide
Malcolm Chendc8c10e2019-04-10 18:25:07 -070010671 */
10672 @Override
Malcolm Chene5ad5792019-04-18 13:51:02 -070010673 public boolean isDataEnabledForApn(int apnType, int subId, String callingPackage) {
Amit Mahajan5d4e1922019-10-07 16:20:43 -070010674 enforceReadPrivilegedPermission("Needs READ_PRIVILEGED_PHONE_STATE for "
10675 + "isDataEnabledForApn");
Malcolm Chendc8c10e2019-04-10 18:25:07 -070010676
10677 // Now that all security checks passes, perform the operation as ourselves.
10678 final long identity = Binder.clearCallingIdentity();
10679 try {
10680 Phone phone = getPhone(subId);
10681 if (phone == null) return false;
10682
Jack Yu27422a52022-03-21 10:38:05 -070010683 boolean isMetered;
Jack Yu99e87332021-12-17 23:14:15 -080010684 boolean isDataEnabled;
Jack Yu7968c6d2022-07-31 00:43:21 -070010685 isMetered = phone.getDataNetworkController().getDataConfigManager()
10686 .isMeteredCapability(DataUtils.apnTypeToNetworkCapability(apnType),
10687 phone.getServiceState().getDataRoaming());
10688 isDataEnabled = phone.getDataSettingsManager().isDataEnabled(apnType);
Jack Yu99e87332021-12-17 23:14:15 -080010689 return !isMetered || isDataEnabled;
Malcolm Chene5ad5792019-04-18 13:51:02 -070010690 } finally {
10691 Binder.restoreCallingIdentity(identity);
10692 }
10693 }
10694
10695 @Override
Jack Yu41407ee2019-05-13 16:54:09 -070010696 public boolean isApnMetered(@ApnType int apnType, int subId) {
Malcolm Chene5ad5792019-04-18 13:51:02 -070010697 enforceReadPrivilegedPermission("isApnMetered");
10698
10699 // Now that all security checks passes, perform the operation as ourselves.
10700 final long identity = Binder.clearCallingIdentity();
10701 try {
10702 Phone phone = getPhone(subId);
10703 if (phone == null) return true; // By default return true.
Jack Yu7968c6d2022-07-31 00:43:21 -070010704 return phone.getDataNetworkController().getDataConfigManager().isMeteredCapability(
10705 DataUtils.apnTypeToNetworkCapability(apnType),
10706 phone.getServiceState().getDataRoaming());
Malcolm Chendc8c10e2019-04-10 18:25:07 -070010707 } finally {
10708 Binder.restoreCallingIdentity(identity);
10709 }
10710 }
Brad Ebingera63db5f2019-04-23 16:31:13 -070010711
10712 @Override
Hall Liu73f5d362020-01-20 13:42:00 -080010713 public void setSystemSelectionChannels(List<RadioAccessSpecifier> specifiers,
10714 int subscriptionId, IBooleanConsumer resultCallback) {
10715 enforceModifyPermission();
10716 long token = Binder.clearCallingIdentity();
10717 try {
10718 Phone phone = getPhone(subscriptionId);
10719 if (phone == null) {
10720 try {
10721 if (resultCallback != null) {
10722 resultCallback.accept(false);
10723 }
10724 } catch (RemoteException e) {
10725 // ignore
10726 }
10727 return;
10728 }
10729 Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> argument =
10730 Pair.create(specifiers, (x) -> {
10731 try {
10732 if (resultCallback != null) {
10733 resultCallback.accept(x);
10734 }
10735 } catch (RemoteException e) {
10736 // ignore
10737 }
10738 });
10739 sendRequestAsync(CMD_SET_SYSTEM_SELECTION_CHANNELS, argument, phone, null);
10740 } finally {
10741 Binder.restoreCallingIdentity(token);
10742 }
10743 }
10744
10745 @Override
Sarah Chin679c08a2020-11-18 13:39:35 -080010746 public List<RadioAccessSpecifier> getSystemSelectionChannels(int subId) {
10747 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -070010748 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Sarah Chin679c08a2020-11-18 13:39:35 -080010749 mApp, subId, "getSystemSelectionChannels");
10750 WorkSource workSource = getWorkSource(Binder.getCallingUid());
10751 final long identity = Binder.clearCallingIdentity();
10752 try {
Sarah Chin428d1d62021-03-13 03:17:40 -080010753 Object result = sendRequest(CMD_GET_SYSTEM_SELECTION_CHANNELS, null, subId, workSource);
10754 if (result instanceof IllegalStateException) {
10755 throw (IllegalStateException) result;
10756 }
10757 List<RadioAccessSpecifier> specifiers = (List<RadioAccessSpecifier>) result;
Sarah Chin679c08a2020-11-18 13:39:35 -080010758 if (DBG) log("getSystemSelectionChannels: " + specifiers);
10759 return specifiers;
10760 } finally {
10761 Binder.restoreCallingIdentity(identity);
10762 }
10763 }
10764
10765 @Override
Jack Yu8b766fc2022-03-21 09:42:33 -070010766 public boolean isMvnoMatched(int slotIndex, int mvnoType, @NonNull String mvnoMatchData) {
changbettyca3d40d2020-03-03 16:27:31 +080010767 enforceReadPrivilegedPermission("isMvnoMatched");
Jack Yu8b766fc2022-03-21 09:42:33 -070010768 return UiccController.getInstance().mvnoMatches(slotIndex, mvnoType, mvnoMatchData);
changbetty7157e9e2019-12-06 18:16:37 +080010769 }
10770
10771 @Override
Philip P. Moltmannd02b7372020-03-18 17:06:12 -070010772 public void enqueueSmsPickResult(String callingPackage, String callingAttributionTag,
10773 IIntegerConsumer pendingSubIdResult) {
Shuo Qianda2d6ec2020-01-14 15:18:28 -080010774 if (callingPackage == null) {
10775 callingPackage = getCurrentPackageName();
10776 }
Brad Ebingera63db5f2019-04-23 16:31:13 -070010777 SmsPermissions permissions = new SmsPermissions(getDefaultPhone(), mApp,
10778 (AppOpsManager) mApp.getSystemService(Context.APP_OPS_SERVICE));
Philip P. Moltmannd02b7372020-03-18 17:06:12 -070010779 if (!permissions.checkCallingCanSendSms(callingPackage, callingAttributionTag,
10780 "Sending message")) {
Brad Ebingera63db5f2019-04-23 16:31:13 -070010781 throw new SecurityException("Requires SEND_SMS permission to perform this operation");
10782 }
10783 PickSmsSubscriptionActivity.addPendingResult(pendingSubIdResult);
10784 Intent intent = new Intent();
10785 intent.setClass(mApp, PickSmsSubscriptionActivity.class);
10786 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10787 // Bring up choose default SMS subscription dialog right now
10788 intent.putExtra(PickSmsSubscriptionActivity.DIALOG_TYPE_KEY,
10789 PickSmsSubscriptionActivity.SMS_PICK_FOR_MESSAGE);
10790 mApp.startActivity(intent);
10791 }
chen xud5ca2d52019-05-28 15:20:57 -070010792
10793 @Override
Ayush Sharma787854b2022-12-12 14:55:02 +000010794 public void showSwitchToManagedProfileDialog() {
10795 enforceModifyPermission();
10796
10797 Intent intent = new Intent();
10798 intent.setClass(mApp, ErrorDialogActivity.class);
10799 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10800 mApp.startActivity(intent);
10801 }
10802
10803 @Override
chen xud5ca2d52019-05-28 15:20:57 -070010804 public String getMmsUAProfUrl(int subId) {
10805 //TODO investigate if this API should require proper permission check in R b/133791609
10806 final long identity = Binder.clearCallingIdentity();
10807 try {
Guoqiang.Qiu171383d2020-07-13 09:38:32 +080010808 String carrierUAProfUrl = mApp.getCarrierConfigForSubId(subId).getString(
10809 CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING);
10810 if (!TextUtils.isEmpty(carrierUAProfUrl)) {
10811 return carrierUAProfUrl;
10812 }
Daniel Brightebb4eb72020-02-18 15:16:33 -080010813 return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
10814 .getString(com.android.internal.R.string.config_mms_user_agent_profile_url);
chen xud5ca2d52019-05-28 15:20:57 -070010815 } finally {
10816 Binder.restoreCallingIdentity(identity);
10817 }
10818 }
10819
10820 @Override
10821 public String getMmsUserAgent(int subId) {
10822 //TODO investigate if this API should require proper permission check in R b/133791609
10823 final long identity = Binder.clearCallingIdentity();
10824 try {
Guoqiang.Qiu171383d2020-07-13 09:38:32 +080010825 String carrierUserAgent = mApp.getCarrierConfigForSubId(subId).getString(
10826 CarrierConfigManager.KEY_MMS_USER_AGENT_STRING);
10827 if (!TextUtils.isEmpty(carrierUserAgent)) {
10828 return carrierUserAgent;
10829 }
Daniel Brightebb4eb72020-02-18 15:16:33 -080010830 return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
10831 .getString(com.android.internal.R.string.config_mms_user_agent);
chen xud5ca2d52019-05-28 15:20:57 -070010832 } finally {
10833 Binder.restoreCallingIdentity(identity);
10834 }
10835 }
Jack Yub07d4972019-05-28 16:12:25 -070010836
10837 @Override
Hall Liua62f5da2020-09-25 10:42:19 -070010838 public boolean isMobileDataPolicyEnabled(int subscriptionId, int policy) {
10839 enforceReadPrivilegedPermission("isMobileDataPolicyEnabled");
Jack Yub07d4972019-05-28 16:12:25 -070010840
Jack Yub07d4972019-05-28 16:12:25 -070010841 final long identity = Binder.clearCallingIdentity();
10842 try {
Hall Liua62f5da2020-09-25 10:42:19 -070010843 Phone phone = getPhone(subscriptionId);
Jack Yub07d4972019-05-28 16:12:25 -070010844 if (phone == null) return false;
10845
Ling Maf188d502022-09-16 15:22:36 -070010846 return phone.getDataSettingsManager().isMobileDataPolicyEnabled(policy);
Jack Yub07d4972019-05-28 16:12:25 -070010847 } finally {
10848 Binder.restoreCallingIdentity(identity);
10849 }
10850 }
10851
10852 @Override
Hall Liuc66bb112021-02-02 12:09:32 -080010853 public void setMobileDataPolicyEnabled(int subscriptionId, int policy,
Hall Liua62f5da2020-09-25 10:42:19 -070010854 boolean enabled) {
changbettyd5c246e2019-12-24 15:40:37 +080010855 enforceModifyPermission();
10856
changbettyd5c246e2019-12-24 15:40:37 +080010857 final long identity = Binder.clearCallingIdentity();
10858 try {
Hall Liua62f5da2020-09-25 10:42:19 -070010859 Phone phone = getPhone(subscriptionId);
10860 if (phone == null) return;
changbettyd5c246e2019-12-24 15:40:37 +080010861
Ling Maf188d502022-09-16 15:22:36 -070010862 phone.getDataSettingsManager().setMobileDataPolicy(policy, enabled);
changbettyd5c246e2019-12-24 15:40:37 +080010863 } finally {
10864 Binder.restoreCallingIdentity(identity);
10865 }
10866 }
10867
Tyler Gunn7bcdc742019-10-04 15:56:59 -070010868 /**
Hall Liu746e03c2020-09-25 11:13:49 -070010869 * Updates whether conference event package handling is enabled.
Tyler Gunn7bcdc742019-10-04 15:56:59 -070010870 * @param isCepEnabled {@code true} if CEP handling is enabled (default), or {@code false}
10871 * otherwise.
10872 */
10873 @Override
10874 public void setCepEnabled(boolean isCepEnabled) {
10875 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setCepEnabled");
10876
10877 final long identity = Binder.clearCallingIdentity();
10878 try {
10879 Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled);
10880 for (Phone phone : PhoneFactory.getPhones()) {
10881 Phone defaultPhone = phone.getImsPhone();
10882 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
10883 ImsPhone imsPhone = (ImsPhone) defaultPhone;
10884 ImsPhoneCallTracker imsPhoneCallTracker =
10885 (ImsPhoneCallTracker) imsPhone.getCallTracker();
10886 imsPhoneCallTracker.setConferenceEventPackageEnabled(isCepEnabled);
10887 Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled + ", for imsPhone "
10888 + imsPhone.getMsisdn());
10889 }
10890 }
10891 } finally {
10892 Binder.restoreCallingIdentity(identity);
10893 }
10894 }
allenwtsu46dcc572020-01-08 18:24:03 +080010895
10896 /**
10897 * Notify that an RCS autoconfiguration XML file has been received for provisioning.
10898 *
10899 * @param config The XML file to be read. ASCII/UTF8 encoded text if not compressed.
10900 * @param isCompressed The XML file is compressed in gzip format and must be decompressed
10901 * before being read.
10902 */
10903 @Override
10904 public void notifyRcsAutoConfigurationReceived(int subId, @NonNull byte[] config, boolean
10905 isCompressed) {
10906 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
10907 mApp, subId, "notifyRcsAutoConfigurationReceived");
Hui Wang761a6682020-10-31 05:12:53 +000010908 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
10909 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
10910 }
10911 if (!isImsAvailableOnDevice()) {
joonhunshin46b49a32022-12-21 05:33:23 +000010912 // ProvisioningManager can not handle ServiceSpecificException.
10913 // Throw the IllegalStateException and annotate ProvisioningManager.
10914 throw new IllegalStateException("IMS not available on device.");
Hui Wang761a6682020-10-31 05:12:53 +000010915 }
10916
10917 final long identity = Binder.clearCallingIdentity();
allenwtsu46dcc572020-01-08 18:24:03 +080010918 try {
Hui Wang761a6682020-10-31 05:12:53 +000010919 RcsProvisioningMonitor.getInstance().updateConfig(subId, config, isCompressed);
10920 } finally {
10921 Binder.restoreCallingIdentity(identity);
allenwtsu46dcc572020-01-08 18:24:03 +080010922 }
10923 }
zoey chene02881a2019-12-30 16:11:23 +080010924
10925 @Override
10926 public boolean isIccLockEnabled(int subId) {
10927 enforceReadPrivilegedPermission("isIccLockEnabled");
10928
10929 // Now that all security checks passes, perform the operation as ourselves.
10930 final long identity = Binder.clearCallingIdentity();
10931 try {
10932 Phone phone = getPhone(subId);
10933 if (phone != null && phone.getIccCard() != null) {
10934 return phone.getIccCard().getIccLockEnabled();
10935 } else {
10936 return false;
10937 }
10938 } finally {
10939 Binder.restoreCallingIdentity(identity);
10940 }
10941 }
10942
10943 /**
10944 * Set the ICC pin lock enabled or disabled.
10945 *
10946 * @return an integer representing the status of IccLock enabled or disabled in the following
10947 * three cases:
10948 * - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if enabled or disabled IccLock
10949 * successfully.
10950 * - Positive number and zero for remaining password attempts.
10951 * - Negative number for other failure cases (such like enabling/disabling PIN failed).
10952 *
10953 */
10954 @Override
10955 public int setIccLockEnabled(int subId, boolean enabled, String password) {
10956 enforceModifyPermission();
10957
10958 Phone phone = getPhone(subId);
10959 if (phone == null) {
10960 return 0;
10961 }
10962 // Now that all security checks passes, perform the operation as ourselves.
10963 final long identity = Binder.clearCallingIdentity();
10964 try {
10965 int attemptsRemaining = (int) sendRequest(CMD_SET_ICC_LOCK_ENABLED,
10966 new Pair<Boolean, String>(enabled, password), phone, null);
10967 return attemptsRemaining;
10968
10969 } catch (Exception e) {
10970 Log.e(LOG_TAG, "setIccLockEnabled. Exception e =" + e);
10971 } finally {
10972 Binder.restoreCallingIdentity(identity);
10973 }
10974 return 0;
10975 }
10976
10977 /**
10978 * Change the ICC password used in ICC pin lock.
10979 *
10980 * @return an integer representing the status of IccLock changed in the following three cases:
10981 * - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if changed IccLock successfully.
10982 * - Positive number and zero for remaining password attempts.
10983 * - Negative number for other failure cases (such like enabling/disabling PIN failed).
10984 *
10985 */
10986 @Override
10987 public int changeIccLockPassword(int subId, String oldPassword, String newPassword) {
10988 enforceModifyPermission();
10989
10990 Phone phone = getPhone(subId);
10991 if (phone == null) {
10992 return 0;
10993 }
10994 // Now that all security checks passes, perform the operation as ourselves.
10995 final long identity = Binder.clearCallingIdentity();
10996 try {
10997 int attemptsRemaining = (int) sendRequest(CMD_CHANGE_ICC_LOCK_PASSWORD,
10998 new Pair<String, String>(oldPassword, newPassword), phone, null);
10999 return attemptsRemaining;
11000
11001 } catch (Exception e) {
11002 Log.e(LOG_TAG, "changeIccLockPassword. Exception e =" + e);
11003 } finally {
11004 Binder.restoreCallingIdentity(identity);
11005 }
11006 return 0;
11007 }
Peter Wangdafb9ac2020-01-15 14:13:38 -080011008
11009 /**
11010 * Request for receiving user activity notification
11011 */
11012 @Override
11013 public void requestUserActivityNotification() {
11014 if (!mNotifyUserActivity.get()
11015 && !mMainThreadHandler.hasMessages(MSG_NOTIFY_USER_ACTIVITY)) {
11016 mNotifyUserActivity.set(true);
11017 }
11018 }
11019
11020 /**
11021 * Called when userActivity is signalled in the power manager.
11022 * This is safe to call from any thread, with any window manager locks held or not.
11023 */
11024 @Override
11025 public void userActivity() {
11026 // ***************************************
11027 // * Inherited from PhoneWindowManager *
11028 // ***************************************
11029 // THIS IS CALLED FROM DEEP IN THE POWER MANAGER
11030 // WITH ITS LOCKS HELD.
11031 //
11032 // This code must be VERY careful about the locks
11033 // it acquires.
11034 // In fact, the current code acquires way too many,
11035 // and probably has lurking deadlocks.
11036
11037 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11038 throw new SecurityException("Only the OS may call notifyUserActivity()");
11039 }
11040
11041 if (mNotifyUserActivity.getAndSet(false)) {
11042 mMainThreadHandler.sendEmptyMessageDelayed(MSG_NOTIFY_USER_ACTIVITY,
11043 USER_ACTIVITY_NOTIFICATION_DELAY);
11044 }
11045 }
Malcolm Chen4639c562020-04-13 11:59:40 -070011046
11047 @Override
11048 public boolean canConnectTo5GInDsdsMode() {
11049 return mApp.getResources().getBoolean(R.bool.config_5g_connection_in_dsds_mode);
11050 }
Jack Yud10cdd42020-09-28 20:28:01 -070011051
11052 @Override
11053 public @NonNull List<String> getEquivalentHomePlmns(int subId, String callingPackage,
11054 String callingFeatureId) {
11055 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
11056 mApp, subId, callingPackage, callingFeatureId, "getEquivalentHomePlmns")) {
11057 throw new SecurityException("Requires READ_PHONE_STATE permission.");
11058 }
11059
11060 Phone phone = getPhone(subId);
11061 if (phone == null) {
11062 throw new RuntimeException("phone is not available");
11063 }
11064 // Now that all security checks passes, perform the operation as ourselves.
11065 final long identity = Binder.clearCallingIdentity();
11066 try {
11067 return phone.getEquivalentHomePlmns();
11068 } finally {
11069 Binder.restoreCallingIdentity(identity);
11070 }
11071 }
Daniel Bright59e67312020-11-13 11:49:37 -080011072
11073 @Override
11074 public boolean isRadioInterfaceCapabilitySupported(
Daniel Bright95a4c1f2021-02-11 09:57:16 -080011075 final @NonNull @TelephonyManager.RadioInterfaceCapability String capability) {
11076 Set<String> radioInterfaceCapabilities =
Daniel Bright94f43662021-03-01 14:43:40 -080011077 mRadioInterfaceCapabilities.getCapabilities();
Daniel Bright59e67312020-11-13 11:49:37 -080011078 if (radioInterfaceCapabilities == null) {
11079 throw new RuntimeException("radio interface capabilities are not available");
Daniel Bright59e67312020-11-13 11:49:37 -080011080 }
Daniel Bright95a4c1f2021-02-11 09:57:16 -080011081 return radioInterfaceCapabilities.contains(capability);
Daniel Bright59e67312020-11-13 11:49:37 -080011082 }
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011083
Hui Wang641e81c2020-10-12 12:14:23 -070011084 @Override
11085 public void bootstrapAuthenticationRequest(int subId, int appType, Uri nafUrl,
11086 UaSecurityProtocolIdentifier securityProtocol,
Brad Ebinger34c09a52021-02-17 23:23:21 +000011087 boolean forceBootStrapping, IBootstrapAuthenticationCallback callback) {
11088 TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
11089 Binder.getCallingUid(), "bootstrapAuthenticationRequest",
11090 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
11091 Manifest.permission.MODIFY_PHONE_STATE);
Hui Wang641e81c2020-10-12 12:14:23 -070011092 if (DBG) {
11093 log("bootstrapAuthenticationRequest, subId:" + subId + ", appType:"
11094 + appType + ", NAF:" + nafUrl + ", sp:" + securityProtocol
11095 + ", forceBootStrapping:" + forceBootStrapping + ", callback:" + callback);
11096 }
11097
11098 if (!SubscriptionManager.isValidSubscriptionId(subId)
11099 || appType < TelephonyManager.APPTYPE_UNKNOWN
11100 || appType > TelephonyManager.APPTYPE_ISIM
11101 || nafUrl == null || securityProtocol == null || callback == null) {
11102 Log.d(LOG_TAG, "bootstrapAuthenticationRequest failed due to invalid parameters");
11103 if (callback != null) {
11104 try {
11105 callback.onAuthenticationFailure(
11106 0, TelephonyManager.GBA_FAILURE_REASON_FEATURE_NOT_SUPPORTED);
11107 } catch (RemoteException exception) {
11108 log("Fail to notify onAuthenticationFailure due to " + exception);
11109 }
11110 return;
11111 }
11112 }
11113
11114 final long token = Binder.clearCallingIdentity();
11115 try {
11116 getGbaManager(subId).bootstrapAuthenticationRequest(
11117 new GbaAuthRequest(subId, appType, nafUrl, securityProtocol.toByteArray(),
Thomas Nguyen8ee49682023-02-01 11:46:09 -080011118 forceBootStrapping, callback));
Hui Wang641e81c2020-10-12 12:14:23 -070011119 } finally {
11120 Binder.restoreCallingIdentity(token);
11121 }
11122 }
11123
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011124 /**
Sooraj Sasindran72cff492021-07-29 09:42:42 -070011125 * Attempts to set the radio power state for all phones for thermal reason.
11126 * This does not guarantee that the
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011127 * requested radio power state will actually be set. See {@link
11128 * PhoneInternalInterface#setRadioPowerForReason} for more details.
11129 *
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011130 * @param enable {@code true} if trying to turn radio on.
11131 * @return {@code true} if phone setRadioPowerForReason was called. Otherwise, returns {@code
11132 * false}.
11133 */
Sooraj Sasindran72cff492021-07-29 09:42:42 -070011134 private boolean setRadioPowerForThermal(boolean enable) {
11135 boolean isPhoneAvailable = false;
11136 for (int i = 0; i < TelephonyManager.getDefault().getActiveModemCount(); i++) {
11137 Phone phone = PhoneFactory.getPhone(i);
11138 if (phone != null) {
Thomas Nguyenfd0572f2022-07-15 22:28:49 +000011139 phone.setRadioPowerForReason(enable, TelephonyManager.RADIO_POWER_REASON_THERMAL);
Sooraj Sasindran72cff492021-07-29 09:42:42 -070011140 isPhoneAvailable = true;
11141 }
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011142 }
Sooraj Sasindran72cff492021-07-29 09:42:42 -070011143
11144 // return true if successfully informed the phone object about the thermal radio power
11145 // request.
11146 return isPhoneAvailable;
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011147 }
11148
11149 private int handleDataThrottlingRequest(int subId,
Sarah Chinecc78c42022-03-31 21:16:48 -070011150 DataThrottlingRequest dataThrottlingRequest, String callingPackage) {
Jack Nudelman5d6a98b2021-03-04 14:26:25 -080011151 boolean isDataThrottlingSupported = isRadioInterfaceCapabilitySupported(
11152 TelephonyManager.CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING);
11153 if (!isDataThrottlingSupported && dataThrottlingRequest.getDataThrottlingAction()
11154 != DataThrottlingRequest.DATA_THROTTLING_ACTION_NO_DATA_THROTTLING) {
11155 throw new IllegalArgumentException("modem does not support data throttling");
11156 }
11157
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011158 // Ensure that radio is on. If not able to power on due to phone being unavailable, return
11159 // THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
Sooraj Sasindran72cff492021-07-29 09:42:42 -070011160 if (!setRadioPowerForThermal(true)) {
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011161 return TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
11162 }
11163
Sarah Chinecc78c42022-03-31 21:16:48 -070011164 setDataEnabledForReason(
11165 subId, TelephonyManager.DATA_ENABLED_REASON_THERMAL, true, callingPackage);
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011166
Jack Nudelman5d6a98b2021-03-04 14:26:25 -080011167 if (isDataThrottlingSupported) {
11168 int thermalMitigationResult =
Thomas Nguyen8ee49682023-02-01 11:46:09 -080011169 (int) sendRequest(CMD_SET_DATA_THROTTLING, dataThrottlingRequest, subId);
Jack Nudelman5d6a98b2021-03-04 14:26:25 -080011170 if (thermalMitigationResult == SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS) {
11171 throw new IllegalArgumentException("modem returned INVALID_ARGUMENTS");
11172 } else if (thermalMitigationResult
11173 == MODEM_DOES_NOT_SUPPORT_DATA_THROTTLING_ERROR_CODE) {
Jack Nudelman760d0962021-05-20 13:57:30 -070011174 log("Modem likely does not support data throttling on secondary carrier. Data " +
11175 "throttling action = " + dataThrottlingRequest.getDataThrottlingAction());
11176 return TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
Jack Nudelman5d6a98b2021-03-04 14:26:25 -080011177 }
11178 return thermalMitigationResult;
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011179 }
Jack Nudelman5d6a98b2021-03-04 14:26:25 -080011180
11181 return TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011182 }
11183
Jack Nudelman644b91a2021-03-12 14:09:48 -080011184 private static List<String> getThermalMitigationAllowlist(Context context) {
11185 if (sThermalMitigationAllowlistedPackages.isEmpty()) {
11186 for (String pckg : context.getResources()
11187 .getStringArray(R.array.thermal_mitigation_allowlisted_packages)) {
11188 sThermalMitigationAllowlistedPackages.add(pckg);
11189 }
11190 }
11191
11192 return sThermalMitigationAllowlistedPackages;
11193 }
11194
Jack Nudelmane69bbc82021-05-13 10:00:15 -070011195 private boolean isAnyPhoneInEmergencyState() {
11196 TelecomManager tm = mApp.getSystemService(TelecomManager.class);
11197 if (tm.isInEmergencyCall()) {
11198 Log.e(LOG_TAG , "Phone state is not valid. One of the phones is in an emergency call");
11199 return true;
11200 }
11201 for (Phone phone : PhoneFactory.getPhones()) {
11202 if (phone.isInEmergencySmsMode() || phone.isInEcm()) {
11203 Log.e(LOG_TAG, "Phone state is not valid. isInEmergencySmsMode = "
Thomas Nguyen8ee49682023-02-01 11:46:09 -080011204 + phone.isInEmergencySmsMode() + " isInEmergencyCallbackMode = "
11205 + phone.isInEcm());
Jack Nudelmane69bbc82021-05-13 10:00:15 -070011206 return true;
11207 }
11208 }
11209
11210 return false;
11211 }
11212
Jack Nudelman644b91a2021-03-12 14:09:48 -080011213 /**
11214 * Used by shell commands to add an authorized package name for thermal mitigation.
11215 * @param packageName name of package to be allowlisted
11216 * @param context
11217 */
11218 static void addPackageToThermalMitigationAllowlist(String packageName, Context context) {
11219 sThermalMitigationAllowlistedPackages = getThermalMitigationAllowlist(context);
11220 sThermalMitigationAllowlistedPackages.add(packageName);
11221 }
11222
11223 /**
11224 * Used by shell commands to remove an authorized package name for thermal mitigation.
11225 * @param packageName name of package to remove from allowlist
11226 * @param context
11227 */
11228 static void removePackageFromThermalMitigationAllowlist(String packageName, Context context) {
11229 sThermalMitigationAllowlistedPackages = getThermalMitigationAllowlist(context);
11230 sThermalMitigationAllowlistedPackages.remove(packageName);
11231 }
11232
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011233 /**
11234 * Thermal mitigation request to control functionalities at modem.
11235 *
11236 * @param subId the id of the subscription.
11237 * @param thermalMitigationRequest holds all necessary information to be passed down to modem.
Jack Nudelman644b91a2021-03-12 14:09:48 -080011238 * @param callingPackage the package name of the calling package.
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011239 *
11240 * @return thermalMitigationResult enum as defined in android.telephony.Annotation.
11241 */
11242 @Override
11243 @ThermalMitigationResult
11244 public int sendThermalMitigationRequest(
11245 int subId,
Jack Nudelman644b91a2021-03-12 14:09:48 -080011246 ThermalMitigationRequest thermalMitigationRequest,
11247 String callingPackage) throws IllegalArgumentException {
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011248 enforceModifyPermission();
11249
Jack Nudelman644b91a2021-03-12 14:09:48 -080011250 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
11251 if (!getThermalMitigationAllowlist(getDefaultPhone().getContext())
11252 .contains(callingPackage)) {
11253 throw new SecurityException("Calling package must be configured in the device config. "
11254 + "calling package: " + callingPackage);
11255 }
11256
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011257 WorkSource workSource = getWorkSource(Binder.getCallingUid());
11258 final long identity = Binder.clearCallingIdentity();
11259
11260 int thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_UNKNOWN_ERROR;
11261 try {
11262 int thermalMitigationAction = thermalMitigationRequest.getThermalMitigationAction();
11263 switch (thermalMitigationAction) {
11264 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_DATA_THROTTLING:
11265 thermalMitigationResult =
Thomas Nguyen8ee49682023-02-01 11:46:09 -080011266 handleDataThrottlingRequest(subId,
11267 thermalMitigationRequest.getDataThrottlingRequest(),
11268 callingPackage);
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011269 break;
11270 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_VOICE_ONLY:
11271 if (thermalMitigationRequest.getDataThrottlingRequest() != null) {
11272 throw new IllegalArgumentException("dataThrottlingRequest must be null for "
11273 + "ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_VOICE_ONLY");
11274 }
11275
11276 // Ensure that radio is on. If not able to power on due to phone being
11277 // unavailable, return THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
Sooraj Sasindran72cff492021-07-29 09:42:42 -070011278 if (!setRadioPowerForThermal(true)) {
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011279 thermalMitigationResult =
11280 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
11281 break;
11282 }
11283
11284 setDataEnabledForReason(subId, TelephonyManager.DATA_ENABLED_REASON_THERMAL,
Sarah Chinecc78c42022-03-31 21:16:48 -070011285 false, callingPackage);
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011286 thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
11287 break;
11288 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_RADIO_OFF:
11289 if (thermalMitigationRequest.getDataThrottlingRequest() != null) {
11290 throw new IllegalArgumentException("dataThrottlingRequest must be null for"
11291 + " ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_RADIO_OFF");
11292 }
11293
11294 TelecomAccountRegistry registry = TelecomAccountRegistry.getInstance(null);
11295 if (registry != null) {
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011296 Phone phone = getPhone(subId);
11297 if (phone == null) {
11298 thermalMitigationResult =
Thomas Nguyen8ee49682023-02-01 11:46:09 -080011299 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011300 break;
11301 }
11302
Jack Nudelmane69bbc82021-05-13 10:00:15 -070011303 TelephonyConnectionService service =
11304 registry.getTelephonyConnectionService();
Jack Nudelmanb30ac302021-06-17 15:39:58 -070011305 if (service != null && service.isEmergencyCallPending()) {
Jack Nudelmane69bbc82021-05-13 10:00:15 -070011306 Log.e(LOG_TAG, "An emergency call is pending");
11307 thermalMitigationResult =
11308 TelephonyManager.THERMAL_MITIGATION_RESULT_INVALID_STATE;
11309 break;
11310 } else if (isAnyPhoneInEmergencyState()) {
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011311 thermalMitigationResult =
Thomas Nguyen8ee49682023-02-01 11:46:09 -080011312 TelephonyManager.THERMAL_MITIGATION_RESULT_INVALID_STATE;
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011313 break;
11314 }
11315 } else {
11316 thermalMitigationResult =
11317 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
11318 break;
11319 }
11320
11321 // Turn radio off. If not able to power off due to phone being unavailable,
11322 // return THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
Sooraj Sasindran72cff492021-07-29 09:42:42 -070011323 if (!setRadioPowerForThermal(false)) {
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011324 thermalMitigationResult =
11325 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
11326 break;
11327 }
11328 thermalMitigationResult =
Thomas Nguyen8ee49682023-02-01 11:46:09 -080011329 TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
Jack Nudelmanb0b87642020-11-12 15:04:39 -080011330 break;
11331 default:
11332 throw new IllegalArgumentException("the requested thermalMitigationAction does "
11333 + "not exist. Requested action: " + thermalMitigationAction);
11334 }
11335 } catch (IllegalArgumentException e) {
11336 throw e;
11337 } catch (Exception e) {
11338 Log.e(LOG_TAG, "thermalMitigationRequest. Exception e =" + e);
11339 thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
11340 } finally {
11341 Binder.restoreCallingIdentity(identity);
11342 }
11343
11344 if (DBG) {
11345 log("thermalMitigationRequest returning with thermalMitigationResult: "
11346 + thermalMitigationResult);
11347 }
11348
11349 return thermalMitigationResult;
11350 }
Hui Wang641e81c2020-10-12 12:14:23 -070011351
11352 /**
11353 * Set the GbaService Package Name that Telephony will bind to.
11354 *
11355 * @param subId The sim that the GbaService is associated with.
11356 * @param packageName The name of the package to be replaced with.
11357 * @return true if setting the GbaService to bind to succeeded, false if it did not.
11358 */
11359 @Override
11360 public boolean setBoundGbaServiceOverride(int subId, String packageName) {
11361 enforceModifyPermission();
11362
11363 final long identity = Binder.clearCallingIdentity();
11364 try {
11365 return getGbaManager(subId).overrideServicePackage(packageName);
11366 } finally {
11367 Binder.restoreCallingIdentity(identity);
11368 }
11369 }
11370
11371 /**
11372 * Return the package name of the currently bound GbaService.
11373 *
11374 * @param subId The sim that the GbaService is associated with.
11375 * @return the package name of the GbaService configuration, null if GBA is not supported.
11376 */
11377 @Override
11378 public String getBoundGbaService(int subId) {
11379 enforceReadPrivilegedPermission("getBoundGbaServicePackage");
11380
11381 final long identity = Binder.clearCallingIdentity();
11382 try {
11383 return getGbaManager(subId).getServicePackage();
11384 } finally {
11385 Binder.restoreCallingIdentity(identity);
11386 }
11387 }
11388
11389 /**
11390 * Set the release time for telephony to unbind GbaService.
11391 *
11392 * @param subId The sim that the GbaService is associated with.
11393 * @param interval The release time to unbind GbaService by millisecond.
11394 * @return true if setting the GbaService to bind to succeeded, false if it did not.
11395 */
11396 @Override
11397 public boolean setGbaReleaseTimeOverride(int subId, int interval) {
11398 enforceModifyPermission();
11399
11400 final long identity = Binder.clearCallingIdentity();
11401 try {
11402 return getGbaManager(subId).overrideReleaseTime(interval);
11403 } finally {
11404 Binder.restoreCallingIdentity(identity);
11405 }
11406 }
11407
11408 /**
11409 * Return the release time for telephony to unbind GbaService.
11410 *
11411 * @param subId The sim that the GbaService is associated with.
11412 * @return The release time to unbind GbaService by millisecond.
11413 */
11414 @Override
11415 public int getGbaReleaseTime(int subId) {
11416 enforceReadPrivilegedPermission("getGbaReleaseTime");
11417
11418 final long identity = Binder.clearCallingIdentity();
11419 try {
11420 return getGbaManager(subId).getReleaseTime();
11421 } finally {
11422 Binder.restoreCallingIdentity(identity);
11423 }
11424 }
11425
11426 private GbaManager getGbaManager(int subId) {
11427 GbaManager instance = GbaManager.getInstance(subId);
11428 if (instance == null) {
11429 String packageName = mApp.getResources().getString(R.string.config_gba_package);
11430 int releaseTime = mApp.getResources().getInteger(R.integer.config_gba_release_time);
11431 instance = GbaManager.make(mApp, subId, packageName, releaseTime);
11432 }
11433 return instance;
11434 }
Hui Wang761a6682020-10-31 05:12:53 +000011435
11436 /**
11437 * indicate whether the device and the carrier can support
11438 * RCS VoLTE single registration.
11439 */
11440 @Override
11441 public boolean isRcsVolteSingleRegistrationCapable(int subId) {
Brad Ebinger34c09a52021-02-17 23:23:21 +000011442 TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
11443 Binder.getCallingUid(), "isRcsVolteSingleRegistrationCapable",
11444 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
11445 permission.READ_PRIVILEGED_PHONE_STATE);
Hui Wang761a6682020-10-31 05:12:53 +000011446
11447 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11448 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11449 }
11450
11451 final long identity = Binder.clearCallingIdentity();
11452 try {
11453 RcsProvisioningMonitor rpm = RcsProvisioningMonitor.getInstance();
11454 if (rpm != null) {
Hui Wang67af90e2021-06-04 16:57:15 -070011455 Boolean isCapable = rpm.isRcsVolteSingleRegistrationEnabled(subId);
11456 if (isCapable != null) {
11457 return isCapable;
11458 }
Hui Wang761a6682020-10-31 05:12:53 +000011459 }
Hui Wang67af90e2021-06-04 16:57:15 -070011460 throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
11461 "service is temporarily unavailable.");
Hui Wang761a6682020-10-31 05:12:53 +000011462 } finally {
11463 Binder.restoreCallingIdentity(identity);
11464 }
11465 }
11466
11467 /**
11468 * Register RCS provisioning callback.
11469 */
11470 @Override
Hui Wang3cac7e52021-01-27 14:45:25 -080011471 public void registerRcsProvisioningCallback(int subId,
Hui Wang761a6682020-10-31 05:12:53 +000011472 IRcsConfigCallback callback) {
Brad Ebinger34c09a52021-02-17 23:23:21 +000011473 TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
Hui Wang3cac7e52021-01-27 14:45:25 -080011474 Binder.getCallingUid(), "registerRcsProvisioningCallback",
Brad Ebinger34c09a52021-02-17 23:23:21 +000011475 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
11476 permission.READ_PRIVILEGED_PHONE_STATE);
Hui Wang761a6682020-10-31 05:12:53 +000011477
11478 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11479 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11480 }
11481 if (!isImsAvailableOnDevice()) {
11482 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
11483 "IMS not available on device.");
11484 }
11485
11486 final long identity = Binder.clearCallingIdentity();
11487 try {
Hui Wang68cd3722021-01-11 20:04:53 -080011488 if (!RcsProvisioningMonitor.getInstance()
Hui Wang3cac7e52021-01-27 14:45:25 -080011489 .registerRcsProvisioningCallback(subId, callback)) {
Brad Ebinger919631e2021-06-02 17:46:35 -070011490 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
11491 "Active subscription not found.");
Hui Wang68cd3722021-01-11 20:04:53 -080011492 }
Hui Wang761a6682020-10-31 05:12:53 +000011493 } finally {
11494 Binder.restoreCallingIdentity(identity);
11495 }
11496 }
11497
11498 /**
11499 * Unregister RCS provisioning callback.
11500 */
11501 @Override
Hui Wang3cac7e52021-01-27 14:45:25 -080011502 public void unregisterRcsProvisioningCallback(int subId,
Hui Wang761a6682020-10-31 05:12:53 +000011503 IRcsConfigCallback callback) {
Brad Ebinger34c09a52021-02-17 23:23:21 +000011504 TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
Hui Wang3cac7e52021-01-27 14:45:25 -080011505 Binder.getCallingUid(), "unregisterRcsProvisioningCallback",
Brad Ebinger34c09a52021-02-17 23:23:21 +000011506 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
11507 permission.READ_PRIVILEGED_PHONE_STATE);
Hui Wang761a6682020-10-31 05:12:53 +000011508
11509 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11510 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11511 }
11512 if (!isImsAvailableOnDevice()) {
joonhunshin46b49a32022-12-21 05:33:23 +000011513 // operation failed silently
11514 Rlog.w(LOG_TAG, "IMS not available on device.");
11515 return;
Hui Wang761a6682020-10-31 05:12:53 +000011516 }
11517
11518 final long identity = Binder.clearCallingIdentity();
11519 try {
Hui Wang68cd3722021-01-11 20:04:53 -080011520 RcsProvisioningMonitor.getInstance()
Hui Wang3cac7e52021-01-27 14:45:25 -080011521 .unregisterRcsProvisioningCallback(subId, callback);
Hui Wang761a6682020-10-31 05:12:53 +000011522 } finally {
11523 Binder.restoreCallingIdentity(identity);
11524 }
11525 }
11526
11527 /**
11528 * trigger RCS reconfiguration.
11529 */
11530 public void triggerRcsReconfiguration(int subId) {
Brad Ebinger34c09a52021-02-17 23:23:21 +000011531 TelephonyPermissions.enforceAnyPermissionGranted(mApp, Binder.getCallingUid(),
11532 "triggerRcsReconfiguration",
11533 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION);
Hui Wang761a6682020-10-31 05:12:53 +000011534
11535 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11536 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11537 }
11538 if (!isImsAvailableOnDevice()) {
joonhunshin46b49a32022-12-21 05:33:23 +000011539 // ProvisioningManager can not handle ServiceSpecificException.
11540 // Throw the IllegalStateException and annotate ProvisioningManager.
11541 throw new IllegalStateException("IMS not available on device.");
Hui Wang761a6682020-10-31 05:12:53 +000011542 }
11543
11544 final long identity = Binder.clearCallingIdentity();
11545 try {
11546 RcsProvisioningMonitor.getInstance().requestReconfig(subId);
11547 } finally {
11548 Binder.restoreCallingIdentity(identity);
11549 }
11550 }
11551
11552 /**
11553 * Provide the client configuration parameters of the RCS application.
11554 */
11555 public void setRcsClientConfiguration(int subId, RcsClientConfiguration rcc) {
Brad Ebinger34c09a52021-02-17 23:23:21 +000011556 TelephonyPermissions.enforceAnyPermissionGranted(mApp, Binder.getCallingUid(),
11557 "setRcsClientConfiguration",
11558 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION);
Hui Wang761a6682020-10-31 05:12:53 +000011559
11560 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11561 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11562 }
11563 if (!isImsAvailableOnDevice()) {
11564 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
11565 "IMS not available on device.");
11566 }
11567
11568 final long identity = Binder.clearCallingIdentity();
11569
11570 try {
11571 IImsConfig configBinder = getImsConfig(getSlotIndex(subId), ImsFeature.FEATURE_RCS);
11572 if (configBinder == null) {
11573 Rlog.e(LOG_TAG, "null result for setRcsClientConfiguration");
Brad Ebinger919631e2021-06-02 17:46:35 -070011574 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
11575 "could not find the requested subscription");
Hui Wang761a6682020-10-31 05:12:53 +000011576 } else {
11577 configBinder.setRcsClientConfiguration(rcc);
11578 }
joonhunshin3e154242021-09-17 06:33:39 +000011579
11580 RcsStats.getInstance().onRcsClientProvisioningStats(subId,
11581 RCS_CLIENT_PROVISIONING_STATS__EVENT__CLIENT_PARAMS_SENT);
Hui Wang761a6682020-10-31 05:12:53 +000011582 } catch (RemoteException e) {
11583 Rlog.e(LOG_TAG, "fail to setRcsClientConfiguration " + e.getMessage());
Brad Ebinger919631e2021-06-02 17:46:35 -070011584 throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
11585 "service is temporarily unavailable.");
Hui Wang761a6682020-10-31 05:12:53 +000011586 } finally {
11587 Binder.restoreCallingIdentity(identity);
11588 }
11589 }
11590
11591 /**
Hui Wangbaaee6a2021-02-19 20:45:36 -080011592 * Enables or disables the test mode for RCS VoLTE single registration.
11593 */
11594 @Override
11595 public void setRcsSingleRegistrationTestModeEnabled(boolean enabled) {
11596 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11597 "setRcsSingleRegistrationTestModeEnabled");
11598
11599 RcsProvisioningMonitor.getInstance().setTestModeEnabled(enabled);
11600 }
11601
11602 /**
11603 * Gets the test mode for RCS VoLTE single registration.
11604 */
11605 @Override
11606 public boolean getRcsSingleRegistrationTestModeEnabled() {
11607 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11608 "getRcsSingleRegistrationTestModeEnabled");
11609
11610 return RcsProvisioningMonitor.getInstance().getTestModeEnabled();
11611 }
11612
11613 /**
Hui Wang761a6682020-10-31 05:12:53 +000011614 * Overrides the config of RCS VoLTE single registration enabled for the device.
11615 */
11616 @Override
11617 public void setDeviceSingleRegistrationEnabledOverride(String enabledStr) {
11618 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11619 "setDeviceSingleRegistrationEnabledOverride");
11620 enforceModifyPermission();
11621
11622 Boolean enabled = "NULL".equalsIgnoreCase(enabledStr) ? null
11623 : Boolean.parseBoolean(enabledStr);
11624 RcsProvisioningMonitor.getInstance().overrideDeviceSingleRegistrationEnabled(enabled);
Brad Ebinger49a72b42021-01-29 00:55:24 +000011625 mApp.imsRcsController.setDeviceSingleRegistrationSupportOverride(enabled);
Hui Wang761a6682020-10-31 05:12:53 +000011626 }
11627
11628 /**
Tyler Gunn92479152021-01-20 16:30:10 -080011629 * Sends a device to device communication message. Only usable via shell.
11630 * @param message message to send.
11631 * @param value message value.
11632 */
11633 @Override
11634 public void sendDeviceToDeviceMessage(int message, int value) {
11635 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
Tyler Gunnbabbda02021-02-10 11:05:02 -080011636 "sendDeviceToDeviceMessage");
Tyler Gunn92479152021-01-20 16:30:10 -080011637 enforceModifyPermission();
11638
11639 final long identity = Binder.clearCallingIdentity();
11640 try {
11641 TelephonyConnectionService service =
11642 TelecomAccountRegistry.getInstance(null).getTelephonyConnectionService();
11643 if (service == null) {
11644 Rlog.e(LOG_TAG, "sendDeviceToDeviceMessage: not in a call.");
11645 return;
11646 }
11647 service.sendTestDeviceToDeviceMessage(message, value);
11648 } finally {
11649 Binder.restoreCallingIdentity(identity);
11650 }
11651 }
11652
Tyler Gunnbabbda02021-02-10 11:05:02 -080011653 /**
11654 * Sets the specified device to device transport active.
11655 * @param transport The transport to set active.
11656 */
11657 @Override
11658 public void setActiveDeviceToDeviceTransport(@NonNull String transport) {
11659 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11660 "setActiveDeviceToDeviceTransport");
11661 enforceModifyPermission();
11662
11663 final long identity = Binder.clearCallingIdentity();
11664 try {
11665 TelephonyConnectionService service =
11666 TelecomAccountRegistry.getInstance(null).getTelephonyConnectionService();
11667 if (service == null) {
11668 Rlog.e(LOG_TAG, "setActiveDeviceToDeviceTransport: not in a call.");
11669 return;
11670 }
11671 service.setActiveDeviceToDeviceTransport(transport);
11672 } finally {
11673 Binder.restoreCallingIdentity(identity);
11674 }
11675 }
Tyler Gunn92479152021-01-20 16:30:10 -080011676
Tyler Gunnd4339262021-05-03 14:46:49 -070011677 @Override
11678 public void setDeviceToDeviceForceEnabled(boolean isForceEnabled) {
11679 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11680 "setDeviceToDeviceForceEnabled");
11681
11682 final long identity = Binder.clearCallingIdentity();
11683 try {
11684 Arrays.stream(PhoneFactory.getPhones()).forEach(
11685 p -> {
11686 Phone thePhone = p.getImsPhone();
11687 if (thePhone != null && thePhone instanceof ImsPhone) {
11688 ImsPhone imsPhone = (ImsPhone) thePhone;
11689 CallTracker tracker = imsPhone.getCallTracker();
11690 if (tracker != null && tracker instanceof ImsPhoneCallTracker) {
11691 ImsPhoneCallTracker imsPhoneCallTracker =
11692 (ImsPhoneCallTracker) tracker;
11693 imsPhoneCallTracker.setDeviceToDeviceForceEnabled(isForceEnabled);
11694 }
11695 }
11696 }
11697 );
11698 } finally {
11699 Binder.restoreCallingIdentity(identity);
11700 }
11701 }
11702
Tyler Gunn92479152021-01-20 16:30:10 -080011703 /**
Hui Wang761a6682020-10-31 05:12:53 +000011704 * Gets the config of RCS VoLTE single registration enabled for the device.
11705 */
11706 @Override
11707 public boolean getDeviceSingleRegistrationEnabled() {
11708 enforceReadPrivilegedPermission("getDeviceSingleRegistrationEnabled");
11709 return RcsProvisioningMonitor.getInstance().getDeviceSingleRegistrationEnabled();
11710 }
11711
11712 /**
11713 * Overrides the config of RCS VoLTE single registration enabled for the carrier/subscription.
11714 */
11715 @Override
11716 public boolean setCarrierSingleRegistrationEnabledOverride(int subId, String enabledStr) {
11717 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11718 "setCarrierSingleRegistrationEnabledOverride");
11719 enforceModifyPermission();
11720
11721 Boolean enabled = "NULL".equalsIgnoreCase(enabledStr) ? null
11722 : Boolean.parseBoolean(enabledStr);
11723 return RcsProvisioningMonitor.getInstance().overrideCarrierSingleRegistrationEnabled(
11724 subId, enabled);
11725 }
11726
11727 /**
11728 * Gets the config of RCS VoLTE single registration enabled for the carrier/subscription.
11729 */
11730 @Override
11731 public boolean getCarrierSingleRegistrationEnabled(int subId) {
11732 enforceReadPrivilegedPermission("getCarrierSingleRegistrationEnabled");
11733 return RcsProvisioningMonitor.getInstance().getCarrierSingleRegistrationEnabled(subId);
11734 }
Chiachang Wangd6d34772020-12-22 11:38:27 +080011735
11736 /**
Hui Wangb647abe2021-02-26 09:33:38 -080011737 * Overrides the ims feature validation result
11738 */
11739 @Override
11740 public boolean setImsFeatureValidationOverride(int subId, String enabledStr) {
11741 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11742 "setImsFeatureValidationOverride");
11743
11744 Boolean enabled = "NULL".equalsIgnoreCase(enabledStr) ? null
11745 : Boolean.parseBoolean(enabledStr);
11746 return RcsProvisioningMonitor.getInstance().overrideImsFeatureValidation(
11747 subId, enabled);
11748 }
11749
11750 /**
11751 * Gets the ims feature validation override value
11752 */
11753 @Override
11754 public boolean getImsFeatureValidationOverride(int subId) {
11755 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11756 "getImsFeatureValidationOverride");
11757 return RcsProvisioningMonitor.getInstance().getImsFeatureValidationOverride(subId);
11758 }
11759
11760 /**
Chiachang Wangd6d34772020-12-22 11:38:27 +080011761 * Get the mobile provisioning url that is used to launch a browser to allow users to manage
11762 * their mobile plan.
11763 */
11764 @Override
11765 public String getMobileProvisioningUrl() {
11766 enforceReadPrivilegedPermission("getMobileProvisioningUrl");
11767 final long identity = Binder.clearCallingIdentity();
11768 try {
11769 return getDefaultPhone().getMobileProvisioningUrl();
11770 } finally {
11771 Binder.restoreCallingIdentity(identity);
11772 }
11773 }
Rambo Wanga5cc9b72021-01-07 10:51:54 -080011774
James.cf Linbcdf8b32021-01-14 16:44:13 +080011775 /**
calvinpane4a8a1d2021-01-25 13:51:18 +080011776 * Get the EAB contact from the EAB database.
11777 */
11778 @Override
11779 public String getContactFromEab(String contact) {
11780 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getContactFromEab");
11781 enforceModifyPermission();
11782 final long identity = Binder.clearCallingIdentity();
11783 try {
11784 return EabUtil.getContactFromEab(getDefaultPhone().getContext(), contact);
11785 } finally {
11786 Binder.restoreCallingIdentity(identity);
11787 }
11788 }
11789
11790 /**
Calvin Pana1434322021-07-01 19:27:01 +080011791 * Get the EAB capability from the EAB database.
11792 */
11793 @Override
11794 public String getCapabilityFromEab(String contact) {
11795 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getCapabilityFromEab");
11796 enforceModifyPermission();
11797 final long identity = Binder.clearCallingIdentity();
11798 try {
11799 return EabUtil.getCapabilityFromEab(getDefaultPhone().getContext(), contact);
11800 } finally {
11801 Binder.restoreCallingIdentity(identity);
11802 }
11803 }
11804
11805 /**
James.cf Linbcdf8b32021-01-14 16:44:13 +080011806 * Remove the EAB contacts from the EAB database.
11807 */
11808 @Override
11809 public int removeContactFromEab(int subId, String contacts) {
11810 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "removeCapabilitiesFromEab");
11811 enforceModifyPermission();
11812 final long identity = Binder.clearCallingIdentity();
11813 try {
11814 return EabUtil.removeContactFromEab(subId, contacts, getDefaultPhone().getContext());
11815 } finally {
11816 Binder.restoreCallingIdentity(identity);
11817 }
11818 }
11819
Rambo Wanga5cc9b72021-01-07 10:51:54 -080011820 @Override
James.cf Lin4b784aa2021-01-31 03:25:15 +080011821 public boolean getDeviceUceEnabled() {
11822 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getDeviceUceEnabled");
11823 final long identity = Binder.clearCallingIdentity();
11824 try {
11825 return mApp.getDeviceUceEnabled();
11826 } finally {
11827 Binder.restoreCallingIdentity(identity);
11828 }
11829 }
11830
11831 @Override
11832 public void setDeviceUceEnabled(boolean isEnabled) {
11833 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setDeviceUceEnabled");
11834 final long identity = Binder.clearCallingIdentity();
11835 try {
11836 mApp.setDeviceUceEnabled(isEnabled);
11837 } finally {
11838 Binder.restoreCallingIdentity(identity);
11839 }
11840 }
11841
Brad Ebinger14d467f2021-02-12 06:18:28 +000011842 /**
11843 * Add new feature tags to the Set used to calculate the capabilities in PUBLISH.
11844 * @return current RcsContactUceCapability instance that will be used for PUBLISH.
11845 */
11846 // Used for SHELL command only right now.
11847 @Override
11848 public RcsContactUceCapability addUceRegistrationOverrideShell(int subId,
11849 List<String> featureTags) {
11850 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11851 "addUceRegistrationOverrideShell");
11852 final long identity = Binder.clearCallingIdentity();
11853 try {
11854 return mApp.imsRcsController.addUceRegistrationOverrideShell(subId,
11855 new ArraySet<>(featureTags));
11856 } catch (ImsException e) {
11857 throw new ServiceSpecificException(e.getCode(), e.getMessage());
11858 } finally {
11859 Binder.restoreCallingIdentity(identity);
11860 }
11861 }
11862
11863 /**
11864 * Remove existing feature tags to the Set used to calculate the capabilities in PUBLISH.
11865 * @return current RcsContactUceCapability instance that will be used for PUBLISH.
11866 */
11867 // Used for SHELL command only right now.
11868 @Override
11869 public RcsContactUceCapability removeUceRegistrationOverrideShell(int subId,
11870 List<String> featureTags) {
11871 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11872 "removeUceRegistrationOverrideShell");
11873 final long identity = Binder.clearCallingIdentity();
11874 try {
11875 return mApp.imsRcsController.removeUceRegistrationOverrideShell(subId,
11876 new ArraySet<>(featureTags));
11877 } catch (ImsException e) {
11878 throw new ServiceSpecificException(e.getCode(), e.getMessage());
11879 } finally {
11880 Binder.restoreCallingIdentity(identity);
11881 }
11882 }
11883
11884 /**
11885 * Clear all overrides in the Set used to calculate the capabilities in PUBLISH.
11886 * @return current RcsContactUceCapability instance that will be used for PUBLISH.
11887 */
11888 // Used for SHELL command only right now.
11889 @Override
11890 public RcsContactUceCapability clearUceRegistrationOverrideShell(int subId) {
11891 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11892 "clearUceRegistrationOverrideShell");
11893 final long identity = Binder.clearCallingIdentity();
11894 try {
11895 return mApp.imsRcsController.clearUceRegistrationOverrideShell(subId);
11896 } catch (ImsException e) {
11897 throw new ServiceSpecificException(e.getCode(), e.getMessage());
11898 } finally {
11899 Binder.restoreCallingIdentity(identity);
11900 }
11901 }
11902
11903 /**
11904 * @return current RcsContactUceCapability instance that will be used for PUBLISH.
11905 */
11906 // Used for SHELL command only right now.
11907 @Override
11908 public RcsContactUceCapability getLatestRcsContactUceCapabilityShell(int subId) {
11909 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11910 "getLatestRcsContactUceCapabilityShell");
11911 final long identity = Binder.clearCallingIdentity();
11912 try {
11913 return mApp.imsRcsController.getLatestRcsContactUceCapabilityShell(subId);
11914 } catch (ImsException e) {
11915 throw new ServiceSpecificException(e.getCode(), e.getMessage());
11916 } finally {
11917 Binder.restoreCallingIdentity(identity);
11918 }
11919 }
11920
11921 /**
11922 * Returns the last PIDF XML sent to the network during the last PUBLISH or "none" if the
11923 * device does not have an active PUBLISH.
11924 */
11925 // Used for SHELL command only right now.
11926 @Override
11927 public String getLastUcePidfXmlShell(int subId) {
11928 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "uceGetLastPidfXml");
11929 final long identity = Binder.clearCallingIdentity();
11930 try {
11931 return mApp.imsRcsController.getLastUcePidfXmlShell(subId);
11932 } catch (ImsException e) {
11933 throw new ServiceSpecificException(e.getCode(), e.getMessage());
11934 } finally {
11935 Binder.restoreCallingIdentity(identity);
11936 }
11937 }
11938
James.cf Line8713a42021-04-29 16:04:26 +080011939 /**
11940 * Remove UCE requests cannot be sent to the network status.
11941 */
11942 // Used for SHELL command only right now.
11943 @Override
11944 public boolean removeUceRequestDisallowedStatus(int subId) {
11945 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "uceRemoveDisallowedStatus");
11946 final long identity = Binder.clearCallingIdentity();
11947 try {
11948 return mApp.imsRcsController.removeUceRequestDisallowedStatus(subId);
11949 } catch (ImsException e) {
11950 throw new ServiceSpecificException(e.getCode(), e.getMessage());
11951 } finally {
11952 Binder.restoreCallingIdentity(identity);
11953 }
11954 }
11955
James.cf Lin18bb9002021-05-25 01:37:38 +080011956 /**
11957 * Remove UCE requests cannot be sent to the network status.
11958 */
11959 // Used for SHELL command only.
11960 @Override
11961 public boolean setCapabilitiesRequestTimeout(int subId, long timeoutAfterMs) {
11962 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setCapRequestTimeout");
11963 final long identity = Binder.clearCallingIdentity();
11964 try {
11965 return mApp.imsRcsController.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
11966 } catch (ImsException e) {
11967 throw new ServiceSpecificException(e.getCode(), e.getMessage());
11968 } finally {
11969 Binder.restoreCallingIdentity(identity);
11970 }
11971 }
Brad Ebinger14d467f2021-02-12 06:18:28 +000011972
James.cf Lin4b784aa2021-01-31 03:25:15 +080011973 @Override
Rambo Wanga5cc9b72021-01-07 10:51:54 -080011974 public void setSignalStrengthUpdateRequest(int subId, SignalStrengthUpdateRequest request,
11975 String callingPackage) {
11976 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
11977 mApp, subId, "setSignalStrengthUpdateRequest");
11978
11979 final int callingUid = Binder.getCallingUid();
11980 // Verify that tha callingPackage belongs to the calling UID
11981 mApp.getSystemService(AppOpsManager.class)
11982 .checkPackage(callingUid, callingPackage);
11983
Rambo Wang3607f502021-02-01 21:51:40 -080011984 validateSignalStrengthUpdateRequest(mApp, request, callingUid);
Rambo Wanga5cc9b72021-01-07 10:51:54 -080011985
11986 final long identity = Binder.clearCallingIdentity();
11987 try {
11988 Object result = sendRequest(CMD_SET_SIGNAL_STRENGTH_UPDATE_REQUEST,
11989 new Pair<Integer, SignalStrengthUpdateRequest>(callingUid, request), subId);
11990
11991 if (result instanceof IllegalStateException) {
11992 throw (IllegalStateException) result;
11993 }
11994 } finally {
11995 Binder.restoreCallingIdentity(identity);
11996 }
11997 }
11998
11999 @Override
12000 public void clearSignalStrengthUpdateRequest(int subId, SignalStrengthUpdateRequest request,
12001 String callingPackage) {
12002 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
12003 mApp, subId, "clearSignalStrengthUpdateRequest");
12004
12005 final int callingUid = Binder.getCallingUid();
12006 // Verify that tha callingPackage belongs to the calling UID
12007 mApp.getSystemService(AppOpsManager.class)
12008 .checkPackage(callingUid, callingPackage);
12009
12010 final long identity = Binder.clearCallingIdentity();
12011 try {
12012 Object result = sendRequest(CMD_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST,
12013 new Pair<Integer, SignalStrengthUpdateRequest>(callingUid, request), subId);
12014
12015 if (result instanceof IllegalStateException) {
12016 throw (IllegalStateException) result;
12017 }
12018 } finally {
12019 Binder.restoreCallingIdentity(identity);
12020 }
12021 }
12022
Rambo Wang3607f502021-02-01 21:51:40 -080012023 private static void validateSignalStrengthUpdateRequest(Context context,
12024 SignalStrengthUpdateRequest request, int callingUid) {
Rambo Wanga5cc9b72021-01-07 10:51:54 -080012025 if (callingUid == Process.PHONE_UID || callingUid == Process.SYSTEM_UID) {
12026 // phone/system process do not have further restriction on request
12027 return;
12028 }
12029
12030 // Applications has restrictions on how to use the request:
Rambo Wang3607f502021-02-01 21:51:40 -080012031 // Non-system callers need permission to set mIsSystemThresholdReportingRequestedWhileIdle
Rambo Wanga5cc9b72021-01-07 10:51:54 -080012032 if (request.isSystemThresholdReportingRequestedWhileIdle()) {
Rambo Wang3607f502021-02-01 21:51:40 -080012033 context.enforceCallingOrSelfPermission(
12034 android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH,
12035 "validateSignalStrengthUpdateRequest");
Rambo Wanga5cc9b72021-01-07 10:51:54 -080012036 }
12037
12038 for (SignalThresholdInfo info : request.getSignalThresholdInfos()) {
Nagendra Prasad Nagarle Basavarajufee544c2022-12-07 16:34:52 +000012039 // Only system caller can set mHysteresisMs/mIsEnabled.
Rambo Wanga5cc9b72021-01-07 10:51:54 -080012040 if (info.getHysteresisMs() != SignalThresholdInfo.HYSTERESIS_MS_DISABLED
Rambo Wanga5cc9b72021-01-07 10:51:54 -080012041 || info.isEnabled()) {
12042 throw new IllegalArgumentException(
12043 "Only system can set hide fields in SignalThresholdInfo");
12044 }
12045
12046 // Thresholds length for each RAN need in range. This has been validated in
12047 // SignalThresholdInfo#Builder#setThreshold. Here we prevent apps calling hide method
12048 // setThresholdUnlimited (e.g. through reflection) with too short or too long thresholds
12049 final int[] thresholds = info.getThresholds();
12050 Objects.requireNonNull(thresholds);
12051 if (thresholds.length < SignalThresholdInfo.getMinimumNumberOfThresholdsAllowed()
12052 || thresholds.length
12053 > SignalThresholdInfo.getMaximumNumberOfThresholdsAllowed()) {
12054 throw new IllegalArgumentException(
12055 "thresholds length is out of range: " + thresholds.length);
12056 }
12057 }
12058 }
SongFerngWang8236caa2021-01-17 21:51:44 +080012059
12060 /**
12061 * Gets the current phone capability.
12062 *
12063 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
12064 * @return the PhoneCapability which describes the data connection capability of modem.
12065 * It's used to evaluate possible phone config change, for example from single
12066 * SIM device to multi-SIM device.
12067 */
12068 @Override
12069 public PhoneCapability getPhoneCapability() {
12070 enforceReadPrivilegedPermission("getPhoneCapability");
12071 final long identity = Binder.clearCallingIdentity();
12072 try {
12073 return mPhoneConfigurationManager.getCurrentPhoneCapability();
12074 } finally {
12075 Binder.restoreCallingIdentity(identity);
12076 }
12077 }
Michele Berionne5e411512020-11-13 02:36:59 +000012078
12079 /**
12080 * Prepare TelephonyManager for an unattended reboot. The reboot is
12081 * required to be done shortly after the API is invoked.
12082 */
12083 @Override
12084 @TelephonyManager.PrepareUnattendedRebootResult
12085 public int prepareForUnattendedReboot() {
Rafael Higuera Silvad9630642021-09-20 15:32:01 +000012086 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Michele Berionne5e411512020-11-13 02:36:59 +000012087 enforceRebootPermission();
12088
12089 final long identity = Binder.clearCallingIdentity();
12090 try {
Rafael Higuera Silvad9630642021-09-20 15:32:01 +000012091 return (int) sendRequest(CMD_PREPARE_UNATTENDED_REBOOT, null, workSource);
Michele Berionne5e411512020-11-13 02:36:59 +000012092 } finally {
12093 Binder.restoreCallingIdentity(identity);
12094 }
12095 }
Hongbo Zeng156aa4a2021-02-08 21:50:28 +080012096
12097 /**
12098 * Request to get the current slicing configuration including URSP rules and
12099 * NSSAIs (configured, allowed and rejected).
12100 *
12101 * Requires carrier privileges or READ_PRIVILEGED_PHONE_STATE permission.
12102 */
12103 @Override
12104 public void getSlicingConfig(ResultReceiver callback) {
Hongbo Zeng1b2063d2022-02-21 01:33:03 +000012105 TelephonyPermissions
12106 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
12107 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, "getSlicingConfig");
Hongbo Zeng156aa4a2021-02-08 21:50:28 +080012108
12109 final long identity = Binder.clearCallingIdentity();
12110 try {
12111 Phone phone = getDefaultPhone();
12112 sendRequestAsync(CMD_GET_SLICING_CONFIG, callback, phone, null);
12113 } finally {
12114 Binder.restoreCallingIdentity(identity);
12115 }
12116 }
Hunsuk Choi3b742d62021-10-25 19:48:34 +000012117
12118 /**
Sarah Chin2ec39f62022-08-31 17:03:26 -070012119 * Check whether the given premium capability is available for purchase from the carrier.
12120 *
12121 * @param capability The premium capability to check.
12122 * @param subId The subId to check the premium capability for.
12123 *
12124 * @return Whether the given premium capability is available to purchase.
12125 */
12126 @Override
12127 public boolean isPremiumCapabilityAvailableForPurchase(int capability, int subId) {
12128 if (!TelephonyPermissions.checkCallingOrSelfReadNonDangerousPhoneStateNoThrow(
12129 mApp, "isPremiumCapabilityAvailableForPurchase")) {
12130 log("Premium capability "
12131 + TelephonyManager.convertPremiumCapabilityToString(capability)
12132 + " is not available for purchase due to missing permissions.");
12133 throw new SecurityException("isPremiumCapabilityAvailableForPurchase requires "
12134 + "permission READ_BASIC_PHONE_STATE.");
12135 }
12136
12137 Phone phone = getPhone(subId);
Thomas Nguyen7216ed62022-11-29 16:45:31 -080012138 if (phone == null) {
12139 loge("isPremiumCapabilityAvailableForPurchase: phone is null, subId=" + subId);
12140 return false;
12141 }
Sarah Chin2ec39f62022-08-31 17:03:26 -070012142 final long identity = Binder.clearCallingIdentity();
12143 try {
Sarah Chin46355ba2022-11-01 23:51:16 -070012144 return SlicePurchaseController.getInstance(phone)
Sarah Chin2ec39f62022-08-31 17:03:26 -070012145 .isPremiumCapabilityAvailableForPurchase(capability);
12146 } finally {
12147 Binder.restoreCallingIdentity(identity);
12148 }
12149 }
12150
12151 /**
12152 * Purchase the given premium capability from the carrier.
12153 *
12154 * @param capability The premium capability to purchase.
12155 * @param callback The result of the purchase request.
12156 * @param subId The subId to purchase the premium capability for.
12157 */
12158 @Override
12159 public void purchasePremiumCapability(int capability, IIntegerConsumer callback, int subId) {
12160 log("purchasePremiumCapability: capability="
12161 + TelephonyManager.convertPremiumCapabilityToString(capability) + ", caller="
12162 + getCurrentPackageName());
12163
12164 if (!TelephonyPermissions.checkCallingOrSelfReadNonDangerousPhoneStateNoThrow(
12165 mApp, "purchasePremiumCapability")) {
12166 log("purchasePremiumCapability "
12167 + TelephonyManager.convertPremiumCapabilityToString(capability)
12168 + " failed due to missing permissions.");
12169 throw new SecurityException("purchasePremiumCapability requires permission "
12170 + "READ_BASIC_PHONE_STATE.");
Sarah Chin532d6bb2022-12-28 22:50:43 -080012171 } else if (!TelephonyPermissions.checkInternetPermissionNoThrow(
12172 mApp, "purchasePremiumCapability")) {
12173 log("purchasePremiumCapability "
12174 + TelephonyManager.convertPremiumCapabilityToString(capability)
12175 + " failed due to missing permissions.");
12176 throw new SecurityException("purchasePremiumCapability requires permission INTERNET.");
Sarah Chin2ec39f62022-08-31 17:03:26 -070012177 }
12178
12179 Phone phone = getPhone(subId);
Sarah Chin19694112022-12-06 15:41:37 -080012180 if (phone == null) {
12181 try {
12182 int result = TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_REQUEST_FAILED;
12183 callback.accept(result);
12184 loge("purchasePremiumCapability: phone is null, subId=" + subId);
12185 } catch (RemoteException e) {
12186 String logStr = "Purchase premium capability "
12187 + TelephonyManager.convertPremiumCapabilityToString(capability)
12188 + " failed due to RemoteException handling null phone: " + e;
12189 if (DBG) log(logStr);
12190 AnomalyReporter.reportAnomaly(
12191 UUID.fromString(PURCHASE_PREMIUM_CAPABILITY_ERROR_UUID), logStr);
12192 }
12193 return;
12194 }
Sarah Chin532d6bb2022-12-28 22:50:43 -080012195
12196 String callingProcess;
Sarah Chin71b3a852022-09-28 15:54:19 -070012197 try {
Sarah Chin532d6bb2022-12-28 22:50:43 -080012198 callingProcess = mApp.getPackageManager().getApplicationInfo(
12199 getCurrentPackageName(), 0).processName;
Sarah Chin71b3a852022-09-28 15:54:19 -070012200 } catch (PackageManager.NameNotFoundException e) {
Sarah Chin532d6bb2022-12-28 22:50:43 -080012201 callingProcess = getCurrentPackageName();
Sarah Chin71b3a852022-09-28 15:54:19 -070012202 }
Sarah Chin532d6bb2022-12-28 22:50:43 -080012203
12204 boolean isVisible = false;
12205 ActivityManager am = mApp.getSystemService(ActivityManager.class);
12206 if (am != null) {
12207 List<ActivityManager.RunningAppProcessInfo> processes = am.getRunningAppProcesses();
12208 if (processes != null) {
12209 for (ActivityManager.RunningAppProcessInfo process : processes) {
12210 log("purchasePremiumCapability: process " + process.processName
12211 + "has importance " + process.importance);
12212 if (process.processName.equals(callingProcess) && process.importance
12213 <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
12214 isVisible = true;
12215 break;
12216 }
12217 }
12218 }
12219 }
12220
12221 if (!isVisible) {
12222 try {
12223 int result = TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_FOREGROUND;
12224 callback.accept(result);
12225 loge("purchasePremiumCapability: " + callingProcess + " is not in the foreground.");
12226 } catch (RemoteException e) {
12227 String logStr = "Purchase premium capability "
12228 + TelephonyManager.convertPremiumCapabilityToString(capability)
12229 + " failed due to RemoteException handling background application: " + e;
12230 if (DBG) log(logStr);
12231 AnomalyReporter.reportAnomaly(
12232 UUID.fromString(PURCHASE_PREMIUM_CAPABILITY_ERROR_UUID), logStr);
12233 }
12234 return;
12235 }
12236
Sarah Chin71b3a852022-09-28 15:54:19 -070012237 sendRequestAsync(CMD_PURCHASE_PREMIUM_CAPABILITY,
Sarah Chinb8218c22023-01-04 13:35:29 -080012238 new PurchasePremiumCapabilityArgument(capability, callback), phone, null);
Sarah Chin2ec39f62022-08-31 17:03:26 -070012239 }
12240
12241 /**
Hunsuk Choi3b742d62021-10-25 19:48:34 +000012242 * Register an IMS connection state callback
12243 */
12244 @Override
Hunsuk Choi89bd22c2021-11-01 13:04:54 +000012245 public void registerImsStateCallback(int subId, int feature, IImsStateCallback cb,
12246 String callingPackage) {
Hunsuk Choi3b742d62021-10-25 19:48:34 +000012247 if (feature == ImsFeature.FEATURE_MMTEL) {
12248 // ImsMmTelManager
12249 // The following also checks READ_PRIVILEGED_PHONE_STATE.
12250 TelephonyPermissions
12251 .enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
12252 mApp, subId, "registerImsStateCallback");
12253 } else if (feature == ImsFeature.FEATURE_RCS) {
12254 // ImsRcsManager or SipDelegateManager
12255 TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
12256 Binder.getCallingUid(), "registerImsStateCallback",
12257 Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
12258 Manifest.permission.READ_PRECISE_PHONE_STATE,
12259 Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE,
12260 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION);
12261 }
12262
12263 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
12264 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
12265 "IMS not available on device.");
12266 }
12267
12268 if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
12269 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
12270 }
12271
12272 ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
12273 if (controller == null) {
12274 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
12275 "IMS not available on device.");
12276 }
12277
Hunsuk Choi89bd22c2021-11-01 13:04:54 +000012278 if (callingPackage == null) {
12279 callingPackage = getCurrentPackageName();
12280 }
12281
Hunsuk Choi3b742d62021-10-25 19:48:34 +000012282 final long token = Binder.clearCallingIdentity();
12283 try {
12284 int slotId = getSlotIndexOrException(subId);
Hunsuk Choi89bd22c2021-11-01 13:04:54 +000012285 controller.registerImsStateCallback(subId, feature, cb, callingPackage);
Hunsuk Choi3b742d62021-10-25 19:48:34 +000012286 } catch (ImsException e) {
12287 throw new ServiceSpecificException(e.getCode());
12288 } finally {
12289 Binder.restoreCallingIdentity(token);
12290 }
12291 }
12292
12293 /**
12294 * Unregister an IMS connection state callback
12295 */
12296 @Override
12297 public void unregisterImsStateCallback(IImsStateCallback cb) {
12298 final long token = Binder.clearCallingIdentity();
12299 ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
12300 if (controller == null) {
12301 return;
12302 }
12303 try {
12304 controller.unregisterImsStateCallback(cb);
12305 } finally {
12306 Binder.restoreCallingIdentity(token);
12307 }
12308 }
Sooraj Sasindranfae41b32021-10-26 02:10:05 -070012309
12310 /**
12311 * @return {@CellIdentity} last known cell identity {@CellIdentity}.
12312 *
12313 * Require {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and
12314 * com.android.phone.permission.ACCESS_LAST_KNOWN_CELL_ID, otherwise throws
12315 * SecurityException.
12316 * If there is current registered network this value will be same as the registered cell
12317 * identity. If the device goes out of service the previous cell identity is cached and
12318 * will be returned. If the cache age of the Cell identity is more than 24 hours
12319 * it will be cleared and null will be returned.
12320 *
12321 */
12322 @Override
12323 public @Nullable CellIdentity getLastKnownCellIdentity(int subId, String callingPackage,
12324 String callingFeatureId) {
12325 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
12326 LocationAccessPolicy.LocationPermissionResult fineLocationResult =
12327 LocationAccessPolicy.checkLocationPermission(mApp,
12328 new LocationAccessPolicy.LocationPermissionQuery.Builder()
12329 .setCallingPackage(callingPackage)
12330 .setCallingFeatureId(callingFeatureId)
12331 .setCallingPid(Binder.getCallingPid())
12332 .setCallingUid(Binder.getCallingUid())
12333 .setMethod("getLastKnownCellIdentity")
12334 .setLogAsInfo(true)
12335 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
12336 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
12337 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
12338 .build());
12339
12340 boolean hasFinePermission =
12341 fineLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
12342 if (!hasFinePermission
12343 || !TelephonyPermissions.checkLastKnownCellIdAccessPermission(mApp)) {
12344 throw new SecurityException("getLastKnownCellIdentity need ACCESS_FINE_LOCATION "
Rambo Wang918993a2022-04-27 09:08:36 -070012345 + "and ACCESS_LAST_KNOWN_CELL_ID permission.");
Sooraj Sasindranfae41b32021-10-26 02:10:05 -070012346 }
12347
12348 final long identity = Binder.clearCallingIdentity();
12349 try {
12350 Phone phone = getPhone(subId);
12351 if (phone == null) return null;
12352 ServiceStateTracker sst = phone.getServiceStateTracker();
12353 if (sst == null) return null;
12354 return sst.getLastKnownCellIdentity();
12355 } finally {
12356 Binder.restoreCallingIdentity(identity);
12357 }
12358 }
Jack Yu4c0a5502021-12-03 23:58:26 -080012359
jimsun3b9ccac2021-10-26 15:01:23 +080012360 /**
12361 * Sets the modem service class Name that Telephony will bind to.
12362 *
12363 * @param serviceName The class name of the modem service.
12364 * @return true if the operation is succeed, otherwise false.
12365 */
12366 public boolean setModemService(String serviceName) {
12367 Log.d(LOG_TAG, "setModemService - " + serviceName);
12368 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setModemService");
12369 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012370 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
12371 "setModemService");
jimsun3b9ccac2021-10-26 15:01:23 +080012372 return mPhoneConfigurationManager.setModemService(serviceName);
12373 }
12374
12375 /**
12376 * Return the class name of the currently bounded modem service.
12377 *
12378 * @return the class name of the modem service.
12379 */
12380 public String getModemService() {
12381 String result;
12382 Log.d(LOG_TAG, "getModemService");
12383 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getModemService");
12384 TelephonyPermissions
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012385 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
jimsun3b9ccac2021-10-26 15:01:23 +080012386 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
12387 "getModemService");
12388 result = mPhoneConfigurationManager.getModemService();
12389 Log.d(LOG_TAG, "result = " + result);
12390 return result;
12391 }
Hunter Knepshield2b076fa2022-01-19 02:26:22 -080012392
12393 @Override
12394 public void setVoiceServiceStateOverride(int subId, boolean hasService, String callingPackage) {
12395 // Only telecom (and shell, for CTS purposes) is allowed to call this method.
12396 mApp.enforceCallingOrSelfPermission(
12397 permission.BIND_TELECOM_CONNECTION_SERVICE, "setVoiceServiceStateOverride");
12398 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
12399
12400 final long identity = Binder.clearCallingIdentity();
12401 try {
12402 Phone phone = getPhone(subId);
12403 if (phone == null) return;
Grant Menke63ade122023-01-20 14:31:54 -080012404 Log.i(LOG_TAG, "setVoiceServiceStateOverride: subId=" + subId + ", phone=" + phone
12405 + ", hasService=" + hasService + ", callingPackage=" + callingPackage);
Hunter Knepshield2b076fa2022-01-19 02:26:22 -080012406 phone.setVoiceServiceStateOverride(hasService);
12407 } finally {
12408 Binder.restoreCallingIdentity(identity);
12409 }
12410 }
Muralidhar Reddy4e5a8012022-05-11 14:49:00 +000012411
12412 /**
12413 * set removable eSIM as default eUICC.
12414 *
12415 * @hide
12416 */
12417 @Override
12418 public void setRemovableEsimAsDefaultEuicc(boolean isDefault, String callingPackage) {
12419 enforceModifyPermission();
12420 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
12421
12422 final long identity = Binder.clearCallingIdentity();
12423 try {
12424 UiccController.getInstance().setRemovableEsimAsDefaultEuicc(isDefault);
12425 } finally {
12426 Binder.restoreCallingIdentity(identity);
12427 }
12428 }
12429
12430 /**
12431 * Returns whether the removable eSIM is default eUICC or not.
12432 *
12433 * @hide
12434 */
12435 @Override
12436 public boolean isRemovableEsimDefaultEuicc(String callingPackage) {
12437 enforceReadPrivilegedPermission("isRemovableEsimDefaultEuicc");
12438 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
12439
12440 final long identity = Binder.clearCallingIdentity();
12441 try {
12442 return UiccController.getInstance().isRemovableEsimDefaultEuicc();
12443 } finally {
12444 Binder.restoreCallingIdentity(identity);
12445 }
12446 }
12447
Aishwarya Mallampatifbc70d32022-11-10 20:33:02 +000012448 /**
12449 * Get the component name of the default app to direct respond-via-message intent for the
12450 * user associated with this subscription, update the cache if there is no respond-via-message
12451 * application currently configured for this user.
12452 * @return component name of the app and class to direct Respond Via Message intent to, or
12453 * {@code null} if the functionality is not supported.
12454 * @hide
12455 */
12456 @Override
12457 public @Nullable ComponentName getDefaultRespondViaMessageApplication(int subId,
12458 boolean updateIfNeeded) {
12459 enforceInteractAcrossUsersPermission("getDefaultRespondViaMessageApplication");
Muralidhar Reddy4e5a8012022-05-11 14:49:00 +000012460
Aishwarya Mallampati5e581e12023-01-17 21:57:06 +000012461 Context context = getPhoneFromSubIdOrDefault(subId).getContext();
12462
Aishwarya Mallampatifbc70d32022-11-10 20:33:02 +000012463 UserHandle userHandle = null;
12464 final long identity = Binder.clearCallingIdentity();
12465 try {
12466 userHandle = TelephonyUtils.getSubscriptionUserHandle(context, subId);
12467 } finally {
12468 Binder.restoreCallingIdentity(identity);
12469 }
12470 return SmsApplication.getDefaultRespondViaMessageApplicationAsUser(context,
12471 updateIfNeeded, userHandle);
12472 }
Jack Yuf5badd92022-12-08 00:50:53 -080012473
12474 /**
Gil Cukierman1c0eb932022-12-06 22:28:24 +000012475 * Set whether the device is able to connect with null ciphering or integrity
12476 * algorithms. This is a global setting and will apply to all active subscriptions
12477 * and all new subscriptions after this.
12478 *
12479 * @param enabled when true, null cipher and integrity algorithms are allowed.
12480 * @hide
12481 */
12482 @Override
12483 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
12484 public void setNullCipherAndIntegrityEnabled(boolean enabled) {
12485 enforceModifyPermission();
12486 checkForNullCipherAndIntegritySupport();
12487
12488 // Persist the state of our preference. Each GsmCdmaPhone instance is responsible
12489 // for listening to these preference changes and applying them immediately.
12490 SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
12491 editor.putBoolean(Phone.PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED, enabled);
12492 editor.apply();
12493
12494 for (Phone phone: PhoneFactory.getPhones()) {
12495 phone.handleNullCipherEnabledChange();
12496 }
12497 }
12498
12499
12500 /**
12501 * Get whether the device is able to connect with null ciphering or integrity
12502 * algorithms. Note that this retrieves the phone-global preference and not
12503 * the state of the radio.
12504 *
12505 * @throws SecurityException if {@link permission#MODIFY_PHONE_STATE} is not satisfied
12506 * @throws UnsupportedOperationException if the device does not support the minimum HAL
12507 * version for this feature.
12508 * @hide
12509 */
12510 @Override
12511 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
12512 public boolean isNullCipherAndIntegrityPreferenceEnabled() {
12513 enforceReadPermission();
12514 checkForNullCipherAndIntegritySupport();
12515 return getDefaultPhone().getNullCipherAndIntegrityEnabledPreference();
12516 }
12517
12518 private void checkForNullCipherAndIntegritySupport() {
12519 if (getHalVersion(HAL_SERVICE_NETWORK) < MIN_NULL_CIPHER_AND_INTEGRITY_VERSION) {
12520 throw new UnsupportedOperationException(
12521 "Null cipher and integrity operations require HAL 2.1 or above");
12522 }
Gil Cukierman92cc7db2023-01-06 19:25:53 +000012523 if (!getDefaultPhone().isNullCipherAndIntegritySupported()) {
12524 throw new UnsupportedOperationException(
12525 "Null cipher and integrity operations unsupported by modem");
12526 }
Gil Cukierman1c0eb932022-12-06 22:28:24 +000012527 }
12528
12529 /**
Jack Yuf5badd92022-12-08 00:50:53 -080012530 * Get the SIM state for the slot index.
12531 * For Remote-SIMs, this method returns {@link IccCardConstants.State#UNKNOWN}
12532 *
12533 * @return SIM state as the ordinal of {@link IccCardConstants.State}
12534 */
12535 @Override
12536 @SimState
12537 public int getSimStateForSlotIndex(int slotIndex) {
12538 IccCardConstants.State simState;
12539 if (slotIndex < 0) {
12540 simState = IccCardConstants.State.UNKNOWN;
12541 } else {
12542 Phone phone = null;
12543 try {
12544 phone = PhoneFactory.getPhone(slotIndex);
12545 } catch (IllegalStateException e) {
12546 // ignore
12547 }
12548 if (phone == null) {
12549 simState = IccCardConstants.State.UNKNOWN;
12550 } else {
12551 IccCard icc = phone.getIccCard();
12552 if (icc == null) {
12553 simState = IccCardConstants.State.UNKNOWN;
12554 } else {
12555 simState = icc.getState();
12556 }
12557 }
12558 }
12559 return simState.ordinal();
12560 }
Hui Wang9b5793a2022-12-05 14:38:06 -060012561
12562 /**
12563 * Get current cell broadcast ranges.
12564 */
12565 @Override
12566 @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS)
12567 public List<CellBroadcastIdRange> getCellBroadcastIdRanges(int subId) {
12568 mApp.enforceCallingPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS,
12569 "getCellBroadcastIdRanges");
12570 final long identity = Binder.clearCallingIdentity();
12571 try {
12572 return getPhone(subId).getCellBroadcastIdRanges();
12573 } finally {
12574 Binder.restoreCallingIdentity(identity);
12575 }
12576 }
12577
12578 /**
12579 * Set reception of cell broadcast messages with the list of the given ranges
12580 *
12581 * @param ranges the list of {@link CellBroadcastIdRange} to be enabled
12582 */
12583 @Override
12584 @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS)
12585 public void setCellBroadcastIdRanges(int subId, @NonNull List<CellBroadcastIdRange> ranges,
12586 @Nullable IIntegerConsumer callback) {
12587 mApp.enforceCallingPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS,
12588 "setCellBroadcastIdRanges");
12589 final long identity = Binder.clearCallingIdentity();
12590 try {
12591 Phone phone = getPhoneFromSubId(subId);
12592 if (DBG) {
12593 log("setCellBroadcastIdRanges for subId :" + subId + ", phone:" + phone);
12594 }
12595 phone.setCellBroadcastIdRanges(ranges, result -> {
12596 if (callback != null) {
12597 try {
12598 callback.accept(result);
12599 } catch (RemoteException e) {
12600 Log.w(LOG_TAG, "setCellBroadcastIdRanges: callback not available.");
12601 }
12602 }
12603 });
12604 } finally {
12605 Binder.restoreCallingIdentity(identity);
12606 }
12607 }
Hunsuk Choi42cc62a2022-10-16 06:03:40 +000012608
12609 /**
12610 * Returns whether the device supports the domain selection service.
12611 *
12612 * @return {@code true} if the device supports the domain selection service.
12613 */
12614 @Override
12615 public boolean isDomainSelectionSupported() {
12616 mApp.enforceCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
12617 "isDomainSelectionSupported");
12618
12619 final long identity = Binder.clearCallingIdentity();
12620 try {
12621 return DomainSelectionResolver.getInstance().isDomainSelectionSupported();
12622 } finally {
12623 Binder.restoreCallingIdentity(identity);
12624 }
12625 }
arunvoddud5c6ce02022-12-11 06:03:12 +000012626
12627 /**
Sarah Chin503828c2023-02-01 23:54:20 -080012628 * Power on or off the satellite modem.
12629 *
12630 * @param subId The subId to set satellite power for.
12631 * @param powerOn {@code true} to power on the satellite modem and {@code false} to power off.
12632 * @return The result of the operation.
12633 *
12634 * @throws SecurityException if the caller doesn't have the required permission.
12635 */
12636 @Override
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012637 @SatelliteManager.SatelliteError public int setSatellitePower(int subId,
Sarah Chin503828c2023-02-01 23:54:20 -080012638 boolean powerOn) {
12639 enforceSatelliteCommunicationPermission("setSatellitePower");
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012640 if (!isSatelliteSupported()) {
12641 return SatelliteManager.SATELLITE_NOT_SUPPORTED;
12642 }
Sarah Chin503828c2023-02-01 23:54:20 -080012643
12644 final int validSubId = getValidSatelliteSubId(subId);
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012645 if (!isSatelliteProvisioned(validSubId)) {
12646 return SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED;
Sarah Chin503828c2023-02-01 23:54:20 -080012647 }
12648
12649 Phone phone = getPhoneOrDefault(validSubId, "setSatellitePower");
12650 if (phone == null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012651 return SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
Sarah Chin503828c2023-02-01 23:54:20 -080012652 }
12653
12654 int result = (int) sendRequest(CMD_SET_SATELLITE_POWER, powerOn, subId);
12655 if (DBG) log("setSatellitePower result: " + result);
12656 return result;
12657 }
12658
12659 /**
12660 * Check whether the satellite modem is powered on.
12661 *
12662 * @param subId The subId to check satellite power for.
12663 * @param callback The callback that will be used to send the result if the operation is
12664 * successful. Returns {@code true} if the satellite modem is powered on and
12665 * {@code false} otherwise.
12666 * @return The result of the operation.
12667 *
12668 * @throws SecurityException if the caller doesn't have the required permission.
12669 */
12670 @Override
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012671 @SatelliteManager.SatelliteError public int isSatellitePowerOn(int subId,
Sarah Chin503828c2023-02-01 23:54:20 -080012672 @NonNull IBooleanConsumer callback) {
12673 enforceSatelliteCommunicationPermission("isSatellitePowerOn");
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012674 if (!isSatelliteSupported()) {
12675 return SatelliteManager.SATELLITE_NOT_SUPPORTED;
12676 }
Sarah Chin503828c2023-02-01 23:54:20 -080012677
12678 final int validSubId = getValidSatelliteSubId(subId);
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012679 if (!isSatelliteProvisioned(validSubId)) {
12680 return SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED;
Sarah Chin503828c2023-02-01 23:54:20 -080012681 }
12682
12683 Phone phone = getPhoneOrDefault(validSubId, "isSatellitePowerOn");
12684 if (phone == null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012685 return SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
Sarah Chin503828c2023-02-01 23:54:20 -080012686 }
12687
12688 Consumer<Boolean> argument = FunctionalUtils.ignoreRemoteException(callback::accept);
12689 int result = (int) sendRequest(CMD_IS_SATELLITE_POWER_ON, argument, subId);
12690 if (DBG) log("isSatellitePowerOn result: " + result);
12691 return result;
12692 }
12693
12694 /**
12695 * Check whether the satellite service is supported on the device.
12696 *
12697 * @param subId The subId to check satellite service support for.
12698 * @param callback The callback that will be used to send the result if the operation is
12699 * successful. Returns {@code true} if the satellite service is supported on
12700 * the device and {@code false} otherwise.
12701 * @return The result of the operation.
12702 *
12703 * @throws SecurityException if the caller doesn't have the required permission.
12704 */
12705 @Override
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012706 @SatelliteManager.SatelliteError public int isSatelliteSupported(int subId,
Sarah Chin503828c2023-02-01 23:54:20 -080012707 @NonNull IBooleanConsumer callback) {
12708 enforceSatelliteCommunicationPermission("isSatelliteSupported");
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012709 synchronized (mIsSatelliteSupportedLock) {
12710 if (mIsSatelliteSupported != null) {
12711 /* We have already successfully queried the satellite modem. */
12712 if (callback != null) {
12713 try {
12714 callback.accept(mIsSatelliteSupported);
12715 } catch (RemoteException ex) {
12716 loge("isSatelliteSupported: callback not available");
12717 }
12718 }
12719 return SatelliteManager.SATELLITE_ERROR_NONE;
12720 }
12721 }
Sarah Chin503828c2023-02-01 23:54:20 -080012722
12723 final int validSubId = getValidSatelliteSubId(subId);
12724 Phone phone = getPhoneOrDefault(validSubId, "isSatelliteSupported");
12725 if (phone == null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012726 return SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
Sarah Chin503828c2023-02-01 23:54:20 -080012727 }
12728
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012729 Consumer<Boolean> argument =
12730 (callback == null) ? null : FunctionalUtils.ignoreRemoteException(callback::accept);
Sarah Chin503828c2023-02-01 23:54:20 -080012731 int result = (int) sendRequest(CMD_IS_SATELLITE_SUPPORTED, argument, subId);
12732 if (DBG) log("isSatelliteSupported result: " + result);
12733 return result;
12734 }
12735
12736 /**
12737 * Get the {@link SatelliteCapabilities} with all capabilities of the satellite service.
12738 *
12739 * @param subId The subId to get the satellite capabilities for.
12740 * @param callback The callback that will be used to send the {@link SatelliteCapabilities}
12741 * if the operation is successful.
12742 * @return The result of the operation.
12743 *
12744 * @throws SecurityException if the caller doesn't have required permission.
12745 */
12746 @Override
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012747 @SatelliteManager.SatelliteError public int getSatelliteCapabilities(int subId,
Sarah Chin503828c2023-02-01 23:54:20 -080012748 @NonNull ISatelliteCapabilitiesConsumer callback) {
12749 enforceSatelliteCommunicationPermission("getSatelliteCapabilities");
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012750 if (!isSatelliteSupported()) {
12751 return SatelliteManager.SATELLITE_NOT_SUPPORTED;
12752 }
Sarah Chin503828c2023-02-01 23:54:20 -080012753
12754 final int validSubId = getValidSatelliteSubId(subId);
12755 Phone phone = getPhoneOrDefault(validSubId, "getSatelliteCapabilities");
12756 if (phone == null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012757 return SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
Sarah Chin503828c2023-02-01 23:54:20 -080012758 }
12759
12760 Consumer<SatelliteCapabilities> argument =
12761 FunctionalUtils.ignoreRemoteException(callback::accept);
12762 int result = (int) sendRequest(CMD_GET_SATELLITE_CAPABILITIES, argument, subId);
12763 if (DBG) log("getSatelliteCapabilities result: " + result);
12764 return result;
12765 }
12766
12767 /**
Sarah Chineccfbd12023-01-20 19:00:35 -080012768 * Start receiving satellite position updates.
12769 * This can be called by the pointing UI when the user starts pointing to the satellite.
12770 * Modem should continue to report the pointing input as the device or satellite moves.
12771 *
12772 * @param subId The subId to start satellite position updates for.
Sarah Chineccfbd12023-01-20 19:00:35 -080012773 * @param callback The callback to notify of changes in satellite position.
12774 * @return The result of the operation.
Sarah Chin503828c2023-02-01 23:54:20 -080012775 *
12776 * @throws SecurityException if the caller doesn't have the required permission.
Sarah Chineccfbd12023-01-20 19:00:35 -080012777 */
12778 @Override
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012779 @SatelliteManager.SatelliteError
12780 public int startSatellitePositionUpdates(int subId,
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012781 @NonNull ISatelliteStateListener callback) {
Sarah Chinf75afa72023-02-01 01:32:19 -080012782 enforceSatelliteCommunicationPermission("startSatellitePositionUpdates");
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012783 if (!isSatelliteSupported()) {
12784 return SatelliteManager.SATELLITE_NOT_SUPPORTED;
12785 }
Sarah Chinf75afa72023-02-01 01:32:19 -080012786
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012787 final int validSubId = getValidSatelliteSubId(subId);
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012788 if (!isSatelliteProvisioned(validSubId)) {
12789 return SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED;
Sarah Chinf75afa72023-02-01 01:32:19 -080012790 }
12791
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012792 Phone phone = getPhoneOrDefault(validSubId, "startSatellitePositionUpdates");
Sarah Chineccfbd12023-01-20 19:00:35 -080012793 if (phone == null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012794 return SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
Sarah Chineccfbd12023-01-20 19:00:35 -080012795 }
12796
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012797 if (mSatellitePositionUpdateHandlers.containsKey(callback.asBinder())) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012798 if (DBG) {
12799 log("startSatellitePositionUpdates: callback already registered: "
12800 + callback.asBinder());
12801 }
12802 return SatelliteManager.SATELLITE_ERROR_NONE;
Sarah Chineccfbd12023-01-20 19:00:35 -080012803 }
12804
12805 SatellitePositionUpdateHandler handler =
12806 new SatellitePositionUpdateHandler(callback, Looper.getMainLooper());
12807 phone.registerForSatellitePointingInfoChanged(handler,
12808 SatellitePositionUpdateHandler.EVENT_POSITION_UPDATE, null);
12809 phone.registerForSatelliteMessagesTransferComplete(handler,
12810 SatellitePositionUpdateHandler.EVENT_MESSAGE_TRANSFER_STATE_UPDATE, null);
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012811 mSatellitePositionUpdateHandlers.put(callback.asBinder(), handler);
Sarah Chineccfbd12023-01-20 19:00:35 -080012812
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012813 int result = (int) sendRequest(CMD_START_SATELLITE_POSITION_UPDATES, null, validSubId);
Sarah Chineccfbd12023-01-20 19:00:35 -080012814 if (DBG) log("startSatellitePositionUpdates result: " + result);
12815 return result;
12816 }
12817
12818 /**
12819 * Stop receiving satellite position updates.
12820 * This can be called by the pointing UI when the user stops pointing to the satellite.
12821 *
12822 * @param subId The subId to stop satellite position updates for.
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012823 * @param callback The callback that was passed in {@link
12824 * #startSatellitePositionUpdates(int, ISatelliteStateListener)}
Sarah Chineccfbd12023-01-20 19:00:35 -080012825 * @return The result of the operation.
Sarah Chin503828c2023-02-01 23:54:20 -080012826 *
12827 * @throws SecurityException if the caller doesn't have the required permission.
Sarah Chineccfbd12023-01-20 19:00:35 -080012828 */
12829 @Override
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012830 @SatelliteManager.SatelliteError
12831 public int stopSatellitePositionUpdates(int subId,
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012832 @NonNull ISatelliteStateListener callback) {
Sarah Chinf75afa72023-02-01 01:32:19 -080012833 enforceSatelliteCommunicationPermission("stopSatellitePositionUpdates");
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012834 if (!isSatelliteSupported()) {
12835 return SatelliteManager.SATELLITE_NOT_SUPPORTED;
12836 }
Sarah Chinf75afa72023-02-01 01:32:19 -080012837
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012838 final int validSubId = getValidSatelliteSubId(subId);
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012839 if (!isSatelliteProvisioned(validSubId)) {
12840 return SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED;
Sarah Chinf75afa72023-02-01 01:32:19 -080012841 }
12842
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012843 Phone phone = getPhoneOrDefault(validSubId, "stopSatellitePositionUpdates");
Sarah Chineccfbd12023-01-20 19:00:35 -080012844 if (phone == null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012845 return SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
Sarah Chineccfbd12023-01-20 19:00:35 -080012846 }
12847
12848 SatellitePositionUpdateHandler handler =
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012849 mSatellitePositionUpdateHandlers.remove(callback.asBinder());
Sarah Chineccfbd12023-01-20 19:00:35 -080012850 if (handler == null) {
12851 loge("stopSatellitePositionUpdates: No SatellitePositionArgument");
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012852 return SatelliteManager.SATELLITE_INVALID_ARGUMENTS;
Sarah Chineccfbd12023-01-20 19:00:35 -080012853 } else {
12854 phone.unregisterForSatellitePointingInfoChanged(handler);
12855 phone.unregisterForSatelliteMessagesTransferComplete(handler);
12856 }
12857
12858 if (!mSatellitePositionUpdateHandlers.isEmpty()) {
12859 log("stopSatellitePositionUpdates: other listeners still exist.");
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012860 return SatelliteManager.SATELLITE_ERROR_NONE;
Sarah Chineccfbd12023-01-20 19:00:35 -080012861 }
12862
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012863 int result = (int) sendRequest(CMD_STOP_SATELLITE_POSITION_UPDATES, null, validSubId);
Sarah Chineccfbd12023-01-20 19:00:35 -080012864 if (DBG) log("stopSatellitePositionUpdates result: " + result);
12865 return result;
12866 }
12867
12868 /**
Aishwarya Mallampati60fe1132023-01-24 19:07:21 +000012869 * Get maximum number of characters per text message on satellite.
12870 * @param subId - The subId of the subscription.
12871 * @param callback - The callback that will be used to send maximum characters limit
12872 * if operation is successful.
12873 * @return The result of the operation.
12874 *
12875 * @throws SecurityException if the caller doesn't have the required permission.
12876 */
12877 @Override
12878 public int getMaxCharactersPerSatelliteTextMessage(int subId, IIntegerConsumer callback) {
12879 enforceSatelliteCommunicationPermission("getMaxCharactersPerSatelliteTextMessage");
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012880 if (!isSatelliteSupported()) {
12881 return SatelliteManager.SATELLITE_NOT_SUPPORTED;
12882 }
Aishwarya Mallampati60fe1132023-01-24 19:07:21 +000012883
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012884 final int validSubId = getValidSatelliteSubId(subId);
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012885 if (!isSatelliteProvisioned(validSubId)) {
12886 return SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED;
Aishwarya Mallampati60fe1132023-01-24 19:07:21 +000012887 }
12888
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012889 Phone phone = getPhoneOrDefault(validSubId, "getMaxCharactersPerSatelliteTextMessage");
Aishwarya Mallampati60fe1132023-01-24 19:07:21 +000012890 if (phone == null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012891 return SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
Aishwarya Mallampati60fe1132023-01-24 19:07:21 +000012892 }
12893
12894 Consumer<Integer> argument = FunctionalUtils.ignoreRemoteException(callback::accept);
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012895 int result = (int) sendRequest(
12896 CMD_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG, argument, validSubId);
Aishwarya Mallampati60fe1132023-01-24 19:07:21 +000012897 if (DBG) log("getMaxCharPerTextMessageOnSatellite result: " + result);
12898 return result;
12899 }
12900
12901 /**
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012902 * Register the subscription with a satellite provider.
12903 * This is needed to register the subscription if the provider allows dynamic registration.
12904 *
12905 * @param subId The subId of the subscription to be provisioned.
12906 * @param features List of features to be provisioned.
12907 * @param callback The callback to get the error code of the request.
12908 * @return The signal transport used by the caller to cancel the provision request.
12909 * @throws SecurityException if the caller doesn't have the required permission.
12910 */
12911 @Override
12912 public ICancellationSignal provisionSatelliteService(int subId, int[] features,
12913 IIntegerConsumer callback) {
12914 enforceSatelliteCommunicationPermission("provisionSatelliteService");
12915
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012916
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012917 String callbackRemoteExErrorMessage = "provisionSatelliteService: callback not available.";
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012918 if (!isSatelliteSupported()) {
12919 sendResponse(callback, SatelliteManager.SATELLITE_NOT_SUPPORTED,
12920 callbackRemoteExErrorMessage);
12921 return null;
12922 }
12923
12924 final int validSubId = getValidSatelliteSubId(subId);
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012925 Phone phone = getPhoneOrDefault(validSubId, "provisionSatelliteService");
12926 if (phone == null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012927 sendResponse(callback, SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE,
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012928 callbackRemoteExErrorMessage);
12929 return null;
12930 }
12931
12932 if (mSatelliteProvisionCallbacks.containsKey(validSubId)) {
12933 sendResponse(callback, SatelliteManager.SATELLITE_SERVICE_PROVISION_IN_PROGRESS,
12934 callbackRemoteExErrorMessage);
12935 return null;
12936 }
12937
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012938 if (isSatelliteProvisioned(validSubId)) {
12939 sendResponse(callback, SatelliteManager.SATELLITE_ERROR_NONE,
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012940 callbackRemoteExErrorMessage);
12941 return null;
12942 }
12943
12944 sendRequestAsync(CMD_PROVISION_SATELLITE_SERVICE,
12945 new ProvisionSatelliteServiceArgument(features, callback, validSubId), phone, null);
12946
12947 ICancellationSignal cancelTransport = CancellationSignal.createTransport();
12948 CancellationSignal.fromTransport(cancelTransport)
12949 .setOnCancelListener(() -> {
12950 sendRequestAsync(CMD_CANCEL_PROVISION_SATELLITE_SERVICE, validSubId);
12951 });
12952 return cancelTransport;
12953 }
12954
12955 /**
12956 * Register for the satellite provision state change.
12957 *
12958 * @param subId The subId of the subscription associated with the satellite service.
12959 * @param callback The callback to handle the satellite provision state changed event.
12960 * @throws SecurityException if the caller doesn't have the required permission.
12961 */
12962 @Override
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012963 @SatelliteManager.SatelliteError
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012964 public int registerForSatelliteProvisionStateChanged(
12965 int subId, ISatelliteStateListener callback) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012966 enforceSatelliteCommunicationPermission("registerForSatelliteProvisionStateChanged");
12967 if (!isSatelliteSupported()) {
12968 return SatelliteManager.SATELLITE_NOT_SUPPORTED;
12969 }
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012970
12971 final int validSubId = getValidSatelliteSubId(subId);
12972 Phone phone = getPhoneOrDefault(
12973 validSubId, "registerForSatelliteProvisionStateChanged");
12974 if (phone == null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012975 return SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012976 }
12977
12978 SatelliteProvisionStateChangedHandler satelliteProvisionStateChangedHandler =
12979 mSatelliteProvisionStateChangedHandlers.get(validSubId);
12980 if (satelliteProvisionStateChangedHandler == null) {
12981 satelliteProvisionStateChangedHandler =
12982 new SatelliteProvisionStateChangedHandler(
12983 Looper.getMainLooper(), validSubId);
12984 phone.registerForSatelliteProvisionStateChanged(
12985 satelliteProvisionStateChangedHandler,
12986 SatelliteProvisionStateChangedHandler.EVENT_PROVISION_STATE_CHANGED, null);
12987 }
12988
12989 if (callback != null) {
12990 satelliteProvisionStateChangedHandler.addListener(callback);
12991 }
12992 mSatelliteProvisionStateChangedHandlers.put(
12993 validSubId, satelliteProvisionStateChangedHandler);
Thomas Nguyene77de6d2023-02-10 17:42:43 -080012994 return SatelliteManager.SATELLITE_ERROR_NONE;
Thomas Nguyen8ee49682023-02-01 11:46:09 -080012995 }
12996
12997 /**
12998 * Unregister for the satellite provision state change.
12999 *
13000 * @param subId The subId of the subscription associated with the satellite service.
13001 * @param callback The callback that was passed to
13002 * {@link #registerForSatelliteProvisionStateChanged(int, ISatelliteStateListener)}
13003 * @throws SecurityException if the caller doesn't have the required permission.
13004 */
13005 @Override
Thomas Nguyene77de6d2023-02-10 17:42:43 -080013006 @SatelliteManager.SatelliteError
Thomas Nguyen8ee49682023-02-01 11:46:09 -080013007 public int unregisterForSatelliteProvisionStateChanged(
13008 int subId, ISatelliteStateListener callback) {
13009 enforceSatelliteCommunicationPermission("unregisterForSatelliteProvisionStateChanged");
Thomas Nguyene77de6d2023-02-10 17:42:43 -080013010 if (!isSatelliteSupported()) {
13011 return SatelliteManager.SATELLITE_NOT_SUPPORTED;
13012 }
Thomas Nguyen8ee49682023-02-01 11:46:09 -080013013
13014 final int validSubId = getValidSatelliteSubId(subId);
13015 SatelliteProvisionStateChangedHandler satelliteProvisionStateChangedHandler =
13016 mSatelliteProvisionStateChangedHandlers.get(validSubId);
13017 if (satelliteProvisionStateChangedHandler != null) {
13018 if (satelliteProvisionStateChangedHandler.removeListener(callback)) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -080013019 return SatelliteManager.SATELLITE_ERROR_NONE;
Thomas Nguyen8ee49682023-02-01 11:46:09 -080013020 }
13021 }
Thomas Nguyene77de6d2023-02-10 17:42:43 -080013022 return SatelliteManager.SATELLITE_INVALID_ARGUMENTS;
Thomas Nguyen8ee49682023-02-01 11:46:09 -080013023 }
13024
13025 /**
13026 * Get the list of provisioned satellite features.
13027 *
13028 * @param subId The subId of the subscription associated with the satellite service.
13029 * @param callback The callback to get the list of provisioned satellite features.
13030 * @return The error code of the request.
13031 * @throws SecurityException if the caller doesn't have the required permission.
13032 */
13033 @Override
Thomas Nguyene77de6d2023-02-10 17:42:43 -080013034 @SatelliteManager.SatelliteError
Thomas Nguyen8ee49682023-02-01 11:46:09 -080013035 public int getProvisionedSatelliteFeatures(int subId, IIntArrayConsumer callback) {
13036 enforceSatelliteCommunicationPermission("getProvisionedSatelliteFeatures");
Thomas Nguyene77de6d2023-02-10 17:42:43 -080013037 if (!isSatelliteSupported()) {
13038 return SatelliteManager.SATELLITE_NOT_SUPPORTED;
13039 }
Thomas Nguyen8ee49682023-02-01 11:46:09 -080013040
13041 final int validSubId = getValidSatelliteSubId(subId);
Thomas Nguyene77de6d2023-02-10 17:42:43 -080013042 if (!isSatelliteProvisioned(validSubId)) {
13043 return SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED;
Thomas Nguyen8ee49682023-02-01 11:46:09 -080013044 }
13045
13046 final Phone phone = getPhoneOrDefault(validSubId, "getProvisionedSatelliteFeatures");
13047 if (phone == null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -080013048 return SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
Thomas Nguyen8ee49682023-02-01 11:46:09 -080013049 }
13050
13051 int result = (int) sendRequest(
13052 CMD_GET_PROVISIONED_SATELLITE_FEATURES, callback, validSubId);
13053 if (DBG) log("getProvisionedSatelliteFeatures result: " + result);
13054 return result;
13055 }
13056
13057 private void handleCmdProvisionSatelliteService(@NonNull ProvisionSatelliteServiceArgument arg,
13058 @NonNull Phone phone, Message onCompleted) {
13059 String callbackRemoteExErrorMessage =
13060 "handleCmdProvisionSatelliteService: callback not available.";
13061 if (arg == null) {
13062 loge("handleCmdProvisionSatelliteService: arg is null");
13063 return;
13064 }
13065 if (phone == null) {
13066 loge("handleCmdProvisionSatelliteService: phone is null");
Thomas Nguyene77de6d2023-02-10 17:42:43 -080013067 sendResponse(arg.callback, SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE,
Thomas Nguyen8ee49682023-02-01 11:46:09 -080013068 callbackRemoteExErrorMessage);
13069 return;
13070 }
13071
13072 if (!mSatelliteProvisionCallbacks.containsKey(arg.subId)) {
13073 mSatelliteProvisionCallbacks.put(arg.subId, arg.callback);
13074 phone.provisionSatelliteService(onCompleted, phone.getImei(), phone.getMsisdn(),
13075 getSatelliteImsi(arg.subId), arg.features);
13076 } else {
13077 sendResponse(arg.callback, SatelliteManager.SATELLITE_SERVICE_PROVISION_IN_PROGRESS,
13078 callbackRemoteExErrorMessage);
13079 }
13080 }
13081
13082 private void handleEventProvisionSatelliteServiceDone(MainThreadRequest request) {
13083 final ProvisionSatelliteServiceArgument arg =
13084 (ProvisionSatelliteServiceArgument) request.argument;
13085 if (arg == null) {
13086 loge("handleEventProvisionSatelliteServiceDone: arg is null");
13087 return;
13088 }
13089
13090 IIntegerConsumer callback = mSatelliteProvisionCallbacks.remove(arg.subId);
13091 if (callback == null) {
13092 loge("handleEventProvisionSatelliteServiceDone: callback is null for subId="
13093 + arg.subId);
13094 return;
13095 }
13096
13097 int result = (int) request.result;
13098 if (DBG) {
13099 log("handleEventProvisionSatelliteServiceDone: result="
13100 + result + ", subId=" + arg.subId);
13101 }
13102 sendResponse(callback, result,
13103 "handleEventProvisionSatelliteServiceDone: callback not available.");
13104
Thomas Nguyene77de6d2023-02-10 17:42:43 -080013105 if (result == SatelliteManager.SATELLITE_ERROR_NONE) {
13106 setSatelliteProvisioned(arg.subId, true);
Thomas Nguyen8ee49682023-02-01 11:46:09 -080013107 }
13108
13109 /**
13110 * We need to update satellite provision status in SubscriptionController
13111 * or SatelliteController.
13112 * TODO (b/267826133) we need to do this for all subscriptions on the device.
13113 */
13114 registerForSatelliteProvisionStateChanged(arg.subId, null);
13115 }
13116
13117 private void handleCmdCancelProvisionSatelliteService(int subId, Message onCompleted) {
13118 final Phone phone = getPhoneOrDefault(
13119 subId, "handleCmdCancelProvisionSatelliteService");
13120 if (phone == null) {
13121 return;
13122 }
13123 phone.cancelProvisionSatelliteService(onCompleted, getSatelliteImsi(subId));
13124 }
13125
13126 private void sendResponse(@NonNull IIntegerConsumer callback, int result, String message) {
13127 Objects.requireNonNull(callback);
13128
13129 try {
13130 callback.accept(result);
13131 } catch (RemoteException e) {
13132 Log.w(LOG_TAG, message);
13133 }
13134 }
13135
13136 private String getSatelliteImsi(int subId) {
13137 if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
13138 return "";
13139 }
13140
13141 if (mSubscriptionController == null) {
13142 loge("getSatelliteImsi: mSubscriptionController is null");
13143 return "";
13144 }
13145 return mSubscriptionController.getImsiPrivileged(subId);
13146 }
13147
13148 private Phone getPhoneOrDefault(int subId, String caller) {
13149 Phone phone = getPhone(subId);
13150 if (phone == null) {
13151 loge(caller + " called with invalid subId: " + subId
13152 + ". Retrying with default phone.");
13153 phone = getDefaultPhone();
13154 if (phone == null) {
13155 loge(caller + " failed with no phone object.");
13156 }
13157 }
13158 return phone;
13159 }
13160
13161 /**
Thomas Nguyene77de6d2023-02-10 17:42:43 -080013162 * Check if satellite is provisioned for a subscription or the device.
Thomas Nguyen8ee49682023-02-01 11:46:09 -080013163 *
13164 * Note: this is the version without permission check for telephony internal use only. The
13165 * caller need to take care of the permission check.
13166 */
Thomas Nguyene77de6d2023-02-10 17:42:43 -080013167 private boolean isSatelliteProvisioned(int subId) {
Thomas Nguyen8ee49682023-02-01 11:46:09 -080013168 if (subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
13169 if (mSubscriptionController == null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -080013170 loge("isSatelliteProvisioned mSubscriptionController is null");
Thomas Nguyen8ee49682023-02-01 11:46:09 -080013171 return false;
13172 }
13173
13174 String strResult = mSubscriptionController.getSubscriptionProperty(
13175 subId, SubscriptionManager.SATELLITE_ENABLED);
13176 if (strResult != null) {
13177 int intResult = Integer.parseInt(strResult);
13178 return (intResult == 1) ? true : false;
13179 }
13180 } else {
13181 //TODO (b/267826133): check via SatelliteController
13182 }
13183 return false;
13184 }
13185
13186 /**
Thomas Nguyene77de6d2023-02-10 17:42:43 -080013187 * Set satellite provisioned for a subscription or the device.
Thomas Nguyen8ee49682023-02-01 11:46:09 -080013188 *
13189 * The permission {@link android.Manifest.permission#MODIFY_PHONE_STATE} will be enforced by
13190 * {@link SubscriptionController} when setting satellite enabled for an active subscription.
13191 * Otherwise, {@link android.Manifest.permission#SATELLITE_COMMUNICATION} will be enforced.
13192 */
Thomas Nguyene77de6d2023-02-10 17:42:43 -080013193 private void setSatelliteProvisioned(int subId, boolean isEnabled) {
Thomas Nguyen8ee49682023-02-01 11:46:09 -080013194 if (subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
13195 if (mSubscriptionController == null) {
Thomas Nguyene77de6d2023-02-10 17:42:43 -080013196 loge("setSatelliteProvisioned mSubscriptionController is null");
Thomas Nguyen8ee49682023-02-01 11:46:09 -080013197 return;
13198 }
13199 mSubscriptionController.setSubscriptionProperty(
13200 subId, SubscriptionManager.SATELLITE_ENABLED, isEnabled ? "1" : "0");
13201 } else {
Thomas Nguyene77de6d2023-02-10 17:42:43 -080013202 //TODO (b/267826133): set via SatelliteController
Thomas Nguyen8ee49682023-02-01 11:46:09 -080013203 }
13204 }
13205
13206 private int getValidSatelliteSubId(int subId) {
13207 if (mSubscriptionController == null) {
13208 loge("getValidSatelliteSubId mSubscriptionController is null. "
13209 + "Use DEFAULT_SUBSCRIPTION_ID for subId=" + subId);
13210 return SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
13211 }
13212 final long identity = Binder.clearCallingIdentity();
13213 try {
13214 Context context = getDefaultPhone().getContext();
13215 if (mSubscriptionController.isActiveSubId(
13216 subId, context.getOpPackageName(), context.getAttributionTag())) {
13217 return subId;
13218 }
13219 } finally {
13220 Binder.restoreCallingIdentity(identity);
13221 }
13222 if (DBG) log("getValidSatelliteSubId: use DEFAULT_SUBSCRIPTION_ID for subId=" + subId);
13223 return SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
13224 }
13225
13226 /**
Thomas Nguyene77de6d2023-02-10 17:42:43 -080013227 * If we have not successfully queried the satellite modem for its satellite service support, we
13228 * will retry the query one more time. Otherwise, we will return the queried result.
13229 */
13230 private boolean isSatelliteSupported() {
13231 synchronized (mIsSatelliteSupportedLock) {
13232 if (mIsSatelliteSupported != null) {
13233 /* We have already successfully queried the satellite modem. */
13234 return mIsSatelliteSupported;
13235 }
13236 }
13237 /**
13238 * We have not successfully checked if the modem support satellite service. Thus, we need to
13239 * retry it now.
13240 */
13241 if (isSatelliteSupported(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, null)
13242 == SatelliteManager.SATELLITE_ERROR_NONE) {
13243 synchronized (mIsSatelliteSupportedLock) {
13244 if (mIsSatelliteSupported != null) {
13245 return mIsSatelliteSupported;
13246 }
13247 }
13248 }
13249 return false;
13250 }
13251
13252 /**
arunvoddud5c6ce02022-12-11 06:03:12 +000013253 * Check whether the caller (or self, if not processing an IPC) can read device identifiers.
13254 *
13255 * <p>This method behaves in one of the following ways:
13256 * <ul>
13257 * <li>return true : if the calling package has the appop permission {@link
13258 * Manifest.permission#USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER} in the manifest </>
13259 * <li>return true : if any one subscription has the READ_PRIVILEGED_PHONE_STATE
13260 * permission, the calling package passes a DevicePolicyManager Device Owner / Profile
13261 * Owner device identifier access check, or the calling package has carrier privileges</>
13262 * <li>throw SecurityException: if the caller does not meet any of the requirements.
13263 * </ul>
13264 */
13265 private static boolean checkCallingOrSelfReadDeviceIdentifiersForAnySub(Context context,
13266 String callingPackage, @Nullable String callingFeatureId, String message) {
13267 for (Phone phone : PhoneFactory.getPhones()) {
13268 if (TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(context,
13269 phone.getSubId(), callingPackage, callingFeatureId, message)) {
13270 return true;
13271 }
13272 }
13273 return false;
13274 }
arunvoddud7401012022-12-15 16:08:12 +000013275
13276 /**
Jack Yufa8ed012023-02-11 15:42:28 -080013277 * @return The subscription manager service instance.
13278 */
13279 public SubscriptionManagerService getSubscriptionManagerService() {
13280 return SubscriptionManagerService.getInstance();
13281 }
13282
13283 /**
arunvoddud7401012022-12-15 16:08:12 +000013284 * Class binds the consumer[callback] and carrierId.
13285 */
13286 private static class CallerCallbackInfo {
13287 private final Consumer<Integer> mConsumer;
13288 private final int mCarrierId;
13289
13290 public CallerCallbackInfo(Consumer<Integer> consumer, int carrierId) {
13291 mConsumer = consumer;
13292 mCarrierId = carrierId;
13293 }
13294
13295 public Consumer<Integer> getConsumer() {
13296 return mConsumer;
13297 }
13298
13299 public int getCarrierId() {
13300 return mCarrierId;
13301 }
13302 }
Jack Yufa8ed012023-02-11 15:42:28 -080013303}