blob: 4da400450902ae9caab031fb18523863ae13fbc1 [file] [log] [blame]
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.phone;
18
Hall Liud892bec2018-11-30 14:51:45 -080019import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20
Shuo Qianccbaf742021-02-22 18:32:21 -080021import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_CDMA;
22import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_GSM;
Tyler Gunn7bcdc742019-10-04 15:56:59 -070023import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_IMS;
Ta-wei Yen87c49842016-05-13 21:19:52 -070024import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
joonhunshin3e154242021-09-17 06:33:39 +000025import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__CLIENT_PARAMS_SENT;
Ta-wei Yen87c49842016-05-13 21:19:52 -070026
Brad Ebinger34c09a52021-02-17 23:23:21 +000027import android.Manifest;
Ta-wei Yen30a69c82016-12-27 14:52:32 -080028import android.Manifest.permission;
Hall Liua1548bd2019-12-24 14:14:12 -080029import android.annotation.NonNull;
Tyler Gunnf70ed162019-04-03 15:28:53 -070030import android.annotation.Nullable;
sandeepjsb6c87872021-09-27 15:34:44 +000031import android.annotation.RequiresPermission;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070032import android.app.AppOpsManager;
Ta-wei Yen30a69c82016-12-27 14:52:32 -080033import android.app.PendingIntent;
Brad Ebinger4f6208e2021-03-23 21:04:45 +000034import android.app.compat.CompatChanges;
Hall Liu82694d52020-12-11 18:22:04 -080035import android.app.role.RoleManager;
Chen Xu540470b2021-12-14 17:15:47 -080036import android.compat.Compatibility;
sandeepjsb6c87872021-09-27 15:34:44 +000037import android.compat.annotation.ChangeId;
38import android.compat.annotation.EnabledSince;
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -070039import android.content.ComponentName;
Amit Mahajan7dbbd822019-03-13 17:33:47 -070040import android.content.ContentResolver;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070041import android.content.Context;
42import android.content.Intent;
Derek Tan97ebb422014-09-05 16:55:38 -070043import android.content.SharedPreferences;
Derek Tan740e1672017-06-27 14:56:27 -070044import android.content.pm.ComponentInfo;
Amith Yamasani6e118872016-02-19 12:53:51 -080045import android.content.pm.PackageInfo;
Shishir Agrawal60f9c952014-06-23 12:00:43 -070046import android.content.pm.PackageManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070047import android.net.Uri;
48import android.os.AsyncResult;
49import android.os.Binder;
Hall Liuf19c44f2018-11-27 14:38:17 -080050import android.os.Build;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070051import android.os.Bundle;
52import android.os.Handler;
yinxu504e1392017-04-12 16:03:22 -070053import android.os.IBinder;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070054import android.os.Looper;
55import android.os.Message;
yinxu504e1392017-04-12 16:03:22 -070056import android.os.Messenger;
Hall Liua1548bd2019-12-24 14:14:12 -080057import android.os.ParcelFileDescriptor;
Malcolm Chen6ca97372019-07-01 16:28:21 -070058import android.os.ParcelUuid;
Tyler Gunn65d45c22017-06-05 11:22:26 -070059import android.os.PersistableBundle;
Shuo Qiancd19c462020-01-16 20:51:11 -080060import android.os.Process;
Brad Ebinger5f64b052017-12-14 14:26:15 -080061import android.os.RemoteException;
Adam Lesinski903a54c2016-04-11 14:49:52 -070062import android.os.ResultReceiver;
Brad Ebinger1ce9c432019-07-16 13:19:44 -070063import android.os.ServiceSpecificException;
Rambo Wang0f050d82021-02-12 11:43:36 -080064import android.os.SystemClock;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070065import android.os.UserHandle;
Stuart Scott981d8582015-04-21 14:09:50 -070066import android.os.UserManager;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070067import android.os.WorkSource;
Derek Tan97ebb422014-09-05 16:55:38 -070068import android.preference.PreferenceManager;
Naina Nallurid63128d2019-09-17 14:10:30 -070069import android.provider.DeviceConfig;
Ihab Awadf2177b72013-11-25 13:33:23 -080070import android.provider.Settings;
Amit Mahajan7dbbd822019-03-13 17:33:47 -070071import android.provider.Telephony;
Inseob Kim14bb3d02018-12-13 17:11:34 +090072import android.sysprop.TelephonyProperties;
Santos Cordon7a1885b2015-02-03 11:15:19 -080073import android.telecom.PhoneAccount;
Nancy Chen31f9ba12016-01-06 11:42:12 -080074import android.telecom.PhoneAccountHandle;
Andrew Lee9431b832015-03-09 18:46:45 -070075import android.telecom.TelecomManager;
Chen Xu227e06f2019-09-26 22:48:11 -070076import android.telephony.Annotation.ApnType;
Jack Nudelmanb0b87642020-11-12 15:04:39 -080077import android.telephony.Annotation.ThermalMitigationResult;
Shuo Qian4a594052020-01-23 11:59:30 -080078import android.telephony.CallForwardingInfo;
Junda Liu12f7d802015-05-01 12:06:44 -070079import android.telephony.CarrierConfigManager;
Michele Berionne482f8202018-11-27 18:57:59 -080080import android.telephony.CarrierRestrictionRules;
yincheng zhao2737e882019-09-06 17:06:54 -070081import android.telephony.CellIdentity;
Meng Wanga10e89e2019-12-09 13:13:01 -080082import android.telephony.CellIdentityCdma;
83import android.telephony.CellIdentityGsm;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070084import android.telephony.CellInfo;
Nathan Haroldf180aac2018-06-01 18:43:55 -070085import android.telephony.CellInfoGsm;
86import android.telephony.CellInfoWcdma;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070087import android.telephony.ClientRequestStats;
Jack Nudelmanb0b87642020-11-12 15:04:39 -080088import android.telephony.DataThrottlingRequest;
Hui Wang641e81c2020-10-12 12:14:23 -070089import android.telephony.IBootstrapAuthenticationCallback;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -070090import android.telephony.ICellInfoCallback;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -070091import android.telephony.IccOpenLogicalChannelResponse;
Hall Liu1aa510f2017-11-22 17:40:08 -080092import android.telephony.LocationAccessPolicy;
Ta-wei Yen87c49842016-05-13 21:19:52 -070093import android.telephony.ModemActivityInfo;
Jake Hambye994d462014-02-03 13:10:13 -080094import android.telephony.NeighboringCellInfo;
yinxu504e1392017-04-12 16:03:22 -070095import android.telephony.NetworkScanRequest;
Michele4245e952019-02-04 11:36:23 -080096import android.telephony.PhoneCapability;
Hall Liud892bec2018-11-30 14:51:45 -080097import android.telephony.PhoneNumberRange;
Wink Saville5d475dd2014-10-17 15:00:58 -070098import android.telephony.RadioAccessFamily;
Hall Liub2ac8ef2019-02-28 15:56:23 -080099import android.telephony.RadioAccessSpecifier;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700100import android.telephony.ServiceState;
Nathan Harold46b42aa2017-03-10 19:38:22 -0800101import android.telephony.SignalStrength;
Rambo Wanga5cc9b72021-01-07 10:51:54 -0800102import android.telephony.SignalStrengthUpdateRequest;
103import android.telephony.SignalThresholdInfo;
Wink Saville0f3b5fc2014-11-11 08:40:49 -0800104import android.telephony.SubscriptionInfo;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800105import android.telephony.SubscriptionManager;
Peter Wangc035ce42020-01-08 21:00:22 -0800106import android.telephony.TelephonyFrameworkInitializer;
Sanket Padawe99ef1e32016-05-18 16:12:33 -0700107import android.telephony.TelephonyHistogram;
Ta-wei Yenb6929602016-05-24 15:48:27 -0700108import android.telephony.TelephonyManager;
Hall Liub2ac8ef2019-02-28 15:56:23 -0800109import android.telephony.TelephonyScanManager;
Jack Nudelmanb0b87642020-11-12 15:04:39 -0800110import android.telephony.ThermalMitigationRequest;
Jordan Liu5aa07002018-12-18 15:44:48 -0800111import android.telephony.UiccCardInfo;
sandeepjsb6c87872021-09-27 15:34:44 +0000112import android.telephony.UiccPortInfo;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000113import android.telephony.UiccSlotInfo;
sandeepjsb6c87872021-09-27 15:34:44 +0000114import android.telephony.UiccSlotMapping;
Tyler Gunn65d45c22017-06-05 11:22:26 -0700115import android.telephony.UssdResponse;
Ta-wei Yenb6929602016-05-24 15:48:27 -0700116import android.telephony.VisualVoicemailSmsFilterSettings;
Jack Yub5d8f642018-11-26 11:20:48 -0800117import android.telephony.data.ApnSetting;
Hongbo Zeng0e18b162021-04-07 16:52:18 +0800118import android.telephony.data.NetworkSlicingConfig;
Jack Yub5d8f642018-11-26 11:20:48 -0800119import android.telephony.emergency.EmergencyNumber;
Hui Wang641e81c2020-10-12 12:14:23 -0700120import android.telephony.gba.GbaAuthRequest;
121import android.telephony.gba.UaSecurityProtocolIdentifier;
Brad Ebinger1ce9c432019-07-16 13:19:44 -0700122import android.telephony.ims.ImsException;
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800123import android.telephony.ims.ProvisioningManager;
Hui Wang761a6682020-10-31 05:12:53 +0000124import android.telephony.ims.RcsClientConfiguration;
Brad Ebinger14d467f2021-02-12 06:18:28 +0000125import android.telephony.ims.RcsContactUceCapability;
Brad Ebingera34a6c22019-10-22 17:36:18 -0700126import android.telephony.ims.RegistrationManager;
Brad Ebinger35c841c2018-10-01 10:40:55 -0700127import android.telephony.ims.aidl.IImsCapabilityCallback;
Brad Ebinger22bc3e42018-01-16 09:39:35 -0800128import android.telephony.ims.aidl.IImsConfig;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -0700129import android.telephony.ims.aidl.IImsConfigCallback;
Brad Ebinger22bc3e42018-01-16 09:39:35 -0800130import android.telephony.ims.aidl.IImsRegistration;
Brad Ebinger35c841c2018-10-01 10:40:55 -0700131import android.telephony.ims.aidl.IImsRegistrationCallback;
Hui Wang761a6682020-10-31 05:12:53 +0000132import android.telephony.ims.aidl.IRcsConfigCallback;
Brad Ebingerbc7dd582019-10-17 17:03:22 -0700133import android.telephony.ims.feature.ImsFeature;
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800134import android.telephony.ims.feature.MmTelFeature;
allenwtsu99c623b2020-01-03 18:24:23 +0800135import android.telephony.ims.feature.RcsFeature;
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800136import android.telephony.ims.stub.ImsConfigImplBase;
Brad Ebinger1f2b5082018-02-08 16:11:32 -0800137import android.telephony.ims.stub.ImsRegistrationImplBase;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700138import android.text.TextUtils;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800139import android.util.ArraySet;
Hall Liud60acc92020-05-21 17:09:35 -0700140import android.util.EventLog;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700141import android.util.Log;
Jake Hambye994d462014-02-03 13:10:13 -0800142import android.util.Pair;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800143
Andrew Lee312e8172014-10-23 17:01:36 -0700144import com.android.ims.ImsManager;
Brad Ebinger34bef922017-11-09 10:27:08 -0800145import com.android.ims.internal.IImsServiceFeatureCallback;
James.cf Linbcdf8b32021-01-14 16:44:13 +0800146import com.android.ims.rcs.uce.eab.EabUtil;
SongFerngWangfd89b102021-05-27 22:44:54 +0800147import com.android.internal.annotations.VisibleForTesting;
Shuo Qian4a594052020-01-23 11:59:30 -0800148import com.android.internal.telephony.CallForwardInfo;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700149import com.android.internal.telephony.CallManager;
Tyler Gunn52dcf772017-04-26 11:30:31 -0700150import com.android.internal.telephony.CallStateException;
Tyler Gunnd4339262021-05-03 14:46:49 -0700151import com.android.internal.telephony.CallTracker;
chen xu651eec72018-11-11 19:03:44 -0800152import com.android.internal.telephony.CarrierResolver;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700153import com.android.internal.telephony.CellNetworkScanResult;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700154import com.android.internal.telephony.CommandException;
Shuo Qian4a594052020-01-23 11:59:30 -0800155import com.android.internal.telephony.CommandsInterface;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700156import com.android.internal.telephony.DefaultPhoneNotifier;
Hui Wang641e81c2020-10-12 12:14:23 -0700157import com.android.internal.telephony.GbaManager;
Shuo Qianccbaf742021-02-22 18:32:21 -0800158import com.android.internal.telephony.GsmCdmaPhone;
Nathan Harold48d6fd52019-02-06 19:01:40 -0800159import com.android.internal.telephony.HalVersion;
Hall Liu73f5d362020-01-20 13:42:00 -0800160import com.android.internal.telephony.IBooleanConsumer;
Hall Liu27d24262020-09-18 19:04:59 -0700161import com.android.internal.telephony.ICallForwardingInfoCallback;
Hunsuk Choi3b742d62021-10-25 19:48:34 +0000162import com.android.internal.telephony.IImsStateCallback;
Brad Ebingera63db5f2019-04-23 16:31:13 -0700163import com.android.internal.telephony.IIntegerConsumer;
Hall Liud892bec2018-11-30 14:51:45 -0800164import com.android.internal.telephony.INumberVerificationCallback;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700165import com.android.internal.telephony.ITelephony;
Jake Hambye994d462014-02-03 13:10:13 -0800166import com.android.internal.telephony.IccCard;
Rambo Wanga1782702021-11-10 20:15:19 -0800167import com.android.internal.telephony.IccLogicalChannelRequest;
Jack Yu5f7092c2018-04-13 14:05:37 -0700168import com.android.internal.telephony.LocaleTracker;
yinxub1bed742017-04-17 11:45:04 -0700169import com.android.internal.telephony.NetworkScanRequestTracker;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700170import com.android.internal.telephony.OperatorInfo;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700171import com.android.internal.telephony.Phone;
Malcolm Chen2c63d402018-08-14 16:00:53 -0700172import com.android.internal.telephony.PhoneConfigurationManager;
Nathan Harolda667c152016-12-14 11:27:20 -0800173import com.android.internal.telephony.PhoneConstantConversions;
Ta-wei Yen87c49842016-05-13 21:19:52 -0700174import com.android.internal.telephony.PhoneConstants;
Wink Saville36469e72014-06-11 15:17:00 -0700175import com.android.internal.telephony.PhoneFactory;
Wink Saville5d475dd2014-10-17 15:00:58 -0700176import com.android.internal.telephony.ProxyController;
Sanket Padawe99ef1e32016-05-18 16:12:33 -0700177import com.android.internal.telephony.RIL;
SongFerngWang8c6e82e2021-03-02 22:09:29 +0800178import com.android.internal.telephony.RILConstants;
Daniel Bright94f43662021-03-01 14:43:40 -0800179import com.android.internal.telephony.RadioInterfaceCapabilityController;
Jack Yu5f7092c2018-04-13 14:05:37 -0700180import com.android.internal.telephony.ServiceStateTracker;
Amit Mahajandccb3f12019-05-13 13:48:32 -0700181import com.android.internal.telephony.SmsController;
Brad Ebingera63db5f2019-04-23 16:31:13 -0700182import com.android.internal.telephony.SmsPermissions;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800183import com.android.internal.telephony.SubscriptionController;
Peter Wang59571be2020-01-27 12:35:15 +0800184import com.android.internal.telephony.TelephonyIntents;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800185import com.android.internal.telephony.TelephonyPermissions;
Malcolm Chendc8c10e2019-04-10 18:25:07 -0700186import com.android.internal.telephony.dataconnection.ApnSettingUtils;
sqianf4ca7ed2019-01-15 18:32:07 -0800187import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Derek Tan740e1672017-06-27 14:56:27 -0700188import com.android.internal.telephony.euicc.EuiccConnector;
Brad Ebinger9c0eb502019-01-23 15:06:19 -0800189import com.android.internal.telephony.ims.ImsResolver;
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700190import com.android.internal.telephony.imsphone.ImsPhone;
191import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
joonhunshin3e154242021-09-17 06:33:39 +0000192import com.android.internal.telephony.metrics.RcsStats;
Pengquan Meng6c2dc9f2019-02-06 11:12:53 -0800193import com.android.internal.telephony.metrics.TelephonyMetrics;
Meng Wangafbc5852019-09-19 17:37:13 -0700194import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700195import com.android.internal.telephony.uicc.IccIoResult;
changbetty7157e9e2019-12-06 18:16:37 +0800196import com.android.internal.telephony.uicc.IccRecords;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700197import com.android.internal.telephony.uicc.IccUtils;
Nathan Haroldb3014052017-01-25 15:57:32 -0800198import com.android.internal.telephony.uicc.SIMRecords;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700199import com.android.internal.telephony.uicc.UiccCard;
Nathan Haroldb3014052017-01-25 15:57:32 -0800200import com.android.internal.telephony.uicc.UiccCardApplication;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700201import com.android.internal.telephony.uicc.UiccController;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000202import com.android.internal.telephony.uicc.UiccPort;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800203import com.android.internal.telephony.uicc.UiccProfile;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000204import com.android.internal.telephony.uicc.UiccSlot;
zoey chenc730df82019-12-18 17:07:20 +0800205import com.android.internal.telephony.util.LocaleUtils;
fionaxu7ed723d2017-05-30 18:58:54 -0700206import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
Hall Liu27d24262020-09-18 19:04:59 -0700207import com.android.internal.util.FunctionalUtils;
Jake Hambye994d462014-02-03 13:10:13 -0800208import com.android.internal.util.HexDump;
Hall Liuaa4211e2021-01-20 15:43:39 -0800209import com.android.phone.callcomposer.CallComposerPictureManager;
210import com.android.phone.callcomposer.CallComposerPictureTransfer;
211import com.android.phone.callcomposer.ImageData;
Brad Ebingera63db5f2019-04-23 16:31:13 -0700212import com.android.phone.settings.PickSmsSubscriptionActivity;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700213import com.android.phone.vvm.PhoneAccountHandleConverter;
Ta-wei Yen527a9c02017-01-06 15:29:25 -0800214import com.android.phone.vvm.RemoteVvmTaskManager;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700215import com.android.phone.vvm.VisualVoicemailSettingsUtil;
Ta-wei Yenc8905312017-03-28 11:14:45 -0700216import com.android.phone.vvm.VisualVoicemailSmsFilterConfig;
Jack Nudelmanb0b87642020-11-12 15:04:39 -0800217import com.android.services.telephony.TelecomAccountRegistry;
218import com.android.services.telephony.TelephonyConnectionService;
Peter Wang44b186e2020-01-13 23:33:09 -0800219import com.android.telephony.Rlog;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800220
Hall Liu82694d52020-12-11 18:22:04 -0800221import java.io.ByteArrayOutputStream;
Ta-wei Yenc236d6b2016-06-21 13:33:12 -0700222import java.io.FileDescriptor;
Hall Liu82694d52020-12-11 18:22:04 -0800223import java.io.IOException;
224import java.io.InputStream;
Ta-wei Yenc236d6b2016-06-21 13:33:12 -0700225import java.io.PrintWriter;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700226import java.util.ArrayList;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800227import java.util.Arrays;
Muralidhar Reddyeb809e32021-11-19 03:07:54 +0000228import java.util.Collection;
sqian11b7a0e2018-12-05 18:48:28 -0800229import java.util.HashMap;
sqianf4ca7ed2019-01-15 18:32:07 -0800230import java.util.HashSet;
Jake Hambye994d462014-02-03 13:10:13 -0800231import java.util.List;
Narayan Kamath1c496c22015-04-16 14:40:19 +0100232import java.util.Locale;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800233import java.util.Map;
Nazanin Bakhshif71371d2019-04-29 17:29:44 -0700234import java.util.NoSuchElementException;
Hall Liu82694d52020-12-11 18:22:04 -0800235import java.util.Objects;
sqianf4ca7ed2019-01-15 18:32:07 -0800236import java.util.Set;
Hall Liu82694d52020-12-11 18:22:04 -0800237import java.util.concurrent.Executors;
Peter Wangdafb9ac2020-01-15 14:13:38 -0800238import java.util.concurrent.atomic.AtomicBoolean;
Hall Liu73f5d362020-01-20 13:42:00 -0800239import java.util.function.Consumer;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700240
241/**
242 * Implementation of the ITelephony interface.
243 */
Santos Cordon117fee72014-05-16 17:56:12 -0700244public class PhoneInterfaceManager extends ITelephony.Stub {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700245 private static final String LOG_TAG = "PhoneInterfaceManager";
246 private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
247 private static final boolean DBG_LOC = false;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800248 private static final boolean DBG_MERGE = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700249
250 // Message codes used with mMainThreadHandler
251 private static final int CMD_HANDLE_PIN_MMI = 1;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700252 private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7;
253 private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700254 private static final int CMD_OPEN_CHANNEL = 9;
255 private static final int EVENT_OPEN_CHANNEL_DONE = 10;
256 private static final int CMD_CLOSE_CHANNEL = 11;
257 private static final int EVENT_CLOSE_CHANNEL_DONE = 12;
Jake Hambye994d462014-02-03 13:10:13 -0800258 private static final int CMD_NV_READ_ITEM = 13;
259 private static final int EVENT_NV_READ_ITEM_DONE = 14;
260 private static final int CMD_NV_WRITE_ITEM = 15;
261 private static final int EVENT_NV_WRITE_ITEM_DONE = 16;
262 private static final int CMD_NV_WRITE_CDMA_PRL = 17;
263 private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18;
chen xu6dac5ab2018-10-26 17:39:23 -0700264 private static final int CMD_RESET_MODEM_CONFIG = 19;
265 private static final int EVENT_RESET_MODEM_CONFIG_DONE = 20;
SongFerngWang3ef3e072020-12-21 16:41:52 +0800266 private static final int CMD_GET_ALLOWED_NETWORK_TYPES_BITMASK = 21;
267 private static final int EVENT_GET_ALLOWED_NETWORK_TYPES_BITMASK_DONE = 22;
Sailesh Nepal35b59452014-03-06 09:26:56 -0800268 private static final int CMD_SEND_ENVELOPE = 25;
269 private static final int EVENT_SEND_ENVELOPE_DONE = 26;
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000270 private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27;
271 private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28;
Derek Tan6b088ee2014-09-05 14:15:18 -0700272 private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29;
273 private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30;
274 private static final int CMD_EXCHANGE_SIM_IO = 31;
275 private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800276 private static final int CMD_SET_VOICEMAIL_NUMBER = 33;
277 private static final int EVENT_SET_VOICEMAIL_NUMBER_DONE = 34;
Stuart Scott54788802015-03-30 13:18:01 -0700278 private static final int CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC = 35;
279 private static final int EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE = 36;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700280 private static final int CMD_GET_MODEM_ACTIVITY_INFO = 37;
281 private static final int EVENT_GET_MODEM_ACTIVITY_INFO_DONE = 38;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700282 private static final int CMD_PERFORM_NETWORK_SCAN = 39;
283 private static final int EVENT_PERFORM_NETWORK_SCAN_DONE = 40;
284 private static final int CMD_SET_NETWORK_SELECTION_MODE_MANUAL = 41;
285 private static final int EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE = 42;
Meng Wang1a7c35a2016-05-05 20:56:15 -0700286 private static final int CMD_SET_ALLOWED_CARRIERS = 43;
287 private static final int EVENT_SET_ALLOWED_CARRIERS_DONE = 44;
288 private static final int CMD_GET_ALLOWED_CARRIERS = 45;
289 private static final int EVENT_GET_ALLOWED_CARRIERS_DONE = 46;
pkanwar32d516d2016-10-14 19:37:38 -0700290 private static final int CMD_HANDLE_USSD_REQUEST = 47;
Nathan Haroldb3014052017-01-25 15:57:32 -0800291 private static final int CMD_GET_FORBIDDEN_PLMNS = 48;
292 private static final int EVENT_GET_FORBIDDEN_PLMNS_DONE = 49;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000293 private static final int CMD_SWITCH_SLOTS = 50;
294 private static final int EVENT_SWITCH_SLOTS_DONE = 51;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700295 private static final int CMD_GET_NETWORK_SELECTION_MODE = 52;
296 private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 53;
297 private static final int CMD_GET_CDMA_ROAMING_MODE = 54;
298 private static final int EVENT_GET_CDMA_ROAMING_MODE_DONE = 55;
299 private static final int CMD_SET_CDMA_ROAMING_MODE = 56;
300 private static final int EVENT_SET_CDMA_ROAMING_MODE_DONE = 57;
301 private static final int CMD_SET_CDMA_SUBSCRIPTION_MODE = 58;
302 private static final int EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE = 59;
Nathan Harold3ff88932018-08-14 10:19:49 -0700303 private static final int CMD_GET_ALL_CELL_INFO = 60;
304 private static final int EVENT_GET_ALL_CELL_INFO_DONE = 61;
305 private static final int CMD_GET_CELL_LOCATION = 62;
306 private static final int EVENT_GET_CELL_LOCATION_DONE = 63;
chen xu6dac5ab2018-10-26 17:39:23 -0700307 private static final int CMD_MODEM_REBOOT = 64;
308 private static final int EVENT_CMD_MODEM_REBOOT_DONE = 65;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -0700309 private static final int CMD_REQUEST_CELL_INFO_UPDATE = 66;
310 private static final int EVENT_REQUEST_CELL_INFO_UPDATE_DONE = 67;
Malcolm Chen8e4ed912019-01-15 20:22:16 -0800311 private static final int CMD_REQUEST_ENABLE_MODEM = 68;
312 private static final int EVENT_ENABLE_MODEM_DONE = 69;
Nazanin Bakhshif71371d2019-04-29 17:29:44 -0700313 private static final int CMD_GET_MODEM_STATUS = 70;
314 private static final int EVENT_GET_MODEM_STATUS_DONE = 71;
yincheng zhao2737e882019-09-06 17:06:54 -0700315 private static final int CMD_SET_FORBIDDEN_PLMNS = 72;
316 private static final int EVENT_SET_FORBIDDEN_PLMNS_DONE = 73;
Naina Nallurid63128d2019-09-17 14:10:30 -0700317 private static final int CMD_ERASE_MODEM_CONFIG = 74;
318 private static final int EVENT_ERASE_MODEM_CONFIG_DONE = 75;
zoey chene02881a2019-12-30 16:11:23 +0800319 private static final int CMD_CHANGE_ICC_LOCK_PASSWORD = 76;
320 private static final int EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE = 77;
321 private static final int CMD_SET_ICC_LOCK_ENABLED = 78;
322 private static final int EVENT_SET_ICC_LOCK_ENABLED_DONE = 79;
Hall Liu73f5d362020-01-20 13:42:00 -0800323 private static final int CMD_SET_SYSTEM_SELECTION_CHANNELS = 80;
324 private static final int EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE = 81;
Peter Wangdafb9ac2020-01-15 14:13:38 -0800325 private static final int MSG_NOTIFY_USER_ACTIVITY = 82;
Shuo Qian4a594052020-01-23 11:59:30 -0800326 private static final int CMD_GET_CALL_FORWARDING = 83;
327 private static final int EVENT_GET_CALL_FORWARDING_DONE = 84;
328 private static final int CMD_SET_CALL_FORWARDING = 85;
329 private static final int EVENT_SET_CALL_FORWARDING_DONE = 86;
330 private static final int CMD_GET_CALL_WAITING = 87;
331 private static final int EVENT_GET_CALL_WAITING_DONE = 88;
332 private static final int CMD_SET_CALL_WAITING = 89;
333 private static final int EVENT_SET_CALL_WAITING_DONE = 90;
Sooraj Sasindran37444802020-08-11 10:40:43 -0700334 private static final int CMD_ENABLE_NR_DUAL_CONNECTIVITY = 91;
335 private static final int EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE = 92;
336 private static final int CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED = 93;
337 private static final int EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE = 94;
Sarah Chinbaab1432020-10-28 13:46:24 -0700338 private static final int CMD_GET_CDMA_SUBSCRIPTION_MODE = 95;
339 private static final int EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE = 96;
Sarah Chin679c08a2020-11-18 13:39:35 -0800340 private static final int CMD_GET_SYSTEM_SELECTION_CHANNELS = 97;
341 private static final int EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE = 98;
Jack Nudelmanb0b87642020-11-12 15:04:39 -0800342 private static final int CMD_SET_DATA_THROTTLING = 99;
343 private static final int EVENT_SET_DATA_THROTTLING_DONE = 100;
Jordan Liu109698e2020-11-24 14:50:34 -0800344 private static final int CMD_SET_SIM_POWER = 101;
345 private static final int EVENT_SET_SIM_POWER_DONE = 102;
Rambo Wanga5cc9b72021-01-07 10:51:54 -0800346 private static final int CMD_SET_SIGNAL_STRENGTH_UPDATE_REQUEST = 103;
347 private static final int EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE = 104;
348 private static final int CMD_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST = 105;
349 private static final int EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE = 106;
SongFerngWang3ef3e072020-12-21 16:41:52 +0800350 private static final int CMD_SET_ALLOWED_NETWORK_TYPES_FOR_REASON = 107;
351 private static final int EVENT_SET_ALLOWED_NETWORK_TYPES_FOR_REASON_DONE = 108;
Michele Berionne5e411512020-11-13 02:36:59 +0000352 private static final int CMD_PREPARE_UNATTENDED_REBOOT = 109;
Hongbo Zeng156aa4a2021-02-08 21:50:28 +0800353 private static final int CMD_GET_SLICING_CONFIG = 110;
354 private static final int EVENT_GET_SLICING_CONFIG_DONE = 111;
Kai Shif70f46f2021-03-03 13:59:46 -0800355 private static final int CMD_ERASE_DATA_SHARED_PREFERENCES = 112;
Sooraj Sasindrandaf060f2021-06-15 14:52:55 -0700356 private static final int CMD_ENABLE_VONR = 113;
357 private static final int EVENT_ENABLE_VONR_DONE = 114;
358 private static final int CMD_IS_VONR_ENABLED = 115;
359 private static final int EVENT_IS_VONR_ENABLED_DONE = 116;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700360
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -0800361 // Parameters of select command.
362 private static final int SELECT_COMMAND = 0xA4;
363 private static final int SELECT_P1 = 0x04;
364 private static final int SELECT_P2 = 0;
365 private static final int SELECT_P3 = 0x10;
366
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700367 /** The singleton instance. */
368 private static PhoneInterfaceManager sInstance;
Jack Nudelman644b91a2021-03-12 14:09:48 -0800369 private static List<String> sThermalMitigationAllowlistedPackages = new ArrayList<>();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700370
Wink Saville3ab207e2014-11-20 13:07:20 -0800371 private PhoneGlobals mApp;
Wink Saville3ab207e2014-11-20 13:07:20 -0800372 private CallManager mCM;
Brad Ebinger24c29992019-12-05 13:03:21 -0800373 private ImsResolver mImsResolver;
Stuart Scott981d8582015-04-21 14:09:50 -0700374 private UserManager mUserManager;
Wink Saville3ab207e2014-11-20 13:07:20 -0800375 private AppOpsManager mAppOps;
Grace Jia0ddb3612021-04-22 13:35:26 -0700376 private PackageManager mPm;
Wink Saville3ab207e2014-11-20 13:07:20 -0800377 private MainThreadHandler mMainThreadHandler;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800378 private SubscriptionController mSubscriptionController;
Wink Saville3ab207e2014-11-20 13:07:20 -0800379 private SharedPreferences mTelephonySharedPreferences;
Malcolm Chen2c63d402018-08-14 16:00:53 -0700380 private PhoneConfigurationManager mPhoneConfigurationManager;
Daniel Bright94f43662021-03-01 14:43:40 -0800381 private final RadioInterfaceCapabilityController mRadioInterfaceCapabilities;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700382
Peter Wangdafb9ac2020-01-15 14:13:38 -0800383 /** User Activity */
384 private AtomicBoolean mNotifyUserActivity;
Peter Wangdafb9ac2020-01-15 14:13:38 -0800385 private static final int USER_ACTIVITY_NOTIFICATION_DELAY = 200;
386
Jeff Davidson8ab02b22020-03-28 12:24:40 -0700387 private Set<Integer> mCarrierPrivilegeTestOverrideSubIds = new ArraySet<>();
388
Derek Tan97ebb422014-09-05 16:55:38 -0700389 private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
390 private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
Jeff Sharkey85190e62014-12-05 09:40:12 -0800391 private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
Brad Ebinger1c8542e2019-01-14 13:43:14 -0800392 private static final String PREF_PROVISION_IMS_MMTEL_PREFIX = "provision_ims_mmtel_";
Derek Tan89e89d42014-07-08 17:00:10 -0700393
Michelecea4cf22018-12-21 15:00:11 -0800394 // String to store multi SIM allowed
395 private static final String PREF_MULTI_SIM_RESTRICTED = "multisim_restricted";
396
Derek Tan740e1672017-06-27 14:56:27 -0700397 // The AID of ISD-R.
398 private static final String ISDR_AID = "A0000005591010FFFFFFFF8900000100";
399
yinxub1bed742017-04-17 11:45:04 -0700400 private NetworkScanRequestTracker mNetworkScanRequestTracker;
401
David Kelly5e06a7f2018-03-12 14:10:59 +0000402 private static final int TYPE_ALLOCATION_CODE_LENGTH = 8;
403 private static final int MANUFACTURER_CODE_LENGTH = 8;
404
Jack Nudelmanb0b87642020-11-12 15:04:39 -0800405 private static final int SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS = -1;
Jack Nudelman5d6a98b2021-03-04 14:26:25 -0800406 private static final int MODEM_DOES_NOT_SUPPORT_DATA_THROTTLING_ERROR_CODE = -2;
Jack Nudelmanb0b87642020-11-12 15:04:39 -0800407
Derek Tan89e89d42014-07-08 17:00:10 -0700408 /**
Naina Nallurid63128d2019-09-17 14:10:30 -0700409 * Experiment flag to enable erase modem config on reset network, default value is false
410 */
411 public static final String RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED =
412 "reset_network_erase_modem_config_enabled";
413
Rambo Wang0f050d82021-02-12 11:43:36 -0800414 private static final int SET_NETWORK_SELECTION_MODE_AUTOMATIC_TIMEOUT_MS = 2000; // 2 seconds
Chen Xu540470b2021-12-14 17:15:47 -0800415
sandeepjsb6c87872021-09-27 15:34:44 +0000416 /**
417 * With support for MEP(multiple enabled profile) in Android T, a SIM card can have more than
418 * one ICCID active at the same time.
419 * Apps should use below API signatures if targeting SDK is T and beyond.
420 *
421 * @hide
422 */
423 @ChangeId
424 @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
425 public static final long GET_API_SIGNATURES_FROM_UICC_PORT_INFO = 202110963L;
Rambo Wang0f050d82021-02-12 11:43:36 -0800426
Naina Nallurid63128d2019-09-17 14:10:30 -0700427 /**
Chen Xu540470b2021-12-14 17:15:47 -0800428 * Apps targeting on Android T and beyond will get exception whenever icc close channel
429 * operation fails.
430 */
431 @ChangeId
432 @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
433 public static final long ICC_CLOSE_CHANNEL_EXCEPTION_ON_FAILURE = 208739934L;
434
435 /**
Shishir Agrawal566b7612013-10-28 14:41:00 -0700436 * A request object to use for transmitting data to an ICC.
437 */
438 private static final class IccAPDUArgument {
439 public int channel, cla, command, p1, p2, p3;
440 public String data;
441
442 public IccAPDUArgument(int channel, int cla, int command,
443 int p1, int p2, int p3, String data) {
444 this.channel = channel;
445 this.cla = cla;
446 this.command = command;
447 this.p1 = p1;
448 this.p2 = p2;
449 this.p3 = p3;
450 this.data = data;
451 }
452 }
453
454 /**
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700455 * A request object to use for transmitting data to an ICC.
456 */
457 private static final class ManualNetworkSelectionArgument {
458 public OperatorInfo operatorInfo;
459 public boolean persistSelection;
460
461 public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) {
462 this.operatorInfo = operatorInfo;
463 this.persistSelection = persistSelection;
464 }
465 }
466
467 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700468 * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
469 * request after sending. The main thread will notify the request when it is complete.
470 */
471 private static final class MainThreadRequest {
472 /** The argument to use for the request */
473 public Object argument;
474 /** The result of the request that is run on the main thread */
475 public Object result;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800476 // The subscriber id that this request applies to. Defaults to
477 // SubscriptionManager.INVALID_SUBSCRIPTION_ID
478 public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700479
Nathan Harold92bed182018-10-12 18:16:49 -0700480 // In cases where subId is unavailable, the caller needs to specify the phone.
481 public Phone phone;
482
vagdeviaf9a5b92018-08-15 16:01:53 -0700483 public WorkSource workSource;
484
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700485 public MainThreadRequest(Object argument) {
486 this.argument = argument;
487 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800488
Nathan Harold92bed182018-10-12 18:16:49 -0700489 MainThreadRequest(Object argument, Phone phone, WorkSource workSource) {
490 this.argument = argument;
491 if (phone != null) {
492 this.phone = phone;
493 }
494 this.workSource = workSource;
495 }
496
vagdeviaf9a5b92018-08-15 16:01:53 -0700497 MainThreadRequest(Object argument, Integer subId, WorkSource workSource) {
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800498 this.argument = argument;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800499 if (subId != null) {
500 this.subId = subId;
501 }
vagdeviaf9a5b92018-08-15 16:01:53 -0700502 this.workSource = workSource;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800503 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700504 }
505
Sailesh Nepalcc0375f2013-11-13 09:15:18 -0800506 private static final class IncomingThirdPartyCallArgs {
507 public final ComponentName component;
508 public final String callId;
509 public final String callerDisplayName;
510
511 public IncomingThirdPartyCallArgs(ComponentName component, String callId,
512 String callerDisplayName) {
513 this.component = component;
514 this.callId = callId;
515 this.callerDisplayName = callerDisplayName;
516 }
517 }
518
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700519 /**
520 * A handler that processes messages on the main thread in the phone process. Since many
521 * of the Phone calls are not thread safe this is needed to shuttle the requests from the
522 * inbound binder threads to the main thread in the phone process. The Binder thread
523 * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
524 * on, which will be notified when the operation completes and will contain the result of the
525 * request.
526 *
527 * <p>If a MainThreadRequest object is provided in the msg.obj field,
528 * note that request.result must be set to something non-null for the calling thread to
529 * unblock.
530 */
531 private final class MainThreadHandler extends Handler {
532 @Override
533 public void handleMessage(Message msg) {
534 MainThreadRequest request;
535 Message onCompleted;
536 AsyncResult ar;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000537 UiccPort uiccPort;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700538 IccAPDUArgument iccArgument;
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800539 final Phone defaultPhone = getDefaultPhone();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700540
541 switch (msg.what) {
Pengquan Menga1bb6272018-09-06 09:59:22 -0700542 case CMD_HANDLE_USSD_REQUEST: {
543 request = (MainThreadRequest) msg.obj;
544 final Phone phone = getPhoneFromRequest(request);
545 Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
Chen Xue9d737e2022-01-01 23:41:31 -0800546 String ussdRequest = ussdObject.first;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700547 ResultReceiver wrappedCallback = ussdObject.second;
Tyler Gunn65d45c22017-06-05 11:22:26 -0700548
Pengquan Menga1bb6272018-09-06 09:59:22 -0700549 if (!isUssdApiAllowed(request.subId)) {
550 // Carrier does not support use of this API, return failure.
551 Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
552 UssdResponse response = new UssdResponse(ussdRequest, null);
553 Bundle returnData = new Bundle();
554 returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
555 wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
Tyler Gunn65d45c22017-06-05 11:22:26 -0700556
Pengquan Menga1bb6272018-09-06 09:59:22 -0700557 request.result = true;
558 notifyRequester(request);
559 return;
560 }
Tyler Gunn65d45c22017-06-05 11:22:26 -0700561
Pengquan Menga1bb6272018-09-06 09:59:22 -0700562 try {
563 request.result = phone != null
564 ? phone.handleUssdRequest(ussdRequest, wrappedCallback) : false;
565 } catch (CallStateException cse) {
566 request.result = false;
567 }
568 // Wake up the requesting thread
569 notifyRequester(request);
570 break;
pkanwar32d516d2016-10-14 19:37:38 -0700571 }
572
Yorke Lee716f67e2015-06-17 15:39:16 -0700573 case CMD_HANDLE_PIN_MMI: {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700574 request = (MainThreadRequest) msg.obj;
Yorke Lee716f67e2015-06-17 15:39:16 -0700575 final Phone phone = getPhoneFromRequest(request);
576 request.result = phone != null ?
577 getPhoneFromRequest(request).handlePinMmi((String) request.argument)
578 : false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700579 // Wake up the requesting thread
Pengquan Menga1bb6272018-09-06 09:59:22 -0700580 notifyRequester(request);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700581 break;
Yorke Lee716f67e2015-06-17 15:39:16 -0700582 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700583
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700584 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700585 request = (MainThreadRequest) msg.obj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700586 iccArgument = (IccAPDUArgument) request.argument;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000587 uiccPort = getUiccPortFromRequest(request);
588 if (uiccPort == null) {
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700589 loge("iccTransmitApduLogicalChannel: No UICC");
Chen Xue9d737e2022-01-01 23:41:31 -0800590 request.result = new IccIoResult(0x6F, 0, (byte[]) null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700591 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700592 } else {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700593 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
Chen Xue9d737e2022-01-01 23:41:31 -0800594 request);
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000595 uiccPort.iccTransmitApduLogicalChannel(
Chen Xue9d737e2022-01-01 23:41:31 -0800596 iccArgument.channel, iccArgument.cla, iccArgument.command,
597 iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data,
598 onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700599 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700600 break;
601
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700602 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700603 ar = (AsyncResult) msg.obj;
604 request = (MainThreadRequest) ar.userObj;
605 if (ar.exception == null && ar.result != null) {
606 request.result = ar.result;
607 } else {
Chen Xue9d737e2022-01-01 23:41:31 -0800608 request.result = new IccIoResult(0x6F, 0, (byte[]) null);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700609 if (ar.result == null) {
610 loge("iccTransmitApduLogicalChannel: Empty response");
Jake Hambye994d462014-02-03 13:10:13 -0800611 } else if (ar.exception instanceof CommandException) {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700612 loge("iccTransmitApduLogicalChannel: CommandException: " +
Jake Hambye994d462014-02-03 13:10:13 -0800613 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700614 } else {
615 loge("iccTransmitApduLogicalChannel: Unknown exception");
616 }
617 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700618 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700619 break;
620
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700621 case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
622 request = (MainThreadRequest) msg.obj;
623 iccArgument = (IccAPDUArgument) request.argument;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000624 uiccPort = getUiccPortFromRequest(request);
625 if (uiccPort == null) {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700626 loge("iccTransmitApduBasicChannel: No UICC");
Chen Xue9d737e2022-01-01 23:41:31 -0800627 request.result = new IccIoResult(0x6F, 0, (byte[]) null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700628 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700629 } else {
630 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
Chen Xue9d737e2022-01-01 23:41:31 -0800631 request);
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000632 uiccPort.iccTransmitApduBasicChannel(
Chen Xue9d737e2022-01-01 23:41:31 -0800633 iccArgument.cla, iccArgument.command, iccArgument.p1,
634 iccArgument.p2,
635 iccArgument.p3, iccArgument.data, onCompleted);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700636 }
637 break;
638
639 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
640 ar = (AsyncResult) msg.obj;
641 request = (MainThreadRequest) ar.userObj;
642 if (ar.exception == null && ar.result != null) {
643 request.result = ar.result;
644 } else {
Chen Xue9d737e2022-01-01 23:41:31 -0800645 request.result = new IccIoResult(0x6F, 0, (byte[]) null);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700646 if (ar.result == null) {
647 loge("iccTransmitApduBasicChannel: Empty response");
648 } else if (ar.exception instanceof CommandException) {
649 loge("iccTransmitApduBasicChannel: CommandException: " +
650 ar.exception);
651 } else {
652 loge("iccTransmitApduBasicChannel: Unknown exception");
653 }
654 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700655 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700656 break;
657
658 case CMD_EXCHANGE_SIM_IO:
659 request = (MainThreadRequest) msg.obj;
660 iccArgument = (IccAPDUArgument) request.argument;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000661 uiccPort = getUiccPortFromRequest(request);
662 if (uiccPort == null) {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700663 loge("iccExchangeSimIO: No UICC");
Chen Xue9d737e2022-01-01 23:41:31 -0800664 request.result = new IccIoResult(0x6F, 0, (byte[]) null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700665 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700666 } else {
667 onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
668 request);
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000669 uiccPort.iccExchangeSimIO(iccArgument.cla, /* fileID */
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700670 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3,
671 iccArgument.data, onCompleted);
672 }
673 break;
674
675 case EVENT_EXCHANGE_SIM_IO_DONE:
676 ar = (AsyncResult) msg.obj;
677 request = (MainThreadRequest) ar.userObj;
678 if (ar.exception == null && ar.result != null) {
679 request.result = ar.result;
680 } else {
Chen Xue9d737e2022-01-01 23:41:31 -0800681 request.result = new IccIoResult(0x6f, 0, (byte[]) null);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700682 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700683 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700684 break;
685
Derek Tan4d5e5c12014-02-04 11:54:58 -0800686 case CMD_SEND_ENVELOPE:
687 request = (MainThreadRequest) msg.obj;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000688 uiccPort = getUiccPortFromRequest(request);
689 if (uiccPort == null) {
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700690 loge("sendEnvelopeWithStatus: No UICC");
Chen Xue9d737e2022-01-01 23:41:31 -0800691 request.result = new IccIoResult(0x6F, 0, (byte[]) null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700692 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700693 } else {
694 onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
Chen Xue9d737e2022-01-01 23:41:31 -0800695 uiccPort.sendEnvelopeWithStatus((String) request.argument, onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700696 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800697 break;
698
699 case EVENT_SEND_ENVELOPE_DONE:
700 ar = (AsyncResult) msg.obj;
701 request = (MainThreadRequest) ar.userObj;
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700702 if (ar.exception == null && ar.result != null) {
703 request.result = ar.result;
Derek Tan4d5e5c12014-02-04 11:54:58 -0800704 } else {
Chen Xue9d737e2022-01-01 23:41:31 -0800705 request.result = new IccIoResult(0x6F, 0, (byte[]) null);
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700706 if (ar.result == null) {
707 loge("sendEnvelopeWithStatus: Empty response");
708 } else if (ar.exception instanceof CommandException) {
709 loge("sendEnvelopeWithStatus: CommandException: " +
710 ar.exception);
711 } else {
712 loge("sendEnvelopeWithStatus: exception:" + ar.exception);
713 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800714 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700715 notifyRequester(request);
Derek Tan4d5e5c12014-02-04 11:54:58 -0800716 break;
717
Shishir Agrawal566b7612013-10-28 14:41:00 -0700718 case CMD_OPEN_CHANNEL:
719 request = (MainThreadRequest) msg.obj;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000720 uiccPort = getUiccPortFromRequest(request);
Rambo Wanga1782702021-11-10 20:15:19 -0800721 IccLogicalChannelRequest openChannelRequest =
722 (IccLogicalChannelRequest) request.argument;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000723 if (uiccPort == null) {
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700724 loge("iccOpenLogicalChannel: No UICC");
Shishir Agrawalfc0492a2016-02-17 11:15:33 -0800725 request.result = new IccOpenLogicalChannelResponse(-1,
Chen Xue9d737e2022-01-01 23:41:31 -0800726 IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700727 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700728 } else {
729 onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
Rambo Wanga1782702021-11-10 20:15:19 -0800730 uiccPort.iccOpenLogicalChannel(openChannelRequest.aid,
731 openChannelRequest.p2, onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700732 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700733 break;
734
735 case EVENT_OPEN_CHANNEL_DONE:
736 ar = (AsyncResult) msg.obj;
737 request = (MainThreadRequest) ar.userObj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700738 IccOpenLogicalChannelResponse openChannelResp;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700739 if (ar.exception == null && ar.result != null) {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700740 int[] result = (int[]) ar.result;
741 int channelId = result[0];
742 byte[] selectResponse = null;
743 if (result.length > 1) {
744 selectResponse = new byte[result.length - 1];
745 for (int i = 1; i < result.length; ++i) {
746 selectResponse[i - 1] = (byte) result[i];
747 }
748 }
749 openChannelResp = new IccOpenLogicalChannelResponse(channelId,
Chen Xue9d737e2022-01-01 23:41:31 -0800750 IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse);
Rambo Wang3b77c4c2021-11-10 20:15:19 -0800751
752 uiccPort = getUiccPortFromRequest(request);
753 IccLogicalChannelRequest channelRequest =
754 (IccLogicalChannelRequest) request.argument;
755 channelRequest.channel = channelId;
756 uiccPort.onLogicalChannelOpened(channelRequest);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700757 } else {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700758 if (ar.result == null) {
759 loge("iccOpenLogicalChannel: Empty response");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700760 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700761 if (ar.exception != null) {
762 loge("iccOpenLogicalChannel: Exception: " + ar.exception);
763 }
764
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700765 int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR;
Junda Liua754ba12015-05-20 01:17:52 -0700766 if (ar.exception instanceof CommandException) {
767 CommandException.Error error =
Chen Xue9d737e2022-01-01 23:41:31 -0800768 ((CommandException) (ar.exception)).getCommandError();
Junda Liua754ba12015-05-20 01:17:52 -0700769 if (error == CommandException.Error.MISSING_RESOURCE) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700770 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE;
Junda Liua754ba12015-05-20 01:17:52 -0700771 } else if (error == CommandException.Error.NO_SUCH_ELEMENT) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700772 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700773 }
774 }
775 openChannelResp = new IccOpenLogicalChannelResponse(
Chen Xue9d737e2022-01-01 23:41:31 -0800776 IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700777 }
Shishir Agrawal82c8a462014-07-31 18:13:17 -0700778 request.result = openChannelResp;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700779 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700780 break;
781
782 case CMD_CLOSE_CHANNEL:
783 request = (MainThreadRequest) msg.obj;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000784 uiccPort = getUiccPortFromRequest(request);
785 if (uiccPort == null) {
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700786 loge("iccCloseLogicalChannel: No UICC");
Chen Xue9d737e2022-01-01 23:41:31 -0800787 // before this feature is enabled, this API should only return false if
788 // the operation fails instead of throwing runtime exception for
789 // backward-compatibility.
790 if (Compatibility.isChangeEnabled(ICC_CLOSE_CHANNEL_EXCEPTION_ON_FAILURE)) {
791 request.result = new IllegalArgumentException(
792 "iccCloseLogicalChannel: No UICC");
793 } else {
794 request.result = false;
795 }
796 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700797 } else {
798 onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +0000799 uiccPort.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700800 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700801 break;
802
803 case EVENT_CLOSE_CHANNEL_DONE:
Chen Xu540470b2021-12-14 17:15:47 -0800804 ar = (AsyncResult) msg.obj;
805 request = (MainThreadRequest) ar.userObj;
806 if (ar.exception == null) {
807 request.result = true;
Rambo Wang3b77c4c2021-11-10 20:15:19 -0800808 uiccPort = getUiccPortFromRequest(request);
809 final int channelId = (Integer) request.argument;
810 uiccPort.onLogicalChannelClosed(channelId);
Chen Xu540470b2021-12-14 17:15:47 -0800811 } else {
812 request.result = false;
Chen Xue9d737e2022-01-01 23:41:31 -0800813 Exception exception = null;
Chen Xu540470b2021-12-14 17:15:47 -0800814 if (ar.exception instanceof CommandException) {
815 loge("iccCloseLogicalChannel: CommandException: " + ar.exception);
816 CommandException.Error error =
817 ((CommandException) (ar.exception)).getCommandError();
Chen Xue9d737e2022-01-01 23:41:31 -0800818 if (error == CommandException.Error.INVALID_ARGUMENTS) {
819 // should only throw exceptions from the binder threads.
820 exception = new IllegalArgumentException(
Chen Xu540470b2021-12-14 17:15:47 -0800821 "iccCloseLogicalChannel: invalid argument ");
822 }
823 } else {
824 loge("iccCloseLogicalChannel: Unknown exception");
825 }
Chen Xue9d737e2022-01-01 23:41:31 -0800826 // before this feature is enabled, this API should only return false if
827 // the operation fails instead of throwing runtime exception for
828 // backward-compatibility.
829 if (Compatibility.isChangeEnabled(ICC_CLOSE_CHANNEL_EXCEPTION_ON_FAILURE))
830 request.result = (exception != null) ? exception :
831 new IllegalStateException(
832 "exception from modem to close iccLogical Channel");
Chen Xu540470b2021-12-14 17:15:47 -0800833 }
834 notifyRequester(request);
Jake Hambye994d462014-02-03 13:10:13 -0800835 break;
836
837 case CMD_NV_READ_ITEM:
838 request = (MainThreadRequest) msg.obj;
839 onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800840 defaultPhone.nvReadItem((Integer) request.argument, onCompleted,
841 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800842 break;
843
844 case EVENT_NV_READ_ITEM_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700845 ar = (AsyncResult) msg.obj;
846 request = (MainThreadRequest) ar.userObj;
Jake Hambye994d462014-02-03 13:10:13 -0800847 if (ar.exception == null && ar.result != null) {
848 request.result = ar.result; // String
Shishir Agrawal566b7612013-10-28 14:41:00 -0700849 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800850 request.result = "";
851 if (ar.result == null) {
852 loge("nvReadItem: Empty response");
853 } else if (ar.exception instanceof CommandException) {
854 loge("nvReadItem: CommandException: " +
855 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700856 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800857 loge("nvReadItem: Unknown exception");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700858 }
859 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700860 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700861 break;
862
Jake Hambye994d462014-02-03 13:10:13 -0800863 case CMD_NV_WRITE_ITEM:
864 request = (MainThreadRequest) msg.obj;
865 onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
866 Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800867 defaultPhone.nvWriteItem(idValue.first, idValue.second, onCompleted,
vagdeviaf9a5b92018-08-15 16:01:53 -0700868 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800869 break;
870
871 case EVENT_NV_WRITE_ITEM_DONE:
872 handleNullReturnEvent(msg, "nvWriteItem");
873 break;
874
875 case CMD_NV_WRITE_CDMA_PRL:
876 request = (MainThreadRequest) msg.obj;
877 onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800878 defaultPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
Jake Hambye994d462014-02-03 13:10:13 -0800879 break;
880
881 case EVENT_NV_WRITE_CDMA_PRL_DONE:
882 handleNullReturnEvent(msg, "nvWriteCdmaPrl");
883 break;
884
chen xu6dac5ab2018-10-26 17:39:23 -0700885 case CMD_RESET_MODEM_CONFIG:
Jake Hambye994d462014-02-03 13:10:13 -0800886 request = (MainThreadRequest) msg.obj;
chen xu6dac5ab2018-10-26 17:39:23 -0700887 onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -0800888 defaultPhone.resetModemConfig(onCompleted);
Jake Hambye994d462014-02-03 13:10:13 -0800889 break;
890
chen xu6dac5ab2018-10-26 17:39:23 -0700891 case EVENT_RESET_MODEM_CONFIG_DONE:
892 handleNullReturnEvent(msg, "resetModemConfig");
Jake Hambye994d462014-02-03 13:10:13 -0800893 break;
894
Sooraj Sasindran37444802020-08-11 10:40:43 -0700895 case CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED: {
896 request = (MainThreadRequest) msg.obj;
897 onCompleted = obtainMessage(EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE,
898 request);
899 Phone phone = getPhoneFromRequest(request);
900 if (phone != null) {
901 phone.isNrDualConnectivityEnabled(onCompleted, request.workSource);
902 } else {
903 loge("isNRDualConnectivityEnabled: No phone object");
904 request.result = false;
905 notifyRequester(request);
906 }
907 break;
908 }
909
910 case EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE:
911 ar = (AsyncResult) msg.obj;
912 request = (MainThreadRequest) ar.userObj;
913 if (ar.exception == null && ar.result != null) {
914 request.result = ar.result;
915 } else {
916 // request.result must be set to something non-null
917 // for the calling thread to unblock
Sooraj Sasindrandaf060f2021-06-15 14:52:55 -0700918 if (ar.result != null) {
Sooraj Sasindran37444802020-08-11 10:40:43 -0700919 request.result = ar.result;
920 } else {
921 request.result = false;
922 }
923 if (ar.result == null) {
924 loge("isNRDualConnectivityEnabled: Empty response");
925 } else if (ar.exception instanceof CommandException) {
926 loge("isNRDualConnectivityEnabled: CommandException: "
927 + ar.exception);
928 } else {
929 loge("isNRDualConnectivityEnabled: Unknown exception");
930 }
931 }
932 notifyRequester(request);
933 break;
934
Sooraj Sasindrandaf060f2021-06-15 14:52:55 -0700935 case CMD_IS_VONR_ENABLED: {
936 request = (MainThreadRequest) msg.obj;
937 onCompleted = obtainMessage(EVENT_IS_VONR_ENABLED_DONE,
938 request);
939 Phone phone = getPhoneFromRequest(request);
940 if (phone != null) {
941 phone.isVoNrEnabled(onCompleted, request.workSource);
942 } else {
943 loge("isVoNrEnabled: No phone object");
944 request.result = false;
945 notifyRequester(request);
946 }
947 break;
948 }
949
950 case EVENT_IS_VONR_ENABLED_DONE:
951 ar = (AsyncResult) msg.obj;
952 request = (MainThreadRequest) ar.userObj;
953 if (ar.exception == null && ar.result != null) {
954 request.result = ar.result;
955 } else {
956 // request.result must be set to something non-null
957 // for the calling thread to unblock
958 if (ar.result != null) {
959 request.result = ar.result;
960 } else {
961 request.result = false;
962 }
963 if (ar.result == null) {
964 loge("isVoNrEnabled: Empty response");
965 } else if (ar.exception instanceof CommandException) {
966 loge("isVoNrEnabled: CommandException: "
967 + ar.exception);
968 } else {
969 loge("isVoNrEnabled: Unknown exception");
970 }
971 }
972 notifyRequester(request);
973 break;
974
Sooraj Sasindran37444802020-08-11 10:40:43 -0700975 case CMD_ENABLE_NR_DUAL_CONNECTIVITY: {
976 request = (MainThreadRequest) msg.obj;
977 onCompleted = obtainMessage(EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE, request);
978 Phone phone = getPhoneFromRequest(request);
979 if (phone != null) {
980 phone.setNrDualConnectivityState((int) request.argument, onCompleted,
981 request.workSource);
982 } else {
983 loge("enableNrDualConnectivity: No phone object");
984 request.result =
985 TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE;
986 notifyRequester(request);
987 }
988 break;
989 }
990
991 case EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE: {
992 ar = (AsyncResult) msg.obj;
993 request = (MainThreadRequest) ar.userObj;
994 if (ar.exception == null) {
995 request.result =
996 TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_SUCCESS;
997 } else {
998 request.result =
999 TelephonyManager
1000 .ENABLE_NR_DUAL_CONNECTIVITY_RADIO_ERROR;
1001 if (ar.exception instanceof CommandException) {
1002 CommandException.Error error =
1003 ((CommandException) (ar.exception)).getCommandError();
1004 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1005 request.result =
1006 TelephonyManager
1007 .ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE;
Sooraj Sasindran29654162021-03-03 23:00:01 +00001008 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1009 request.result =
1010 TelephonyManager
1011 .ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED;
Sooraj Sasindran37444802020-08-11 10:40:43 -07001012 }
1013 loge("enableNrDualConnectivity" + ": CommandException: "
1014 + ar.exception);
1015 } else {
1016 loge("enableNrDualConnectivity" + ": Unknown exception");
1017 }
1018 }
1019 notifyRequester(request);
1020 break;
1021 }
1022
Sooraj Sasindrandaf060f2021-06-15 14:52:55 -07001023 case CMD_ENABLE_VONR: {
1024 request = (MainThreadRequest) msg.obj;
1025 onCompleted = obtainMessage(EVENT_ENABLE_VONR_DONE, request);
1026 Phone phone = getPhoneFromRequest(request);
1027 if (phone != null) {
1028 phone.setVoNrEnabled((boolean) request.argument, onCompleted,
1029 request.workSource);
1030 } else {
1031 loge("setVoNrEnabled: No phone object");
1032 request.result =
1033 TelephonyManager.ENABLE_VONR_RADIO_NOT_AVAILABLE;
1034 notifyRequester(request);
1035 }
1036 break;
1037 }
1038
1039 case EVENT_ENABLE_VONR_DONE: {
1040 ar = (AsyncResult) msg.obj;
1041 request = (MainThreadRequest) ar.userObj;
1042 if (ar.exception == null) {
1043 request.result = TelephonyManager.ENABLE_VONR_SUCCESS;
1044 } else {
1045 request.result = TelephonyManager.ENABLE_VONR_RADIO_ERROR;
1046 if (ar.exception instanceof CommandException) {
1047 CommandException.Error error =
1048 ((CommandException) (ar.exception)).getCommandError();
1049 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1050 request.result = TelephonyManager.ENABLE_VONR_RADIO_NOT_AVAILABLE;
1051 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1052 request.result = TelephonyManager.ENABLE_VONR_REQUEST_NOT_SUPPORTED;
1053 } else {
1054 request.result = TelephonyManager.ENABLE_VONR_RADIO_ERROR;
1055 }
1056 loge("setVoNrEnabled" + ": CommandException: "
1057 + ar.exception);
1058 } else {
1059 loge("setVoNrEnabled" + ": Unknown exception");
1060 }
1061 }
1062 notifyRequester(request);
1063 break;
1064 }
1065
SongFerngWang3ef3e072020-12-21 16:41:52 +08001066 case CMD_GET_ALLOWED_NETWORK_TYPES_BITMASK:
Jake Hamby7c27be32014-03-03 13:25:59 -08001067 request = (MainThreadRequest) msg.obj;
SongFerngWang3ef3e072020-12-21 16:41:52 +08001068 onCompleted = obtainMessage(EVENT_GET_ALLOWED_NETWORK_TYPES_BITMASK_DONE,
1069 request);
1070 getPhoneFromRequest(request).getAllowedNetworkTypesBitmask(onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -08001071 break;
1072
SongFerngWang3ef3e072020-12-21 16:41:52 +08001073 case EVENT_GET_ALLOWED_NETWORK_TYPES_BITMASK_DONE:
Jake Hamby7c27be32014-03-03 13:25:59 -08001074 ar = (AsyncResult) msg.obj;
1075 request = (MainThreadRequest) ar.userObj;
1076 if (ar.exception == null && ar.result != null) {
1077 request.result = ar.result; // Integer
1078 } else {
Nazish Tabassume8ba43a2020-07-28 14:49:25 +05301079 // request.result must be set to something non-null
1080 // for the calling thread to unblock
1081 request.result = new int[]{-1};
Jake Hamby7c27be32014-03-03 13:25:59 -08001082 if (ar.result == null) {
SongFerngWang3ef3e072020-12-21 16:41:52 +08001083 loge("getAllowedNetworkTypesBitmask: Empty response");
Jake Hamby7c27be32014-03-03 13:25:59 -08001084 } else if (ar.exception instanceof CommandException) {
SongFerngWang3ef3e072020-12-21 16:41:52 +08001085 loge("getAllowedNetworkTypesBitmask: CommandException: "
1086 + ar.exception);
Jake Hamby7c27be32014-03-03 13:25:59 -08001087 } else {
SongFerngWang3ef3e072020-12-21 16:41:52 +08001088 loge("getAllowedNetworkTypesBitmask: Unknown exception");
Jake Hamby7c27be32014-03-03 13:25:59 -08001089 }
1090 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001091 notifyRequester(request);
Jake Hamby7c27be32014-03-03 13:25:59 -08001092 break;
1093
SongFerngWang3ef3e072020-12-21 16:41:52 +08001094 case CMD_SET_ALLOWED_NETWORK_TYPES_FOR_REASON:
Jake Hamby7c27be32014-03-03 13:25:59 -08001095 request = (MainThreadRequest) msg.obj;
SongFerngWang3ef3e072020-12-21 16:41:52 +08001096 onCompleted = obtainMessage(EVENT_SET_ALLOWED_NETWORK_TYPES_FOR_REASON_DONE,
1097 request);
1098 Pair<Integer, Long> reasonWithNetworkTypes =
1099 (Pair<Integer, Long>) request.argument;
1100 getPhoneFromRequest(request).setAllowedNetworkTypes(
1101 reasonWithNetworkTypes.first,
1102 reasonWithNetworkTypes.second,
1103 onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -08001104 break;
1105
SongFerngWang3ef3e072020-12-21 16:41:52 +08001106 case EVENT_SET_ALLOWED_NETWORK_TYPES_FOR_REASON_DONE:
1107 handleNullReturnEvent(msg, "setAllowedNetworkTypesForReason");
Jake Hamby7c27be32014-03-03 13:25:59 -08001108 break;
1109
Shuo Qian850e4d6a2018-04-25 21:02:08 +00001110 case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
1111 request = (MainThreadRequest)msg.obj;
1112 onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001113 defaultPhone.invokeOemRilRequestRaw((byte[]) request.argument, onCompleted);
Shuo Qian850e4d6a2018-04-25 21:02:08 +00001114 break;
1115
1116 case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
1117 ar = (AsyncResult)msg.obj;
1118 request = (MainThreadRequest)ar.userObj;
1119 request.result = ar;
Pengquan Menga1bb6272018-09-06 09:59:22 -07001120 notifyRequester(request);
Shuo Qian850e4d6a2018-04-25 21:02:08 +00001121 break;
1122
Shishir Agrawal76d5da92014-11-09 16:17:25 -08001123 case CMD_SET_VOICEMAIL_NUMBER:
1124 request = (MainThreadRequest) msg.obj;
1125 onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
1126 Pair<String, String> tagNum = (Pair<String, String>) request.argument;
Stuart Scott584921c2015-01-15 17:10:34 -08001127 getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
1128 onCompleted);
Shishir Agrawal76d5da92014-11-09 16:17:25 -08001129 break;
1130
1131 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
1132 handleNullReturnEvent(msg, "setVoicemailNumber");
1133 break;
1134
Stuart Scott54788802015-03-30 13:18:01 -07001135 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC:
1136 request = (MainThreadRequest) msg.obj;
1137 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE,
1138 request);
1139 getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted);
1140 break;
1141
1142 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE:
1143 handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic");
1144 break;
1145
Shishir Agrawal302c8692015-06-19 13:49:39 -07001146 case CMD_PERFORM_NETWORK_SCAN:
1147 request = (MainThreadRequest) msg.obj;
1148 onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request);
1149 getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
1150 break;
1151
Hall Liu27d24262020-09-18 19:04:59 -07001152 case CMD_GET_CALL_FORWARDING: {
Shuo Qian4a594052020-01-23 11:59:30 -08001153 request = (MainThreadRequest) msg.obj;
1154 onCompleted = obtainMessage(EVENT_GET_CALL_FORWARDING_DONE, request);
Hall Liu27d24262020-09-18 19:04:59 -07001155 Pair<Integer, TelephonyManager.CallForwardingInfoCallback> args =
1156 (Pair<Integer, TelephonyManager.CallForwardingInfoCallback>)
1157 request.argument;
1158 int callForwardingReason = args.first;
1159 request.phone.getCallForwardingOption(callForwardingReason, onCompleted);
Shuo Qian4a594052020-01-23 11:59:30 -08001160 break;
Hall Liu27d24262020-09-18 19:04:59 -07001161 }
1162 case EVENT_GET_CALL_FORWARDING_DONE: {
Shuo Qian4a594052020-01-23 11:59:30 -08001163 ar = (AsyncResult) msg.obj;
1164 request = (MainThreadRequest) ar.userObj;
Hall Liu27d24262020-09-18 19:04:59 -07001165 TelephonyManager.CallForwardingInfoCallback callback =
1166 ((Pair<Integer, TelephonyManager.CallForwardingInfoCallback>)
1167 request.argument).second;
Shuo Qian4a594052020-01-23 11:59:30 -08001168 if (ar.exception == null && ar.result != null) {
Hall Liu27d24262020-09-18 19:04:59 -07001169 CallForwardingInfo callForwardingInfo = null;
Shuo Qian4a594052020-01-23 11:59:30 -08001170 CallForwardInfo[] callForwardInfos = (CallForwardInfo[]) ar.result;
1171 for (CallForwardInfo callForwardInfo : callForwardInfos) {
1172 // Service Class is a bit mask per 3gpp 27.007. Search for
1173 // any service for voice call.
1174 if ((callForwardInfo.serviceClass
1175 & CommandsInterface.SERVICE_CLASS_VOICE) > 0) {
Yuchen Dong69cc1412021-09-27 20:27:01 +08001176 callForwardingInfo = new CallForwardingInfo(
1177 callForwardInfo.status
1178 == CommandsInterface.CF_ACTION_ENABLE,
Hall Liu27d24262020-09-18 19:04:59 -07001179 callForwardInfo.reason,
1180 callForwardInfo.number,
1181 callForwardInfo.timeSeconds);
Shuo Qian4a594052020-01-23 11:59:30 -08001182 break;
1183 }
1184 }
1185 // Didn't find a call forward info for voice call.
1186 if (callForwardingInfo == null) {
Hall Liu27d24262020-09-18 19:04:59 -07001187 callForwardingInfo = new CallForwardingInfo(false /* enabled */,
1188 0 /* reason */, null /* number */, 0 /* timeout */);
Shuo Qian4a594052020-01-23 11:59:30 -08001189 }
Hall Liu27d24262020-09-18 19:04:59 -07001190 callback.onCallForwardingInfoAvailable(callForwardingInfo);
Shuo Qian4a594052020-01-23 11:59:30 -08001191 } else {
1192 if (ar.result == null) {
1193 loge("EVENT_GET_CALL_FORWARDING_DONE: Empty response");
1194 }
1195 if (ar.exception != null) {
1196 loge("EVENT_GET_CALL_FORWARDING_DONE: Exception: " + ar.exception);
1197 }
Hall Liu940c4ca2020-09-29 17:10:18 -07001198 int errorCode = TelephonyManager
1199 .CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN;
Shuo Qian4a594052020-01-23 11:59:30 -08001200 if (ar.exception instanceof CommandException) {
1201 CommandException.Error error =
1202 ((CommandException) (ar.exception)).getCommandError();
1203 if (error == CommandException.Error.FDN_CHECK_FAILURE) {
Hall Liu940c4ca2020-09-29 17:10:18 -07001204 errorCode = TelephonyManager
1205 .CallForwardingInfoCallback.RESULT_ERROR_FDN_CHECK_FAILURE;
Shuo Qian4a594052020-01-23 11:59:30 -08001206 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
Hall Liu940c4ca2020-09-29 17:10:18 -07001207 errorCode = TelephonyManager
1208 .CallForwardingInfoCallback.RESULT_ERROR_NOT_SUPPORTED;
Shuo Qian4a594052020-01-23 11:59:30 -08001209 }
1210 }
Hall Liu27d24262020-09-18 19:04:59 -07001211 callback.onError(errorCode);
Shuo Qian4a594052020-01-23 11:59:30 -08001212 }
Shuo Qian4a594052020-01-23 11:59:30 -08001213 break;
Hall Liu27d24262020-09-18 19:04:59 -07001214 }
Shuo Qian4a594052020-01-23 11:59:30 -08001215
Hall Liu27d24262020-09-18 19:04:59 -07001216 case CMD_SET_CALL_FORWARDING: {
Shuo Qian4a594052020-01-23 11:59:30 -08001217 request = (MainThreadRequest) msg.obj;
1218 onCompleted = obtainMessage(EVENT_SET_CALL_FORWARDING_DONE, request);
Hall Liu27d24262020-09-18 19:04:59 -07001219 request = (MainThreadRequest) msg.obj;
Shuo Qian4a594052020-01-23 11:59:30 -08001220 CallForwardingInfo callForwardingInfoToSet =
Hall Liu27d24262020-09-18 19:04:59 -07001221 ((Pair<CallForwardingInfo, Consumer<Integer>>)
1222 request.argument).first;
1223 request.phone.setCallForwardingOption(
1224 callForwardingInfoToSet.isEnabled()
Calvin Pan258f1f72021-07-28 21:46:56 +08001225 ? CommandsInterface.CF_ACTION_REGISTRATION
Hall Liu27d24262020-09-18 19:04:59 -07001226 : CommandsInterface.CF_ACTION_DISABLE,
Shuo Qian4a594052020-01-23 11:59:30 -08001227 callForwardingInfoToSet.getReason(),
1228 callForwardingInfoToSet.getNumber(),
1229 callForwardingInfoToSet.getTimeoutSeconds(), onCompleted);
1230 break;
Hall Liu27d24262020-09-18 19:04:59 -07001231 }
Shuo Qian4a594052020-01-23 11:59:30 -08001232
Hall Liu27d24262020-09-18 19:04:59 -07001233 case EVENT_SET_CALL_FORWARDING_DONE: {
Shuo Qian4a594052020-01-23 11:59:30 -08001234 ar = (AsyncResult) msg.obj;
1235 request = (MainThreadRequest) ar.userObj;
Hall Liu27d24262020-09-18 19:04:59 -07001236 Consumer<Integer> callback =
1237 ((Pair<CallForwardingInfo, Consumer<Integer>>)
1238 request.argument).second;
1239 if (ar.exception != null) {
Shuo Qian4a594052020-01-23 11:59:30 -08001240 loge("setCallForwarding exception: " + ar.exception);
Hall Liu940c4ca2020-09-29 17:10:18 -07001241 int errorCode = TelephonyManager.CallForwardingInfoCallback
1242 .RESULT_ERROR_UNKNOWN;
Hall Liu27d24262020-09-18 19:04:59 -07001243 if (ar.exception instanceof CommandException) {
1244 CommandException.Error error =
1245 ((CommandException) (ar.exception)).getCommandError();
1246 if (error == CommandException.Error.FDN_CHECK_FAILURE) {
Hall Liu940c4ca2020-09-29 17:10:18 -07001247 errorCode = TelephonyManager.CallForwardingInfoCallback
1248 .RESULT_ERROR_FDN_CHECK_FAILURE;
Hall Liu27d24262020-09-18 19:04:59 -07001249 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
Hall Liu940c4ca2020-09-29 17:10:18 -07001250 errorCode = TelephonyManager.CallForwardingInfoCallback
1251 .RESULT_ERROR_NOT_SUPPORTED;
Hall Liu27d24262020-09-18 19:04:59 -07001252 }
1253 }
1254 callback.accept(errorCode);
1255 } else {
Hall Liu940c4ca2020-09-29 17:10:18 -07001256 callback.accept(TelephonyManager.CallForwardingInfoCallback.RESULT_SUCCESS);
Shuo Qian4a594052020-01-23 11:59:30 -08001257 }
Shuo Qian4a594052020-01-23 11:59:30 -08001258 break;
Hall Liu27d24262020-09-18 19:04:59 -07001259 }
Shuo Qian4a594052020-01-23 11:59:30 -08001260
Hall Liu27d24262020-09-18 19:04:59 -07001261 case CMD_GET_CALL_WAITING: {
Shuo Qian4a594052020-01-23 11:59:30 -08001262 request = (MainThreadRequest) msg.obj;
1263 onCompleted = obtainMessage(EVENT_GET_CALL_WAITING_DONE, request);
1264 getPhoneFromRequest(request).getCallWaiting(onCompleted);
1265 break;
Hall Liu27d24262020-09-18 19:04:59 -07001266 }
Shuo Qian4a594052020-01-23 11:59:30 -08001267
Hall Liu27d24262020-09-18 19:04:59 -07001268 case EVENT_GET_CALL_WAITING_DONE: {
Shuo Qian4a594052020-01-23 11:59:30 -08001269 ar = (AsyncResult) msg.obj;
1270 request = (MainThreadRequest) ar.userObj;
Hall Liu27d24262020-09-18 19:04:59 -07001271 Consumer<Integer> callback = (Consumer<Integer>) request.argument;
Shuo Qian4a594052020-01-23 11:59:30 -08001272 int callForwardingStatus = TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR;
1273 if (ar.exception == null && ar.result != null) {
Shuo Qiand6a0dba2020-02-18 18:13:49 -08001274 int[] callForwardResults = (int[]) ar.result;
Shuo Qian4a594052020-01-23 11:59:30 -08001275 // Service Class is a bit mask per 3gpp 27.007.
1276 // Search for any service for voice call.
Shuo Qiand6a0dba2020-02-18 18:13:49 -08001277 if (callForwardResults.length > 1
1278 && ((callForwardResults[1]
Hall Liu27d24262020-09-18 19:04:59 -07001279 & CommandsInterface.SERVICE_CLASS_VOICE) > 0)) {
Shuo Qiand6a0dba2020-02-18 18:13:49 -08001280 callForwardingStatus = callForwardResults[0] == 0
Hall Liu27d24262020-09-18 19:04:59 -07001281 ? TelephonyManager.CALL_WAITING_STATUS_DISABLED
1282 : TelephonyManager.CALL_WAITING_STATUS_ENABLED;
Shuo Qian4a594052020-01-23 11:59:30 -08001283 } else {
Hall Liu27d24262020-09-18 19:04:59 -07001284 callForwardingStatus = TelephonyManager.CALL_WAITING_STATUS_DISABLED;
Shuo Qian4a594052020-01-23 11:59:30 -08001285 }
1286 } else {
1287 if (ar.result == null) {
1288 loge("EVENT_GET_CALL_WAITING_DONE: Empty response");
1289 }
1290 if (ar.exception != null) {
1291 loge("EVENT_GET_CALL_WAITING_DONE: Exception: " + ar.exception);
1292 }
1293 if (ar.exception instanceof CommandException) {
1294 CommandException.Error error =
1295 ((CommandException) (ar.exception)).getCommandError();
1296 if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1297 callForwardingStatus =
1298 TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED;
1299 }
1300 }
1301 }
Hall Liu27d24262020-09-18 19:04:59 -07001302 callback.accept(callForwardingStatus);
Shuo Qian4a594052020-01-23 11:59:30 -08001303 break;
Hall Liu27d24262020-09-18 19:04:59 -07001304 }
Shuo Qian4a594052020-01-23 11:59:30 -08001305
Hall Liu27d24262020-09-18 19:04:59 -07001306 case CMD_SET_CALL_WAITING: {
Shuo Qian4a594052020-01-23 11:59:30 -08001307 request = (MainThreadRequest) msg.obj;
1308 onCompleted = obtainMessage(EVENT_SET_CALL_WAITING_DONE, request);
Hall Liu27d24262020-09-18 19:04:59 -07001309 boolean enable = ((Pair<Boolean, Consumer<Integer>>) request.argument).first;
1310 getPhoneFromRequest(request).setCallWaiting(enable, onCompleted);
Shuo Qian4a594052020-01-23 11:59:30 -08001311 break;
Hall Liu27d24262020-09-18 19:04:59 -07001312 }
Shuo Qian4a594052020-01-23 11:59:30 -08001313
Hall Liu27d24262020-09-18 19:04:59 -07001314 case EVENT_SET_CALL_WAITING_DONE: {
Shuo Qian4a594052020-01-23 11:59:30 -08001315 ar = (AsyncResult) msg.obj;
1316 request = (MainThreadRequest) ar.userObj;
Hall Liu27d24262020-09-18 19:04:59 -07001317 boolean enable = ((Pair<Boolean, Consumer<Integer>>) request.argument).first;
1318 Consumer<Integer> callback =
1319 ((Pair<Boolean, Consumer<Integer>>) request.argument).second;
1320 if (ar.exception != null) {
Shuo Qian4a594052020-01-23 11:59:30 -08001321 loge("setCallWaiting exception: " + ar.exception);
Hall Liu27d24262020-09-18 19:04:59 -07001322 if (ar.exception instanceof CommandException) {
1323 CommandException.Error error =
1324 ((CommandException) (ar.exception)).getCommandError();
1325 if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1326 callback.accept(TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED);
1327 } else {
1328 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
1329 }
1330 } else {
1331 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
1332 }
1333 } else {
1334 callback.accept(enable ? TelephonyManager.CALL_WAITING_STATUS_ENABLED
1335 : TelephonyManager.CALL_WAITING_STATUS_DISABLED);
Shuo Qian4a594052020-01-23 11:59:30 -08001336 }
Shuo Qian4a594052020-01-23 11:59:30 -08001337 break;
Hall Liu27d24262020-09-18 19:04:59 -07001338 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07001339 case EVENT_PERFORM_NETWORK_SCAN_DONE:
1340 ar = (AsyncResult) msg.obj;
1341 request = (MainThreadRequest) ar.userObj;
1342 CellNetworkScanResult cellScanResult;
1343 if (ar.exception == null && ar.result != null) {
1344 cellScanResult = new CellNetworkScanResult(
1345 CellNetworkScanResult.STATUS_SUCCESS,
1346 (List<OperatorInfo>) ar.result);
1347 } else {
1348 if (ar.result == null) {
1349 loge("getCellNetworkScanResults: Empty response");
1350 }
1351 if (ar.exception != null) {
1352 loge("getCellNetworkScanResults: Exception: " + ar.exception);
1353 }
1354 int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR;
1355 if (ar.exception instanceof CommandException) {
1356 CommandException.Error error =
1357 ((CommandException) (ar.exception)).getCommandError();
1358 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1359 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE;
1360 } else if (error == CommandException.Error.GENERIC_FAILURE) {
1361 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE;
1362 }
1363 }
1364 cellScanResult = new CellNetworkScanResult(errorCode, null);
1365 }
1366 request.result = cellScanResult;
Pengquan Menga1bb6272018-09-06 09:59:22 -07001367 notifyRequester(request);
Shishir Agrawal302c8692015-06-19 13:49:39 -07001368 break;
1369
1370 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
1371 request = (MainThreadRequest) msg.obj;
Shishir Agrawal77ba3172015-09-10 14:50:19 -07001372 ManualNetworkSelectionArgument selArg =
1373 (ManualNetworkSelectionArgument) request.argument;
Shishir Agrawal302c8692015-06-19 13:49:39 -07001374 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE,
1375 request);
Shishir Agrawal77ba3172015-09-10 14:50:19 -07001376 getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo,
1377 selArg.persistSelection, onCompleted);
Shishir Agrawal302c8692015-06-19 13:49:39 -07001378 break;
1379
1380 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
Pengquan Menge3d01e22018-09-20 15:25:35 -07001381 ar = (AsyncResult) msg.obj;
1382 request = (MainThreadRequest) ar.userObj;
1383 if (ar.exception == null) {
1384 request.result = true;
1385 } else {
1386 request.result = false;
1387 loge("setNetworkSelectionModeManual " + ar.exception);
1388 }
1389 notifyRequester(request);
1390 mApp.onNetworkSelectionChanged(request.subId);
Shishir Agrawal302c8692015-06-19 13:49:39 -07001391 break;
1392
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001393 case CMD_GET_MODEM_ACTIVITY_INFO:
1394 request = (MainThreadRequest) msg.obj;
1395 onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
James Mattisab947702019-04-03 14:18:34 -07001396 if (defaultPhone != null) {
1397 defaultPhone.getModemActivityInfo(onCompleted, request.workSource);
Shuo Qian8f4750a2020-02-20 17:12:10 -08001398 } else {
1399 ResultReceiver result = (ResultReceiver) request.argument;
1400 Bundle bundle = new Bundle();
1401 bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY,
Hall Liu49656c02020-10-09 19:00:11 -07001402 new ModemActivityInfo(0, 0, 0,
1403 new int[ModemActivityInfo.getNumTxPowerLevels()], 0));
Shuo Qian8f4750a2020-02-20 17:12:10 -08001404 result.send(0, bundle);
James Mattisab947702019-04-03 14:18:34 -07001405 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001406 break;
1407
Hall Liud0f208c2020-10-14 16:54:44 -07001408 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE: {
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001409 ar = (AsyncResult) msg.obj;
1410 request = (MainThreadRequest) ar.userObj;
Shuo Qian8f4750a2020-02-20 17:12:10 -08001411 ResultReceiver result = (ResultReceiver) request.argument;
1412
Hall Liud0f208c2020-10-14 16:54:44 -07001413 ModemActivityInfo ret = null;
1414 int error = 0;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001415 if (ar.exception == null && ar.result != null) {
Shuo Qian8f4750a2020-02-20 17:12:10 -08001416 // Update the last modem activity info and the result of the request.
1417 ModemActivityInfo info = (ModemActivityInfo) ar.result;
1418 if (isModemActivityInfoValid(info)) {
Hall Liu49656c02020-10-09 19:00:11 -07001419 int[] mergedTxTimeMs = new int[ModemActivityInfo.getNumTxPowerLevels()];
Shuo Qian8f4750a2020-02-20 17:12:10 -08001420 int[] txTimeMs = info.getTransmitTimeMillis();
1421 int[] lastModemTxTimeMs = mLastModemActivityInfo
1422 .getTransmitTimeMillis();
1423 for (int i = 0; i < mergedTxTimeMs.length; i++) {
1424 mergedTxTimeMs[i] = txTimeMs[i] + lastModemTxTimeMs[i];
1425 }
Hall Liu49656c02020-10-09 19:00:11 -07001426 mLastModemActivityInfo.setTimestamp(info.getTimestampMillis());
Shuo Qian8f4750a2020-02-20 17:12:10 -08001427 mLastModemActivityInfo.setSleepTimeMillis(info.getSleepTimeMillis()
1428 + mLastModemActivityInfo.getSleepTimeMillis());
1429 mLastModemActivityInfo.setIdleTimeMillis(info.getIdleTimeMillis()
1430 + mLastModemActivityInfo.getIdleTimeMillis());
1431 mLastModemActivityInfo.setTransmitTimeMillis(mergedTxTimeMs);
1432 mLastModemActivityInfo.setReceiveTimeMillis(
1433 info.getReceiveTimeMillis()
1434 + mLastModemActivityInfo.getReceiveTimeMillis());
1435 }
Hall Liu49656c02020-10-09 19:00:11 -07001436 ret = new ModemActivityInfo(mLastModemActivityInfo.getTimestampMillis(),
Shuo Qian8f4750a2020-02-20 17:12:10 -08001437 mLastModemActivityInfo.getSleepTimeMillis(),
1438 mLastModemActivityInfo.getIdleTimeMillis(),
1439 mLastModemActivityInfo.getTransmitTimeMillis(),
1440 mLastModemActivityInfo.getReceiveTimeMillis());
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001441 } else {
1442 if (ar.result == null) {
1443 loge("queryModemActivityInfo: Empty response");
Hall Liud0f208c2020-10-14 16:54:44 -07001444 error = TelephonyManager.ModemActivityInfoException
1445 .ERROR_INVALID_INFO_RECEIVED;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001446 } else if (ar.exception instanceof CommandException) {
1447 loge("queryModemActivityInfo: CommandException: " +
1448 ar.exception);
Hall Liud0f208c2020-10-14 16:54:44 -07001449 error = TelephonyManager.ModemActivityInfoException
1450 .ERROR_MODEM_RESPONSE_ERROR;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001451 } else {
1452 loge("queryModemActivityInfo: Unknown exception");
Hall Liud0f208c2020-10-14 16:54:44 -07001453 error = TelephonyManager.ModemActivityInfoException
1454 .ERROR_UNKNOWN;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001455 }
1456 }
Shuo Qian8f4750a2020-02-20 17:12:10 -08001457 Bundle bundle = new Bundle();
Hall Liud0f208c2020-10-14 16:54:44 -07001458 if (ret != null) {
1459 bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, ret);
1460 } else {
1461 bundle.putInt(TelephonyManager.EXCEPTION_RESULT_KEY, error);
1462 }
Shuo Qian8f4750a2020-02-20 17:12:10 -08001463 result.send(0, bundle);
Pengquan Menga1bb6272018-09-06 09:59:22 -07001464 notifyRequester(request);
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001465 break;
Hall Liud0f208c2020-10-14 16:54:44 -07001466 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07001467
Meng Wang1a7c35a2016-05-05 20:56:15 -07001468 case CMD_SET_ALLOWED_CARRIERS:
1469 request = (MainThreadRequest) msg.obj;
Michele Berionne482f8202018-11-27 18:57:59 -08001470 CarrierRestrictionRules argument =
1471 (CarrierRestrictionRules) request.argument;
Meng Wang1a7c35a2016-05-05 20:56:15 -07001472 onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
Michele Berionne482f8202018-11-27 18:57:59 -08001473 defaultPhone.setAllowedCarriers(argument, onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -07001474 break;
1475
1476 case EVENT_SET_ALLOWED_CARRIERS_DONE:
1477 ar = (AsyncResult) msg.obj;
1478 request = (MainThreadRequest) ar.userObj;
1479 if (ar.exception == null && ar.result != null) {
1480 request.result = ar.result;
1481 } else {
Michele Berionne482f8202018-11-27 18:57:59 -08001482 request.result = TelephonyManager.SET_CARRIER_RESTRICTION_ERROR;
1483 if (ar.exception instanceof CommandException) {
1484 loge("setAllowedCarriers: CommandException: " + ar.exception);
1485 CommandException.Error error =
1486 ((CommandException) (ar.exception)).getCommandError();
1487 if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1488 request.result =
1489 TelephonyManager.SET_CARRIER_RESTRICTION_NOT_SUPPORTED;
1490 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07001491 } else {
1492 loge("setAllowedCarriers: Unknown exception");
1493 }
1494 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001495 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -07001496 break;
1497
1498 case CMD_GET_ALLOWED_CARRIERS:
1499 request = (MainThreadRequest) msg.obj;
1500 onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001501 defaultPhone.getAllowedCarriers(onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -07001502 break;
1503
1504 case EVENT_GET_ALLOWED_CARRIERS_DONE:
1505 ar = (AsyncResult) msg.obj;
1506 request = (MainThreadRequest) ar.userObj;
1507 if (ar.exception == null && ar.result != null) {
1508 request.result = ar.result;
1509 } else {
Michele Berionne482f8202018-11-27 18:57:59 -08001510 request.result = new IllegalStateException(
1511 "Failed to get carrier restrictions");
Meng Wang1a7c35a2016-05-05 20:56:15 -07001512 if (ar.result == null) {
1513 loge("getAllowedCarriers: Empty response");
1514 } else if (ar.exception instanceof CommandException) {
1515 loge("getAllowedCarriers: CommandException: " +
1516 ar.exception);
1517 } else {
1518 loge("getAllowedCarriers: Unknown exception");
1519 }
1520 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001521 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -07001522 break;
1523
Nathan Haroldb3014052017-01-25 15:57:32 -08001524 case EVENT_GET_FORBIDDEN_PLMNS_DONE:
1525 ar = (AsyncResult) msg.obj;
1526 request = (MainThreadRequest) ar.userObj;
1527 if (ar.exception == null && ar.result != null) {
1528 request.result = ar.result;
1529 } else {
1530 request.result = new IllegalArgumentException(
1531 "Failed to retrieve Forbidden Plmns");
1532 if (ar.result == null) {
1533 loge("getForbiddenPlmns: Empty response");
1534 } else {
1535 loge("getForbiddenPlmns: Unknown exception");
1536 }
1537 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001538 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -08001539 break;
1540
1541 case CMD_GET_FORBIDDEN_PLMNS:
1542 request = (MainThreadRequest) msg.obj;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00001543 uiccPort = getUiccPortFromRequest(request);
1544 if (uiccPort == null) {
1545 loge("getForbiddenPlmns() UiccPort is null");
Nathan Haroldb3014052017-01-25 15:57:32 -08001546 request.result = new IllegalArgumentException(
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00001547 "getForbiddenPlmns() UiccPort is null");
Pengquan Menga1bb6272018-09-06 09:59:22 -07001548 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -08001549 break;
1550 }
1551 Integer appType = (Integer) request.argument;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00001552 UiccCardApplication uiccApp = uiccPort.getApplicationByType(appType);
Nathan Haroldb3014052017-01-25 15:57:32 -08001553 if (uiccApp == null) {
1554 loge("getForbiddenPlmns() no app with specified type -- "
1555 + appType);
1556 request.result = new IllegalArgumentException("Failed to get UICC App");
Pengquan Menga1bb6272018-09-06 09:59:22 -07001557 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -08001558 break;
1559 } else {
1560 if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
1561 + " specified type -- " + appType);
1562 }
1563 onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
1564 ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
1565 onCompleted);
1566 break;
1567
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001568 case CMD_SWITCH_SLOTS:
1569 request = (MainThreadRequest) msg.obj;
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00001570 List<UiccSlotMapping> slotMapping = (List<UiccSlotMapping>) request.argument;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001571 onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00001572 UiccController.getInstance().switchSlots(slotMapping, onCompleted);
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001573 break;
1574
1575 case EVENT_SWITCH_SLOTS_DONE:
1576 ar = (AsyncResult) msg.obj;
1577 request = (MainThreadRequest) ar.userObj;
1578 request.result = (ar.exception == null);
Pengquan Menga1bb6272018-09-06 09:59:22 -07001579 notifyRequester(request);
1580 break;
1581 case CMD_GET_NETWORK_SELECTION_MODE:
1582 request = (MainThreadRequest) msg.obj;
1583 onCompleted = obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE, request);
1584 getPhoneFromRequest(request).getNetworkSelectionMode(onCompleted);
1585 break;
1586
1587 case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
1588 ar = (AsyncResult) msg.obj;
1589 request = (MainThreadRequest) ar.userObj;
1590 if (ar.exception != null) {
1591 request.result = TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
1592 } else {
1593 int mode = ((int[]) ar.result)[0];
1594 if (mode == 0) {
1595 request.result = TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
1596 } else {
1597 request.result = TelephonyManager.NETWORK_SELECTION_MODE_MANUAL;
1598 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001599 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001600 notifyRequester(request);
1601 break;
1602 case CMD_GET_CDMA_ROAMING_MODE:
1603 request = (MainThreadRequest) msg.obj;
1604 onCompleted = obtainMessage(EVENT_GET_CDMA_ROAMING_MODE_DONE, request);
1605 getPhoneFromRequest(request).queryCdmaRoamingPreference(onCompleted);
1606 break;
1607 case EVENT_GET_CDMA_ROAMING_MODE_DONE:
1608 ar = (AsyncResult) msg.obj;
1609 request = (MainThreadRequest) ar.userObj;
1610 if (ar.exception != null) {
1611 request.result = TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT;
1612 } else {
1613 request.result = ((int[]) ar.result)[0];
1614 }
1615 notifyRequester(request);
1616 break;
1617 case CMD_SET_CDMA_ROAMING_MODE:
1618 request = (MainThreadRequest) msg.obj;
1619 onCompleted = obtainMessage(EVENT_SET_CDMA_ROAMING_MODE_DONE, request);
1620 int mode = (int) request.argument;
1621 getPhoneFromRequest(request).setCdmaRoamingPreference(mode, onCompleted);
1622 break;
1623 case EVENT_SET_CDMA_ROAMING_MODE_DONE:
1624 ar = (AsyncResult) msg.obj;
1625 request = (MainThreadRequest) ar.userObj;
1626 request.result = ar.exception == null;
1627 notifyRequester(request);
1628 break;
Sarah Chinbaab1432020-10-28 13:46:24 -07001629 case CMD_GET_CDMA_SUBSCRIPTION_MODE:
1630 request = (MainThreadRequest) msg.obj;
1631 onCompleted = obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1632 getPhoneFromRequest(request).queryCdmaSubscriptionMode(onCompleted);
1633 break;
1634 case EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE:
1635 ar = (AsyncResult) msg.obj;
1636 request = (MainThreadRequest) ar.userObj;
1637 if (ar.exception != null) {
1638 request.result = TelephonyManager.CDMA_SUBSCRIPTION_RUIM_SIM;
1639 } else {
1640 request.result = ((int[]) ar.result)[0];
1641 }
1642 notifyRequester(request);
1643 break;
Pengquan Menga1bb6272018-09-06 09:59:22 -07001644 case CMD_SET_CDMA_SUBSCRIPTION_MODE:
1645 request = (MainThreadRequest) msg.obj;
1646 onCompleted = obtainMessage(EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1647 int subscriptionMode = (int) request.argument;
Sarah Chinbaab1432020-10-28 13:46:24 -07001648 getPhoneFromRequest(request).setCdmaSubscriptionMode(
1649 subscriptionMode, onCompleted);
Pengquan Menga1bb6272018-09-06 09:59:22 -07001650 break;
1651 case EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE:
1652 ar = (AsyncResult) msg.obj;
1653 request = (MainThreadRequest) ar.userObj;
1654 request.result = ar.exception == null;
1655 notifyRequester(request);
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001656 break;
Nathan Harold3ff88932018-08-14 10:19:49 -07001657 case CMD_GET_ALL_CELL_INFO:
1658 request = (MainThreadRequest) msg.obj;
Nathan Harold3ff88932018-08-14 10:19:49 -07001659 onCompleted = obtainMessage(EVENT_GET_ALL_CELL_INFO_DONE, request);
Nathan Harold92bed182018-10-12 18:16:49 -07001660 request.phone.requestCellInfoUpdate(request.workSource, onCompleted);
Nathan Harold3ff88932018-08-14 10:19:49 -07001661 break;
Nathan Harold3ff88932018-08-14 10:19:49 -07001662 case EVENT_GET_ALL_CELL_INFO_DONE:
1663 ar = (AsyncResult) msg.obj;
1664 request = (MainThreadRequest) ar.userObj;
Nathan Harold8d0f1742018-10-02 12:14:47 -07001665 // If a timeout occurs, the response will be null
1666 request.result = (ar.exception == null && ar.result != null)
1667 ? ar.result : new ArrayList<CellInfo>();
Nathan Harold3ff88932018-08-14 10:19:49 -07001668 synchronized (request) {
1669 request.notifyAll();
1670 }
1671 break;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001672 case CMD_REQUEST_CELL_INFO_UPDATE:
1673 request = (MainThreadRequest) msg.obj;
1674 request.phone.requestCellInfoUpdate(request.workSource,
1675 obtainMessage(EVENT_REQUEST_CELL_INFO_UPDATE_DONE, request));
1676 break;
1677 case EVENT_REQUEST_CELL_INFO_UPDATE_DONE:
1678 ar = (AsyncResult) msg.obj;
1679 request = (MainThreadRequest) ar.userObj;
1680 ICellInfoCallback cb = (ICellInfoCallback) request.argument;
1681 try {
1682 if (ar.exception != null) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001683 Log.e(LOG_TAG, "Exception retrieving CellInfo=" + ar.exception);
Meng Wangd8921f42019-09-30 17:13:54 -07001684 cb.onError(
1685 TelephonyManager.CellInfoCallback.ERROR_MODEM_ERROR,
1686 ar.exception.getClass().getName(),
1687 ar.exception.toString());
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001688 } else if (ar.result == null) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001689 Log.w(LOG_TAG, "Timeout Waiting for CellInfo!");
Meng Wangd8921f42019-09-30 17:13:54 -07001690 cb.onError(TelephonyManager.CellInfoCallback.ERROR_TIMEOUT, null, null);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001691 } else {
1692 // use the result as returned
1693 cb.onCellInfo((List<CellInfo>) ar.result);
1694 }
1695 } catch (RemoteException re) {
1696 Log.w(LOG_TAG, "Discarded CellInfo due to Callback RemoteException");
1697 }
1698 break;
Sarah Chin679c08a2020-11-18 13:39:35 -08001699 case CMD_GET_CELL_LOCATION: {
Nathan Harold3ff88932018-08-14 10:19:49 -07001700 request = (MainThreadRequest) msg.obj;
1701 WorkSource ws = (WorkSource) request.argument;
1702 Phone phone = getPhoneFromRequest(request);
Meng Wanga10e89e2019-12-09 13:13:01 -08001703 phone.getCellIdentity(ws, obtainMessage(EVENT_GET_CELL_LOCATION_DONE, request));
Nathan Harold3ff88932018-08-14 10:19:49 -07001704 break;
Sarah Chin679c08a2020-11-18 13:39:35 -08001705 }
1706 case EVENT_GET_CELL_LOCATION_DONE: {
Nathan Harold3ff88932018-08-14 10:19:49 -07001707 ar = (AsyncResult) msg.obj;
1708 request = (MainThreadRequest) ar.userObj;
1709 if (ar.exception == null) {
1710 request.result = ar.result;
1711 } else {
Sarah Chin679c08a2020-11-18 13:39:35 -08001712 Phone phone = getPhoneFromRequest(request);
Nathan Harold3ff88932018-08-14 10:19:49 -07001713 request.result = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
Meng Wanga10e89e2019-12-09 13:13:01 -08001714 ? new CellIdentityCdma() : new CellIdentityGsm();
Nathan Harold3ff88932018-08-14 10:19:49 -07001715 }
1716
1717 synchronized (request) {
1718 request.notifyAll();
1719 }
1720 break;
Sarah Chin679c08a2020-11-18 13:39:35 -08001721 }
chen xu6dac5ab2018-10-26 17:39:23 -07001722 case CMD_MODEM_REBOOT:
1723 request = (MainThreadRequest) msg.obj;
1724 onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08001725 defaultPhone.rebootModem(onCompleted);
chen xu6dac5ab2018-10-26 17:39:23 -07001726 break;
chen xu6dac5ab2018-10-26 17:39:23 -07001727 case EVENT_CMD_MODEM_REBOOT_DONE:
1728 handleNullReturnEvent(msg, "rebootModem");
1729 break;
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001730 case CMD_REQUEST_ENABLE_MODEM:
1731 request = (MainThreadRequest) msg.obj;
1732 boolean enable = (boolean) request.argument;
1733 onCompleted = obtainMessage(EVENT_ENABLE_MODEM_DONE, request);
Nazanin Bakhshi33d584b2019-02-27 10:44:32 -08001734 onCompleted.arg1 = enable ? 1 : 0;
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001735 PhoneConfigurationManager.getInstance()
1736 .enablePhone(request.phone, enable, onCompleted);
1737 break;
Michele Berionne5e411512020-11-13 02:36:59 +00001738 case EVENT_ENABLE_MODEM_DONE: {
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001739 ar = (AsyncResult) msg.obj;
1740 request = (MainThreadRequest) ar.userObj;
1741 request.result = (ar.exception == null);
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07001742 int phoneId = request.phone.getPhoneId();
Nazanin Bakhshi33d584b2019-02-27 10:44:32 -08001743 //update the cache as modem status has changed
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07001744 if ((boolean) request.result) {
1745 mPhoneConfigurationManager.addToPhoneStatusCache(phoneId, msg.arg1 == 1);
1746 updateModemStateMetrics();
1747 } else {
1748 Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1749 + ar.exception);
1750 }
1751 notifyRequester(request);
1752 break;
Michele Berionne5e411512020-11-13 02:36:59 +00001753 }
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07001754 case CMD_GET_MODEM_STATUS:
1755 request = (MainThreadRequest) msg.obj;
1756 onCompleted = obtainMessage(EVENT_GET_MODEM_STATUS_DONE, request);
1757 PhoneConfigurationManager.getInstance()
1758 .getPhoneStatusFromModem(request.phone, onCompleted);
1759 break;
1760 case EVENT_GET_MODEM_STATUS_DONE:
1761 ar = (AsyncResult) msg.obj;
1762 request = (MainThreadRequest) ar.userObj;
1763 int id = request.phone.getPhoneId();
1764 if (ar.exception == null && ar.result != null) {
1765 request.result = ar.result;
1766 //update the cache as modem status has changed
1767 mPhoneConfigurationManager.addToPhoneStatusCache(id,
1768 (boolean) request.result);
1769 } else {
1770 // Return true if modem status cannot be retrieved. For most cases,
1771 // modem status is on. And for older version modems, GET_MODEM_STATUS
1772 // and disable modem are not supported. Modem is always on.
1773 // TODO: this should be fixed in R to support a third
1774 // status UNKNOWN b/131631629
1775 request.result = true;
1776 Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1777 + ar.exception);
1778 }
Malcolm Chen8e4ed912019-01-15 20:22:16 -08001779 notifyRequester(request);
1780 break;
Hall Liu73f5d362020-01-20 13:42:00 -08001781 case CMD_SET_SYSTEM_SELECTION_CHANNELS: {
1782 request = (MainThreadRequest) msg.obj;
1783 onCompleted = obtainMessage(EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE, request);
1784 Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> args =
1785 (Pair<List<RadioAccessSpecifier>, Consumer<Boolean>>) request.argument;
1786 request.phone.setSystemSelectionChannels(args.first, onCompleted);
1787 break;
1788 }
1789 case EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE: {
1790 ar = (AsyncResult) msg.obj;
1791 request = (MainThreadRequest) ar.userObj;
1792 Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> args =
1793 (Pair<List<RadioAccessSpecifier>, Consumer<Boolean>>) request.argument;
1794 args.second.accept(ar.exception == null);
1795 notifyRequester(request);
1796 break;
1797 }
Sarah Chin679c08a2020-11-18 13:39:35 -08001798 case CMD_GET_SYSTEM_SELECTION_CHANNELS: {
1799 request = (MainThreadRequest) msg.obj;
1800 onCompleted = obtainMessage(EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE, request);
1801 Phone phone = getPhoneFromRequest(request);
1802 if (phone != null) {
1803 phone.getSystemSelectionChannels(onCompleted);
1804 } else {
1805 loge("getSystemSelectionChannels: No phone object");
1806 request.result = new ArrayList<RadioAccessSpecifier>();
1807 notifyRequester(request);
1808 }
1809 break;
1810 }
1811 case EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE:
1812 ar = (AsyncResult) msg.obj;
1813 request = (MainThreadRequest) ar.userObj;
1814 if (ar.exception == null && ar.result != null) {
1815 request.result = ar.result;
1816 } else {
Sarah Chin428d1d62021-03-13 03:17:40 -08001817 request.result = new IllegalStateException(
1818 "Failed to retrieve system selecton channels");
Sarah Chin679c08a2020-11-18 13:39:35 -08001819 if (ar.result == null) {
1820 loge("getSystemSelectionChannels: Empty response");
1821 } else {
1822 loge("getSystemSelectionChannels: Unknown exception");
1823 }
1824 }
1825 notifyRequester(request);
1826 break;
yincheng zhao2737e882019-09-06 17:06:54 -07001827 case EVENT_SET_FORBIDDEN_PLMNS_DONE:
1828 ar = (AsyncResult) msg.obj;
1829 request = (MainThreadRequest) ar.userObj;
1830 if (ar.exception == null && ar.result != null) {
1831 request.result = ar.result;
1832 } else {
1833 request.result = -1;
1834 loge("Failed to set Forbidden Plmns");
1835 if (ar.result == null) {
1836 loge("setForbidenPlmns: Empty response");
1837 } else if (ar.exception != null) {
1838 loge("setForbiddenPlmns: Exception: " + ar.exception);
1839 request.result = -1;
1840 } else {
1841 loge("setForbiddenPlmns: Unknown exception");
1842 }
1843 }
1844 notifyRequester(request);
1845 break;
1846 case CMD_SET_FORBIDDEN_PLMNS:
1847 request = (MainThreadRequest) msg.obj;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00001848 uiccPort = getUiccPortFromRequest(request);
1849 if (uiccPort == null) {
1850 loge("setForbiddenPlmns: UiccPort is null");
yincheng zhao2737e882019-09-06 17:06:54 -07001851 request.result = -1;
1852 notifyRequester(request);
1853 break;
1854 }
1855 Pair<Integer, List<String>> setFplmnsArgs =
1856 (Pair<Integer, List<String>>) request.argument;
1857 appType = setFplmnsArgs.first;
1858 List<String> fplmns = setFplmnsArgs.second;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00001859 uiccApp = uiccPort.getApplicationByType(appType);
yincheng zhao2737e882019-09-06 17:06:54 -07001860 if (uiccApp == null) {
1861 loge("setForbiddenPlmns: no app with specified type -- " + appType);
1862 request.result = -1;
1863 loge("Failed to get UICC App");
1864 notifyRequester(request);
1865 } else {
1866 onCompleted = obtainMessage(EVENT_SET_FORBIDDEN_PLMNS_DONE, request);
1867 ((SIMRecords) uiccApp.getIccRecords())
1868 .setForbiddenPlmns(onCompleted, fplmns);
1869 }
yinchengzhao4d163c02019-12-12 15:21:47 -08001870 break;
Naina Nallurid63128d2019-09-17 14:10:30 -07001871 case CMD_ERASE_MODEM_CONFIG:
1872 request = (MainThreadRequest) msg.obj;
1873 onCompleted = obtainMessage(EVENT_ERASE_MODEM_CONFIG_DONE, request);
1874 defaultPhone.eraseModemConfig(onCompleted);
1875 break;
1876 case EVENT_ERASE_MODEM_CONFIG_DONE:
1877 handleNullReturnEvent(msg, "eraseModemConfig");
yincheng zhao2737e882019-09-06 17:06:54 -07001878 break;
zoey chene02881a2019-12-30 16:11:23 +08001879
Kai Shif70f46f2021-03-03 13:59:46 -08001880 case CMD_ERASE_DATA_SHARED_PREFERENCES:
1881 request = (MainThreadRequest) msg.obj;
1882 request.result = defaultPhone.eraseDataInSharedPreferences();
1883 notifyRequester(request);
1884 break;
1885
zoey chene02881a2019-12-30 16:11:23 +08001886 case CMD_CHANGE_ICC_LOCK_PASSWORD:
1887 request = (MainThreadRequest) msg.obj;
1888 onCompleted = obtainMessage(EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE, request);
1889 Pair<String, String> changed = (Pair<String, String>) request.argument;
1890 getPhoneFromRequest(request).getIccCard().changeIccLockPassword(
1891 changed.first, changed.second, onCompleted);
1892 break;
1893 case EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE:
1894 ar = (AsyncResult) msg.obj;
1895 request = (MainThreadRequest) ar.userObj;
1896 if (ar.exception == null) {
1897 request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
Michele Berionne5e411512020-11-13 02:36:59 +00001898 // If the operation is successful, update the PIN storage
1899 Pair<String, String> passwords = (Pair<String, String>) request.argument;
1900 int phoneId = getPhoneFromRequest(request).getPhoneId();
Jon Spivack9c3bc762021-10-06 20:53:09 +00001901 UiccController.getInstance().getPinStorage()
1902 .storePin(passwords.second, phoneId);
zoey chene02881a2019-12-30 16:11:23 +08001903 } else {
1904 request.result = msg.arg1;
1905 }
1906 notifyRequester(request);
1907 break;
1908
Michele Berionne5e411512020-11-13 02:36:59 +00001909 case CMD_SET_ICC_LOCK_ENABLED: {
zoey chene02881a2019-12-30 16:11:23 +08001910 request = (MainThreadRequest) msg.obj;
1911 onCompleted = obtainMessage(EVENT_SET_ICC_LOCK_ENABLED_DONE, request);
1912 Pair<Boolean, String> enabled = (Pair<Boolean, String>) request.argument;
1913 getPhoneFromRequest(request).getIccCard().setIccLockEnabled(
1914 enabled.first, enabled.second, onCompleted);
1915 break;
Michele Berionne5e411512020-11-13 02:36:59 +00001916 }
zoey chene02881a2019-12-30 16:11:23 +08001917 case EVENT_SET_ICC_LOCK_ENABLED_DONE:
1918 ar = (AsyncResult) msg.obj;
1919 request = (MainThreadRequest) ar.userObj;
1920 if (ar.exception == null) {
1921 request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
Michele Berionne5e411512020-11-13 02:36:59 +00001922 // If the operation is successful, update the PIN storage
1923 Pair<Boolean, String> enabled = (Pair<Boolean, String>) request.argument;
1924 int phoneId = getPhoneFromRequest(request).getPhoneId();
1925 if (enabled.first) {
Jon Spivack9c3bc762021-10-06 20:53:09 +00001926 UiccController.getInstance().getPinStorage()
1927 .storePin(enabled.second, phoneId);
Michele Berionne5e411512020-11-13 02:36:59 +00001928 } else {
1929 UiccController.getInstance().getPinStorage().clearPin(phoneId);
1930 }
zoey chene02881a2019-12-30 16:11:23 +08001931 } else {
1932 request.result = msg.arg1;
1933 }
Michele Berionne5e411512020-11-13 02:36:59 +00001934
1935
zoey chene02881a2019-12-30 16:11:23 +08001936 notifyRequester(request);
1937 break;
1938
Peter Wangdafb9ac2020-01-15 14:13:38 -08001939 case MSG_NOTIFY_USER_ACTIVITY:
1940 removeMessages(MSG_NOTIFY_USER_ACTIVITY);
Peter Wang59571be2020-01-27 12:35:15 +08001941 Intent intent = new Intent(TelephonyIntents.ACTION_USER_ACTIVITY_NOTIFICATION);
Peter Wangdafb9ac2020-01-15 14:13:38 -08001942 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1943 getDefaultPhone().getContext().sendBroadcastAsUser(
1944 intent, UserHandle.ALL, permission.USER_ACTIVITY);
1945 break;
Jack Nudelmanb0b87642020-11-12 15:04:39 -08001946
1947 case CMD_SET_DATA_THROTTLING: {
1948 request = (MainThreadRequest) msg.obj;
1949 onCompleted = obtainMessage(EVENT_SET_DATA_THROTTLING_DONE, request);
1950 DataThrottlingRequest dataThrottlingRequest =
1951 (DataThrottlingRequest) request.argument;
1952 Phone phone = getPhoneFromRequest(request);
1953 if (phone != null) {
1954 phone.setDataThrottling(onCompleted,
1955 request.workSource, dataThrottlingRequest.getDataThrottlingAction(),
1956 dataThrottlingRequest.getCompletionDurationMillis());
1957 } else {
1958 loge("setDataThrottling: No phone object");
1959 request.result =
1960 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
1961 notifyRequester(request);
1962 }
1963
1964 break;
1965 }
1966 case EVENT_SET_DATA_THROTTLING_DONE:
1967 ar = (AsyncResult) msg.obj;
1968 request = (MainThreadRequest) ar.userObj;
1969
1970 if (ar.exception == null) {
1971 request.result = TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
1972 } else if (ar.exception instanceof CommandException) {
1973 loge("setDataThrottling: CommandException: " + ar.exception);
1974 CommandException.Error error =
1975 ((CommandException) (ar.exception)).getCommandError();
1976
1977 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1978 request.result = TelephonyManager
1979 .THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
1980 } else if (error == CommandException.Error.INVALID_ARGUMENTS) {
1981 request.result = SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS;
Jack Nudelman5d6a98b2021-03-04 14:26:25 -08001982 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1983 request.result = MODEM_DOES_NOT_SUPPORT_DATA_THROTTLING_ERROR_CODE;
Jack Nudelmanb0b87642020-11-12 15:04:39 -08001984 } else {
1985 request.result =
1986 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
1987 }
1988 } else {
1989 request.result = TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
1990 }
1991 Log.w(LOG_TAG, "DataThrottlingResult = " + request.result);
1992 notifyRequester(request);
1993 break;
Jordan Liu109698e2020-11-24 14:50:34 -08001994
1995 case CMD_SET_SIM_POWER: {
1996 request = (MainThreadRequest) msg.obj;
1997 onCompleted = obtainMessage(EVENT_SET_SIM_POWER_DONE, request);
1998 request = (MainThreadRequest) msg.obj;
1999 int stateToSet =
2000 ((Pair<Integer, IIntegerConsumer>)
2001 request.argument).first;
2002 request.phone.setSimPowerState(stateToSet, onCompleted, request.workSource);
2003 break;
2004 }
2005 case EVENT_SET_SIM_POWER_DONE: {
2006 ar = (AsyncResult) msg.obj;
2007 request = (MainThreadRequest) ar.userObj;
2008 IIntegerConsumer callback =
2009 ((Pair<Integer, IIntegerConsumer>) request.argument).second;
2010 if (ar.exception != null) {
2011 loge("setSimPower exception: " + ar.exception);
2012 int errorCode = TelephonyManager.CallForwardingInfoCallback
2013 .RESULT_ERROR_UNKNOWN;
2014 if (ar.exception instanceof CommandException) {
2015 CommandException.Error error =
2016 ((CommandException) (ar.exception)).getCommandError();
2017 if (error == CommandException.Error.SIM_ERR) {
2018 errorCode = TelephonyManager.SET_SIM_POWER_STATE_SIM_ERROR;
2019 } else if (error == CommandException.Error.INVALID_ARGUMENTS) {
2020 errorCode = TelephonyManager.SET_SIM_POWER_STATE_ALREADY_IN_STATE;
2021 } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
2022 errorCode = TelephonyManager.SET_SIM_POWER_STATE_NOT_SUPPORTED;
2023 } else {
2024 errorCode = TelephonyManager.SET_SIM_POWER_STATE_MODEM_ERROR;
2025 }
2026 }
2027 try {
2028 callback.accept(errorCode);
2029 } catch (RemoteException e) {
2030 // Ignore if the remote process is no longer available to call back.
2031 Log.w(LOG_TAG, "setSimPower: callback not available.");
2032 }
2033 } else {
2034 try {
2035 callback.accept(TelephonyManager.SET_SIM_POWER_STATE_SUCCESS);
2036 } catch (RemoteException e) {
2037 // Ignore if the remote process is no longer available to call back.
2038 Log.w(LOG_TAG, "setSimPower: callback not available.");
2039 }
2040 }
2041 break;
2042 }
Rambo Wanga5cc9b72021-01-07 10:51:54 -08002043 case CMD_SET_SIGNAL_STRENGTH_UPDATE_REQUEST: {
2044 request = (MainThreadRequest) msg.obj;
2045
2046 final Phone phone = getPhoneFromRequest(request);
2047 if (phone == null || phone.getServiceStateTracker() == null) {
2048 request.result = new IllegalStateException("Phone or SST is null");
2049 notifyRequester(request);
2050 break;
2051 }
2052
2053 Pair<Integer, SignalStrengthUpdateRequest> pair =
2054 (Pair<Integer, SignalStrengthUpdateRequest>) request.argument;
2055 onCompleted = obtainMessage(EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE,
2056 request);
Rambo Wang6568f172021-02-03 16:56:47 -08002057 phone.getSignalStrengthController().setSignalStrengthUpdateRequest(
Rambo Wanga5cc9b72021-01-07 10:51:54 -08002058 request.subId, pair.first /*callingUid*/,
2059 pair.second /*request*/, onCompleted);
2060 break;
2061 }
2062 case EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE: {
2063 ar = (AsyncResult) msg.obj;
2064 request = (MainThreadRequest) ar.userObj;
2065 // request.result will be the exception of ar if present, true otherwise.
2066 // Be cautious not to leave result null which will wait() forever
2067 request.result = ar.exception != null ? ar.exception : true;
2068 notifyRequester(request);
2069 break;
2070 }
2071 case CMD_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST: {
2072 request = (MainThreadRequest) msg.obj;
2073
2074 Phone phone = getPhoneFromRequest(request);
2075 if (phone == null || phone.getServiceStateTracker() == null) {
2076 request.result = new IllegalStateException("Phone or SST is null");
2077 notifyRequester(request);
2078 break;
2079 }
2080
2081 Pair<Integer, SignalStrengthUpdateRequest> pair =
2082 (Pair<Integer, SignalStrengthUpdateRequest>) request.argument;
2083 onCompleted = obtainMessage(EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE,
2084 request);
Rambo Wang6568f172021-02-03 16:56:47 -08002085 phone.getSignalStrengthController().clearSignalStrengthUpdateRequest(
Rambo Wanga5cc9b72021-01-07 10:51:54 -08002086 request.subId, pair.first /*callingUid*/,
2087 pair.second /*request*/, onCompleted);
2088 break;
2089 }
2090 case EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE: {
2091 ar = (AsyncResult) msg.obj;
2092 request = (MainThreadRequest) ar.userObj;
2093 request.result = ar.exception != null ? ar.exception : true;
2094 notifyRequester(request);
2095 break;
2096 }
Jordan Liu109698e2020-11-24 14:50:34 -08002097
Hongbo Zeng156aa4a2021-02-08 21:50:28 +08002098 case CMD_GET_SLICING_CONFIG: {
2099 request = (MainThreadRequest) msg.obj;
2100 onCompleted = obtainMessage(EVENT_GET_SLICING_CONFIG_DONE, request);
2101 request.phone.getSlicingConfig(onCompleted);
2102 break;
2103 }
2104 case EVENT_GET_SLICING_CONFIG_DONE: {
2105 ar = (AsyncResult) msg.obj;
2106 request = (MainThreadRequest) ar.userObj;
2107 ResultReceiver result = (ResultReceiver) request.argument;
2108
Hongbo Zeng0e18b162021-04-07 16:52:18 +08002109 NetworkSlicingConfig slicingConfig = null;
Hongbo Zeng156aa4a2021-02-08 21:50:28 +08002110 Bundle bundle = new Bundle();
2111 int resultCode = 0;
2112 if (ar.exception != null) {
2113 Log.e(LOG_TAG, "Exception retrieving slicing configuration="
2114 + ar.exception);
Hongbo Zeng0e18b162021-04-07 16:52:18 +08002115 resultCode = TelephonyManager.NetworkSlicingException.ERROR_MODEM_ERROR;
Hongbo Zeng156aa4a2021-02-08 21:50:28 +08002116 } else if (ar.result == null) {
2117 Log.w(LOG_TAG, "Timeout Waiting for slicing configuration!");
Hongbo Zeng0e18b162021-04-07 16:52:18 +08002118 resultCode = TelephonyManager.NetworkSlicingException.ERROR_TIMEOUT;
Hongbo Zeng156aa4a2021-02-08 21:50:28 +08002119 } else {
2120 // use the result as returned
Hongbo Zeng0e18b162021-04-07 16:52:18 +08002121 resultCode = TelephonyManager.NetworkSlicingException.SUCCESS;
2122 slicingConfig = (NetworkSlicingConfig) ar.result;
Hongbo Zeng156aa4a2021-02-08 21:50:28 +08002123 }
2124
2125 if (slicingConfig == null) {
Hongbo Zeng0e18b162021-04-07 16:52:18 +08002126 slicingConfig = new NetworkSlicingConfig();
Hongbo Zeng156aa4a2021-02-08 21:50:28 +08002127 }
2128 bundle.putParcelable(TelephonyManager.KEY_SLICING_CONFIG_HANDLE, slicingConfig);
2129 result.send(resultCode, bundle);
2130 notifyRequester(request);
2131 break;
2132 }
2133
Michele Berionne5e411512020-11-13 02:36:59 +00002134 case CMD_PREPARE_UNATTENDED_REBOOT:
2135 request = (MainThreadRequest) msg.obj;
2136 request.result =
Rafael Higuera Silvad9630642021-09-20 15:32:01 +00002137 UiccController.getInstance().getPinStorage()
2138 .prepareUnattendedReboot(request.workSource);
Michele Berionne5e411512020-11-13 02:36:59 +00002139 notifyRequester(request);
2140 break;
2141
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002142 default:
2143 Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
2144 break;
2145 }
2146 }
Jake Hambye994d462014-02-03 13:10:13 -08002147
Pengquan Menga1bb6272018-09-06 09:59:22 -07002148 private void notifyRequester(MainThreadRequest request) {
2149 synchronized (request) {
2150 request.notifyAll();
2151 }
2152 }
2153
Jake Hambye994d462014-02-03 13:10:13 -08002154 private void handleNullReturnEvent(Message msg, String command) {
2155 AsyncResult ar = (AsyncResult) msg.obj;
2156 MainThreadRequest request = (MainThreadRequest) ar.userObj;
2157 if (ar.exception == null) {
2158 request.result = true;
2159 } else {
2160 request.result = false;
2161 if (ar.exception instanceof CommandException) {
2162 loge(command + ": CommandException: " + ar.exception);
2163 } else {
2164 loge(command + ": Unknown exception");
2165 }
2166 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07002167 notifyRequester(request);
Jake Hambye994d462014-02-03 13:10:13 -08002168 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002169 }
2170
2171 /**
2172 * Posts the specified command to be executed on the main thread,
2173 * waits for the request to complete, and returns the result.
2174 * @see #sendRequestAsync
2175 */
2176 private Object sendRequest(int command, Object argument) {
Rambo Wang0f050d82021-02-12 11:43:36 -08002177 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, null,
2178 null, -1 /*timeoutInMs*/);
vagdeviaf9a5b92018-08-15 16:01:53 -07002179 }
2180
2181 /**
2182 * Posts the specified command to be executed on the main thread,
2183 * waits for the request to complete, and returns the result.
2184 * @see #sendRequestAsync
2185 */
2186 private Object sendRequest(int command, Object argument, WorkSource workSource) {
2187 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
Rambo Wang0f050d82021-02-12 11:43:36 -08002188 null, workSource, -1 /*timeoutInMs*/);
Wink Saville36469e72014-06-11 15:17:00 -07002189 }
2190
2191 /**
2192 * Posts the specified command to be executed on the main thread,
2193 * waits for the request to complete, and returns the result.
2194 * @see #sendRequestAsync
2195 */
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002196 private Object sendRequest(int command, Object argument, Integer subId) {
Rambo Wang0f050d82021-02-12 11:43:36 -08002197 return sendRequest(command, argument, subId, null, null, -1 /*timeoutInMs*/);
2198 }
2199
2200 /**
2201 * Posts the specified command to be executed on the main thread,
2202 * waits for the request to complete for at most {@code timeoutInMs}, and returns the result
2203 * if not timeout or null otherwise.
2204 * @see #sendRequestAsync
2205 */
2206 private @Nullable Object sendRequest(int command, Object argument, Integer subId,
2207 long timeoutInMs) {
2208 return sendRequest(command, argument, subId, null, null, timeoutInMs);
vagdeviaf9a5b92018-08-15 16:01:53 -07002209 }
2210
2211 /**
2212 * Posts the specified command to be executed on the main thread,
2213 * waits for the request to complete, and returns the result.
2214 * @see #sendRequestAsync
2215 */
Nathan Harold92bed182018-10-12 18:16:49 -07002216 private Object sendRequest(int command, Object argument, int subId, WorkSource workSource) {
Rambo Wang0f050d82021-02-12 11:43:36 -08002217 return sendRequest(command, argument, subId, null, workSource, -1 /*timeoutInMs*/);
Nathan Harold92bed182018-10-12 18:16:49 -07002218 }
2219
2220 /**
2221 * Posts the specified command to be executed on the main thread,
2222 * waits for the request to complete, and returns the result.
2223 * @see #sendRequestAsync
2224 */
2225 private Object sendRequest(int command, Object argument, Phone phone, WorkSource workSource) {
Rambo Wang0f050d82021-02-12 11:43:36 -08002226 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phone,
2227 workSource, -1 /*timeoutInMs*/);
Nathan Harold92bed182018-10-12 18:16:49 -07002228 }
2229
2230 /**
Rambo Wang0f050d82021-02-12 11:43:36 -08002231 * Posts the specified command to be executed on the main thread. If {@code timeoutInMs} is
2232 * negative, waits for the request to complete, and returns the result. Otherwise, wait for
2233 * maximum of {@code timeoutInMs} milliseconds, interrupt and return null.
Nathan Harold92bed182018-10-12 18:16:49 -07002234 * @see #sendRequestAsync
2235 */
Rambo Wang0f050d82021-02-12 11:43:36 -08002236 private @Nullable Object sendRequest(int command, Object argument, Integer subId, Phone phone,
2237 WorkSource workSource, long timeoutInMs) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002238 if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
2239 throw new RuntimeException("This method will deadlock if called from the main thread.");
2240 }
2241
Nathan Harold92bed182018-10-12 18:16:49 -07002242 MainThreadRequest request = null;
2243 if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && phone != null) {
2244 throw new IllegalArgumentException("subId and phone cannot both be specified!");
2245 } else if (phone != null) {
2246 request = new MainThreadRequest(argument, phone, workSource);
2247 } else {
2248 request = new MainThreadRequest(argument, subId, workSource);
2249 }
2250
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002251 Message msg = mMainThreadHandler.obtainMessage(command, request);
2252 msg.sendToTarget();
2253
Rambo Wang0f050d82021-02-12 11:43:36 -08002254
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002255 synchronized (request) {
Rambo Wang0f050d82021-02-12 11:43:36 -08002256 if (timeoutInMs >= 0) {
2257 // Wait for at least timeoutInMs before returning null request result
2258 long now = SystemClock.elapsedRealtime();
2259 long deadline = now + timeoutInMs;
Grace Jia8a0a1e82021-05-23 22:59:52 -07002260 while (request.result == null && now < deadline) {
Rambo Wang0f050d82021-02-12 11:43:36 -08002261 try {
2262 request.wait(deadline - now);
2263 } catch (InterruptedException e) {
2264 // Do nothing, go back and check if request is completed or timeout
2265 } finally {
2266 now = SystemClock.elapsedRealtime();
2267 }
2268 }
2269 } else {
2270 // Wait for the request to complete
2271 while (request.result == null) {
2272 try {
2273 request.wait();
2274 } catch (InterruptedException e) {
2275 // Do nothing, go back and wait until the request is complete
2276 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002277 }
2278 }
2279 }
Rambo Wang0f050d82021-02-12 11:43:36 -08002280 if (request.result == null) {
2281 Log.wtf(LOG_TAG,
2282 "sendRequest: Blocking command timed out. Something has gone terribly wrong.");
2283 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002284 return request.result;
2285 }
2286
2287 /**
2288 * Asynchronous ("fire and forget") version of sendRequest():
2289 * Posts the specified command to be executed on the main thread, and
2290 * returns immediately.
2291 * @see #sendRequest
2292 */
2293 private void sendRequestAsync(int command) {
2294 mMainThreadHandler.sendEmptyMessage(command);
2295 }
2296
2297 /**
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07002298 * Same as {@link #sendRequestAsync(int)} except it takes an argument.
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002299 * @see {@link #sendRequest(int)}
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07002300 */
2301 private void sendRequestAsync(int command, Object argument) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07002302 sendRequestAsync(command, argument, null, null);
2303 }
2304
2305 /**
2306 * Same as {@link #sendRequestAsync(int,Object)} except it takes a Phone and WorkSource.
2307 * @see {@link #sendRequest(int,Object)}
2308 */
2309 private void sendRequestAsync(
2310 int command, Object argument, Phone phone, WorkSource workSource) {
2311 MainThreadRequest request = new MainThreadRequest(argument, phone, workSource);
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07002312 Message msg = mMainThreadHandler.obtainMessage(command, request);
2313 msg.sendToTarget();
2314 }
2315
2316 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002317 * Initialize the singleton PhoneInterfaceManager instance.
2318 * This is only done once, at startup, from PhoneApp.onCreate().
2319 */
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002320 /* package */ static PhoneInterfaceManager init(PhoneGlobals app) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002321 synchronized (PhoneInterfaceManager.class) {
2322 if (sInstance == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002323 sInstance = new PhoneInterfaceManager(app);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002324 } else {
2325 Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
2326 }
2327 return sInstance;
2328 }
2329 }
2330
2331 /** Private constructor; @see init() */
Jordan Liu1979a042020-03-20 21:39:35 +00002332 private PhoneInterfaceManager(PhoneGlobals app) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002333 mApp = app;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002334 mCM = PhoneGlobals.getInstance().mCM;
Brad Ebingerd1947d82021-05-17 20:54:49 +00002335 mImsResolver = ImsResolver.getInstance();
Stuart Scott981d8582015-04-21 14:09:50 -07002336 mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002337 mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
Grace Jia0ddb3612021-04-22 13:35:26 -07002338 mPm = app.getSystemService(PackageManager.class);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002339 mMainThreadHandler = new MainThreadHandler();
Tobias Thiererb19e1f12018-12-11 17:54:03 +00002340 mSubscriptionController = SubscriptionController.getInstance();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002341 mTelephonySharedPreferences =
2342 PreferenceManager.getDefaultSharedPreferences(mApp);
yinxub1bed742017-04-17 11:45:04 -07002343 mNetworkScanRequestTracker = new NetworkScanRequestTracker();
Malcolm Chen2c63d402018-08-14 16:00:53 -07002344 mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
Daniel Bright94f43662021-03-01 14:43:40 -08002345 mRadioInterfaceCapabilities = RadioInterfaceCapabilityController.getInstance();
Peter Wanga3cf4ac2020-01-27 09:39:46 +08002346 mNotifyUserActivity = new AtomicBoolean(false);
Wink Saville3ab207e2014-11-20 13:07:20 -08002347
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002348 publish();
2349 }
2350
Nazanin Bakhshif782e562018-12-11 15:15:39 -08002351 private Phone getDefaultPhone() {
2352 Phone thePhone = getPhone(getDefaultSubscription());
2353 return (thePhone != null) ? thePhone : PhoneFactory.getDefaultPhone();
2354 }
2355
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002356 private void publish() {
2357 if (DBG) log("publish: " + this);
2358
Peter Wangc035ce42020-01-08 21:00:22 -08002359 TelephonyFrameworkInitializer
2360 .getTelephonyServiceManager()
2361 .getTelephonyServiceRegisterer()
2362 .register(this);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002363 }
2364
Stuart Scott584921c2015-01-15 17:10:34 -08002365 private Phone getPhoneFromRequest(MainThreadRequest request) {
Jordan Liu4c733742019-02-28 12:03:40 -08002366 if (request.phone != null) {
2367 return request.phone;
2368 } else {
2369 return getPhoneFromSubId(request.subId);
2370 }
2371 }
2372
2373 private Phone getPhoneFromSubId(int subId) {
2374 return (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
2375 ? getDefaultPhone() : getPhone(subId);
Stuart Scott584921c2015-01-15 17:10:34 -08002376 }
2377
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00002378 private UiccPort getUiccPortFromRequest(MainThreadRequest request) {
Shishir Agrawalc04d9752016-02-19 10:41:00 -08002379 Phone phone = getPhoneFromRequest(request);
2380 return phone == null ? null :
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00002381 UiccController.getInstance().getUiccPort(phone.getPhoneId());
Shishir Agrawalc04d9752016-02-19 10:41:00 -08002382 }
2383
Wink Saville36469e72014-06-11 15:17:00 -07002384 // returns phone associated with the subId.
Wink Savilleb564aae2014-10-23 10:18:09 -07002385 private Phone getPhone(int subId) {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08002386 return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId));
Wink Saville36469e72014-06-11 15:17:00 -07002387 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002388
Kai Shif70f46f2021-03-03 13:59:46 -08002389 private void sendEraseModemConfig(@NonNull Phone phone) {
2390 Boolean success = (Boolean) sendRequest(CMD_ERASE_MODEM_CONFIG, null);
2391 if (DBG) log("eraseModemConfig:" + ' ' + (success ? "ok" : "fail"));
2392 }
2393
2394 private void sendEraseDataInSharedPreferences(@NonNull Phone phone) {
2395 Boolean success = (Boolean) sendRequest(CMD_ERASE_DATA_SHARED_PREFERENCES, null);
2396 if (DBG) log("eraseDataInSharedPreferences:" + ' ' + (success ? "ok" : "fail"));
Naina Nallurid63128d2019-09-17 14:10:30 -07002397 }
2398
Peter Wang44b186e2020-01-13 23:33:09 -08002399 private boolean isImsAvailableOnDevice() {
2400 PackageManager pm = getDefaultPhone().getContext().getPackageManager();
2401 if (pm == null) {
2402 // For some reason package manger is not available.. This will fail internally anyway,
2403 // so do not throw error and allow.
2404 return true;
2405 }
2406 return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS, 0);
2407 }
2408
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002409 public void dial(String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002410 dialForSubscriber(getPreferredVoiceSubscription(), number);
Wink Saville36469e72014-06-11 15:17:00 -07002411 }
2412
Wink Savilleb564aae2014-10-23 10:18:09 -07002413 public void dialForSubscriber(int subId, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002414 if (DBG) log("dial: " + number);
2415 // No permission check needed here: This is just a wrapper around the
2416 // ACTION_DIAL intent, which is available to any app since it puts up
2417 // the UI before it does anything.
2418
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002419 final long identity = Binder.clearCallingIdentity();
2420 try {
2421 String url = createTelUrl(number);
2422 if (url == null) {
2423 return;
2424 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002425
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002426 // PENDING: should we just silently fail if phone is offhook or ringing?
2427 PhoneConstants.State state = mCM.getState(subId);
2428 if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
2429 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
2430 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2431 mApp.startActivity(intent);
2432 }
2433 } finally {
2434 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002435 }
2436 }
2437
2438 public void call(String callingPackage, String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002439 callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number);
Wink Saville36469e72014-06-11 15:17:00 -07002440 }
2441
Wink Savilleb564aae2014-10-23 10:18:09 -07002442 public void callForSubscriber(int subId, String callingPackage, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002443 if (DBG) log("call: " + number);
2444
2445 // This is just a wrapper around the ACTION_CALL intent, but we still
2446 // need to do a permission check since we're calling startActivity()
2447 // from the context of the phone app.
2448 enforceCallPermission();
2449
Jordan Liu1617b712019-07-10 15:06:26 -07002450 if (mAppOps.noteOp(AppOpsManager.OPSTR_CALL_PHONE, Binder.getCallingUid(), callingPackage)
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002451 != AppOpsManager.MODE_ALLOWED) {
2452 return;
2453 }
2454
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002455 final long identity = Binder.clearCallingIdentity();
2456 try {
2457 String url = createTelUrl(number);
2458 if (url == null) {
2459 return;
2460 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002461
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002462 boolean isValid = false;
2463 final List<SubscriptionInfo> slist = getActiveSubscriptionInfoListPrivileged();
2464 if (slist != null) {
2465 for (SubscriptionInfo subInfoRecord : slist) {
2466 if (subInfoRecord.getSubscriptionId() == subId) {
2467 isValid = true;
2468 break;
2469 }
Wink Saville3ab207e2014-11-20 13:07:20 -08002470 }
Wink Saville08874612014-08-31 19:19:58 -07002471 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002472 if (!isValid) {
2473 return;
2474 }
Wink Saville08874612014-08-31 19:19:58 -07002475
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002476 Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
2477 intent.putExtra(SUBSCRIPTION_KEY, subId);
2478 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2479 mApp.startActivity(intent);
2480 } finally {
2481 Binder.restoreCallingIdentity(identity);
2482 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002483 }
2484
Wink Savilleb564aae2014-10-23 10:18:09 -07002485 public boolean supplyPinForSubscriber(int subId, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002486 int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07002487 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
2488 }
2489
Wink Savilleb564aae2014-10-23 10:18:09 -07002490 public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002491 int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07002492 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
2493 }
2494
Wink Savilleb564aae2014-10-23 10:18:09 -07002495 public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002496 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002497
2498 final long identity = Binder.clearCallingIdentity();
2499 try {
Michele Berionne5e411512020-11-13 02:36:59 +00002500 Phone phone = getPhone(subId);
2501 final UnlockSim checkSimPin = new UnlockSim(phone.getPhoneId(), phone.getIccCard());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002502 checkSimPin.start();
2503 return checkSimPin.unlockSim(null, pin);
2504 } finally {
2505 Binder.restoreCallingIdentity(identity);
2506 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002507 }
2508
Wink Savilleb564aae2014-10-23 10:18:09 -07002509 public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002510 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002511
2512 final long identity = Binder.clearCallingIdentity();
2513 try {
Michele Berionne5e411512020-11-13 02:36:59 +00002514 Phone phone = getPhone(subId);
2515 final UnlockSim checkSimPuk = new UnlockSim(phone.getPhoneId(), phone.getIccCard());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002516 checkSimPuk.start();
2517 return checkSimPuk.unlockSim(puk, pin);
2518 } finally {
2519 Binder.restoreCallingIdentity(identity);
2520 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002521 }
2522
2523 /**
Wink Saville9de0f752013-10-22 19:04:03 -07002524 * Helper thread to turn async call to SimCard#supplyPin into
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002525 * a synchronous one.
2526 */
2527 private static class UnlockSim extends Thread {
2528
2529 private final IccCard mSimCard;
Michele Berionne5e411512020-11-13 02:36:59 +00002530 private final int mPhoneId;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002531
2532 private boolean mDone = false;
Wink Saville9de0f752013-10-22 19:04:03 -07002533 private int mResult = PhoneConstants.PIN_GENERAL_FAILURE;
2534 private int mRetryCount = -1;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002535
2536 // For replies from SimCard interface
2537 private Handler mHandler;
2538
2539 // For async handler to identify request type
2540 private static final int SUPPLY_PIN_COMPLETE = 100;
2541
Michele Berionne5e411512020-11-13 02:36:59 +00002542 UnlockSim(int phoneId, IccCard simCard) {
2543 mPhoneId = phoneId;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002544 mSimCard = simCard;
2545 }
2546
2547 @Override
2548 public void run() {
2549 Looper.prepare();
2550 synchronized (UnlockSim.this) {
2551 mHandler = new Handler() {
2552 @Override
2553 public void handleMessage(Message msg) {
2554 AsyncResult ar = (AsyncResult) msg.obj;
2555 switch (msg.what) {
2556 case SUPPLY_PIN_COMPLETE:
2557 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
2558 synchronized (UnlockSim.this) {
Wink Saville9de0f752013-10-22 19:04:03 -07002559 mRetryCount = msg.arg1;
2560 if (ar.exception != null) {
2561 if (ar.exception instanceof CommandException &&
2562 ((CommandException)(ar.exception)).getCommandError()
2563 == CommandException.Error.PASSWORD_INCORRECT) {
2564 mResult = PhoneConstants.PIN_PASSWORD_INCORRECT;
vivi.lib5e9ada2019-09-12 16:04:24 +08002565 } //When UiccCardApp dispose,handle message and return exception
2566 else if (ar.exception instanceof CommandException &&
2567 ((CommandException) (ar.exception)).getCommandError()
2568 == CommandException.Error.ABORTED) {
2569 mResult = PhoneConstants.PIN_OPERATION_ABORTED;
Wink Saville9de0f752013-10-22 19:04:03 -07002570 } else {
2571 mResult = PhoneConstants.PIN_GENERAL_FAILURE;
2572 }
2573 } else {
2574 mResult = PhoneConstants.PIN_RESULT_SUCCESS;
2575 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002576 mDone = true;
2577 UnlockSim.this.notifyAll();
2578 }
2579 break;
2580 }
2581 }
2582 };
2583 UnlockSim.this.notifyAll();
2584 }
2585 Looper.loop();
2586 }
2587
2588 /*
2589 * Use PIN or PUK to unlock SIM card
2590 *
2591 * If PUK is null, unlock SIM card with PIN
2592 *
2593 * If PUK is not null, unlock SIM card with PUK and set PIN code
2594 */
Wink Saville9de0f752013-10-22 19:04:03 -07002595 synchronized int[] unlockSim(String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002596
2597 while (mHandler == null) {
2598 try {
2599 wait();
2600 } catch (InterruptedException e) {
2601 Thread.currentThread().interrupt();
2602 }
2603 }
2604 Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
2605
2606 if (puk == null) {
2607 mSimCard.supplyPin(pin, callback);
2608 } else {
2609 mSimCard.supplyPuk(puk, pin, callback);
2610 }
2611
2612 while (!mDone) {
2613 try {
2614 Log.d(LOG_TAG, "wait for done");
2615 wait();
2616 } catch (InterruptedException e) {
2617 // Restore the interrupted status
2618 Thread.currentThread().interrupt();
2619 }
2620 }
2621 Log.d(LOG_TAG, "done");
Wink Saville9de0f752013-10-22 19:04:03 -07002622 int[] resultArray = new int[2];
2623 resultArray[0] = mResult;
2624 resultArray[1] = mRetryCount;
Michele Berionne5e411512020-11-13 02:36:59 +00002625
2626 if (mResult == PhoneConstants.PIN_RESULT_SUCCESS && pin.length() > 0) {
Jon Spivack9c3bc762021-10-06 20:53:09 +00002627 UiccController.getInstance().getPinStorage().storePin(pin, mPhoneId);
Michele Berionne5e411512020-11-13 02:36:59 +00002628 }
2629
Wink Saville9de0f752013-10-22 19:04:03 -07002630 return resultArray;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002631 }
2632 }
2633
Nathan Harold7c8d0f12020-05-28 20:40:31 -07002634 /**
2635 * This method has been removed due to privacy and stability concerns.
2636 */
2637 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002638 public void updateServiceLocation() {
Nathan Harold7c8d0f12020-05-28 20:40:31 -07002639 Log.e(LOG_TAG, "Call to unsupported method updateServiceLocation()");
2640 return;
Wink Saville36469e72014-06-11 15:17:00 -07002641 }
2642
Nathan Harold1f889d82020-06-04 17:05:26 -07002643 @Override
2644 public void updateServiceLocationWithPackageName(String callingPackage) {
2645 mApp.getSystemService(AppOpsManager.class)
2646 .checkPackage(Binder.getCallingUid(), callingPackage);
2647
Nathan Haroldf096d982020-11-18 17:18:06 -08002648 final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
Nathan Harold1f889d82020-06-04 17:05:26 -07002649 if (targetSdk > android.os.Build.VERSION_CODES.R) {
2650 // Callers targeting S have no business invoking this method.
2651 return;
2652 }
2653
2654 LocationAccessPolicy.LocationPermissionResult locationResult =
2655 LocationAccessPolicy.checkLocationPermission(mApp,
2656 new LocationAccessPolicy.LocationPermissionQuery.Builder()
2657 .setCallingPackage(callingPackage)
2658 .setCallingFeatureId(null)
2659 .setCallingPid(Binder.getCallingPid())
2660 .setCallingUid(Binder.getCallingUid())
2661 .setMethod("updateServiceLocation")
2662 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
2663 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2664 .build());
2665 // Apps that lack location permission have no business calling this method;
2666 // however, because no permission was declared in the public API, denials must
2667 // all be "soft".
2668 switch (locationResult) {
2669 case DENIED_HARD: /* fall through */
2670 case DENIED_SOFT:
2671 return;
2672 }
2673
2674 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002675 final long identity = Binder.clearCallingIdentity();
2676 try {
Nathan Harold1f889d82020-06-04 17:05:26 -07002677 final Phone phone = getPhone(getDefaultSubscription());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002678 if (phone != null) {
Nathan Harold1f889d82020-06-04 17:05:26 -07002679 phone.updateServiceLocation(workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002680 }
2681 } finally {
2682 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002683 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002684 }
2685
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002686 @Deprecated
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002687 @Override
2688 public boolean isRadioOn(String callingPackage) {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002689 return isRadioOnWithFeature(callingPackage, null);
2690 }
2691
2692
2693 @Override
2694 public boolean isRadioOnWithFeature(String callingPackage, String callingFeatureId) {
2695 return isRadioOnForSubscriberWithFeature(getDefaultSubscription(), callingPackage,
2696 callingFeatureId);
2697 }
2698
2699 @Deprecated
2700 @Override
2701 public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
2702 return isRadioOnForSubscriberWithFeature(subId, callingPackage, null);
Wink Saville36469e72014-06-11 15:17:00 -07002703 }
2704
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002705 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002706 public boolean isRadioOnForSubscriberWithFeature(int subId, String callingPackage,
2707 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002708 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07002709 mApp, subId, callingPackage, callingFeatureId, "isRadioOnForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002710 return false;
2711 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002712
2713 final long identity = Binder.clearCallingIdentity();
2714 try {
2715 return isRadioOnForSubscriber(subId);
2716 } finally {
2717 Binder.restoreCallingIdentity(identity);
2718 }
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002719 }
2720
2721 private boolean isRadioOnForSubscriber(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002722 final long identity = Binder.clearCallingIdentity();
2723 try {
2724 final Phone phone = getPhone(subId);
2725 if (phone != null) {
2726 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
2727 } else {
2728 return false;
2729 }
2730 } finally {
2731 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002732 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002733 }
2734
2735 public void toggleRadioOnOff() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002736 toggleRadioOnOffForSubscriber(getDefaultSubscription());
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002737 }
Wink Saville36469e72014-06-11 15:17:00 -07002738
Wink Savilleb564aae2014-10-23 10:18:09 -07002739 public void toggleRadioOnOffForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002740 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002741
2742 final long identity = Binder.clearCallingIdentity();
2743 try {
2744 final Phone phone = getPhone(subId);
2745 if (phone != null) {
2746 phone.setRadioPower(!isRadioOnForSubscriber(subId));
2747 }
2748 } finally {
2749 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002750 }
Wink Saville36469e72014-06-11 15:17:00 -07002751 }
2752
2753 public boolean setRadio(boolean turnOn) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002754 return setRadioForSubscriber(getDefaultSubscription(), turnOn);
Wink Saville36469e72014-06-11 15:17:00 -07002755 }
2756
Wink Savilleb564aae2014-10-23 10:18:09 -07002757 public boolean setRadioForSubscriber(int subId, boolean turnOn) {
Wink Saville36469e72014-06-11 15:17:00 -07002758 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002759
2760 final long identity = Binder.clearCallingIdentity();
2761 try {
2762 final Phone phone = getPhone(subId);
2763 if (phone == null) {
2764 return false;
2765 }
2766 if ((phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF) != turnOn) {
2767 toggleRadioOnOffForSubscriber(subId);
2768 }
2769 return true;
2770 } finally {
2771 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002772 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002773 }
Wink Saville36469e72014-06-11 15:17:00 -07002774
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002775 public boolean needMobileRadioShutdown() {
Shuo Qianfa7b6b32019-12-10 10:40:38 -08002776 enforceReadPrivilegedPermission("needMobileRadioShutdown");
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002777 /*
2778 * If any of the Radios are available, it will need to be
2779 * shutdown. So return true if any Radio is available.
2780 */
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002781 final long identity = Binder.clearCallingIdentity();
2782 try {
2783 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
2784 Phone phone = PhoneFactory.getPhone(i);
2785 if (phone != null && phone.isRadioAvailable()) return true;
2786 }
2787 logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown.");
2788 return false;
2789 } finally {
2790 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002791 }
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002792 }
2793
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002794 @Override
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002795 public void shutdownMobileRadios() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002796 enforceModifyPermission();
2797
2798 final long identity = Binder.clearCallingIdentity();
2799 try {
2800 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
2801 logv("Shutting down Phone " + i);
2802 shutdownRadioUsingPhoneId(i);
2803 }
2804 } finally {
2805 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002806 }
2807 }
2808
2809 private void shutdownRadioUsingPhoneId(int phoneId) {
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002810 Phone phone = PhoneFactory.getPhone(phoneId);
2811 if (phone != null && phone.isRadioAvailable()) {
2812 phone.shutdownRadio();
2813 }
2814 }
2815
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002816 public boolean setRadioPower(boolean turnOn) {
Jack Yub4e16162017-05-15 12:48:40 -07002817 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002818
2819 final long identity = Binder.clearCallingIdentity();
2820 try {
2821 final Phone defaultPhone = PhoneFactory.getDefaultPhone();
2822 if (defaultPhone != null) {
2823 defaultPhone.setRadioPower(turnOn);
2824 return true;
2825 } else {
2826 loge("There's no default phone.");
2827 return false;
2828 }
2829 } finally {
2830 Binder.restoreCallingIdentity(identity);
Wei Liu9ae2a062016-08-08 11:09:34 -07002831 }
Wink Saville36469e72014-06-11 15:17:00 -07002832 }
2833
Wink Savilleb564aae2014-10-23 10:18:09 -07002834 public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002835 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002836
2837 final long identity = Binder.clearCallingIdentity();
2838 try {
2839 final Phone phone = getPhone(subId);
2840 if (phone != null) {
2841 phone.setRadioPower(turnOn);
2842 return true;
2843 } else {
2844 return false;
2845 }
2846 } finally {
2847 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002848 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002849 }
2850
Wink Saville36469e72014-06-11 15:17:00 -07002851 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07002852 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002853 public boolean enableDataConnectivity() {
2854 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002855
2856 final long identity = Binder.clearCallingIdentity();
2857 try {
2858 int subId = mSubscriptionController.getDefaultDataSubId();
2859 final Phone phone = getPhone(subId);
2860 if (phone != null) {
Jack Yu99e87332021-12-17 23:14:15 -08002861 if (phone.isUsingNewDataStack()) {
2862 phone.getDataSettingsManager().setDataEnabled(
2863 TelephonyManager.DATA_ENABLED_REASON_USER, true);
2864 } else {
2865 phone.getDataEnabledSettings().setDataEnabled(
2866 TelephonyManager.DATA_ENABLED_REASON_USER, true);
2867 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002868 return true;
2869 } else {
2870 return false;
2871 }
2872 } finally {
2873 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002874 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002875 }
2876
Wink Saville36469e72014-06-11 15:17:00 -07002877 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07002878 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002879 public boolean disableDataConnectivity() {
2880 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002881
2882 final long identity = Binder.clearCallingIdentity();
2883 try {
2884 int subId = mSubscriptionController.getDefaultDataSubId();
2885 final Phone phone = getPhone(subId);
2886 if (phone != null) {
Jack Yu99e87332021-12-17 23:14:15 -08002887 if (phone.isUsingNewDataStack()) {
2888 phone.getDataSettingsManager().setDataEnabled(
2889 TelephonyManager.DATA_ENABLED_REASON_USER, false);
2890 } else {
2891 phone.getDataEnabledSettings().setDataEnabled(
2892 TelephonyManager.DATA_ENABLED_REASON_USER, false);
2893 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002894 return true;
2895 } else {
2896 return false;
2897 }
2898 } finally {
2899 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002900 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002901 }
2902
Sanket Padawe356d7632015-06-22 14:03:32 -07002903 @Override
Jack Yuacf8a132017-05-01 17:00:48 -07002904 public boolean isDataConnectivityPossible(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002905 final long identity = Binder.clearCallingIdentity();
2906 try {
2907 final Phone phone = getPhone(subId);
2908 if (phone != null) {
Jack Yub5d8f642018-11-26 11:20:48 -08002909 return phone.isDataAllowed(ApnSetting.TYPE_DEFAULT);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002910 } else {
2911 return false;
2912 }
2913 } finally {
2914 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002915 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002916 }
2917
2918 public boolean handlePinMmi(String dialString) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002919 return handlePinMmiForSubscriber(getDefaultSubscription(), dialString);
Wink Saville36469e72014-06-11 15:17:00 -07002920 }
2921
pkanwarae03a6b2016-11-06 20:37:09 -08002922 public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002923 enforceCallPermission();
2924
2925 final long identity = Binder.clearCallingIdentity();
2926 try {
2927 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2928 return;
2929 }
2930 Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback);
2931 sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId);
2932 } finally {
2933 Binder.restoreCallingIdentity(identity);
2934 }
pkanwar32d516d2016-10-14 19:37:38 -07002935 };
2936
Wink Savilleb564aae2014-10-23 10:18:09 -07002937 public boolean handlePinMmiForSubscriber(int subId, String dialString) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002938 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002939
2940 final long identity = Binder.clearCallingIdentity();
2941 try {
2942 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2943 return false;
2944 }
2945 return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
2946 } finally {
2947 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002948 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002949 }
2950
Brad Ebinger4f6208e2021-03-23 21:04:45 +00002951 /**
2952 * @deprecated This method is deprecated and is only being kept due to an UnsupportedAppUsage
2953 * tag on getCallState Binder call.
2954 */
2955 @Deprecated
2956 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002957 public int getCallState() {
Brad Ebinger4f6208e2021-03-23 21:04:45 +00002958 if (CompatChanges.isChangeEnabled(
2959 TelecomManager.ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION,
2960 Binder.getCallingUid())) {
2961 // Do not allow this API to be called on API version 31+, it should only be
2962 // called on old apps using this Binder call directly.
2963 throw new SecurityException("This method can only be used for applications "
2964 + "targeting API version 30 or less.");
2965 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002966 final long identity = Binder.clearCallingIdentity();
2967 try {
Brad Ebinger4f6208e2021-03-23 21:04:45 +00002968 Phone phone = getPhone(getDefaultSubscription());
2969 return phone == null ? TelephonyManager.CALL_STATE_IDLE :
2970 PhoneConstantConversions.convertCallState(phone.getState());
2971 } finally {
2972 Binder.restoreCallingIdentity(identity);
2973 }
2974 }
2975
2976 @Override
2977 public int getCallStateForSubscription(int subId, String callingPackage, String featureId) {
2978 if (CompatChanges.isChangeEnabled(
2979 TelecomManager.ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION,
2980 Binder.getCallingUid())) {
2981 // Check READ_PHONE_STATE for API version 31+
2982 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
2983 featureId, "getCallStateForSubscription")) {
2984 throw new SecurityException("getCallState requires READ_PHONE_STATE for apps "
2985 + "targeting API level 31+.");
2986 }
2987 }
2988 final long identity = Binder.clearCallingIdentity();
2989 try {
2990 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002991 return phone == null ? TelephonyManager.CALL_STATE_IDLE :
2992 PhoneConstantConversions.convertCallState(phone.getState());
2993 } finally {
2994 Binder.restoreCallingIdentity(identity);
2995 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002996 }
2997
Sanket Padawe356d7632015-06-22 14:03:32 -07002998 @Override
Nathan Harolde037c472019-06-26 00:41:07 +00002999 public int getDataState() {
Nathan Haroldc4689b12019-06-14 16:58:30 -07003000 return getDataStateForSubId(mSubscriptionController.getDefaultDataSubId());
3001 }
3002
3003 @Override
3004 public int getDataStateForSubId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003005 final long identity = Binder.clearCallingIdentity();
3006 try {
Nathan Haroldc4689b12019-06-14 16:58:30 -07003007 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003008 if (phone != null) {
Jack Yu2c450952021-11-29 11:36:17 -08003009 if (phone.isUsingNewDataStack()) {
3010 return phone.getDataNetworkController().getInternetDataNetworkState();
3011 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003012 return PhoneConstantConversions.convertDataState(phone.getDataConnectionState());
3013 } else {
3014 return PhoneConstantConversions.convertDataState(
3015 PhoneConstants.DataState.DISCONNECTED);
3016 }
3017 } finally {
3018 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003019 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003020 }
3021
Sanket Padawe356d7632015-06-22 14:03:32 -07003022 @Override
Nathan Harolde037c472019-06-26 00:41:07 +00003023 public int getDataActivity() {
Nathan Haroldc4689b12019-06-14 16:58:30 -07003024 return getDataActivityForSubId(mSubscriptionController.getDefaultDataSubId());
3025 }
3026
3027 @Override
3028 public int getDataActivityForSubId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003029 final long identity = Binder.clearCallingIdentity();
3030 try {
Nathan Haroldc4689b12019-06-14 16:58:30 -07003031 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003032 if (phone != null) {
3033 return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState());
3034 } else {
3035 return TelephonyManager.DATA_ACTIVITY_NONE;
3036 }
3037 } finally {
3038 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003039 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003040 }
3041
3042 @Override
Meng Wanga10e89e2019-12-09 13:13:01 -08003043 public CellIdentity getCellLocation(String callingPackage, String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003044 mApp.getSystemService(AppOpsManager.class)
Hall Liu1aa510f2017-11-22 17:40:08 -08003045 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08003046
3047 LocationAccessPolicy.LocationPermissionResult locationResult =
3048 LocationAccessPolicy.checkLocationPermission(mApp,
3049 new LocationAccessPolicy.LocationPermissionQuery.Builder()
3050 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003051 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08003052 .setCallingPid(Binder.getCallingPid())
3053 .setCallingUid(Binder.getCallingUid())
3054 .setMethod("getCellLocation")
Hall Liu773ba022020-01-24 18:07:12 -08003055 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
Hall Liuf19c44f2018-11-27 14:38:17 -08003056 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
3057 .build());
3058 switch (locationResult) {
3059 case DENIED_HARD:
3060 throw new SecurityException("Not allowed to access cell location");
3061 case DENIED_SOFT:
Meng Wanga10e89e2019-12-09 13:13:01 -08003062 return (getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
3063 ? new CellIdentityCdma() : new CellIdentityGsm();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003064 }
3065
Narayan Kamathf04b5a12018-01-09 11:47:15 +00003066 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003067 final long identity = Binder.clearCallingIdentity();
3068 try {
3069 if (DBG_LOC) log("getCellLocation: is active user");
Nathan Harold3ff88932018-08-14 10:19:49 -07003070 int subId = mSubscriptionController.getDefaultDataSubId();
Meng Wanga10e89e2019-12-09 13:13:01 -08003071 return (CellIdentity) sendRequest(CMD_GET_CELL_LOCATION, workSource, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003072 } finally {
3073 Binder.restoreCallingIdentity(identity);
3074 }
Svetoslav64fad262015-04-14 14:35:21 -07003075 }
3076
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003077 @Override
Jack Yueb1e7fe2020-02-22 19:38:58 -08003078 public String getNetworkCountryIsoForPhone(int phoneId) {
Jonathan Basseribf5362b2017-07-19 12:22:35 -07003079 // Reporting the correct network country is ambiguous when IWLAN could conflict with
3080 // registered cell info, so return a NULL country instead.
3081 final long identity = Binder.clearCallingIdentity();
3082 try {
Malcolm Chen3732c2b2018-07-18 20:15:24 -07003083 if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
3084 // Get default phone in this case.
3085 phoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
3086 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07003087 final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003088 Phone phone = PhoneFactory.getPhone(phoneId);
Nathan Harold532f51c2020-04-21 19:31:10 -07003089 if (phone == null) return "";
3090 ServiceStateTracker sst = phone.getServiceStateTracker();
3091 if (sst == null) return "";
3092 LocaleTracker lt = sst.getLocaleTracker();
3093 if (lt == null) return "";
Shuo Qian9418a922021-03-09 11:21:16 -08003094 return lt.getCurrentCountry();
Jonathan Basseribf5362b2017-07-19 12:22:35 -07003095 } finally {
3096 Binder.restoreCallingIdentity(identity);
3097 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07003098 }
3099
Nathan Harold7c8d0f12020-05-28 20:40:31 -07003100 /**
3101 * This method was removed due to potential issues caused by performing partial
3102 * updates of service state, and lack of a credible use case.
3103 *
3104 * This has the ability to break the telephony implementation by disabling notification of
3105 * changes in device connectivity. DO NOT USE THIS!
3106 */
Jonathan Basseribf5362b2017-07-19 12:22:35 -07003107 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003108 public void enableLocationUpdates() {
3109 mApp.enforceCallingOrSelfPermission(
3110 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003111 }
3112
Nathan Harold7c8d0f12020-05-28 20:40:31 -07003113 /**
3114 * This method was removed due to potential issues caused by performing partial
3115 * updates of service state, and lack of a credible use case.
3116 *
3117 * This has the ability to break the telephony implementation by disabling notification of
3118 * changes in device connectivity. DO NOT USE THIS!
3119 */
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003120 @Override
3121 public void disableLocationUpdates() {
3122 mApp.enforceCallingOrSelfPermission(
3123 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003124 }
3125
3126 @Override
3127 @SuppressWarnings("unchecked")
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003128 public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage,
3129 String callingFeatureId) {
Nathan Haroldb55f63b2021-07-27 11:27:38 -07003130 try {
3131 mApp.getSystemService(AppOpsManager.class)
3132 .checkPackage(Binder.getCallingUid(), callingPackage);
3133 } catch (SecurityException e) {
3134 EventLog.writeEvent(0x534e4554, "190619791", Binder.getCallingUid());
3135 throw e;
3136 }
3137
Nathan Haroldf096d982020-11-18 17:18:06 -08003138 final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
Nathan Harolddbea45a2018-08-30 14:35:07 -07003139 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
3140 throw new SecurityException(
3141 "getNeighboringCellInfo() is unavailable to callers targeting Q+ SDK levels.");
3142 }
Nathan Haroldb4d55612018-07-20 13:13:08 -07003143
Jordan Liu1617b712019-07-10 15:06:26 -07003144 if (mAppOps.noteOp(AppOpsManager.OPSTR_NEIGHBORING_CELLS, Binder.getCallingUid(),
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003145 callingPackage) != AppOpsManager.MODE_ALLOWED) {
3146 return null;
3147 }
Svetoslav64fad262015-04-14 14:35:21 -07003148
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07003149 if (DBG_LOC) log("getNeighboringCellInfo: is active user");
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003150
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003151 List<CellInfo> info = getAllCellInfo(callingPackage, callingFeatureId);
Nathan Haroldf180aac2018-06-01 18:43:55 -07003152 if (info == null) return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003153
Nathan Haroldf180aac2018-06-01 18:43:55 -07003154 List<NeighboringCellInfo> neighbors = new ArrayList<NeighboringCellInfo>();
3155 for (CellInfo ci : info) {
3156 if (ci instanceof CellInfoGsm) {
3157 neighbors.add(new NeighboringCellInfo((CellInfoGsm) ci));
3158 } else if (ci instanceof CellInfoWcdma) {
3159 neighbors.add(new NeighboringCellInfo((CellInfoWcdma) ci));
3160 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003161 }
Nathan Haroldf180aac2018-06-01 18:43:55 -07003162 return (neighbors.size()) > 0 ? neighbors : null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003163 }
3164
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07003165 private List<CellInfo> getCachedCellInfo() {
3166 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
3167 for (Phone phone : PhoneFactory.getPhones()) {
3168 List<CellInfo> info = phone.getAllCellInfo();
3169 if (info != null) cellInfos.addAll(info);
3170 }
3171 return cellInfos;
3172 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003173
3174 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003175 public List<CellInfo> getAllCellInfo(String callingPackage, String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003176 mApp.getSystemService(AppOpsManager.class)
Hall Liu1aa510f2017-11-22 17:40:08 -08003177 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08003178
3179 LocationAccessPolicy.LocationPermissionResult locationResult =
3180 LocationAccessPolicy.checkLocationPermission(mApp,
3181 new LocationAccessPolicy.LocationPermissionQuery.Builder()
3182 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003183 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08003184 .setCallingPid(Binder.getCallingPid())
3185 .setCallingUid(Binder.getCallingUid())
3186 .setMethod("getAllCellInfo")
Nathan Harold5ae50b52019-02-20 15:46:36 -08003187 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
Hall Liuf19c44f2018-11-27 14:38:17 -08003188 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
3189 .build());
3190 switch (locationResult) {
3191 case DENIED_HARD:
3192 throw new SecurityException("Not allowed to access cell info");
3193 case DENIED_SOFT:
3194 return new ArrayList<>();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003195 }
3196
Nathan Haroldf096d982020-11-18 17:18:06 -08003197 final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07003198 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
3199 return getCachedCellInfo();
3200 }
3201
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07003202 if (DBG_LOC) log("getAllCellInfo: is active user");
Narayan Kamathf04b5a12018-01-09 11:47:15 +00003203 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003204 final long identity = Binder.clearCallingIdentity();
3205 try {
3206 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
3207 for (Phone phone : PhoneFactory.getPhones()) {
Nathan Harold3ff88932018-08-14 10:19:49 -07003208 final List<CellInfo> info = (List<CellInfo>) sendRequest(
Nathan Harold92bed182018-10-12 18:16:49 -07003209 CMD_GET_ALL_CELL_INFO, null, phone, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003210 if (info != null) cellInfos.addAll(info);
3211 }
3212 return cellInfos;
3213 } finally {
3214 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003215 }
3216 }
3217
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07003218 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003219 public void requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage,
3220 String callingFeatureId) {
3221 requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId,
3222 getWorkSource(Binder.getCallingUid()));
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07003223 }
3224
3225 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003226 public void requestCellInfoUpdateWithWorkSource(int subId, ICellInfoCallback cb,
3227 String callingPackage, String callingFeatureId, WorkSource workSource) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07003228 enforceModifyPermission();
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003229 requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId, workSource);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07003230 }
3231
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003232 private void requestCellInfoUpdateInternal(int subId, ICellInfoCallback cb,
3233 String callingPackage, String callingFeatureId, WorkSource workSource) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003234 mApp.getSystemService(AppOpsManager.class)
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07003235 .checkPackage(Binder.getCallingUid(), callingPackage);
Hall Liuf19c44f2018-11-27 14:38:17 -08003236
3237 LocationAccessPolicy.LocationPermissionResult locationResult =
3238 LocationAccessPolicy.checkLocationPermission(mApp,
3239 new LocationAccessPolicy.LocationPermissionQuery.Builder()
3240 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07003241 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08003242 .setCallingPid(Binder.getCallingPid())
3243 .setCallingUid(Binder.getCallingUid())
3244 .setMethod("requestCellInfoUpdate")
Hall Liud60acc92020-05-21 17:09:35 -07003245 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
3246 .setMinSdkVersionForFine(Build.VERSION_CODES.BASE)
Hall Liuf19c44f2018-11-27 14:38:17 -08003247 .build());
3248 switch (locationResult) {
3249 case DENIED_HARD:
Nathan Haroldf096d982020-11-18 17:18:06 -08003250 if (TelephonyPermissions
3251 .getTargetSdk(mApp, callingPackage) < Build.VERSION_CODES.Q) {
Hall Liud60acc92020-05-21 17:09:35 -07003252 // Safetynet logging for b/154934934
3253 EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
3254 }
Hall Liuf19c44f2018-11-27 14:38:17 -08003255 throw new SecurityException("Not allowed to access cell info");
3256 case DENIED_SOFT:
Nathan Haroldf096d982020-11-18 17:18:06 -08003257 if (TelephonyPermissions
3258 .getTargetSdk(mApp, callingPackage) < Build.VERSION_CODES.Q) {
Hall Liud60acc92020-05-21 17:09:35 -07003259 // Safetynet logging for b/154934934
3260 EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
3261 }
Nathan Harold5320c422019-05-09 10:26:08 -07003262 try {
3263 cb.onCellInfo(new ArrayList<CellInfo>());
3264 } catch (RemoteException re) {
3265 // Drop without consequences
3266 }
Hall Liuf19c44f2018-11-27 14:38:17 -08003267 return;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07003268 }
3269
Nathan Harolda939a962019-05-09 10:13:47 -07003270
3271 final Phone phone = getPhoneFromSubId(subId);
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07003272 if (phone == null) throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
3273
3274 sendRequestAsync(CMD_REQUEST_CELL_INFO_UPDATE, cb, phone, workSource);
3275 }
3276
3277 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003278 public void setCellInfoListRate(int rateInMillis) {
Jack Yua8d8cb82017-01-16 10:15:34 -08003279 enforceModifyPermission();
Narayan Kamathf04b5a12018-01-09 11:47:15 +00003280 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003281
3282 final long identity = Binder.clearCallingIdentity();
3283 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003284 getDefaultPhone().setCellInfoListRate(rateInMillis, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003285 } finally {
3286 Binder.restoreCallingIdentity(identity);
3287 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003288 }
3289
Shishir Agrawala9f32182016-04-12 12:00:16 -07003290 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003291 public String getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
Jeff Davidson913390f2018-02-23 17:11:49 -08003292 Phone phone = PhoneFactory.getPhone(slotIndex);
3293 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003294 return null;
3295 }
Jeff Davidson913390f2018-02-23 17:11:49 -08003296 int subId = phone.getSubId();
Grace Jia0ddb3612021-04-22 13:35:26 -07003297 enforceCallingPackage(callingPackage, Binder.getCallingUid(), "getImeiForSlot");
Michael Groover70af6dc2018-10-01 16:23:15 -07003298 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003299 callingPackage, callingFeatureId, "getImeiForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08003300 return null;
3301 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003302
3303 final long identity = Binder.clearCallingIdentity();
3304 try {
3305 return phone.getImei();
3306 } finally {
3307 Binder.restoreCallingIdentity(identity);
3308 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07003309 }
3310
3311 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00003312 public String getTypeAllocationCodeForSlot(int slotIndex) {
3313 Phone phone = PhoneFactory.getPhone(slotIndex);
3314 String tac = null;
3315 if (phone != null) {
3316 String imei = phone.getImei();
Vala Zadehab005552021-09-21 15:54:29 -07003317 try {
3318 tac = imei == null ? null : imei.substring(0, TYPE_ALLOCATION_CODE_LENGTH);
3319 } catch (IndexOutOfBoundsException e) {
3320 Log.e(LOG_TAG, "IMEI length shorter than upper index.");
3321 return null;
3322 }
David Kelly5e06a7f2018-03-12 14:10:59 +00003323 }
3324 return tac;
3325 }
3326
3327 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003328 public String getMeidForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
Shuo Qian13d89152021-05-10 23:58:11 -07003329 try {
3330 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3331 } catch (SecurityException se) {
3332 EventLog.writeEvent(0x534e4554, "186530496", Binder.getCallingUid());
3333 throw new SecurityException("Package " + callingPackage + " does not belong to "
3334 + Binder.getCallingUid());
3335 }
Jeff Davidson913390f2018-02-23 17:11:49 -08003336 Phone phone = PhoneFactory.getPhone(slotIndex);
3337 if (phone == null) {
Jack Yu2af8d712017-03-15 17:14:14 -07003338 return null;
3339 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003340
Jeff Davidson913390f2018-02-23 17:11:49 -08003341 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07003342 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003343 callingPackage, callingFeatureId, "getMeidForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08003344 return null;
3345 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003346
3347 final long identity = Binder.clearCallingIdentity();
3348 try {
3349 return phone.getMeid();
3350 } finally {
3351 Binder.restoreCallingIdentity(identity);
3352 }
Jack Yu2af8d712017-03-15 17:14:14 -07003353 }
3354
3355 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00003356 public String getManufacturerCodeForSlot(int slotIndex) {
3357 Phone phone = PhoneFactory.getPhone(slotIndex);
3358 String manufacturerCode = null;
3359 if (phone != null) {
3360 String meid = phone.getMeid();
Vala Zadehab005552021-09-21 15:54:29 -07003361 try {
3362 manufacturerCode =
3363 meid == null ? null : meid.substring(0, MANUFACTURER_CODE_LENGTH);
3364 } catch (IndexOutOfBoundsException e) {
3365 Log.e(LOG_TAG, "MEID length shorter than upper index.");
3366 return null;
3367 }
David Kelly5e06a7f2018-03-12 14:10:59 +00003368 }
3369 return manufacturerCode;
3370 }
3371
3372 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003373 public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage,
3374 String callingFeatureId) {
Jeff Davidson913390f2018-02-23 17:11:49 -08003375 Phone phone = PhoneFactory.getPhone(slotIndex);
3376 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003377 return null;
3378 }
Jeff Davidson913390f2018-02-23 17:11:49 -08003379 int subId = phone.getSubId();
3380 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003381 mApp, subId, callingPackage, callingFeatureId,
3382 "getDeviceSoftwareVersionForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08003383 return null;
3384 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003385
3386 final long identity = Binder.clearCallingIdentity();
3387 try {
3388 return phone.getDeviceSvn();
3389 } finally {
3390 Binder.restoreCallingIdentity(identity);
3391 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07003392 }
3393
fionaxu43304da2017-11-27 22:51:16 -08003394 @Override
3395 public int getSubscriptionCarrierId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003396 final long identity = Binder.clearCallingIdentity();
3397 try {
3398 final Phone phone = getPhone(subId);
3399 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getCarrierId();
3400 } finally {
3401 Binder.restoreCallingIdentity(identity);
3402 }
fionaxu43304da2017-11-27 22:51:16 -08003403 }
3404
3405 @Override
3406 public String getSubscriptionCarrierName(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003407 final long identity = Binder.clearCallingIdentity();
3408 try {
3409 final Phone phone = getPhone(subId);
3410 return phone == null ? null : phone.getCarrierName();
3411 } finally {
3412 Binder.restoreCallingIdentity(identity);
3413 }
fionaxu43304da2017-11-27 22:51:16 -08003414 }
3415
calvinpanffe225e2018-11-01 19:43:06 +08003416 @Override
chen xu0026ca62019-03-06 15:28:50 -08003417 public int getSubscriptionSpecificCarrierId(int subId) {
chen xu25637222018-11-04 17:17:00 -08003418 final long identity = Binder.clearCallingIdentity();
3419 try {
3420 final Phone phone = getPhone(subId);
3421 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID
chen xu0026ca62019-03-06 15:28:50 -08003422 : phone.getSpecificCarrierId();
chen xu25637222018-11-04 17:17:00 -08003423 } finally {
3424 Binder.restoreCallingIdentity(identity);
3425 }
3426 }
3427
3428 @Override
chen xu0026ca62019-03-06 15:28:50 -08003429 public String getSubscriptionSpecificCarrierName(int subId) {
chen xu25637222018-11-04 17:17:00 -08003430 final long identity = Binder.clearCallingIdentity();
3431 try {
3432 final Phone phone = getPhone(subId);
chen xu0026ca62019-03-06 15:28:50 -08003433 return phone == null ? null : phone.getSpecificCarrierName();
chen xu25637222018-11-04 17:17:00 -08003434 } finally {
3435 Binder.restoreCallingIdentity(identity);
3436 }
3437 }
3438
chen xu651eec72018-11-11 19:03:44 -08003439 @Override
chen xu864e11c2018-12-06 22:10:03 -08003440 public int getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc) {
3441 if (!isSubscriptionMccMnc) {
3442 enforceReadPrivilegedPermission("getCarrierIdFromMccMnc");
3443 }
chen xu651eec72018-11-11 19:03:44 -08003444 final Phone phone = PhoneFactory.getPhone(slotIndex);
3445 if (phone == null) {
3446 return TelephonyManager.UNKNOWN_CARRIER_ID;
3447 }
3448 final long identity = Binder.clearCallingIdentity();
3449 try {
3450 return CarrierResolver.getCarrierIdFromMccMnc(phone.getContext(), mccmnc);
3451 } finally {
3452 Binder.restoreCallingIdentity(identity);
3453 }
3454 }
3455
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003456 //
3457 // Internal helper methods.
3458 //
3459
Sanket Padaweee13a9b2016-03-08 17:30:28 -08003460 /**
Grace Jia0ddb3612021-04-22 13:35:26 -07003461 * Make sure the caller is the calling package itself
3462 *
3463 * @throws SecurityException if the caller is not the calling package
3464 */
3465 private void enforceCallingPackage(String callingPackage, int callingUid, String message) {
3466 int packageUid = -1;
Grace Jiadbefca02021-04-26 15:13:31 -07003467 PackageManager pm = mApp.getBaseContext().createContextAsUser(
3468 UserHandle.getUserHandleForUid(callingUid), 0).getPackageManager();
Grace Jia0ddb3612021-04-22 13:35:26 -07003469 try {
Grace Jiadbefca02021-04-26 15:13:31 -07003470 packageUid = pm.getPackageUid(callingPackage, 0);
Grace Jia0ddb3612021-04-22 13:35:26 -07003471 } catch (PackageManager.NameNotFoundException e) {
3472 // packageUid is -1
3473 }
3474 if (packageUid != callingUid) {
3475 throw new SecurityException(message + ": Package " + callingPackage
3476 + " does not belong to " + callingUid);
3477 }
3478 }
3479
3480 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003481 * Make sure the caller has the MODIFY_PHONE_STATE permission.
3482 *
3483 * @throws SecurityException if the caller does not have the required permission
3484 */
3485 private void enforceModifyPermission() {
3486 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
3487 }
3488
Shuo Qian3b6ee772019-11-13 17:43:31 -08003489 private void enforceActiveEmergencySessionPermission() {
3490 mApp.enforceCallingOrSelfPermission(
3491 android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION, null);
3492 }
3493
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003494 /**
3495 * Make sure the caller has the CALL_PHONE permission.
3496 *
3497 * @throws SecurityException if the caller does not have the required permission
3498 */
3499 private void enforceCallPermission() {
3500 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
3501 }
3502
paulhu5a773602019-08-23 19:17:33 +08003503 private void enforceSettingsPermission() {
3504 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.NETWORK_SETTINGS, null);
Stuart Scott8eef64f2015-04-08 15:13:54 -07003505 }
3506
Michele Berionne5e411512020-11-13 02:36:59 +00003507 private void enforceRebootPermission() {
3508 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
3509 }
3510
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003511 private String createTelUrl(String number) {
3512 if (TextUtils.isEmpty(number)) {
3513 return null;
3514 }
3515
Jake Hambye994d462014-02-03 13:10:13 -08003516 return "tel:" + number;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003517 }
3518
Ihab Awadf9e92732013-12-05 18:02:52 -08003519 private static void log(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003520 Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg);
3521 }
3522
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07003523 private static void logv(String msg) {
3524 Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg);
3525 }
3526
Ihab Awadf9e92732013-12-05 18:02:52 -08003527 private static void loge(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003528 Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg);
3529 }
3530
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003531 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003532 public int getActivePhoneType() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07003533 return getActivePhoneTypeForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07003534 }
3535
Sanket Padawe356d7632015-06-22 14:03:32 -07003536 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07003537 public int getActivePhoneTypeForSlot(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003538 final long identity = Binder.clearCallingIdentity();
3539 try {
3540 final Phone phone = PhoneFactory.getPhone(slotIndex);
3541 if (phone == null) {
3542 return PhoneConstants.PHONE_TYPE_NONE;
3543 } else {
3544 return phone.getPhoneType();
3545 }
3546 } finally {
3547 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003548 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003549 }
3550
3551 /**
3552 * Returns the CDMA ERI icon index to display
3553 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003554 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003555 public int getCdmaEriIconIndex(String callingPackage, String callingFeatureId) {
3556 return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage,
3557 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07003558 }
3559
Sanket Padawe356d7632015-06-22 14:03:32 -07003560 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003561 public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage,
3562 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003563 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003564 mApp, subId, callingPackage, callingFeatureId,
3565 "getCdmaEriIconIndexForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003566 return -1;
3567 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003568
3569 final long identity = Binder.clearCallingIdentity();
3570 try {
3571 final Phone phone = getPhone(subId);
3572 if (phone != null) {
3573 return phone.getCdmaEriIconIndex();
3574 } else {
3575 return -1;
3576 }
3577 } finally {
3578 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003579 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003580 }
3581
3582 /**
3583 * Returns the CDMA ERI icon mode,
3584 * 0 - ON
3585 * 1 - FLASHING
3586 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003587 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003588 public int getCdmaEriIconMode(String callingPackage, String callingFeatureId) {
3589 return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage,
3590 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07003591 }
3592
Sanket Padawe356d7632015-06-22 14:03:32 -07003593 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003594 public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage,
3595 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003596 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003597 mApp, subId, callingPackage, callingFeatureId,
3598 "getCdmaEriIconModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003599 return -1;
3600 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003601
3602 final long identity = Binder.clearCallingIdentity();
3603 try {
3604 final Phone phone = getPhone(subId);
3605 if (phone != null) {
3606 return phone.getCdmaEriIconMode();
3607 } else {
3608 return -1;
3609 }
3610 } finally {
3611 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003612 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003613 }
3614
3615 /**
3616 * Returns the CDMA ERI text,
3617 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003618 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003619 public String getCdmaEriText(String callingPackage, String callingFeatureId) {
3620 return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage,
3621 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07003622 }
3623
Sanket Padawe356d7632015-06-22 14:03:32 -07003624 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003625 public String getCdmaEriTextForSubscriber(int subId, String callingPackage,
3626 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003627 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003628 mApp, subId, callingPackage, callingFeatureId,
3629 "getCdmaEriIconTextForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003630 return null;
3631 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003632
3633 final long identity = Binder.clearCallingIdentity();
3634 try {
3635 final Phone phone = getPhone(subId);
3636 if (phone != null) {
3637 return phone.getCdmaEriText();
3638 } else {
3639 return null;
3640 }
3641 } finally {
3642 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003643 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003644 }
3645
3646 /**
Junda Liuca05d5d2014-08-14 22:36:34 -07003647 * Returns the CDMA MDN.
3648 */
Sanket Padawe356d7632015-06-22 14:03:32 -07003649 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07003650 public String getCdmaMdn(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003651 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3652 mApp, subId, "getCdmaMdn");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003653
3654 final long identity = Binder.clearCallingIdentity();
3655 try {
3656 final Phone phone = getPhone(subId);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003657 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003658 return phone.getLine1Number();
3659 } else {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003660 loge("getCdmaMdn: no phone found. Invalid subId: " + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003661 return null;
3662 }
3663 } finally {
3664 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07003665 }
3666 }
3667
3668 /**
3669 * Returns the CDMA MIN.
3670 */
Sanket Padawe356d7632015-06-22 14:03:32 -07003671 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07003672 public String getCdmaMin(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003673 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3674 mApp, subId, "getCdmaMin");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003675
3676 final long identity = Binder.clearCallingIdentity();
3677 try {
3678 final Phone phone = getPhone(subId);
3679 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
3680 return phone.getCdmaMin();
3681 } else {
3682 return null;
3683 }
3684 } finally {
3685 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07003686 }
3687 }
3688
Hall Liud892bec2018-11-30 14:51:45 -08003689 @Override
3690 public void requestNumberVerification(PhoneNumberRange range, long timeoutMillis,
3691 INumberVerificationCallback callback, String callingPackage) {
3692 if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
3693 != PERMISSION_GRANTED) {
3694 throw new SecurityException("Caller must hold the MODIFY_PHONE_STATE permission");
3695 }
3696 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3697
3698 String authorizedPackage = NumberVerificationManager.getAuthorizedPackage(mApp);
3699 if (!TextUtils.equals(callingPackage, authorizedPackage)) {
Hall Liub9d8feb2021-01-13 10:28:04 -08003700 throw new SecurityException("Calling package must be configured in the device config: "
3701 + "calling package: " + callingPackage
3702 + ", configured package: " + authorizedPackage);
Hall Liud892bec2018-11-30 14:51:45 -08003703 }
3704
3705 if (range == null) {
3706 throw new NullPointerException("Range must be non-null");
3707 }
3708
3709 timeoutMillis = Math.min(timeoutMillis,
Hall Liubd069e32019-02-28 18:56:30 -08003710 TelephonyManager.getMaxNumberVerificationTimeoutMillis());
Hall Liud892bec2018-11-30 14:51:45 -08003711
3712 NumberVerificationManager.getInstance().requestVerification(range, callback, timeoutMillis);
3713 }
3714
Junda Liuca05d5d2014-08-14 22:36:34 -07003715 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003716 * Returns true if CDMA provisioning needs to run.
3717 */
3718 public boolean needsOtaServiceProvisioning() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003719 final long identity = Binder.clearCallingIdentity();
3720 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003721 return getDefaultPhone().needsOtaServiceProvisioning();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003722 } finally {
3723 Binder.restoreCallingIdentity(identity);
3724 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003725 }
3726
3727 /**
Shishir Agrawal76d5da92014-11-09 16:17:25 -08003728 * Sets the voice mail number of a given subId.
3729 */
3730 @Override
3731 public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08003732 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
3733 mApp, subId, "setVoiceMailNumber");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003734
3735 final long identity = Binder.clearCallingIdentity();
3736 try {
3737 Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
3738 new Pair<String, String>(alphaTag, number), new Integer(subId));
3739 return success;
3740 } finally {
3741 Binder.restoreCallingIdentity(identity);
3742 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08003743 }
3744
Ta-wei Yen87c49842016-05-13 21:19:52 -07003745 @Override
Ta-wei Yenc9df0432017-04-17 17:09:07 -07003746 public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
3747 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07003748 TelecomManager tm = mApp.getSystemService(TelecomManager.class);
3749 String systemDialer = tm.getSystemDialerPackage();
Ta-wei Yenc9df0432017-04-17 17:09:07 -07003750 if (!TextUtils.equals(callingPackage, systemDialer)) {
3751 throw new SecurityException("caller must be system dialer");
3752 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003753
3754 final long identity = Binder.clearCallingIdentity();
3755 try {
3756 PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
3757 if (phoneAccountHandle == null) {
3758 return null;
3759 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003760 return VisualVoicemailSettingsUtil.dump(mApp, phoneAccountHandle);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003761 } finally {
3762 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc9df0432017-04-17 17:09:07 -07003763 }
Ta-wei Yenc9df0432017-04-17 17:09:07 -07003764 }
3765
3766 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003767 public String getVisualVoicemailPackageName(String callingPackage, String callingFeatureId,
3768 int subId) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08003769 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jeff Davidson7e17e312018-02-13 18:17:36 -08003770 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003771 mApp, subId, callingPackage, callingFeatureId,
3772 "getVisualVoicemailPackageName")) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08003773 return null;
3774 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003775
Jeff Davidsona8e4e242018-03-15 17:16:18 -07003776 final long identity = Binder.clearCallingIdentity();
3777 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003778 return RemoteVvmTaskManager.getRemotePackage(mApp, subId).getPackageName();
Jeff Davidsona8e4e242018-03-15 17:16:18 -07003779 } finally {
3780 Binder.restoreCallingIdentity(identity);
3781 }
Ta-wei Yendca928f2017-01-10 16:17:08 -08003782 }
3783
3784 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07003785 public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
3786 VisualVoicemailSmsFilterSettings settings) {
3787 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003788
3789 final long identity = Binder.clearCallingIdentity();
3790 try {
3791 VisualVoicemailSmsFilterConfig.enableVisualVoicemailSmsFilter(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003792 mApp, callingPackage, subId, settings);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003793 } finally {
3794 Binder.restoreCallingIdentity(identity);
3795 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07003796 }
3797
3798 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07003799 public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
3800 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003801
3802 final long identity = Binder.clearCallingIdentity();
3803 try {
3804 VisualVoicemailSmsFilterConfig.disableVisualVoicemailSmsFilter(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003805 mApp, callingPackage, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003806 } finally {
3807 Binder.restoreCallingIdentity(identity);
3808 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07003809 }
3810
3811 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07003812 public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
3813 String callingPackage, int subId) {
3814 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003815
3816 final long identity = Binder.clearCallingIdentity();
3817 try {
3818 return VisualVoicemailSmsFilterConfig.getVisualVoicemailSmsFilterSettings(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003819 mApp, callingPackage, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003820 } finally {
3821 Binder.restoreCallingIdentity(identity);
3822 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07003823 }
3824
3825 @Override
Ta-wei Yen30a69c82016-12-27 14:52:32 -08003826 public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003827 enforceReadPrivilegedPermission("getActiveVisualVoicemailSmsFilterSettings");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003828
3829 final long identity = Binder.clearCallingIdentity();
3830 try {
3831 return VisualVoicemailSmsFilterConfig.getActiveVisualVoicemailSmsFilterSettings(
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003832 mApp, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003833 } finally {
3834 Binder.restoreCallingIdentity(identity);
3835 }
Ta-wei Yen30a69c82016-12-27 14:52:32 -08003836 }
3837
3838 @Override
Philip P. Moltmann2f6f8ce2020-03-18 18:17:02 -07003839 public void sendVisualVoicemailSmsForSubscriber(String callingPackage,
3840 String callingAttributionTag, int subId, String number, int port, String text,
3841 PendingIntent sentIntent) {
Ta-wei Yen30a69c82016-12-27 14:52:32 -08003842 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Ta-wei Yen527a9c02017-01-06 15:29:25 -08003843 enforceVisualVoicemailPackage(callingPackage, subId);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08003844 enforceSendSmsPermission();
Amit Mahajandccb3f12019-05-13 13:48:32 -07003845 SmsController smsController = PhoneFactory.getSmsController();
Philip P. Moltmann2f6f8ce2020-03-18 18:17:02 -07003846 smsController.sendVisualVoicemailSmsForSubscriber(callingPackage, callingAttributionTag,
3847 subId, number, port, text, sentIntent);
Ta-wei Yen87c49842016-05-13 21:19:52 -07003848 }
Amit Mahajandccb3f12019-05-13 13:48:32 -07003849
Shishir Agrawal76d5da92014-11-09 16:17:25 -08003850 /**
fionaxu0152e512016-11-14 13:36:14 -08003851 * Sets the voice activation state of a given subId.
3852 */
3853 @Override
3854 public void setVoiceActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003855 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3856 mApp, subId, "setVoiceActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003857
3858 final long identity = Binder.clearCallingIdentity();
3859 try {
3860 final Phone phone = getPhone(subId);
3861 if (phone != null) {
3862 phone.setVoiceActivationState(activationState);
3863 } else {
3864 loge("setVoiceActivationState fails with invalid subId: " + subId);
3865 }
3866 } finally {
3867 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08003868 }
3869 }
3870
3871 /**
3872 * Sets the data activation state of a given subId.
3873 */
3874 @Override
3875 public void setDataActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003876 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3877 mApp, subId, "setDataActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003878
3879 final long identity = Binder.clearCallingIdentity();
3880 try {
3881 final Phone phone = getPhone(subId);
3882 if (phone != null) {
3883 phone.setDataActivationState(activationState);
3884 } else {
Taesu Leef8fbed92019-10-07 18:47:02 +09003885 loge("setDataActivationState fails with invalid subId: " + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003886 }
3887 } finally {
3888 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08003889 }
3890 }
3891
3892 /**
3893 * Returns the voice activation state of a given subId.
3894 */
3895 @Override
3896 public int getVoiceActivationState(int subId, String callingPackage) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003897 enforceReadPrivilegedPermission("getVoiceActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003898
fionaxu0152e512016-11-14 13:36:14 -08003899 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003900 final long identity = Binder.clearCallingIdentity();
3901 try {
3902 if (phone != null) {
3903 return phone.getVoiceActivationState();
3904 } else {
3905 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
3906 }
3907 } finally {
3908 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08003909 }
3910 }
3911
3912 /**
3913 * Returns the data activation state of a given subId.
3914 */
3915 @Override
3916 public int getDataActivationState(int subId, String callingPackage) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07003917 enforceReadPrivilegedPermission("getDataActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003918
fionaxu0152e512016-11-14 13:36:14 -08003919 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003920 final long identity = Binder.clearCallingIdentity();
3921 try {
3922 if (phone != null) {
3923 return phone.getDataActivationState();
3924 } else {
3925 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
3926 }
3927 } finally {
3928 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08003929 }
3930 }
3931
3932 /**
Wink Saville36469e72014-06-11 15:17:00 -07003933 * Returns the unread count of voicemails for a subId
3934 */
Sanket Padawe356d7632015-06-22 14:03:32 -07003935 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003936 public int getVoiceMessageCountForSubscriber(int subId, String callingPackage,
3937 String callingFeatureId) {
Brad Ebingerf7664ba2018-11-29 12:43:38 -08003938 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07003939 mApp, subId, callingPackage, callingFeatureId,
3940 "getVoiceMessageCountForSubscriber")) {
Brad Ebingerf7664ba2018-11-29 12:43:38 -08003941 return 0;
3942 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003943 final long identity = Binder.clearCallingIdentity();
3944 try {
3945 final Phone phone = getPhone(subId);
3946 if (phone != null) {
3947 return phone.getVoiceMessageCount();
3948 } else {
3949 return 0;
3950 }
3951 } finally {
3952 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003953 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003954 }
3955
3956 /**
pkanwar8a4dcfb2017-01-19 13:43:16 -08003957 * returns true, if the device is in a state where both voice and data
3958 * are supported simultaneously. This can change based on location or network condition.
3959 */
3960 @Override
3961 public boolean isConcurrentVoiceAndDataAllowed(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003962 final long identity = Binder.clearCallingIdentity();
3963 try {
3964 final Phone phone = getPhone(subId);
3965 return (phone == null ? false : phone.isConcurrentVoiceAndDataAllowed());
3966 } finally {
3967 Binder.restoreCallingIdentity(identity);
3968 }
pkanwar8a4dcfb2017-01-19 13:43:16 -08003969 }
3970
3971 /**
fionaxu235cc5e2017-03-06 22:25:57 -08003972 * Send the dialer code if called from the current default dialer or the caller has
3973 * carrier privilege.
3974 * @param inputCode The dialer code to send
3975 */
3976 @Override
3977 public void sendDialerSpecialCode(String callingPackage, String inputCode) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003978 final Phone defaultPhone = getDefaultPhone();
fionaxu235cc5e2017-03-06 22:25:57 -08003979 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07003980 TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
3981 String defaultDialer = tm.getDefaultDialerPackage();
fionaxu235cc5e2017-03-06 22:25:57 -08003982 if (!TextUtils.equals(callingPackage, defaultDialer)) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08003983 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
Jeff Davidson7e17e312018-02-13 18:17:36 -08003984 getDefaultSubscription(), "sendDialerSpecialCode");
fionaxu235cc5e2017-03-06 22:25:57 -08003985 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003986
3987 final long identity = Binder.clearCallingIdentity();
3988 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08003989 defaultPhone.sendDialerSpecialCode(inputCode);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003990 } finally {
3991 Binder.restoreCallingIdentity(identity);
3992 }
fionaxu235cc5e2017-03-06 22:25:57 -08003993 }
3994
Pengquan Menga1bb6272018-09-06 09:59:22 -07003995 @Override
3996 public int getNetworkSelectionMode(int subId) {
shilufc958392020-01-20 11:36:01 -08003997 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07003998 .enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
shilufc958392020-01-20 11:36:01 -08003999 mApp, subId, "getNetworkSelectionMode");
4000 final long identity = Binder.clearCallingIdentity();
4001 try {
4002 if (!isActiveSubscription(subId)) {
4003 return TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
4004 }
4005 return (int) sendRequest(CMD_GET_NETWORK_SELECTION_MODE, null /* argument */, subId);
4006 } finally {
4007 Binder.restoreCallingIdentity(identity);
Pengquan Menge92a50d2018-09-21 15:54:48 -07004008 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07004009 }
4010
Brad Ebinger35c841c2018-10-01 10:40:55 -07004011 @Override
Brad Ebingerb2b65522019-03-15 13:48:47 -07004012 public boolean isInEmergencySmsMode() {
4013 enforceReadPrivilegedPermission("isInEmergencySmsMode");
4014 final long identity = Binder.clearCallingIdentity();
4015 try {
4016 for (Phone phone : PhoneFactory.getPhones()) {
4017 if (phone.isInEmergencySmsMode()) {
4018 return true;
4019 }
4020 }
4021 } finally {
4022 Binder.restoreCallingIdentity(identity);
4023 }
4024 return false;
4025 }
4026
shilu366312e2019-12-17 09:28:10 -08004027 /**
4028 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4029 * @param subId The subscription to use to check the configuration.
4030 * @param c The callback that will be used to send the result.
4031 */
Brad Ebingerb2b65522019-03-15 13:48:47 -07004032 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08004033 public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback c)
4034 throws RemoteException {
Nathan Harold62c68512021-04-06 11:26:02 -07004035 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004036 mApp, subId, "registerImsRegistrationCallback");
shilu366312e2019-12-17 09:28:10 -08004037
Brad Ebingerbc7dd582019-10-17 17:03:22 -07004038 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4039 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4040 "IMS not available on device.");
4041 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07004042 final long token = Binder.clearCallingIdentity();
4043 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004044 int slotId = getSlotIndexOrException(subId);
4045 verifyImsMmTelConfiguredOrThrow(slotId);
4046 ImsManager.getInstance(mApp, slotId).addRegistrationCallbackForSubscription(c, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004047 } catch (ImsException e) {
4048 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004049 } finally {
4050 Binder.restoreCallingIdentity(token);
4051 }
4052 }
4053
shilu366312e2019-12-17 09:28:10 -08004054 /**
4055 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4056 * @param subId The subscription to use to check the configuration.
4057 * @param c The callback that will be used to send the result.
4058 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07004059 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08004060 public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c) {
Nathan Harold62c68512021-04-06 11:26:02 -07004061 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004062 mApp, subId, "unregisterImsRegistrationCallback");
Brad Ebinger4ae57f92019-01-09 16:51:30 -08004063 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4064 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
4065 }
Meng Wangafbc5852019-09-19 17:37:13 -07004066 final long token = Binder.clearCallingIdentity();
4067 try {
Meng Wangafbc5852019-09-19 17:37:13 -07004068 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
4069 .removeRegistrationCallbackForSubscription(c, subId);
4070 } catch (ImsException e) {
4071 Log.i(LOG_TAG, "unregisterImsRegistrationCallback: " + subId
4072 + "is inactive, ignoring unregister.");
4073 // If the subscription is no longer active, just return, since the callback
4074 // will already have been removed internally.
4075 } finally {
4076 Binder.restoreCallingIdentity(token);
4077 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07004078 }
4079
Brad Ebingera34a6c22019-10-22 17:36:18 -07004080 /**
4081 * Get the IMS service registration state for the MmTelFeature associated with this sub id.
4082 */
4083 @Override
4084 public void getImsMmTelRegistrationState(int subId, IIntegerConsumer consumer) {
4085 enforceReadPrivilegedPermission("getImsMmTelRegistrationState");
4086 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4087 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4088 "IMS not available on device.");
4089 }
4090 final long token = Binder.clearCallingIdentity();
4091 try {
4092 Phone phone = getPhone(subId);
4093 if (phone == null) {
4094 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
4095 + subId + "'");
4096 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
4097 }
4098 phone.getImsRegistrationState(regState -> {
4099 try {
4100 consumer.accept((regState == null)
4101 ? RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED : regState);
4102 } catch (RemoteException e) {
4103 // Ignore if the remote process is no longer available to call back.
4104 Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
4105 }
4106 });
4107 } finally {
4108 Binder.restoreCallingIdentity(token);
4109 }
4110 }
4111
4112 /**
4113 * Get the transport type for the IMS service registration state.
4114 */
4115 @Override
4116 public void getImsMmTelRegistrationTransportType(int subId, IIntegerConsumer consumer) {
Nathan Harold62c68512021-04-06 11:26:02 -07004117 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004118 mApp, subId, "getImsMmTelRegistrationTransportType");
Brad Ebingera34a6c22019-10-22 17:36:18 -07004119 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4120 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4121 "IMS not available on device.");
4122 }
4123 final long token = Binder.clearCallingIdentity();
4124 try {
4125 Phone phone = getPhone(subId);
4126 if (phone == null) {
4127 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
4128 + subId + "'");
4129 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
4130 }
4131 phone.getImsRegistrationTech(regTech -> {
4132 // Convert registration tech from ImsRegistrationImplBase -> RegistrationManager
4133 int regTechConverted = (regTech == null)
4134 ? ImsRegistrationImplBase.REGISTRATION_TECH_NONE : regTech;
4135 regTechConverted = RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(
4136 regTechConverted);
4137 try {
4138 consumer.accept(regTechConverted);
4139 } catch (RemoteException e) {
4140 // Ignore if the remote process is no longer available to call back.
4141 Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
4142 }
4143 });
4144 } finally {
4145 Binder.restoreCallingIdentity(token);
4146 }
4147 }
4148
shilu366312e2019-12-17 09:28:10 -08004149 /**
4150 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4151 * @param subId The subscription to use to check the configuration.
4152 * @param c The callback that will be used to send the result.
4153 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07004154 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08004155 public void registerMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)
4156 throws RemoteException {
Nathan Harold62c68512021-04-06 11:26:02 -07004157 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004158 mApp, subId, "registerMmTelCapabilityCallback");
Brad Ebingerbc7dd582019-10-17 17:03:22 -07004159 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4160 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4161 "IMS not available on device.");
4162 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07004163 final long token = Binder.clearCallingIdentity();
4164 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004165 int slotId = getSlotIndexOrException(subId);
4166 verifyImsMmTelConfiguredOrThrow(slotId);
4167 ImsManager.getInstance(mApp, slotId).addCapabilitiesCallbackForSubscription(c, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004168 } catch (ImsException e) {
4169 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004170 } finally {
4171 Binder.restoreCallingIdentity(token);
4172 }
4173 }
4174
shilu366312e2019-12-17 09:28:10 -08004175 /**
4176 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4177 * @param subId The subscription to use to check the configuration.
4178 * @param c The callback that will be used to send the result.
4179 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07004180 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08004181 public void unregisterMmTelCapabilityCallback(int subId, IImsCapabilityCallback c) {
Nathan Harold62c68512021-04-06 11:26:02 -07004182 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004183 mApp, subId, "unregisterMmTelCapabilityCallback");
Brad Ebinger4ae57f92019-01-09 16:51:30 -08004184 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4185 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
4186 }
Meng Wangafbc5852019-09-19 17:37:13 -07004187
4188 final long token = Binder.clearCallingIdentity();
4189 try {
Meng Wangafbc5852019-09-19 17:37:13 -07004190 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08004191 .removeCapabilitiesCallbackForSubscription(c, subId);
Meng Wangafbc5852019-09-19 17:37:13 -07004192 } catch (ImsException e) {
4193 Log.i(LOG_TAG, "unregisterMmTelCapabilityCallback: " + subId
4194 + "is inactive, ignoring unregister.");
4195 // If the subscription is no longer active, just return, since the callback
4196 // will already have been removed internally.
4197 } finally {
4198 Binder.restoreCallingIdentity(token);
4199 }
Brad Ebinger35c841c2018-10-01 10:40:55 -07004200 }
4201
4202 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08004203 public boolean isCapable(int subId, int capability, int regTech) {
4204 enforceReadPrivilegedPermission("isCapable");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004205 final long token = Binder.clearCallingIdentity();
4206 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004207 int slotId = getSlotIndexOrException(subId);
4208 verifyImsMmTelConfiguredOrThrow(slotId);
4209 return ImsManager.getInstance(mApp, slotId).queryMmTelCapability(capability, regTech);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004210 } catch (com.android.ims.ImsException e) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07004211 Log.w(LOG_TAG, "IMS isCapable - service unavailable: " + e.getMessage());
4212 return false;
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004213 } catch (ImsException e) {
Brad Ebinger6b5ac222019-02-04 14:36:52 -08004214 Log.i(LOG_TAG, "isCapable: " + subId + " is inactive, returning false.");
4215 return false;
Brad Ebinger35c841c2018-10-01 10:40:55 -07004216 } finally {
4217 Binder.restoreCallingIdentity(token);
4218 }
4219 }
4220
4221 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08004222 public boolean isAvailable(int subId, int capability, int regTech) {
4223 enforceReadPrivilegedPermission("isAvailable");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004224 final long token = Binder.clearCallingIdentity();
4225 try {
4226 Phone phone = getPhone(subId);
4227 if (phone == null) return false;
4228 return phone.isImsCapabilityAvailable(capability, regTech);
Daniel Bright5e40e4e2020-03-11 16:35:39 -07004229 } catch (com.android.ims.ImsException e) {
4230 Log.w(LOG_TAG, "IMS isAvailable - service unavailable: " + e.getMessage());
4231 return false;
Brad Ebinger35c841c2018-10-01 10:40:55 -07004232 } finally {
4233 Binder.restoreCallingIdentity(token);
4234 }
4235 }
4236
Brad Ebingerbc7dd582019-10-17 17:03:22 -07004237 /**
4238 * Determines if the MmTel feature capability is supported by the carrier configuration for this
4239 * subscription.
4240 * @param subId The subscription to use to check the configuration.
4241 * @param callback The callback that will be used to send the result.
4242 * @param capability The MmTelFeature capability that will be used to send the result.
4243 * @param transportType The transport type of the MmTelFeature capability.
4244 */
4245 @Override
4246 public void isMmTelCapabilitySupported(int subId, IIntegerConsumer callback, int capability,
4247 int transportType) {
4248 enforceReadPrivilegedPermission("isMmTelCapabilitySupported");
4249 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4250 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4251 "IMS not available on device.");
4252 }
4253 final long token = Binder.clearCallingIdentity();
4254 try {
4255 int slotId = getSlotIndex(subId);
4256 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4257 Log.w(LOG_TAG, "isMmTelCapabilitySupported: called with an inactive subscription '"
4258 + subId + "'");
4259 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
4260 }
Brad Ebinger919631e2021-06-02 17:46:35 -07004261 verifyImsMmTelConfiguredOrThrow(slotId);
Brad Ebingerbc7dd582019-10-17 17:03:22 -07004262 ImsManager.getInstance(mApp, slotId).isSupported(capability,
4263 transportType, aBoolean -> {
4264 try {
4265 callback.accept((aBoolean == null) ? 0 : (aBoolean ? 1 : 0));
4266 } catch (RemoteException e) {
4267 Log.w(LOG_TAG, "isMmTelCapabilitySupported: remote caller is not "
4268 + "running. Ignore");
4269 }
4270 });
Brad Ebinger919631e2021-06-02 17:46:35 -07004271 } catch (ImsException e) {
4272 throw new ServiceSpecificException(e.getCode());
Brad Ebingerbc7dd582019-10-17 17:03:22 -07004273 } finally {
4274 Binder.restoreCallingIdentity(token);
4275 }
4276 }
4277
shilu366312e2019-12-17 09:28:10 -08004278 /**
4279 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4280 * @param subId The subscription to use to check the configuration.
4281 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07004282 @Override
4283 public boolean isAdvancedCallingSettingEnabled(int subId) {
Nathan Harold62c68512021-04-06 11:26:02 -07004284 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004285 mApp, subId, "isAdvancedCallingSettingEnabled");
shilu366312e2019-12-17 09:28:10 -08004286
Brad Ebinger35c841c2018-10-01 10:40:55 -07004287 final long token = Binder.clearCallingIdentity();
4288 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004289 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004290 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07004291 return ImsManager.getInstance(mApp, slotId).isEnhanced4gLteModeSettingEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004292 } catch (ImsException e) {
4293 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004294 } finally {
4295 Binder.restoreCallingIdentity(token);
4296 }
4297 }
4298
4299 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08004300 public void setAdvancedCallingSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07004301 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08004302 "setAdvancedCallingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004303 final long identity = Binder.clearCallingIdentity();
4304 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004305 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004306 // This setting doesn't require an active ImsService connection, so do not verify. The
4307 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07004308 ImsManager.getInstance(mApp, slotId).setEnhanced4gLteModeSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004309 } catch (ImsException e) {
4310 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004311 } finally {
4312 Binder.restoreCallingIdentity(identity);
4313 }
4314 }
4315
shilu366312e2019-12-17 09:28:10 -08004316 /**
4317 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4318 * @param subId The subscription to use to check the configuration.
4319 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07004320 @Override
Brad Ebinger9878b0b2018-11-08 17:43:22 -08004321 public boolean isVtSettingEnabled(int subId) {
Nathan Harold62c68512021-04-06 11:26:02 -07004322 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004323 mApp, subId, "isVtSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004324 final long identity = Binder.clearCallingIdentity();
4325 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004326 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004327 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07004328 return ImsManager.getInstance(mApp, slotId).isVtEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004329 } catch (ImsException e) {
4330 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004331 } finally {
4332 Binder.restoreCallingIdentity(identity);
4333 }
4334 }
4335
4336 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08004337 public void setVtSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07004338 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08004339 "setVtSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004340 final long identity = Binder.clearCallingIdentity();
4341 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004342 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004343 // This setting doesn't require an active ImsService connection, so do not verify. The
4344 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07004345 ImsManager.getInstance(mApp, slotId).setVtSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004346 } catch (ImsException e) {
4347 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004348 } finally {
4349 Binder.restoreCallingIdentity(identity);
4350 }
4351 }
4352
shilu366312e2019-12-17 09:28:10 -08004353 /**
4354 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4355 * @param subId The subscription to use to check the configuration.
4356 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07004357 @Override
4358 public boolean isVoWiFiSettingEnabled(int subId) {
Nathan Harold62c68512021-04-06 11:26:02 -07004359 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004360 mApp, subId, "isVoWiFiSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004361 final long identity = Binder.clearCallingIdentity();
4362 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004363 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004364 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07004365 return ImsManager.getInstance(mApp, slotId).isWfcEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004366 } catch (ImsException e) {
4367 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004368 } finally {
4369 Binder.restoreCallingIdentity(identity);
4370 }
4371 }
4372
4373 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08004374 public void setVoWiFiSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07004375 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08004376 "setVoWiFiSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004377 final long identity = Binder.clearCallingIdentity();
4378 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004379 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004380 // This setting doesn't require an active ImsService connection, so do not verify. The
4381 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07004382 ImsManager.getInstance(mApp, slotId).setWfcSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004383 } catch (ImsException e) {
4384 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004385 } finally {
4386 Binder.restoreCallingIdentity(identity);
4387 }
4388 }
4389
shilu366312e2019-12-17 09:28:10 -08004390 /**
Sooraj Sasindrane655add2020-11-23 19:40:38 -08004391 * @return true if the user's setting for Voice over Cross SIM is enabled and false if it is not
4392 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4393 * @param subId The subscription to use to check the configuration.
4394 */
4395 @Override
4396 public boolean isCrossSimCallingEnabledByUser(int subId) {
Nathan Harold62c68512021-04-06 11:26:02 -07004397 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Sooraj Sasindrane655add2020-11-23 19:40:38 -08004398 mApp, subId, "isCrossSimCallingEnabledByUser");
4399 final long identity = Binder.clearCallingIdentity();
4400 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004401 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004402 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07004403 return ImsManager.getInstance(mApp, slotId).isCrossSimCallingEnabledByUser();
Sooraj Sasindrane655add2020-11-23 19:40:38 -08004404 } catch (ImsException e) {
4405 throw new ServiceSpecificException(e.getCode());
4406 } finally {
4407 Binder.restoreCallingIdentity(identity);
4408 }
4409 }
4410
4411 /**
4412 * Sets the user's setting for whether or not Voice over Cross SIM is enabled.
4413 * Requires MODIFY_PHONE_STATE permission.
4414 * @param subId The subscription to use to check the configuration.
4415 * @param isEnabled true if the user's setting for Voice over Cross SIM is enabled,
4416 * false otherwise
4417 */
4418 @Override
4419 public void setCrossSimCallingEnabled(int subId, boolean isEnabled) {
4420 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4421 "setCrossSimCallingEnabled");
4422 final long identity = Binder.clearCallingIdentity();
4423 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004424 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004425 // This setting doesn't require an active ImsService connection, so do not verify. The
4426 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07004427 ImsManager.getInstance(mApp, slotId).setCrossSimCallingEnabled(isEnabled);
Sooraj Sasindrane655add2020-11-23 19:40:38 -08004428 } catch (ImsException e) {
4429 throw new ServiceSpecificException(e.getCode());
4430 } finally {
4431 Binder.restoreCallingIdentity(identity);
4432 }
4433 }
4434
4435 /**
shilu366312e2019-12-17 09:28:10 -08004436 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4437 * @param subId The subscription to use to check the configuration.
4438 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07004439 @Override
Nathan Harold62c68512021-04-06 11:26:02 -07004440
Brad Ebinger35c841c2018-10-01 10:40:55 -07004441 public boolean isVoWiFiRoamingSettingEnabled(int subId) {
Nathan Harold62c68512021-04-06 11:26:02 -07004442 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004443 mApp, subId, "isVoWiFiRoamingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004444 final long identity = Binder.clearCallingIdentity();
4445 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004446 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004447 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07004448 return ImsManager.getInstance(mApp, slotId).isWfcRoamingEnabledByUser();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004449 } catch (ImsException e) {
4450 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004451 } finally {
4452 Binder.restoreCallingIdentity(identity);
4453 }
4454 }
4455
4456 @Override
Brad Ebinger1c162042019-02-21 14:49:10 -08004457 public void setVoWiFiRoamingSettingEnabled(int subId, boolean isEnabled) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07004458 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
Brad Ebinger1c162042019-02-21 14:49:10 -08004459 "setVoWiFiRoamingSettingEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004460 final long identity = Binder.clearCallingIdentity();
4461 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004462 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004463 // This setting doesn't require an active ImsService connection, so do not verify. The
4464 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07004465 ImsManager.getInstance(mApp, slotId).setWfcRoamingSetting(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004466 } catch (ImsException e) {
4467 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004468 } finally {
4469 Binder.restoreCallingIdentity(identity);
4470 }
4471 }
4472
4473 @Override
4474 public void setVoWiFiNonPersistent(int subId, boolean isCapable, int mode) {
4475 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4476 "setVoWiFiNonPersistent");
4477 final long identity = Binder.clearCallingIdentity();
4478 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004479 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004480 // This setting will be ignored if the ImsService isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07004481 ImsManager.getInstance(mApp, slotId).setWfcNonPersistent(isCapable, mode);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004482 } catch (ImsException e) {
4483 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004484 } finally {
4485 Binder.restoreCallingIdentity(identity);
4486 }
4487 }
4488
shilu366312e2019-12-17 09:28:10 -08004489 /**
4490 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4491 * @param subId The subscription to use to check the configuration.
4492 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07004493 @Override
4494 public int getVoWiFiModeSetting(int subId) {
Nathan Harold62c68512021-04-06 11:26:02 -07004495 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004496 mApp, subId, "getVoWiFiModeSetting");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004497 final long identity = Binder.clearCallingIdentity();
4498 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004499 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004500 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07004501 return ImsManager.getInstance(mApp, slotId).getWfcMode(false /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004502 } catch (ImsException e) {
4503 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004504 } finally {
4505 Binder.restoreCallingIdentity(identity);
4506 }
4507 }
4508
4509 @Override
4510 public void setVoWiFiModeSetting(int subId, int mode) {
4511 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4512 "setVoWiFiModeSetting");
4513 final long identity = Binder.clearCallingIdentity();
4514 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004515 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004516 // This setting doesn't require an active ImsService connection, so do not verify. The
4517 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07004518 ImsManager.getInstance(mApp, slotId).setWfcMode(mode, false /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004519 } catch (ImsException e) {
4520 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004521 } finally {
4522 Binder.restoreCallingIdentity(identity);
4523 }
4524 }
4525
4526 @Override
4527 public int getVoWiFiRoamingModeSetting(int subId) {
4528 enforceReadPrivilegedPermission("getVoWiFiRoamingModeSetting");
4529 final long identity = Binder.clearCallingIdentity();
4530 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004531 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004532 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07004533 return ImsManager.getInstance(mApp, slotId).getWfcMode(true /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004534 } catch (ImsException e) {
4535 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004536 } finally {
4537 Binder.restoreCallingIdentity(identity);
4538 }
4539 }
4540
4541 @Override
4542 public void setVoWiFiRoamingModeSetting(int subId, int mode) {
4543 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4544 "setVoWiFiRoamingModeSetting");
4545 final long identity = Binder.clearCallingIdentity();
4546 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004547 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004548 // This setting doesn't require an active ImsService connection, so do not verify. The
4549 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07004550 ImsManager.getInstance(mApp, slotId).setWfcMode(mode, true /*isRoaming*/);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004551 } catch (ImsException e) {
4552 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004553 } finally {
4554 Binder.restoreCallingIdentity(identity);
4555 }
4556 }
4557
4558 @Override
4559 public void setRttCapabilitySetting(int subId, boolean isEnabled) {
4560 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4561 "setRttCapabilityEnabled");
4562 final long identity = Binder.clearCallingIdentity();
4563 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004564 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004565 // This setting doesn't require an active ImsService connection, so do not verify. The
4566 // new setting will be picked up when the ImsService comes up next if it isn't up.
Brad Ebinger919631e2021-06-02 17:46:35 -07004567 ImsManager.getInstance(mApp, slotId).setRttEnabled(isEnabled);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004568 } catch (ImsException e) {
4569 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004570 } finally {
4571 Binder.restoreCallingIdentity(identity);
4572 }
4573 }
4574
shilu366312e2019-12-17 09:28:10 -08004575 /**
4576 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4577 * @param subId The subscription to use to check the configuration.
4578 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07004579 @Override
4580 public boolean isTtyOverVolteEnabled(int subId) {
Nathan Harold62c68512021-04-06 11:26:02 -07004581 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
Rambo Wang37f9c242020-02-10 14:45:28 -08004582 mApp, subId, "isTtyOverVolteEnabled");
Brad Ebinger35c841c2018-10-01 10:40:55 -07004583 final long identity = Binder.clearCallingIdentity();
4584 try {
Brad Ebinger919631e2021-06-02 17:46:35 -07004585 int slotId = getSlotIndexOrException(subId);
Brad Ebinger735c5ce2021-07-12 13:58:21 -07004586 // This setting doesn't require an active ImsService connection, so do not verify.
Brad Ebinger919631e2021-06-02 17:46:35 -07004587 return ImsManager.getInstance(mApp, slotId).isTtyOnVoLteCapable();
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004588 } catch (ImsException e) {
4589 throw new ServiceSpecificException(e.getCode());
Brad Ebinger35c841c2018-10-01 10:40:55 -07004590 } finally {
4591 Binder.restoreCallingIdentity(identity);
4592 }
4593 }
4594
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004595 @Override
4596 public void registerImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
4597 enforceReadPrivilegedPermission("registerImsProvisioningChangedCallback");
4598 final long identity = Binder.clearCallingIdentity();
4599 try {
Brad Ebingerd0331732020-01-16 11:21:18 -08004600 if (!isImsAvailableOnDevice()) {
4601 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4602 "IMS not available on device.");
Peter Wang44b186e2020-01-13 23:33:09 -08004603 }
Brad Ebinger919631e2021-06-02 17:46:35 -07004604 int slotId = getSlotIndexOrException(subId);
4605 verifyImsMmTelConfiguredOrThrow(slotId);
4606 ImsManager.getInstance(mApp, slotId)
Brad Ebinger4ae57f92019-01-09 16:51:30 -08004607 .addProvisioningCallbackForSubscription(callback, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004608 } catch (ImsException e) {
4609 throw new ServiceSpecificException(e.getCode());
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004610 } finally {
4611 Binder.restoreCallingIdentity(identity);
4612 }
4613 }
4614
4615 @Override
4616 public void unregisterImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
4617 enforceReadPrivilegedPermission("unregisterImsProvisioningChangedCallback");
4618 final long identity = Binder.clearCallingIdentity();
Brad Ebinger4ae57f92019-01-09 16:51:30 -08004619 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4620 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
4621 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004622 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08004623 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
Brad Ebinger4ae57f92019-01-09 16:51:30 -08004624 .removeProvisioningCallbackForSubscription(callback, subId);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004625 } catch (ImsException e) {
Brad Ebinger4ae57f92019-01-09 16:51:30 -08004626 Log.i(LOG_TAG, "unregisterImsProvisioningChangedCallback: " + subId
4627 + "is inactive, ignoring unregister.");
4628 // If the subscription is no longer active, just return, since the callback will already
4629 // have been removed internally.
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004630 } finally {
4631 Binder.restoreCallingIdentity(identity);
4632 }
4633 }
4634
allenwtsu99c623b2020-01-03 18:24:23 +08004635
4636 private void checkModifyPhoneStatePermission(int subId, String message) {
4637 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4638 message);
4639 }
4640
4641 private boolean isImsProvisioningRequired(int subId, int capability,
4642 boolean isMmtelCapability) {
4643 Phone phone = getPhone(subId);
4644 if (phone == null) {
4645 loge("phone instance null for subid " + subId);
4646 return false;
4647 }
4648 if (isMmtelCapability) {
4649 if (!doesImsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
4650 return false;
4651 }
4652 } else {
4653 if (!doesRcsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
4654 return false;
4655 }
4656 }
4657 return true;
4658 }
4659
4660 @Override
4661 public void setRcsProvisioningStatusForCapability(int subId, int capability,
4662 boolean isProvisioned) {
4663 checkModifyPhoneStatePermission(subId, "setRcsProvisioningStatusForCapability");
4664
4665 final long identity = Binder.clearCallingIdentity();
4666 try {
4667 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4668 if (!isImsProvisioningRequired(subId, capability, false)) {
4669 return;
4670 }
4671
4672 // this capability requires provisioning, route to the correct API.
4673 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
4674 switch (capability) {
4675 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE:
4676 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
4677 ims.setEabProvisioned(isProvisioned);
4678 break;
4679 default: {
4680 throw new IllegalArgumentException("Tried to set provisioning for "
4681 + "rcs capability '" + capability + "', which does not require "
4682 + "provisioning.");
4683 }
4684 }
4685 } finally {
4686 Binder.restoreCallingIdentity(identity);
4687 }
4688
4689 }
4690
4691
4692 @Override
4693 public boolean getRcsProvisioningStatusForCapability(int subId, int capability) {
4694 enforceReadPrivilegedPermission("getRcsProvisioningStatusForCapability");
4695 final long identity = Binder.clearCallingIdentity();
4696 try {
4697 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4698 if (!isImsProvisioningRequired(subId, capability, false)) {
4699 return true;
4700 }
4701
4702 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
4703 switch (capability) {
4704 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE:
4705 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
4706 return ims.isEabProvisionedOnDevice();
4707
4708 default: {
4709 throw new IllegalArgumentException("Tried to get rcs provisioning for "
4710 + "capability '" + capability + "', which does not require "
4711 + "provisioning.");
4712 }
4713 }
4714
4715 } finally {
4716 Binder.restoreCallingIdentity(identity);
4717 }
4718 }
4719
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004720 @Override
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004721 public void setImsProvisioningStatusForCapability(int subId, int capability, int tech,
4722 boolean isProvisioned) {
4723 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
Brad Ebinger0d79c572021-04-17 15:20:49 -07004724 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE
4725 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_NR
4726 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004727 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
4728 }
allenwtsu99c623b2020-01-03 18:24:23 +08004729 checkModifyPhoneStatePermission(subId, "setImsProvisioningStatusForCapability");
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004730 final long identity = Binder.clearCallingIdentity();
4731 try {
4732 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
allenwtsu99c623b2020-01-03 18:24:23 +08004733 if (!isImsProvisioningRequired(subId, capability, true)) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004734 return;
4735 }
Brad Ebinger0d79c572021-04-17 15:20:49 -07004736 if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_NR
4737 || tech == ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM) {
4738 loge("setImsProvisioningStatusForCapability: called for technology that does "
4739 + "not support provisioning - " + tech);
4740 return;
4741 }
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004742
4743 // this capability requires provisioning, route to the correct API.
4744 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
4745 switch (capability) {
4746 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
4747 if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4748 ims.setVolteProvisioned(isProvisioned);
4749 } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
4750 ims.setWfcProvisioned(isProvisioned);
4751 }
4752 break;
4753 }
4754 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
4755 // There is currently no difference in VT provisioning type.
4756 ims.setVtProvisioned(isProvisioned);
4757 break;
4758 }
4759 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
4760 // There is no "deprecated" UT provisioning mechanism through ImsConfig, so
4761 // change the capability of the feature instead if needed.
4762 if (isMmTelCapabilityProvisionedInCache(subId, capability, tech)
4763 == isProvisioned) {
4764 // No change in provisioning.
4765 return;
4766 }
4767 cacheMmTelCapabilityProvisioning(subId, capability, tech, isProvisioned);
4768 try {
Brad Ebinger0d79c572021-04-17 15:20:49 -07004769 ims.changeMmTelCapability(isProvisioned, capability, tech);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004770 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004771 loge("setImsProvisioningStatusForCapability: couldn't change UT capability"
4772 + ", Exception" + e.getMessage());
4773 }
4774 break;
4775 }
4776 default: {
allenwtsu99c623b2020-01-03 18:24:23 +08004777 throw new IllegalArgumentException("Tried to set provisioning for "
4778 + "MmTel capability '" + capability + "', which does not require "
4779 + "provisioning. ");
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004780 }
4781 }
4782
4783 } finally {
4784 Binder.restoreCallingIdentity(identity);
4785 }
4786 }
4787
4788 @Override
4789 public boolean getImsProvisioningStatusForCapability(int subId, int capability, int tech) {
4790 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
Brad Ebinger0d79c572021-04-17 15:20:49 -07004791 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE
4792 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_NR
4793 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004794 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
4795 }
4796 enforceReadPrivilegedPermission("getProvisioningStatusForCapability");
4797 final long identity = Binder.clearCallingIdentity();
4798 try {
4799 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
allenwtsu99c623b2020-01-03 18:24:23 +08004800 if (!isImsProvisioningRequired(subId, capability, true)) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004801 return true;
4802 }
4803
Brad Ebinger0d79c572021-04-17 15:20:49 -07004804 if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_NR
4805 || tech == ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM) {
4806 loge("getImsProvisioningStatusForCapability: called for technology that does "
4807 + "not support provisioning - " + tech);
4808 return true;
4809 }
4810
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004811 ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
4812 switch (capability) {
4813 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
4814 if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4815 return ims.isVolteProvisionedOnDevice();
4816 } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
4817 return ims.isWfcProvisionedOnDevice();
4818 }
4819 // This should never happen, since we are checking tech above to make sure it
4820 // is either LTE or IWLAN.
4821 throw new IllegalArgumentException("Invalid radio technology for voice "
4822 + "capability.");
4823 }
4824 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
4825 // There is currently no difference in VT provisioning type.
4826 return ims.isVtProvisionedOnDevice();
4827 }
4828 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
4829 // There is no "deprecated" UT provisioning mechanism, so get from shared prefs.
4830 return isMmTelCapabilityProvisionedInCache(subId, capability, tech);
4831 }
4832 default: {
allenwtsu99c623b2020-01-03 18:24:23 +08004833 throw new IllegalArgumentException(
4834 "Tried to get provisioning for MmTel capability '" + capability
4835 + "', which does not require provisioning.");
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004836 }
4837 }
4838
4839 } finally {
4840 Binder.restoreCallingIdentity(identity);
4841 }
4842 }
4843
4844 @Override
4845 public boolean isMmTelCapabilityProvisionedInCache(int subId, int capability, int tech) {
4846 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
4847 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4848 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
4849 }
4850 enforceReadPrivilegedPermission("isMmTelCapabilityProvisionedInCache");
4851 int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
4852 return (provisionedBits & capability) > 0;
4853 }
4854
4855 @Override
4856 public void cacheMmTelCapabilityProvisioning(int subId, int capability, int tech,
4857 boolean isProvisioned) {
4858 if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
4859 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4860 throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
4861 }
4862 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4863 "setProvisioningStatusForCapability");
4864 int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
4865 // If the current provisioning status for capability already matches isProvisioned,
4866 // do nothing.
4867 if (((provisionedBits & capability) > 0) == isProvisioned) {
4868 return;
4869 }
4870 if (isProvisioned) {
4871 setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits | capability));
4872 } else {
4873 setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits & ~capability));
4874 }
4875 }
4876
4877 /**
4878 * @return the bitfield containing the MmTel provisioning for the provided subscription and
4879 * technology. The bitfield should mirror the bitfield defined by
4880 * {@link MmTelFeature.MmTelCapabilities.MmTelCapability}.
4881 */
4882 private int getMmTelCapabilityProvisioningBitfield(int subId, int tech) {
4883 String key = getMmTelProvisioningKey(subId, tech);
4884 // Default is no capabilities are provisioned.
4885 return mTelephonySharedPreferences.getInt(key, 0 /*default*/);
4886 }
4887
4888 /**
4889 * Sets the MmTel capability provisioning bitfield (defined by
4890 * {@link MmTelFeature.MmTelCapabilities.MmTelCapability}) for the subscription and
4891 * technology specified.
4892 *
4893 * Note: This is a synchronous command and should not be called on UI thread.
4894 */
4895 private void setMmTelCapabilityProvisioningBitfield(int subId, int tech, int newField) {
4896 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
4897 String key = getMmTelProvisioningKey(subId, tech);
4898 editor.putInt(key, newField);
4899 editor.commit();
4900 }
4901
4902 private static String getMmTelProvisioningKey(int subId, int tech) {
4903 // resulting key is provision_ims_mmtel_{subId}_{tech}
4904 return PREF_PROVISION_IMS_MMTEL_PREFIX + subId + "_" + tech;
4905 }
4906
4907 /**
4908 * Query CarrierConfig to see if the specified capability requires provisioning for the
4909 * carrier associated with the subscription id.
4910 */
4911 private boolean doesImsCapabilityRequireProvisioning(Context context, int subId,
4912 int capability) {
4913 CarrierConfigManager configManager = new CarrierConfigManager(context);
4914 PersistableBundle c = configManager.getConfigForSubId(subId);
4915 boolean requireUtProvisioning = c.getBoolean(
Brad Ebinger076903f2019-05-13 10:00:22 -07004916 CarrierConfigManager.KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL, false)
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004917 && c.getBoolean(CarrierConfigManager.KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL,
4918 false);
4919 boolean requireVoiceVtProvisioning = c.getBoolean(
4920 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, false);
4921
4922 // First check to make sure that the capability requires provisioning.
4923 switch (capability) {
4924 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE:
4925 // intentional fallthrough
4926 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
4927 if (requireVoiceVtProvisioning) {
4928 // Voice and Video requires provisioning
4929 return true;
4930 }
4931 break;
4932 }
4933 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
4934 if (requireUtProvisioning) {
4935 // UT requires provisioning
4936 return true;
4937 }
4938 break;
4939 }
4940 }
4941 return false;
4942 }
4943
allenwtsu99c623b2020-01-03 18:24:23 +08004944 private boolean doesRcsCapabilityRequireProvisioning(Context context, int subId,
4945 int capability) {
4946 CarrierConfigManager configManager = new CarrierConfigManager(context);
4947 PersistableBundle c = configManager.getConfigForSubId(subId);
4948
4949 boolean requireRcsProvisioning = c.getBoolean(
4950 CarrierConfigManager.KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL, false);
4951
4952 // First check to make sure that the capability requires provisioning.
4953 switch (capability) {
4954 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
4955 // intentional fallthrough
4956 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE: {
4957 if (requireRcsProvisioning) {
4958 // OPTION or PRESENCE requires provisioning
4959 return true;
4960 }
4961 break;
4962 }
4963 }
4964 return false;
4965 }
4966
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004967 @Override
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004968 public int getImsProvisioningInt(int subId, int key) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004969 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4970 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4971 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004972 enforceReadPrivilegedPermission("getImsProvisioningInt");
4973 final long identity = Binder.clearCallingIdentity();
4974 try {
4975 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004976 int slotId = getSlotIndex(subId);
4977 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4978 Log.w(LOG_TAG, "getImsProvisioningInt: called with an inactive subscription '"
4979 + subId + "' for key:" + key);
4980 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
4981 }
calvinpanb5a34062021-02-08 19:59:36 +08004982 return ImsManager.getInstance(mApp, slotId).getConfigInt(key);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07004983 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004984 Log.w(LOG_TAG, "getImsProvisioningInt: ImsService is not available for subscription '"
4985 + subId + "' for key:" + key);
4986 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004987 } finally {
4988 Binder.restoreCallingIdentity(identity);
4989 }
4990 }
4991
4992 @Override
4993 public String getImsProvisioningString(int subId, int key) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08004994 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4995 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4996 }
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07004997 enforceReadPrivilegedPermission("getImsProvisioningString");
4998 final long identity = Binder.clearCallingIdentity();
4999 try {
5000 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005001 int slotId = getSlotIndex(subId);
5002 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5003 Log.w(LOG_TAG, "getImsProvisioningString: called for an inactive subscription id '"
5004 + subId + "' for key:" + key);
5005 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_GENERIC;
5006 }
calvinpanb5a34062021-02-08 19:59:36 +08005007 return ImsManager.getInstance(mApp, slotId).getConfigString(key);
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005008 } catch (com.android.ims.ImsException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005009 Log.w(LOG_TAG, "getImsProvisioningString: ImsService is not available for sub '"
5010 + subId + "' for key:" + key);
5011 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_NOT_READY;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005012 } finally {
5013 Binder.restoreCallingIdentity(identity);
5014 }
5015 }
5016
5017 @Override
5018 public int setImsProvisioningInt(int subId, int key, int value) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005019 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5020 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
5021 }
Brad Ebinger3d0b34e2018-11-15 14:13:12 -08005022 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5023 "setImsProvisioningInt");
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005024 final long identity = Binder.clearCallingIdentity();
5025 try {
5026 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005027 int slotId = getSlotIndex(subId);
5028 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5029 Log.w(LOG_TAG, "setImsProvisioningInt: called with an inactive subscription id '"
5030 + subId + "' for key:" + key);
5031 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
5032 }
calvinpanb5a34062021-02-08 19:59:36 +08005033 return ImsManager.getInstance(mApp, slotId).setConfig(key, value);
5034 } catch (com.android.ims.ImsException | RemoteException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005035 Log.w(LOG_TAG, "setImsProvisioningInt: ImsService unavailable for sub '" + subId
calvinpanb5a34062021-02-08 19:59:36 +08005036 + "' for key:" + key, e);
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005037 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005038 } finally {
5039 Binder.restoreCallingIdentity(identity);
5040 }
5041 }
5042
5043 @Override
5044 public int setImsProvisioningString(int subId, int key, String value) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005045 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5046 throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
5047 }
Brad Ebinger3d0b34e2018-11-15 14:13:12 -08005048 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5049 "setImsProvisioningString");
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005050 final long identity = Binder.clearCallingIdentity();
5051 try {
5052 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005053 int slotId = getSlotIndex(subId);
5054 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5055 Log.w(LOG_TAG, "setImsProvisioningString: called with an inactive subscription id '"
5056 + subId + "' for key:" + key);
5057 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
5058 }
calvinpanb5a34062021-02-08 19:59:36 +08005059 return ImsManager.getInstance(mApp, slotId).setConfig(key, value);
5060 } catch (com.android.ims.ImsException | RemoteException e) {
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005061 Log.w(LOG_TAG, "setImsProvisioningString: ImsService unavailable for sub '" + subId
calvinpanb5a34062021-02-08 19:59:36 +08005062 + "' for key:" + key, e);
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005063 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07005064 } finally {
5065 Binder.restoreCallingIdentity(identity);
5066 }
5067 }
5068
Brad Ebinger919631e2021-06-02 17:46:35 -07005069 /**
5070 * Throw an ImsException if the IMS resolver does not have an ImsService configured for MMTEL
5071 * for the given slot ID or no ImsResolver instance has been created.
5072 * @param slotId The slot ID that the IMS service is created for.
5073 * @throws ImsException If there is no ImsService configured for this slot.
5074 */
5075 private void verifyImsMmTelConfiguredOrThrow(int slotId) throws ImsException {
5076 if (mImsResolver == null || !mImsResolver.isImsServiceConfiguredForFeature(slotId,
5077 ImsFeature.FEATURE_MMTEL)) {
5078 throw new ImsException("This subscription does not support MMTEL over IMS",
5079 ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
5080 }
5081 }
5082
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005083 private int getSlotIndexOrException(int subId) throws ImsException {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005084 int slotId = SubscriptionManager.getSlotIndex(subId);
5085 if (!SubscriptionManager.isValidSlotIndex(slotId)) {
Brad Ebinger1ce9c432019-07-16 13:19:44 -07005086 throw new ImsException("Invalid Subscription Id, subId=" + subId,
5087 ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
Brad Ebinger35c841c2018-10-01 10:40:55 -07005088 }
5089 return slotId;
5090 }
5091
Brad Ebinger1c8542e2019-01-14 13:43:14 -08005092 private int getSlotIndex(int subId) {
5093 int slotId = SubscriptionManager.getSlotIndex(subId);
5094 if (!SubscriptionManager.isValidSlotIndex(slotId)) {
5095 return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
5096 }
5097 return slotId;
5098 }
5099
Wink Saville36469e72014-06-11 15:17:00 -07005100 /**
Nathan Harold9042f0b2019-05-21 15:51:27 -07005101 * Returns the data network type for a subId; does not throw SecurityException.
Wink Saville36469e72014-06-11 15:17:00 -07005102 */
5103 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005104 public int getNetworkTypeForSubscriber(int subId, String callingPackage,
5105 String callingFeatureId) {
Shuo Qian13d89152021-05-10 23:58:11 -07005106 try {
5107 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
5108 } catch (SecurityException se) {
5109 EventLog.writeEvent(0x534e4554, "186776740", Binder.getCallingUid());
5110 throw new SecurityException("Package " + callingPackage + " does not belong to "
5111 + Binder.getCallingUid());
5112 }
Nathan Haroldf096d982020-11-18 17:18:06 -08005113 final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
Nathan Haroldef60dba2019-05-22 13:55:14 -07005114 if (targetSdk > android.os.Build.VERSION_CODES.Q) {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005115 return getDataNetworkTypeForSubscriber(subId, callingPackage, callingFeatureId);
Nathan Haroldef60dba2019-05-22 13:55:14 -07005116 } else if (targetSdk == android.os.Build.VERSION_CODES.Q
Nathan Harold9042f0b2019-05-21 15:51:27 -07005117 && !TelephonyPermissions.checkCallingOrSelfReadPhoneStateNoThrow(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005118 mApp, subId, callingPackage, callingFeatureId,
5119 "getNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07005120 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5121 }
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07005122
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005123 final long identity = Binder.clearCallingIdentity();
5124 try {
5125 final Phone phone = getPhone(subId);
5126 if (phone != null) {
5127 return phone.getServiceState().getDataNetworkType();
5128 } else {
5129 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5130 }
5131 } finally {
5132 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07005133 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005134 }
5135
5136 /**
5137 * Returns the data network type
5138 */
5139 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005140 public int getDataNetworkType(String callingPackage, String callingFeatureId) {
Zoey Chenfd61f7f2021-04-21 13:42:10 +08005141 return getDataNetworkTypeForSubscriber(mSubscriptionController.getDefaultDataSubId(),
5142 callingPackage, callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07005143 }
5144
5145 /**
5146 * Returns the data network type for a subId
5147 */
5148 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005149 public int getDataNetworkTypeForSubscriber(int subId, String callingPackage,
5150 String callingFeatureId) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07005151 String functionName = "getDataNetworkTypeForSubscriber";
5152 if (!TelephonyPermissions.checkCallingOrSelfReadNonDangerousPhoneStateNoThrow(
5153 mApp, functionName)) {
5154 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5155 mApp, subId, callingPackage, callingFeatureId, functionName)) {
5156 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5157 }
Robert Greenwalt36b23af2015-07-06 17:59:14 -07005158 }
5159
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005160 final long identity = Binder.clearCallingIdentity();
5161 try {
5162 final Phone phone = getPhone(subId);
5163 if (phone != null) {
5164 return phone.getServiceState().getDataNetworkType();
5165 } else {
5166 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5167 }
5168 } finally {
5169 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07005170 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005171 }
5172
5173 /**
Wink Saville36469e72014-06-11 15:17:00 -07005174 * Returns the Voice network type for a subId
5175 */
5176 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005177 public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage,
5178 String callingFeatureId) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07005179 String functionName = "getVoiceNetworkTypeForSubscriber";
5180 if (!TelephonyPermissions.checkCallingOrSelfReadNonDangerousPhoneStateNoThrow(
5181 mApp, functionName)) {
5182 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5183 mApp, subId, callingPackage, callingFeatureId, functionName)) {
5184 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5185 }
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07005186 }
5187
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005188 final long identity = Binder.clearCallingIdentity();
5189 try {
5190 final Phone phone = getPhone(subId);
5191 if (phone != null) {
5192 return phone.getServiceState().getVoiceNetworkType();
5193 } else {
5194 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5195 }
5196 } finally {
5197 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07005198 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005199 }
5200
5201 /**
5202 * @return true if a ICC card is present
5203 */
5204 public boolean hasIccCard() {
Wink Saville36469e72014-06-11 15:17:00 -07005205 // FIXME Make changes to pass defaultSimId of type int
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005206 return hasIccCardUsingSlotIndex(mSubscriptionController.getSlotIndex(
5207 getDefaultSubscription()));
Wink Saville36469e72014-06-11 15:17:00 -07005208 }
5209
5210 /**
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005211 * @return true if a ICC card is present for a slotIndex
Wink Saville36469e72014-06-11 15:17:00 -07005212 */
Sanket Padawe356d7632015-06-22 14:03:32 -07005213 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005214 public boolean hasIccCardUsingSlotIndex(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005215 final long identity = Binder.clearCallingIdentity();
5216 try {
5217 final Phone phone = PhoneFactory.getPhone(slotIndex);
5218 if (phone != null) {
5219 return phone.getIccCard().hasIccCard();
5220 } else {
5221 return false;
5222 }
5223 } finally {
5224 Binder.restoreCallingIdentity(identity);
Amit Mahajana6fc2a82015-01-06 11:53:51 -08005225 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005226 }
5227
5228 /**
5229 * Return if the current radio is LTE on CDMA. This
5230 * is a tri-state return value as for a period of time
5231 * the mode may be unknown.
5232 *
Robert Greenwalt36b23af2015-07-06 17:59:14 -07005233 * @param callingPackage the name of the package making the call.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005234 * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
Jake Hambye994d462014-02-03 13:10:13 -08005235 * or {@link Phone#LTE_ON_CDMA_TRUE}
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005236 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07005237 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005238 public int getLteOnCdmaMode(String callingPackage, String callingFeatureId) {
5239 return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage,
5240 callingFeatureId);
Wink Saville36469e72014-06-11 15:17:00 -07005241 }
5242
Sanket Padawe356d7632015-06-22 14:03:32 -07005243 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005244 public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage,
5245 String callingFeatureId) {
Sarah Chin790d2922020-01-16 12:17:23 -08005246 try {
5247 enforceReadPrivilegedPermission("getLteOnCdmaModeForSubscriber");
5248 } catch (SecurityException e) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07005249 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
5250 }
5251
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005252 final long identity = Binder.clearCallingIdentity();
5253 try {
5254 final Phone phone = getPhone(subId);
5255 if (phone == null) {
5256 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
5257 } else {
Nathan Harold05ad6332020-07-10 11:54:36 -07005258 return TelephonyProperties.lte_on_cdma_device()
5259 .orElse(PhoneConstants.LTE_ON_CDMA_FALSE);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005260 }
5261 } finally {
5262 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07005263 }
Wink Saville36469e72014-06-11 15:17:00 -07005264 }
5265
Wink Saville36469e72014-06-11 15:17:00 -07005266 /**
5267 * {@hide}
5268 * Returns Default subId, 0 in the case of single standby.
5269 */
Wink Savilleb564aae2014-10-23 10:18:09 -07005270 private int getDefaultSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08005271 return mSubscriptionController.getDefaultSubId();
Wink Saville36469e72014-06-11 15:17:00 -07005272 }
5273
Shishir Agrawala9f32182016-04-12 12:00:16 -07005274 private int getSlotForDefaultSubscription() {
5275 return mSubscriptionController.getPhoneId(getDefaultSubscription());
5276 }
5277
Wink Savilleb564aae2014-10-23 10:18:09 -07005278 private int getPreferredVoiceSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08005279 return mSubscriptionController.getDefaultVoiceSubId();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005280 }
Ihab Awadf2177b72013-11-25 13:33:23 -08005281
Pengquan Menge92a50d2018-09-21 15:54:48 -07005282 private boolean isActiveSubscription(int subId) {
5283 return mSubscriptionController.isActiveSubId(subId);
5284 }
5285
Ihab Awadf2177b72013-11-25 13:33:23 -08005286 /**
5287 * @see android.telephony.TelephonyManager.WifiCallingChoices
5288 */
5289 public int getWhenToMakeWifiCalls() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005290 final long identity = Binder.clearCallingIdentity();
5291 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005292 return Settings.System.getInt(mApp.getContentResolver(),
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005293 Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
5294 getWhenToMakeWifiCallsDefaultPreference());
5295 } finally {
5296 Binder.restoreCallingIdentity(identity);
5297 }
Ihab Awadf2177b72013-11-25 13:33:23 -08005298 }
5299
5300 /**
5301 * @see android.telephony.TelephonyManager.WifiCallingChoices
5302 */
5303 public void setWhenToMakeWifiCalls(int preference) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005304 final long identity = Binder.clearCallingIdentity();
5305 try {
5306 if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005307 Settings.System.putInt(mApp.getContentResolver(),
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005308 Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference);
5309 } finally {
5310 Binder.restoreCallingIdentity(identity);
5311 }
Ihab Awadf9e92732013-12-05 18:02:52 -08005312 }
5313
Sailesh Nepald1e68152013-12-12 19:08:02 -08005314 private static int getWhenToMakeWifiCallsDefaultPreference() {
Santos Cordonda120f42014-08-06 04:44:34 -07005315 // TODO: Use a build property to choose this value.
Evan Charlton9829e882013-12-19 15:30:38 -08005316 return TelephonyManager.WifiCallingChoices.ALWAYS_USE;
Ihab Awadf2177b72013-11-25 13:33:23 -08005317 }
Shishir Agrawal69f68122013-12-16 17:25:49 -08005318
Muralidhar Reddybd38d952021-12-02 21:04:16 +00005319 private Phone getPhoneFromSlotPortIndexOrThrowException(int slotIndex, int portIndex) {
5320 int phoneId = UiccController.getInstance().getPhoneIdFromSlotPortIndex(slotIndex,
5321 portIndex);
Jordan Liu4c733742019-02-28 12:03:40 -08005322 if (phoneId == -1) {
Muralidhar Reddybd38d952021-12-02 21:04:16 +00005323 throw new IllegalArgumentException("Given slot index: " + slotIndex + " port index: "
5324 + portIndex + " does not correspond to an active phone");
Jordan Liu4c733742019-02-28 12:03:40 -08005325 }
5326 return PhoneFactory.getPhone(phoneId);
5327 }
5328
Shishir Agrawal566b7612013-10-28 14:41:00 -07005329 @Override
Derek Tan740e1672017-06-27 14:56:27 -07005330 public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
Rambo Wanga1782702021-11-10 20:15:19 -08005331 @NonNull IccLogicalChannelRequest request) {
5332 Phone phone = getPhoneFromValidIccLogicalChannelRequest(request,
5333 /*message=*/ "iccOpenLogicalChannel");
5334
5335 if (DBG) log("iccOpenLogicalChannel: request=" + request);
5336 // Verify that the callingPackage in the request belongs to the calling UID
5337 mAppOps.checkPackage(Binder.getCallingUid(), request.callingPackage);
5338
5339 return iccOpenLogicalChannelWithPermission(phone, request);
Jordan Liu4c733742019-02-28 12:03:40 -08005340 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07005341
Rambo Wanga1782702021-11-10 20:15:19 -08005342 private Phone getPhoneFromValidIccLogicalChannelRequest(
5343 @NonNull IccLogicalChannelRequest request, String message) {
5344 Phone phone;
5345 if (request.subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
5346 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5347 mApp, request.subId, message);
5348 phone = getPhoneFromSubId(request.subId);
5349 } else if (request.slotIndex != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5350 enforceModifyPermission();
5351 phone = getPhoneFromSlotPortIndexOrThrowException(request.slotIndex, request.portIndex);
5352 } else {
5353 throw new IllegalArgumentException("Both subId and slotIndex in request are invalid.");
Jordan Liu4c733742019-02-28 12:03:40 -08005354 }
Rambo Wanga1782702021-11-10 20:15:19 -08005355 return phone;
Jordan Liu4c733742019-02-28 12:03:40 -08005356 }
5357
5358 private IccOpenLogicalChannelResponse iccOpenLogicalChannelWithPermission(Phone phone,
Rambo Wanga1782702021-11-10 20:15:19 -08005359 IccLogicalChannelRequest channelRequest) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005360 final long identity = Binder.clearCallingIdentity();
5361 try {
Rambo Wanga1782702021-11-10 20:15:19 -08005362 if (TextUtils.equals(ISDR_AID, channelRequest.aid)) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005363 // Only allows LPA to open logical channel to ISD-R.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005364 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
5365 .getContext().getPackageManager());
Rambo Wanga1782702021-11-10 20:15:19 -08005366 if (bestComponent == null || !TextUtils.equals(channelRequest.callingPackage,
5367 bestComponent.packageName)) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005368 loge("The calling package is not allowed to access ISD-R.");
5369 throw new SecurityException(
5370 "The calling package is not allowed to access ISD-R.");
5371 }
Derek Tan740e1672017-06-27 14:56:27 -07005372 }
Derek Tan740e1672017-06-27 14:56:27 -07005373
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005374 IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse) sendRequest(
Rambo Wanga1782702021-11-10 20:15:19 -08005375 CMD_OPEN_CHANNEL, channelRequest, phone, null /* workSource */);
5376 if (DBG) log("iccOpenLogicalChannelWithPermission: response=" + response);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005377 return response;
5378 } finally {
5379 Binder.restoreCallingIdentity(identity);
5380 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07005381 }
5382
5383 @Override
Rambo Wanga1782702021-11-10 20:15:19 -08005384 public boolean iccCloseLogicalChannel(@NonNull IccLogicalChannelRequest request) {
5385 Phone phone = getPhoneFromValidIccLogicalChannelRequest(request,
5386 /*message=*/"iccCloseLogicalChannel");
5387
5388 if (DBG) log("iccCloseLogicalChannel: request=" + request);
5389
5390 return iccCloseLogicalChannelWithPermission(phone, request);
Jordan Liu4c733742019-02-28 12:03:40 -08005391 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07005392
Rambo Wanga1782702021-11-10 20:15:19 -08005393 private boolean iccCloseLogicalChannelWithPermission(Phone phone,
5394 IccLogicalChannelRequest request) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005395 final long identity = Binder.clearCallingIdentity();
5396 try {
Rambo Wanga1782702021-11-10 20:15:19 -08005397 if (request.channel < 0) {
Chen Xu540470b2021-12-14 17:15:47 -08005398 throw new IllegalArgumentException("request.channel is less than 0");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005399 }
Chen Xue9d737e2022-01-01 23:41:31 -08005400 Object result = sendRequest(CMD_CLOSE_CHANNEL, request.channel, phone,
Jordan Liu4c733742019-02-28 12:03:40 -08005401 null /* workSource */);
Chen Xue9d737e2022-01-01 23:41:31 -08005402 Boolean success = false;
5403 if (result instanceof RuntimeException) {
5404 // if there is an exception returned, throw from the binder thread here.
5405 throw (RuntimeException) result;
5406 } else if (result instanceof Boolean) {
5407 success = (Boolean) result;
5408 } else {
5409 loge("iccCloseLogicalChannelWithPermission: supported return type " + result);
5410 }
Rambo Wanga1782702021-11-10 20:15:19 -08005411 if (DBG) log("iccCloseLogicalChannelWithPermission: success=" + success);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005412 return success;
5413 } finally {
5414 Binder.restoreCallingIdentity(identity);
Shishir Agrawal566b7612013-10-28 14:41:00 -07005415 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07005416 }
5417
5418 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08005419 public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
Shishir Agrawal566b7612013-10-28 14:41:00 -07005420 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005421 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5422 mApp, subId, "iccTransmitApduLogicalChannel");
Jordan Liu4c733742019-02-28 12:03:40 -08005423 if (DBG) {
5424 log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel
5425 + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
5426 + p3 + " data=" + data);
5427 }
5428 return iccTransmitApduLogicalChannelWithPermission(getPhoneFromSubId(subId), channel, cla,
5429 command, p1, p2, p3, data);
5430 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07005431
Jordan Liu4c733742019-02-28 12:03:40 -08005432 @Override
Muralidhar Reddybd38d952021-12-02 21:04:16 +00005433 public String iccTransmitApduLogicalChannelByPort(int slotIndex, int portIndex, int channel,
5434 int cla, int command, int p1, int p2, int p3, String data) {
Jordan Liu4c733742019-02-28 12:03:40 -08005435 enforceModifyPermission();
5436 if (DBG) {
Muralidhar Reddybd38d952021-12-02 21:04:16 +00005437 log("iccTransmitApduLogicalChannelByPort: slotIndex=" + slotIndex + " portIndex="
5438 + portIndex + " chnl=" + channel + " cla=" + cla + " cmd=" + command + " p1="
5439 + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
Jordan Liu4c733742019-02-28 12:03:40 -08005440 }
5441 return iccTransmitApduLogicalChannelWithPermission(
Muralidhar Reddybd38d952021-12-02 21:04:16 +00005442 getPhoneFromSlotPortIndexOrThrowException(slotIndex, portIndex), channel, cla,
5443 command, p1, p2, p3, data);
Jordan Liu4c733742019-02-28 12:03:40 -08005444 }
5445
5446 private String iccTransmitApduLogicalChannelWithPermission(Phone phone, int channel, int cla,
5447 int command, int p1, int p2, int p3, String data) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005448 final long identity = Binder.clearCallingIdentity();
5449 try {
Hall Liu4fd771b2019-05-02 09:16:29 -07005450 if (channel <= 0) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005451 return "";
5452 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07005453
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005454 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL,
Jordan Liu4c733742019-02-28 12:03:40 -08005455 new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), phone,
5456 null /* workSource */);
5457 if (DBG) log("iccTransmitApduLogicalChannelWithPermission: " + response);
Shishir Agrawal566b7612013-10-28 14:41:00 -07005458
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005459 // Append the returned status code to the end of the response payload.
5460 String s = Integer.toHexString(
5461 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
5462 if (response.payload != null) {
5463 s = IccUtils.bytesToHexString(response.payload) + s;
5464 }
5465 return s;
5466 } finally {
5467 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07005468 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07005469 }
Jake Hambye994d462014-02-03 13:10:13 -08005470
Evan Charltonc66da362014-05-16 14:06:40 -07005471 @Override
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08005472 public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
5473 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005474 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5475 mApp, subId, "iccTransmitApduBasicChannel");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005476 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jordan Liu4c733742019-02-28 12:03:40 -08005477 if (DBG) {
5478 log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd="
5479 + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
5480 }
5481 return iccTransmitApduBasicChannelWithPermission(getPhoneFromSubId(subId), callingPackage,
5482 cla, command, p1, p2, p3, data);
5483 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07005484
Jordan Liu4c733742019-02-28 12:03:40 -08005485 @Override
Muralidhar Reddybd38d952021-12-02 21:04:16 +00005486 public String iccTransmitApduBasicChannelByPort(int slotIndex, int portIndex,
5487 String callingPackage, int cla, int command, int p1, int p2, int p3, String data) {
Jordan Liu4c733742019-02-28 12:03:40 -08005488 enforceModifyPermission();
5489 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
5490 if (DBG) {
Muralidhar Reddybd38d952021-12-02 21:04:16 +00005491 log("iccTransmitApduBasicChannelByPort: slotIndex=" + slotIndex + " portIndex="
5492 + portIndex + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2="
5493 + p2 + " p3=" + p3 + " data=" + data);
Jordan Liu4c733742019-02-28 12:03:40 -08005494 }
5495
5496 return iccTransmitApduBasicChannelWithPermission(
Muralidhar Reddybd38d952021-12-02 21:04:16 +00005497 getPhoneFromSlotPortIndexOrThrowException(slotIndex, portIndex), callingPackage,
5498 cla, command, p1, p2, p3, data);
Jordan Liu4c733742019-02-28 12:03:40 -08005499 }
5500
5501 // open APDU basic channel assuming the caller has sufficient permissions
5502 private String iccTransmitApduBasicChannelWithPermission(Phone phone, String callingPackage,
5503 int cla, int command, int p1, int p2, int p3, String data) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005504 final long identity = Binder.clearCallingIdentity();
5505 try {
5506 if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
5507 && TextUtils.equals(ISDR_AID, data)) {
5508 // Only allows LPA to select ISD-R.
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005509 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
5510 .getContext().getPackageManager());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005511 if (bestComponent == null
5512 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
5513 loge("The calling package is not allowed to select ISD-R.");
5514 throw new SecurityException(
5515 "The calling package is not allowed to select ISD-R.");
5516 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08005517 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08005518
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005519 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL,
Jordan Liu4c733742019-02-28 12:03:40 -08005520 new IccAPDUArgument(0, cla, command, p1, p2, p3, data), phone,
5521 null /* workSource */);
5522 if (DBG) log("iccTransmitApduBasicChannelWithPermission: " + response);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07005523
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005524 // Append the returned status code to the end of the response payload.
5525 String s = Integer.toHexString(
5526 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
5527 if (response.payload != null) {
5528 s = IccUtils.bytesToHexString(response.payload) + s;
5529 }
5530 return s;
5531 } finally {
5532 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07005533 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07005534 }
5535
5536 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08005537 public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07005538 String filePath) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005539 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5540 mApp, subId, "iccExchangeSimIO");
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07005541
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005542 final long identity = Binder.clearCallingIdentity();
5543 try {
5544 if (DBG) {
5545 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " "
5546 + p1 + " " + p2 + " " + p3 + ":" + filePath);
5547 }
5548
5549 IccIoResult response =
5550 (IccIoResult) sendRequest(CMD_EXCHANGE_SIM_IO,
5551 new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath),
5552 subId);
5553
5554 if (DBG) {
5555 log("Exchange SIM_IO [R]" + response);
5556 }
5557
5558 byte[] result = null;
5559 int length = 2;
5560 if (response.payload != null) {
5561 length = 2 + response.payload.length;
5562 result = new byte[length];
5563 System.arraycopy(response.payload, 0, result, 0, response.payload.length);
5564 } else {
5565 result = new byte[length];
5566 }
5567
5568 result[length - 1] = (byte) response.sw2;
5569 result[length - 2] = (byte) response.sw1;
5570 return result;
5571 } finally {
5572 Binder.restoreCallingIdentity(identity);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07005573 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07005574 }
5575
Nathan Haroldb3014052017-01-25 15:57:32 -08005576 /**
5577 * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
5578 * on a particular subscription
5579 */
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005580 public String[] getForbiddenPlmns(int subId, int appType, String callingPackage,
5581 String callingFeatureId) {
sqianb6e41952018-03-12 14:54:01 -07005582 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005583 mApp, subId, callingPackage, callingFeatureId, "getForbiddenPlmns")) {
sqianb6e41952018-03-12 14:54:01 -07005584 return null;
5585 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005586
5587 final long identity = Binder.clearCallingIdentity();
5588 try {
5589 if (appType != TelephonyManager.APPTYPE_USIM
5590 && appType != TelephonyManager.APPTYPE_SIM) {
5591 loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
5592 return null;
5593 }
5594 Object response = sendRequest(
5595 CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
5596 if (response instanceof String[]) {
5597 return (String[]) response;
5598 }
yincheng zhao2737e882019-09-06 17:06:54 -07005599 // Response is an Exception of some kind
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005600 // which is signalled to the user as a NULL retval
Nathan Haroldb3014052017-01-25 15:57:32 -08005601 return null;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005602 } finally {
5603 Binder.restoreCallingIdentity(identity);
Nathan Haroldb3014052017-01-25 15:57:32 -08005604 }
Nathan Haroldb3014052017-01-25 15:57:32 -08005605 }
5606
yincheng zhao2737e882019-09-06 17:06:54 -07005607 /**
5608 * Set the forbidden PLMN list from the given app type (ex APPTYPE_USIM) on a particular
5609 * subscription.
5610 *
5611 * @param subId the id of the subscription.
5612 * @param appType the uicc app type, must be USIM or SIM.
5613 * @param fplmns the Forbiden plmns list that needed to be written to the SIM.
5614 * @param callingPackage the op Package name.
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005615 * @param callingFeatureId the feature in the package.
yincheng zhao2737e882019-09-06 17:06:54 -07005616 * @return number of fplmns that is successfully written to the SIM.
5617 */
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005618 public int setForbiddenPlmns(int subId, int appType, List<String> fplmns, String callingPackage,
5619 String callingFeatureId) {
Jayachandran C5b0d75a2021-10-21 22:15:27 -07005620 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5621 mApp, subId, "setForbiddenPlmns");
5622
yincheng zhao2737e882019-09-06 17:06:54 -07005623 if (appType != TelephonyManager.APPTYPE_USIM && appType != TelephonyManager.APPTYPE_SIM) {
5624 loge("setForbiddenPlmnList(): App Type must be USIM or SIM");
5625 throw new IllegalArgumentException("Invalid appType: App Type must be USIM or SIM");
5626 }
5627 if (fplmns == null) {
5628 throw new IllegalArgumentException("Fplmn List provided is null");
5629 }
5630 for (String fplmn : fplmns) {
5631 if (!CellIdentity.isValidPlmn(fplmn)) {
5632 throw new IllegalArgumentException("Invalid fplmn provided: " + fplmn);
5633 }
5634 }
5635 final long identity = Binder.clearCallingIdentity();
5636 try {
5637 Object response = sendRequest(
5638 CMD_SET_FORBIDDEN_PLMNS,
5639 new Pair<Integer, List<String>>(new Integer(appType), fplmns),
5640 subId);
5641 return (int) response;
5642 } finally {
5643 Binder.restoreCallingIdentity(identity);
5644 }
5645 }
5646
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07005647 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08005648 public String sendEnvelopeWithStatus(int subId, String content) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005649 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5650 mApp, subId, "sendEnvelopeWithStatus");
Evan Charltonc66da362014-05-16 14:06:40 -07005651
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005652 final long identity = Binder.clearCallingIdentity();
5653 try {
5654 IccIoResult response = (IccIoResult) sendRequest(CMD_SEND_ENVELOPE, content, subId);
5655 if (response.payload == null) {
5656 return "";
5657 }
Evan Charltonc66da362014-05-16 14:06:40 -07005658
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005659 // Append the returned status code to the end of the response payload.
5660 String s = Integer.toHexString(
5661 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
5662 s = IccUtils.bytesToHexString(response.payload) + s;
5663 return s;
5664 } finally {
5665 Binder.restoreCallingIdentity(identity);
5666 }
Evan Charltonc66da362014-05-16 14:06:40 -07005667 }
5668
Jake Hambye994d462014-02-03 13:10:13 -08005669 /**
5670 * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
5671 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
5672 *
5673 * @param itemID the ID of the item to read
5674 * @return the NV item as a String, or null on error.
5675 */
5676 @Override
5677 public String nvReadItem(int itemID) {
vagdeviaf9a5b92018-08-15 16:01:53 -07005678 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08005679 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5680 mApp, getDefaultSubscription(), "nvReadItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005681
5682 final long identity = Binder.clearCallingIdentity();
5683 try {
5684 if (DBG) log("nvReadItem: item " + itemID);
vagdeviaf9a5b92018-08-15 16:01:53 -07005685 String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005686 if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
5687 return value;
5688 } finally {
5689 Binder.restoreCallingIdentity(identity);
5690 }
Jake Hambye994d462014-02-03 13:10:13 -08005691 }
5692
5693 /**
5694 * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
5695 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
5696 *
5697 * @param itemID the ID of the item to read
5698 * @param itemValue the value to write, as a String
5699 * @return true on success; false on any failure
5700 */
5701 @Override
5702 public boolean nvWriteItem(int itemID, String itemValue) {
vagdeviaf9a5b92018-08-15 16:01:53 -07005703 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08005704 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5705 mApp, getDefaultSubscription(), "nvWriteItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005706
5707 final long identity = Binder.clearCallingIdentity();
5708 try {
5709 if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
5710 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
vagdeviaf9a5b92018-08-15 16:01:53 -07005711 new Pair<Integer, String>(itemID, itemValue), workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005712 if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
5713 return success;
5714 } finally {
5715 Binder.restoreCallingIdentity(identity);
5716 }
Jake Hambye994d462014-02-03 13:10:13 -08005717 }
5718
5719 /**
5720 * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
5721 * Used for device configuration by some CDMA operators.
5722 *
5723 * @param preferredRoamingList byte array containing the new PRL
5724 * @return true on success; false on any failure
5725 */
5726 @Override
5727 public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005728 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5729 mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005730
5731 final long identity = Binder.clearCallingIdentity();
5732 try {
5733 if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
5734 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
5735 if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
5736 return success;
5737 } finally {
5738 Binder.restoreCallingIdentity(identity);
5739 }
Jake Hambye994d462014-02-03 13:10:13 -08005740 }
5741
5742 /**
chen xu6dac5ab2018-10-26 17:39:23 -07005743 * Rollback modem configurations to factory default except some config which are in whitelist.
Jake Hambye994d462014-02-03 13:10:13 -08005744 * Used for device configuration by some CDMA operators.
5745 *
chen xu6dac5ab2018-10-26 17:39:23 -07005746 * @param slotIndex - device slot.
5747 *
Jake Hambye994d462014-02-03 13:10:13 -08005748 * @return true on success; false on any failure
5749 */
5750 @Override
chen xu6dac5ab2018-10-26 17:39:23 -07005751 public boolean resetModemConfig(int slotIndex) {
5752 Phone phone = PhoneFactory.getPhone(slotIndex);
5753 if (phone != null) {
5754 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5755 mApp, phone.getSubId(), "resetModemConfig");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005756
chen xu6dac5ab2018-10-26 17:39:23 -07005757 final long identity = Binder.clearCallingIdentity();
5758 try {
5759 Boolean success = (Boolean) sendRequest(CMD_RESET_MODEM_CONFIG, null);
5760 if (DBG) log("resetModemConfig:" + ' ' + (success ? "ok" : "fail"));
5761 return success;
5762 } finally {
5763 Binder.restoreCallingIdentity(identity);
5764 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005765 }
chen xu6dac5ab2018-10-26 17:39:23 -07005766 return false;
5767 }
5768
5769 /**
5770 * Generate a radio modem reset. Used for device configuration by some CDMA operators.
5771 *
5772 * @param slotIndex - device slot.
5773 *
5774 * @return true on success; false on any failure
5775 */
5776 @Override
5777 public boolean rebootModem(int slotIndex) {
5778 Phone phone = PhoneFactory.getPhone(slotIndex);
5779 if (phone != null) {
5780 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5781 mApp, phone.getSubId(), "rebootModem");
5782
5783 final long identity = Binder.clearCallingIdentity();
5784 try {
5785 Boolean success = (Boolean) sendRequest(CMD_MODEM_REBOOT, null);
5786 if (DBG) log("rebootModem:" + ' ' + (success ? "ok" : "fail"));
5787 return success;
5788 } finally {
5789 Binder.restoreCallingIdentity(identity);
5790 }
5791 }
5792 return false;
Jake Hambye994d462014-02-03 13:10:13 -08005793 }
Jake Hamby7c27be32014-03-03 13:25:59 -08005794
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005795 public String[] getPcscfAddress(String apnType, String callingPackage,
5796 String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005797 final Phone defaultPhone = getDefaultPhone();
Philip P. Moltmann700a9592019-10-03 11:53:50 -07005798 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
5799 callingPackage, callingFeatureId, "getPcscfAddress")) {
Svet Ganovb320e182015-04-16 12:30:10 -07005800 return new String[0];
5801 }
5802
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005803 final long identity = Binder.clearCallingIdentity();
5804 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08005805 return defaultPhone.getPcscfAddress(apnType);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005806 } finally {
5807 Binder.restoreCallingIdentity(identity);
5808 }
Wink Saville36469e72014-06-11 15:17:00 -07005809 }
5810
Brad Ebinger51f743a2017-01-23 13:50:20 -08005811 /**
Grace Jiaaa2eb6b2020-01-09 16:26:08 -08005812 * Toggle IMS disable and enable for the framework to reset it. See {@link #enableIms(int)} and
5813 * {@link #disableIms(int)}.
5814 * @param slotIndex device slot.
5815 */
5816 public void resetIms(int slotIndex) {
5817 enforceModifyPermission();
5818
5819 final long identity = Binder.clearCallingIdentity();
5820 try {
5821 if (mImsResolver == null) {
5822 // may happen if the does not support IMS.
5823 return;
5824 }
5825 mImsResolver.disableIms(slotIndex);
5826 mImsResolver.enableIms(slotIndex);
5827 } finally {
5828 Binder.restoreCallingIdentity(identity);
5829 }
5830 }
5831
5832 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005833 * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
5834 * status updates, if not already enabled.
Brad Ebinger51f743a2017-01-23 13:50:20 -08005835 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005836 public void enableIms(int slotId) {
Brad Ebinger51f743a2017-01-23 13:50:20 -08005837 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005838
5839 final long identity = Binder.clearCallingIdentity();
5840 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08005841 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005842 // may happen if the device does not support IMS.
5843 return;
5844 }
Brad Ebinger24c29992019-12-05 13:03:21 -08005845 mImsResolver.enableIms(slotId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005846 } finally {
5847 Binder.restoreCallingIdentity(identity);
5848 }
Brad Ebinger34bef922017-11-09 10:27:08 -08005849 }
5850
5851 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005852 * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
5853 * status updates to disabled.
Brad Ebinger34bef922017-11-09 10:27:08 -08005854 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005855 public void disableIms(int slotId) {
5856 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005857
5858 final long identity = Binder.clearCallingIdentity();
5859 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08005860 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005861 // may happen if the device does not support IMS.
5862 return;
5863 }
Brad Ebinger24c29992019-12-05 13:03:21 -08005864 mImsResolver.disableIms(slotId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005865 } finally {
5866 Binder.restoreCallingIdentity(identity);
5867 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005868 }
5869
5870 /**
Brad Ebinger67b3e042020-09-11 12:45:11 -07005871 * Registers for updates to the MmTelFeature connection through the IImsServiceFeatureCallback
5872 * callback.
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005873 */
Brad Ebinger67b3e042020-09-11 12:45:11 -07005874 @Override
Brad Ebingerf6aca002020-10-01 13:51:05 -07005875 public void registerMmTelFeatureCallback(int slotId, IImsServiceFeatureCallback callback) {
Brad Ebinger34bef922017-11-09 10:27:08 -08005876 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005877
5878 final long identity = Binder.clearCallingIdentity();
5879 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08005880 if (mImsResolver == null) {
Brad Ebinger67b3e042020-09-11 12:45:11 -07005881 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
5882 "Device does not support IMS");
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005883 }
Brad Ebingerf6aca002020-10-01 13:51:05 -07005884 mImsResolver.listenForFeature(slotId, ImsFeature.FEATURE_MMTEL, callback);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005885 } finally {
5886 Binder.restoreCallingIdentity(identity);
5887 }
Brad Ebinger34bef922017-11-09 10:27:08 -08005888 }
Brad Ebinger5f64b052017-12-14 14:26:15 -08005889 /**
Brad Ebinger075ff3a2020-05-18 17:52:58 -07005890 * Unregister a previously registered IImsServiceFeatureCallback associated with an ImsFeature.
5891 */
Brad Ebinger67b3e042020-09-11 12:45:11 -07005892 @Override
5893 public void unregisterImsFeatureCallback(IImsServiceFeatureCallback callback) {
Brad Ebinger075ff3a2020-05-18 17:52:58 -07005894 enforceModifyPermission();
5895
5896 final long identity = Binder.clearCallingIdentity();
5897 try {
5898 if (mImsResolver == null) return;
Brad Ebinger67b3e042020-09-11 12:45:11 -07005899 mImsResolver.unregisterImsFeatureCallback(callback);
Brad Ebinger075ff3a2020-05-18 17:52:58 -07005900 } finally {
5901 Binder.restoreCallingIdentity(identity);
5902 }
5903 }
5904
5905 /**
Brad Ebinger5f64b052017-12-14 14:26:15 -08005906 * Returns the {@link IImsRegistration} structure associated with the slotId and feature
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005907 * specified or null if IMS is not supported on the slot specified.
Brad Ebinger5f64b052017-12-14 14:26:15 -08005908 */
5909 public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
5910 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005911
5912 final long identity = Binder.clearCallingIdentity();
5913 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08005914 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005915 // may happen if the device does not support IMS.
5916 return null;
5917 }
Brad Ebinger24c29992019-12-05 13:03:21 -08005918 return mImsResolver.getImsRegistration(slotId, feature);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005919 } finally {
5920 Binder.restoreCallingIdentity(identity);
5921 }
Brad Ebinger5f64b052017-12-14 14:26:15 -08005922 }
5923
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005924 /**
5925 * Returns the {@link IImsConfig} structure associated with the slotId and feature
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005926 * specified or null if IMS is not supported on the slot specified.
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005927 */
5928 public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
5929 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005930
5931 final long identity = Binder.clearCallingIdentity();
5932 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08005933 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005934 // may happen if the device does not support IMS.
5935 return null;
5936 }
Brad Ebinger24c29992019-12-05 13:03:21 -08005937 return mImsResolver.getImsConfig(slotId, feature);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005938 } finally {
5939 Binder.restoreCallingIdentity(identity);
5940 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08005941 }
5942
Brad Ebinger884c07b2018-02-15 16:17:40 -08005943 /**
Brad Ebingerdac2f002018-04-03 15:17:52 -07005944 * Sets the ImsService Package Name that Telephony will bind to.
5945 *
Brad Ebinger24c29992019-12-05 13:03:21 -08005946 * @param slotIndex the slot ID that the ImsService should bind for.
5947 * @param isCarrierService true if the ImsService is the carrier override, false if the
Brad Ebingerdac2f002018-04-03 15:17:52 -07005948 * ImsService is the device default ImsService.
Brad Ebinger24c29992019-12-05 13:03:21 -08005949 * @param featureTypes An integer array of feature types associated with a packageName.
5950 * @param packageName The name of the package that the current configuration will be replaced
5951 * with.
Brad Ebingerdac2f002018-04-03 15:17:52 -07005952 * @return true if setting the ImsService to bind to succeeded, false if it did not.
Brad Ebingerdac2f002018-04-03 15:17:52 -07005953 */
Brad Ebinger24c29992019-12-05 13:03:21 -08005954 public boolean setBoundImsServiceOverride(int slotIndex, boolean isCarrierService,
5955 int[] featureTypes, String packageName) {
5956 int[] subIds = SubscriptionManager.getSubId(slotIndex);
5957 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setBoundImsServiceOverride");
Brad Ebingerde696de2018-04-06 09:56:40 -07005958 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
5959 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
Brad Ebinger24c29992019-12-05 13:03:21 -08005960 "setBoundImsServiceOverride");
Brad Ebingerde696de2018-04-06 09:56:40 -07005961
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005962 final long identity = Binder.clearCallingIdentity();
5963 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08005964 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08005965 // may happen if the device does not support IMS.
5966 return false;
5967 }
Brad Ebinger24c29992019-12-05 13:03:21 -08005968 Map<Integer, String> featureConfig = new HashMap<>();
5969 for (int featureType : featureTypes) {
5970 featureConfig.put(featureType, packageName);
5971 }
5972 return mImsResolver.overrideImsServiceConfiguration(slotIndex, isCarrierService,
5973 featureConfig);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005974 } finally {
5975 Binder.restoreCallingIdentity(identity);
5976 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07005977 }
5978
5979 /**
Brad Ebinger999d3302020-11-25 14:31:39 -08005980 * Clears any carrier ImsService overrides for the slot index specified that were previously
5981 * set with {@link #setBoundImsServiceOverride(int, boolean, int[], String)}.
5982 *
5983 * This should only be used for testing.
5984 *
5985 * @param slotIndex the slot ID that the ImsService should bind for.
5986 * @return true if clearing the carrier ImsService override succeeded or false if it did not.
5987 */
5988 @Override
5989 public boolean clearCarrierImsServiceOverride(int slotIndex) {
5990 int[] subIds = SubscriptionManager.getSubId(slotIndex);
5991 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
5992 "clearCarrierImsServiceOverride");
5993 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
5994 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
5995 "clearCarrierImsServiceOverride");
5996
5997 final long identity = Binder.clearCallingIdentity();
5998 try {
5999 if (mImsResolver == null) {
6000 // may happen if the device does not support IMS.
6001 return false;
6002 }
6003 return mImsResolver.clearCarrierImsServiceConfiguration(slotIndex);
6004 } finally {
6005 Binder.restoreCallingIdentity(identity);
6006 }
6007 }
6008
6009 /**
Brad Ebinger24c29992019-12-05 13:03:21 -08006010 * Return the package name of the currently bound ImsService.
Brad Ebingerdac2f002018-04-03 15:17:52 -07006011 *
6012 * @param slotId The slot that the ImsService is associated with.
6013 * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
6014 * the device default.
Brad Ebinger24c29992019-12-05 13:03:21 -08006015 * @param featureType The feature associated with the queried configuration.
Brad Ebingerdac2f002018-04-03 15:17:52 -07006016 * @return the package name of the ImsService configuration.
6017 */
Brad Ebinger24c29992019-12-05 13:03:21 -08006018 public String getBoundImsServicePackage(int slotId, boolean isCarrierImsService,
6019 @ImsFeature.FeatureType int featureType) {
Brad Ebingerde696de2018-04-06 09:56:40 -07006020 int[] subIds = SubscriptionManager.getSubId(slotId);
Brad Ebinger24c29992019-12-05 13:03:21 -08006021 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07006022 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Brad Ebinger24c29992019-12-05 13:03:21 -08006023 mApp, (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
6024 "getBoundImsServicePackage");
Brad Ebingerde696de2018-04-06 09:56:40 -07006025
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006026 final long identity = Binder.clearCallingIdentity();
6027 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08006028 if (mImsResolver == null) {
Brad Ebinger9c0eb502019-01-23 15:06:19 -08006029 // may happen if the device does not support IMS.
6030 return "";
6031 }
Brad Ebingera80c3312019-12-02 10:59:39 -08006032 // TODO: change API to query RCS separately.
Brad Ebinger24c29992019-12-05 13:03:21 -08006033 return mImsResolver.getImsServiceConfiguration(slotId, isCarrierImsService,
6034 featureType);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006035 } finally {
6036 Binder.restoreCallingIdentity(identity);
6037 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07006038 }
6039
Brad Ebingerbc7dd582019-10-17 17:03:22 -07006040 /**
6041 * Get the MmTelFeature state associated with the requested subscription id.
6042 * @param subId The subscription that the MmTelFeature is associated with.
6043 * @param callback A callback with an integer containing the
6044 * {@link android.telephony.ims.feature.ImsFeature.ImsState} associated with the MmTelFeature.
6045 */
6046 @Override
6047 public void getImsMmTelFeatureState(int subId, IIntegerConsumer callback) {
6048 enforceReadPrivilegedPermission("getImsMmTelFeatureState");
6049 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
6050 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
6051 "IMS not available on device.");
6052 }
6053 final long token = Binder.clearCallingIdentity();
6054 try {
6055 int slotId = getSlotIndex(subId);
6056 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
6057 Log.w(LOG_TAG, "getImsMmTelFeatureState: called with an inactive subscription '"
6058 + subId + "'");
6059 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
6060 }
Brad Ebinger919631e2021-06-02 17:46:35 -07006061 verifyImsMmTelConfiguredOrThrow(slotId);
Brad Ebingerbc7dd582019-10-17 17:03:22 -07006062 ImsManager.getInstance(mApp, slotId).getImsServiceState(anInteger -> {
6063 try {
6064 callback.accept(anInteger == null ? ImsFeature.STATE_UNAVAILABLE : anInteger);
6065 } catch (RemoteException e) {
6066 Log.w(LOG_TAG, "getImsMmTelFeatureState: remote caller is no longer running. "
6067 + "Ignore");
6068 }
6069 });
Brad Ebinger919631e2021-06-02 17:46:35 -07006070 } catch (ImsException e) {
6071 throw new ServiceSpecificException(e.getCode());
Brad Ebingerbc7dd582019-10-17 17:03:22 -07006072 } finally {
6073 Binder.restoreCallingIdentity(token);
6074 }
6075 }
6076
Daniel Brightbb5840b2021-01-12 15:48:18 -08006077 /**
6078 * Sets the ims registration state on all valid {@link Phone}s.
6079 */
6080 public void setImsRegistrationState(final boolean registered) {
Wink Saville36469e72014-06-11 15:17:00 -07006081 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006082
6083 final long identity = Binder.clearCallingIdentity();
6084 try {
Daniel Brightbb5840b2021-01-12 15:48:18 -08006085 // NOTE: Before S, this method only set the default phone.
6086 for (final Phone phone : PhoneFactory.getPhones()) {
6087 if (SubscriptionManager.isValidSubscriptionId(phone.getSubId())) {
6088 phone.setImsRegistrationState(registered);
6089 }
6090 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006091 } finally {
6092 Binder.restoreCallingIdentity(identity);
6093 }
Wink Saville36469e72014-06-11 15:17:00 -07006094 }
6095
6096 /**
Stuart Scott54788802015-03-30 13:18:01 -07006097 * Set the network selection mode to automatic.
6098 *
6099 */
6100 @Override
6101 public void setNetworkSelectionModeAutomatic(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006102 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6103 mApp, subId, "setNetworkSelectionModeAutomatic");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006104
6105 final long identity = Binder.clearCallingIdentity();
6106 try {
shilufc958392020-01-20 11:36:01 -08006107 if (!isActiveSubscription(subId)) {
6108 return;
6109 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006110 if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
Rambo Wang0f050d82021-02-12 11:43:36 -08006111 sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId,
6112 SET_NETWORK_SELECTION_MODE_AUTOMATIC_TIMEOUT_MS);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006113 } finally {
6114 Binder.restoreCallingIdentity(identity);
6115 }
Stuart Scott54788802015-03-30 13:18:01 -07006116 }
6117
Jack Yud10cdd42020-09-28 20:28:01 -07006118 /**
Pengquan Mengea84e042018-09-20 14:57:26 -07006119 * Ask the radio to connect to the input network and change selection mode to manual.
6120 *
6121 * @param subId the id of the subscription.
6122 * @param operatorInfo the operator information, included the PLMN, long name and short name of
6123 * the operator to attach to.
6124 * @param persistSelection whether the selection will persist until reboot. If true, only allows
6125 * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
6126 * normal network selection next time.
6127 * @return {@code true} on success; {@code true} on any failure.
Shishir Agrawal302c8692015-06-19 13:49:39 -07006128 */
6129 @Override
Pengquan Mengea84e042018-09-20 14:57:26 -07006130 public boolean setNetworkSelectionModeManual(
6131 int subId, OperatorInfo operatorInfo, boolean persistSelection) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006132 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6133 mApp, subId, "setNetworkSelectionModeManual");
Pengquan Menge92a50d2018-09-21 15:54:48 -07006134
6135 if (!isActiveSubscription(subId)) {
6136 return false;
6137 }
6138
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006139 final long identity = Binder.clearCallingIdentity();
6140 try {
Pengquan Mengea84e042018-09-20 14:57:26 -07006141 ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operatorInfo,
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006142 persistSelection);
Pengquan Mengea84e042018-09-20 14:57:26 -07006143 if (DBG) {
6144 log("setNetworkSelectionModeManual: subId: " + subId
6145 + " operator: " + operatorInfo);
6146 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006147 return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
6148 } finally {
6149 Binder.restoreCallingIdentity(identity);
6150 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07006151 }
shilu84f6e8b2019-12-19 13:58:01 -08006152 /**
6153 * Get the manual network selection
6154 *
6155 * @param subId the id of the subscription.
6156 *
6157 * @return the previously saved user selected PLMN
6158 */
6159 @Override
6160 public String getManualNetworkSelectionPlmn(int subId) {
6161 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07006162 .enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
shilu84f6e8b2019-12-19 13:58:01 -08006163 mApp, subId, "getManualNetworkSelectionPlmn");
6164
6165 final long identity = Binder.clearCallingIdentity();
6166 try {
6167 if (!isActiveSubscription(subId)) {
shilufa1c2592020-03-10 10:59:43 -07006168 throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
shilu84f6e8b2019-12-19 13:58:01 -08006169 }
6170
6171 final Phone phone = getPhone(subId);
6172 if (phone == null) {
shilufa1c2592020-03-10 10:59:43 -07006173 throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
shilu84f6e8b2019-12-19 13:58:01 -08006174 }
6175 OperatorInfo networkSelection = phone.getSavedNetworkSelection();
6176 return TextUtils.isEmpty(networkSelection.getOperatorNumeric())
6177 ? phone.getManualNetworkSelectionPlmn() : networkSelection.getOperatorNumeric();
6178 } finally {
6179 Binder.restoreCallingIdentity(identity);
6180 }
6181 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07006182
6183 /**
6184 * Scans for available networks.
6185 */
6186 @Override
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07006187 public CellNetworkScanResult getCellNetworkScanResults(int subId, String callingPackage,
6188 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006189 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6190 mApp, subId, "getCellNetworkScanResults");
Hall Liuf19c44f2018-11-27 14:38:17 -08006191 LocationAccessPolicy.LocationPermissionResult locationResult =
6192 LocationAccessPolicy.checkLocationPermission(mApp,
6193 new LocationAccessPolicy.LocationPermissionQuery.Builder()
6194 .setCallingPackage(callingPackage)
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07006195 .setCallingFeatureId(callingFeatureId)
Hall Liuf19c44f2018-11-27 14:38:17 -08006196 .setCallingPid(Binder.getCallingPid())
6197 .setCallingUid(Binder.getCallingUid())
6198 .setMethod("getCellNetworkScanResults")
6199 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
Hall Liuc4a3e422020-05-26 17:18:03 -07006200 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
6201 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
Hall Liuf19c44f2018-11-27 14:38:17 -08006202 .build());
6203 switch (locationResult) {
6204 case DENIED_HARD:
6205 throw new SecurityException("Not allowed to access scan results -- location");
6206 case DENIED_SOFT:
6207 return null;
6208 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006209
Pengquan Menga1bb6272018-09-06 09:59:22 -07006210 long identity = Binder.clearCallingIdentity();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006211 try {
6212 if (DBG) log("getCellNetworkScanResults: subId " + subId);
Pengquan Menga1bb6272018-09-06 09:59:22 -07006213 return (CellNetworkScanResult) sendRequest(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006214 CMD_PERFORM_NETWORK_SCAN, null, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006215 } finally {
6216 Binder.restoreCallingIdentity(identity);
6217 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07006218 }
6219
6220 /**
Shuo Qian4a594052020-01-23 11:59:30 -08006221 * Get the call forwarding info, given the call forwarding reason.
6222 */
6223 @Override
Hall Liu27d24262020-09-18 19:04:59 -07006224 public void getCallForwarding(int subId, int callForwardingReason,
6225 ICallForwardingInfoCallback callback) {
Shuo Qian4a594052020-01-23 11:59:30 -08006226 enforceReadPrivilegedPermission("getCallForwarding");
6227 long identity = Binder.clearCallingIdentity();
6228 try {
6229 if (DBG) {
6230 log("getCallForwarding: subId " + subId
6231 + " callForwardingReason" + callForwardingReason);
6232 }
Hall Liu27d24262020-09-18 19:04:59 -07006233
6234 Phone phone = getPhone(subId);
6235 if (phone == null) {
6236 try {
Hall Liu940c4ca2020-09-29 17:10:18 -07006237 callback.onError(
6238 TelephonyManager.CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN);
Hall Liu27d24262020-09-18 19:04:59 -07006239 } catch (RemoteException e) {
6240 // ignore
6241 }
6242 return;
6243 }
6244
6245 Pair<Integer, TelephonyManager.CallForwardingInfoCallback> argument = Pair.create(
6246 callForwardingReason, new TelephonyManager.CallForwardingInfoCallback() {
6247 @Override
6248 public void onCallForwardingInfoAvailable(CallForwardingInfo info) {
6249 try {
6250 callback.onCallForwardingInfoAvailable(info);
6251 } catch (RemoteException e) {
6252 // ignore
6253 }
6254 }
6255
6256 @Override
6257 public void onError(int error) {
6258 try {
6259 callback.onError(error);
6260 } catch (RemoteException e) {
6261 // ignore
6262 }
6263 }
6264 });
6265 sendRequestAsync(CMD_GET_CALL_FORWARDING, argument, phone, null);
Shuo Qian4a594052020-01-23 11:59:30 -08006266 } finally {
6267 Binder.restoreCallingIdentity(identity);
6268 }
6269 }
6270
6271 /**
6272 * Sets the voice call forwarding info including status (enable/disable), call forwarding
6273 * reason, the number to forward, and the timeout before the forwarding is attempted.
6274 */
6275 @Override
Hall Liu27d24262020-09-18 19:04:59 -07006276 public void setCallForwarding(int subId, CallForwardingInfo callForwardingInfo,
6277 IIntegerConsumer callback) {
Shuo Qian4a594052020-01-23 11:59:30 -08006278 enforceModifyPermission();
6279 long identity = Binder.clearCallingIdentity();
6280 try {
6281 if (DBG) {
6282 log("setCallForwarding: subId " + subId
6283 + " callForwardingInfo" + callForwardingInfo);
6284 }
Hall Liu27d24262020-09-18 19:04:59 -07006285
6286 Phone phone = getPhone(subId);
6287 if (phone == null) {
6288 try {
Hall Liu940c4ca2020-09-29 17:10:18 -07006289 callback.accept(
6290 TelephonyManager.CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN);
Hall Liu27d24262020-09-18 19:04:59 -07006291 } catch (RemoteException e) {
6292 // ignore
6293 }
6294 return;
6295 }
6296
6297 Pair<CallForwardingInfo, Consumer<Integer>> arguments = Pair.create(callForwardingInfo,
6298 FunctionalUtils.ignoreRemoteException(callback::accept));
6299
6300 sendRequestAsync(CMD_SET_CALL_FORWARDING, arguments, phone, null);
Shuo Qian4a594052020-01-23 11:59:30 -08006301 } finally {
6302 Binder.restoreCallingIdentity(identity);
6303 }
6304 }
6305
6306 /**
Hall Liu27d24262020-09-18 19:04:59 -07006307 * Get the call waiting status for a subId.
Shuo Qian4a594052020-01-23 11:59:30 -08006308 */
6309 @Override
Hall Liu27d24262020-09-18 19:04:59 -07006310 public void getCallWaitingStatus(int subId, IIntegerConsumer callback) {
SongFerngWang0e767992021-03-31 22:08:45 +08006311 enforceReadPrivilegedPermission("getCallWaitingStatus");
Shuo Qian4a594052020-01-23 11:59:30 -08006312 long identity = Binder.clearCallingIdentity();
6313 try {
Hall Liu27d24262020-09-18 19:04:59 -07006314 Phone phone = getPhone(subId);
6315 if (phone == null) {
6316 try {
6317 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
6318 } catch (RemoteException e) {
6319 // ignore
6320 }
6321 return;
6322 }
SongFerngWang0e767992021-03-31 22:08:45 +08006323 CarrierConfigManager configManager = new CarrierConfigManager(phone.getContext());
6324 PersistableBundle c = configManager.getConfigForSubId(subId);
6325 boolean requireUssd = c.getBoolean(
6326 CarrierConfigManager.KEY_USE_CALL_WAITING_USSD_BOOL, false);
Hall Liu27d24262020-09-18 19:04:59 -07006327
Shuo Qian4a594052020-01-23 11:59:30 -08006328 if (DBG) log("getCallWaitingStatus: subId " + subId);
SongFerngWang0e767992021-03-31 22:08:45 +08006329 if (requireUssd) {
6330 CarrierXmlParser carrierXmlParser = new CarrierXmlParser(phone.getContext(),
6331 getSubscriptionCarrierId(subId));
6332 String newUssdCommand = "";
6333 try {
6334 newUssdCommand = carrierXmlParser.getFeature(
6335 CarrierXmlParser.FEATURE_CALL_WAITING)
6336 .makeCommand(CarrierXmlParser.SsEntry.SSAction.QUERY, null);
6337 } catch (NullPointerException e) {
6338 loge("Failed to generate USSD number" + e);
6339 }
6340 ResultReceiver wrappedCallback = new CallWaitingUssdResultReceiver(
6341 mMainThreadHandler, callback, carrierXmlParser,
6342 CarrierXmlParser.SsEntry.SSAction.QUERY);
6343 final String ussdCommand = newUssdCommand;
6344 Executors.newSingleThreadExecutor().execute(() -> {
6345 handleUssdRequest(subId, ussdCommand, wrappedCallback);
6346 });
6347 } else {
6348 Consumer<Integer> argument = FunctionalUtils.ignoreRemoteException(
6349 callback::accept);
6350 sendRequestAsync(CMD_GET_CALL_WAITING, argument, phone, null);
6351 }
Shuo Qian4a594052020-01-23 11:59:30 -08006352 } finally {
6353 Binder.restoreCallingIdentity(identity);
6354 }
6355 }
6356
6357 /**
Hall Liu27d24262020-09-18 19:04:59 -07006358 * Sets whether call waiting is enabled for a given subId.
Shuo Qian4a594052020-01-23 11:59:30 -08006359 */
6360 @Override
Hall Liu27d24262020-09-18 19:04:59 -07006361 public void setCallWaitingStatus(int subId, boolean enable, IIntegerConsumer callback) {
Shuo Qian4a594052020-01-23 11:59:30 -08006362 enforceModifyPermission();
6363 long identity = Binder.clearCallingIdentity();
6364 try {
Hall Liu27d24262020-09-18 19:04:59 -07006365 if (DBG) log("setCallWaitingStatus: subId " + subId + " enable: " + enable);
6366
6367 Phone phone = getPhone(subId);
6368 if (phone == null) {
6369 try {
6370 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
6371 } catch (RemoteException e) {
6372 // ignore
6373 }
6374 return;
6375 }
6376
SongFerngWang0e767992021-03-31 22:08:45 +08006377 CarrierConfigManager configManager = new CarrierConfigManager(phone.getContext());
6378 PersistableBundle c = configManager.getConfigForSubId(subId);
6379 boolean requireUssd = c.getBoolean(
6380 CarrierConfigManager.KEY_USE_CALL_WAITING_USSD_BOOL, false);
Hall Liu27d24262020-09-18 19:04:59 -07006381
SongFerngWang0e767992021-03-31 22:08:45 +08006382 if (DBG) log("getCallWaitingStatus: subId " + subId);
6383 if (requireUssd) {
6384 CarrierXmlParser carrierXmlParser = new CarrierXmlParser(phone.getContext(),
6385 getSubscriptionCarrierId(subId));
6386 CarrierXmlParser.SsEntry.SSAction ssAction =
6387 enable ? CarrierXmlParser.SsEntry.SSAction.UPDATE_ACTIVATE
6388 : CarrierXmlParser.SsEntry.SSAction.UPDATE_DEACTIVATE;
6389 String newUssdCommand = "";
6390 try {
6391 newUssdCommand = carrierXmlParser.getFeature(
6392 CarrierXmlParser.FEATURE_CALL_WAITING)
6393 .makeCommand(ssAction, null);
6394 } catch (NullPointerException e) {
6395 loge("Failed to generate USSD number" + e);
6396 }
6397 ResultReceiver wrappedCallback = new CallWaitingUssdResultReceiver(
6398 mMainThreadHandler, callback, carrierXmlParser, ssAction);
6399 final String ussdCommand = newUssdCommand;
6400 Executors.newSingleThreadExecutor().execute(() -> {
6401 handleUssdRequest(subId, ussdCommand, wrappedCallback);
6402 });
6403 } else {
6404 Pair<Boolean, Consumer<Integer>> arguments = Pair.create(enable,
6405 FunctionalUtils.ignoreRemoteException(callback::accept));
6406
6407 sendRequestAsync(CMD_SET_CALL_WAITING, arguments, phone, null);
6408 }
Shuo Qian4a594052020-01-23 11:59:30 -08006409 } finally {
6410 Binder.restoreCallingIdentity(identity);
6411 }
6412 }
6413
6414 /**
yinxub1bed742017-04-17 11:45:04 -07006415 * Starts a new network scan and returns the id of this scan.
yinxu504e1392017-04-12 16:03:22 -07006416 *
yinxub1bed742017-04-17 11:45:04 -07006417 * @param subId id of the subscription
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08006418 * @param renounceFineLocationAccess Set this to true if the caller would not like to receive
6419 * location related information which will be sent if the caller already possess
6420 * {@android.Manifest.permission.ACCESS_FINE_LOCATION} and do not renounce the permission
yinxub1bed742017-04-17 11:45:04 -07006421 * @param request contains the radio access networks with bands/channels to scan
6422 * @param messenger callback messenger for scan results or errors
6423 * @param binder for the purpose of auto clean when the user thread crashes
yinxu504e1392017-04-12 16:03:22 -07006424 * @return the id of the requested scan which can be used to stop the scan.
6425 */
6426 @Override
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08006427 public int requestNetworkScan(int subId, boolean renounceFineLocationAccess,
6428 NetworkScanRequest request, Messenger messenger,
Philip P. Moltmann3a2772a2019-10-04 08:15:00 -07006429 IBinder binder, String callingPackage, String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006430 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6431 mApp, subId, "requestNetworkScan");
Hall Liuf19c44f2018-11-27 14:38:17 -08006432 LocationAccessPolicy.LocationPermissionResult locationResult =
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08006433 LocationAccessPolicy.LocationPermissionResult.DENIED_HARD;
6434 if (!renounceFineLocationAccess) {
6435 locationResult = LocationAccessPolicy.checkLocationPermission(mApp,
6436 new LocationAccessPolicy.LocationPermissionQuery.Builder()
6437 .setCallingPackage(callingPackage)
6438 .setCallingFeatureId(callingFeatureId)
6439 .setCallingPid(Binder.getCallingPid())
6440 .setCallingUid(Binder.getCallingUid())
6441 .setMethod("requestNetworkScan")
6442 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
6443 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
6444 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
6445 .build());
6446 }
Hall Liub2ac8ef2019-02-28 15:56:23 -08006447 if (locationResult != LocationAccessPolicy.LocationPermissionResult.ALLOWED) {
Nathan Harold1c11dba2020-09-22 17:54:53 -07006448 SecurityException e = checkNetworkRequestForSanitizedLocationAccess(
6449 request, subId, callingPackage);
Hall Liub2ac8ef2019-02-28 15:56:23 -08006450 if (e != null) {
6451 if (locationResult == LocationAccessPolicy.LocationPermissionResult.DENIED_HARD) {
6452 throw e;
6453 } else {
Hall Liu0e5abaf2019-04-04 01:25:30 -07006454 loge(e.getMessage());
Hall Liub2ac8ef2019-02-28 15:56:23 -08006455 return TelephonyScanManager.INVALID_SCAN_ID;
6456 }
6457 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006458 }
Hall Liu912dfd32019-04-25 14:02:26 -07006459 int callingUid = Binder.getCallingUid();
6460 int callingPid = Binder.getCallingPid();
Ying Xu94a46582019-04-18 17:14:56 -07006461 final long identity = Binder.clearCallingIdentity();
6462 try {
6463 return mNetworkScanRequestTracker.startNetworkScan(
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08006464 renounceFineLocationAccess, request, messenger, binder, getPhone(subId),
Hall Liu912dfd32019-04-25 14:02:26 -07006465 callingUid, callingPid, callingPackage);
Ying Xu94a46582019-04-18 17:14:56 -07006466 } finally {
6467 Binder.restoreCallingIdentity(identity);
6468 }
yinxu504e1392017-04-12 16:03:22 -07006469 }
6470
Hall Liub2ac8ef2019-02-28 15:56:23 -08006471 private SecurityException checkNetworkRequestForSanitizedLocationAccess(
Nathan Harold1c11dba2020-09-22 17:54:53 -07006472 NetworkScanRequest request, int subId, String callingPackage) {
6473 boolean hasCarrierPriv = checkCarrierPrivilegesForPackage(subId, callingPackage)
Hall Liu558027f2019-05-15 19:14:05 -07006474 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
6475 boolean hasNetworkScanPermission =
6476 mApp.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_SCAN)
6477 == PERMISSION_GRANTED;
6478
6479 if (!hasCarrierPriv && !hasNetworkScanPermission) {
6480 return new SecurityException("permission.NETWORK_SCAN or carrier privileges is needed"
6481 + " for network scans without location access.");
Hall Liub2ac8ef2019-02-28 15:56:23 -08006482 }
6483
6484 if (request.getSpecifiers() != null && request.getSpecifiers().length > 0) {
6485 for (RadioAccessSpecifier ras : request.getSpecifiers()) {
Hall Liub2ac8ef2019-02-28 15:56:23 -08006486 if (ras.getChannels() != null && ras.getChannels().length > 0) {
6487 return new SecurityException("Specific channels must not be"
6488 + " scanned without location access.");
6489 }
6490 }
6491 }
6492
Hall Liub2ac8ef2019-02-28 15:56:23 -08006493 return null;
6494 }
6495
yinxu504e1392017-04-12 16:03:22 -07006496 /**
6497 * Stops an existing network scan with the given scanId.
yinxub1bed742017-04-17 11:45:04 -07006498 *
6499 * @param subId id of the subscription
6500 * @param scanId id of the scan that needs to be stopped
yinxu504e1392017-04-12 16:03:22 -07006501 */
6502 @Override
6503 public void stopNetworkScan(int subId, int scanId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006504 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6505 mApp, subId, "stopNetworkScan");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006506
Hall Liu912dfd32019-04-25 14:02:26 -07006507 int callingUid = Binder.getCallingUid();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006508 final long identity = Binder.clearCallingIdentity();
6509 try {
Hall Liu912dfd32019-04-25 14:02:26 -07006510 mNetworkScanRequestTracker.stopNetworkScan(scanId, callingUid);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006511 } finally {
6512 Binder.restoreCallingIdentity(identity);
6513 }
yinxu504e1392017-04-12 16:03:22 -07006514 }
6515
6516 /**
SongFerngWang3ef3e072020-12-21 16:41:52 +08006517 * Get the allowed network types bitmask.
Junda Liu84d15a22014-07-02 11:21:04 -07006518 *
SongFerngWang3ef3e072020-12-21 16:41:52 +08006519 * @return the allowed network types bitmask, defined in RILConstants.java.
Junda Liu84d15a22014-07-02 11:21:04 -07006520 */
6521 @Override
SongFerngWang3ef3e072020-12-21 16:41:52 +08006522 public int getAllowedNetworkTypesBitmask(int subId) {
Pengquan Menga4009cb2018-12-20 11:00:24 -08006523 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07006524 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
SongFerngWang3ef3e072020-12-21 16:41:52 +08006525 mApp, subId, "getAllowedNetworkTypesBitmask");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006526
6527 final long identity = Binder.clearCallingIdentity();
6528 try {
SongFerngWang3ef3e072020-12-21 16:41:52 +08006529 if (DBG) log("getAllowedNetworkTypesBitmask");
6530 int[] result = (int[]) sendRequest(CMD_GET_ALLOWED_NETWORK_TYPES_BITMASK, null, subId);
6531 int networkTypesBitmask = (result != null ? result[0] : -1);
6532 if (DBG) log("getAllowedNetworkTypesBitmask: " + networkTypesBitmask);
6533 return networkTypesBitmask;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006534 } finally {
6535 Binder.restoreCallingIdentity(identity);
6536 }
Jake Hamby7c27be32014-03-03 13:25:59 -08006537 }
6538
6539 /**
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07006540 * Get the allowed network types for certain reason.
6541 *
6542 * @param subId the id of the subscription.
6543 * @param reason the reason the allowed network type change is taking place
6544 * @return the allowed network types.
6545 */
6546 @Override
6547 public long getAllowedNetworkTypesForReason(int subId,
6548 @TelephonyManager.AllowedNetworkTypesReason int reason) {
Nathan Harold62c68512021-04-06 11:26:02 -07006549 TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
SongFerngWang8c6e82e2021-03-02 22:09:29 +08006550 mApp, subId, "getAllowedNetworkTypesForReason");
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07006551 final long identity = Binder.clearCallingIdentity();
6552 try {
6553 return getPhoneFromSubId(subId).getAllowedNetworkTypes(reason);
6554 } finally {
6555 Binder.restoreCallingIdentity(identity);
6556 }
6557 }
6558
6559 /**
Sooraj Sasindran37444802020-08-11 10:40:43 -07006560 * Enable/Disable E-UTRA-NR Dual Connectivity
6561 * @param subId subscription id of the sim card
6562 * @param nrDualConnectivityState expected NR dual connectivity state
6563 * This can be passed following states
6564 * <ol>
6565 * <li>Enable NR dual connectivity {@link TelephonyManager#NR_DUAL_CONNECTIVITY_ENABLE}
6566 * <li>Disable NR dual connectivity {@link TelephonyManager#NR_DUAL_CONNECTIVITY_DISABLE}
6567 * <li>Disable NR dual connectivity and force secondary cell to be released
6568 * {@link TelephonyManager#NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE}
6569 * </ol>
6570 * @return operation result.
6571 */
6572 @Override
6573 public int setNrDualConnectivityState(int subId,
6574 @TelephonyManager.NrDualConnectivityState int nrDualConnectivityState) {
6575 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6576 mApp, subId, "enableNRDualConnectivity");
Sooraj Sasindran0e4e00a2021-03-16 18:02:32 -07006577 if (!isRadioInterfaceCapabilitySupported(
Sooraj Sasindrandfd595b2021-03-11 17:38:13 -08006578 TelephonyManager.CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE)) {
6579 return TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED;
6580 }
6581
Sooraj Sasindran37444802020-08-11 10:40:43 -07006582 WorkSource workSource = getWorkSource(Binder.getCallingUid());
6583 final long identity = Binder.clearCallingIdentity();
6584 try {
6585 int result = (int) sendRequest(CMD_ENABLE_NR_DUAL_CONNECTIVITY,
6586 nrDualConnectivityState, subId,
6587 workSource);
6588 if (DBG) log("enableNRDualConnectivity result: " + result);
6589 return result;
6590 } finally {
6591 Binder.restoreCallingIdentity(identity);
6592 }
6593 }
6594
6595 /**
6596 * Is E-UTRA-NR Dual Connectivity enabled
6597 * @return true if dual connectivity is enabled else false
6598 */
6599 @Override
6600 public boolean isNrDualConnectivityEnabled(int subId) {
6601 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07006602 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Sooraj Sasindran37444802020-08-11 10:40:43 -07006603 mApp, subId, "isNRDualConnectivityEnabled");
Sooraj Sasindran0e4e00a2021-03-16 18:02:32 -07006604 if (!isRadioInterfaceCapabilitySupported(
Sooraj Sasindrandfd595b2021-03-11 17:38:13 -08006605 TelephonyManager.CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE)) {
6606 return false;
6607 }
Sooraj Sasindran37444802020-08-11 10:40:43 -07006608 WorkSource workSource = getWorkSource(Binder.getCallingUid());
6609 final long identity = Binder.clearCallingIdentity();
6610 try {
6611 boolean isEnabled = (boolean) sendRequest(CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED,
6612 null, subId, workSource);
6613 if (DBG) log("isNRDualConnectivityEnabled: " + isEnabled);
6614 return isEnabled;
6615 } finally {
6616 Binder.restoreCallingIdentity(identity);
6617 }
6618 }
6619
6620 /**
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07006621 * Set the allowed network types of the device and
6622 * provide the reason triggering the allowed network change.
6623 *
6624 * @param subId the id of the subscription.
6625 * @param reason the reason the allowed network type change is taking place
6626 * @param allowedNetworkTypes the allowed network types.
6627 * @return true on success; false on any failure.
6628 */
6629 @Override
6630 public boolean setAllowedNetworkTypesForReason(int subId,
SongFerngWang3ef3e072020-12-21 16:41:52 +08006631 @TelephonyManager.AllowedNetworkTypesReason int reason,
6632 @TelephonyManager.NetworkTypeBitMask long allowedNetworkTypes) {
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07006633 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6634 mApp, subId, "setAllowedNetworkTypesForReason");
SongFerngWang3ef3e072020-12-21 16:41:52 +08006635 if (!TelephonyManager.isValidAllowedNetworkTypesReason(reason)) {
SongFerngWang7ffc2732021-04-15 19:46:33 +08006636 loge("setAllowedNetworkTypesForReason: Invalid allowed network type reason: " + reason);
6637 return false;
6638 }
6639 if (!SubscriptionManager.isUsableSubscriptionId(subId)) {
6640 loge("setAllowedNetworkTypesForReason: Invalid subscriptionId:" + subId);
SongFerngWang3ef3e072020-12-21 16:41:52 +08006641 return false;
6642 }
6643
SongFerngWang8c6e82e2021-03-02 22:09:29 +08006644 log("setAllowedNetworkTypesForReason: " + reason + " value: "
6645 + TelephonyManager.convertNetworkTypeBitmaskToString(allowedNetworkTypes));
6646
6647
6648 if (allowedNetworkTypes == getPhoneFromSubId(subId).getAllowedNetworkTypes(reason)) {
6649 log("setAllowedNetworkTypesForReason: " + reason + "does not change value");
6650 return true;
SongFerngWang3ef3e072020-12-21 16:41:52 +08006651 }
SongFerngWang8c6e82e2021-03-02 22:09:29 +08006652
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07006653 final long identity = Binder.clearCallingIdentity();
6654 try {
SongFerngWang3ef3e072020-12-21 16:41:52 +08006655 Boolean success = (Boolean) sendRequest(
6656 CMD_SET_ALLOWED_NETWORK_TYPES_FOR_REASON,
6657 new Pair<Integer, Long>(reason, allowedNetworkTypes), subId);
6658
6659 if (DBG) log("setAllowedNetworkTypesForReason: " + (success ? "ok" : "fail"));
6660 return success;
Sooraj Sasindranc46dfbd2020-06-03 01:06:00 -07006661 } finally {
6662 Binder.restoreCallingIdentity(identity);
6663 }
6664 }
6665
6666 /**
Miaoa84611c2019-03-15 09:21:10 +08006667 * Check whether DUN APN is required for tethering with subId.
Junda Liu475951f2014-11-07 16:45:03 -08006668 *
Miaoa84611c2019-03-15 09:21:10 +08006669 * @param subId the id of the subscription to require tethering.
Amit Mahajanfe58cdf2017-07-11 12:01:53 -07006670 * @return {@code true} if DUN APN is required for tethering.
Junda Liu475951f2014-11-07 16:45:03 -08006671 * @hide
6672 */
6673 @Override
SongFerngWangf08d8122019-11-15 14:58:44 +08006674 public boolean isTetheringApnRequiredForSubscriber(int subId) {
Shishir Agrawalc04d9752016-02-19 10:41:00 -08006675 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006676 final long identity = Binder.clearCallingIdentity();
Miaoa84611c2019-03-15 09:21:10 +08006677 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006678 try {
Miaoa84611c2019-03-15 09:21:10 +08006679 if (phone != null) {
6680 return phone.hasMatchedTetherApnSetting();
6681 } else {
6682 return false;
6683 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006684 } finally {
6685 Binder.restoreCallingIdentity(identity);
Junda Liu475951f2014-11-07 16:45:03 -08006686 }
Junda Liu475951f2014-11-07 16:45:03 -08006687 }
6688
6689 /**
Malcolm Chen964682d2017-11-28 16:20:07 -08006690 * Get the user enabled state of Mobile Data.
6691 *
6692 * TODO: remove and use isUserDataEnabled.
6693 * This can't be removed now because some vendor codes
6694 * calls through ITelephony directly while they should
6695 * use TelephonyManager.
6696 *
6697 * @return true on enabled
6698 */
6699 @Override
6700 public boolean getDataEnabled(int subId) {
6701 return isUserDataEnabled(subId);
6702 }
6703
6704 /**
6705 * Get whether mobile data is enabled per user setting.
6706 *
6707 * There are other factors deciding whether mobile data is actually enabled, but they are
6708 * not considered here. See {@link #isDataEnabled(int)} for more details.
Robert Greenwalt646120a2014-05-23 11:54:03 -07006709 *
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07006710 * Accepts either READ_BASIC_PHONE_STATE, ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE
6711 * or carrier privileges.
Robert Greenwalted86e582014-05-21 20:03:20 -07006712 *
6713 * @return {@code true} if data is enabled else {@code false}
6714 */
6715 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08006716 public boolean isUserDataEnabled(int subId) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07006717 String functionName = "isUserDataEnabled";
Robert Greenwalt646120a2014-05-23 11:54:03 -07006718 try {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07006719 try {
6720 mApp.enforceCallingOrSelfPermission(permission.READ_BASIC_PHONE_STATE,
6721 functionName);
6722 } catch (Exception e) {
6723 mApp.enforceCallingOrSelfPermission(permission.ACCESS_NETWORK_STATE, functionName);
6724 }
Robert Greenwalt646120a2014-05-23 11:54:03 -07006725 } catch (Exception e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08006726 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07006727 mApp, subId, functionName);
6728
Robert Greenwalt646120a2014-05-23 11:54:03 -07006729 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006730
6731 final long identity = Binder.clearCallingIdentity();
6732 try {
6733 int phoneId = mSubscriptionController.getPhoneId(subId);
6734 if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
6735 Phone phone = PhoneFactory.getPhone(phoneId);
6736 if (phone != null) {
6737 boolean retVal = phone.isUserDataEnabled();
6738 if (DBG) log("isUserDataEnabled: subId=" + subId + " retVal=" + retVal);
6739 return retVal;
6740 } else {
6741 if (DBG) loge("isUserDataEnabled: no phone subId=" + subId + " retVal=false");
6742 return false;
6743 }
6744 } finally {
6745 Binder.restoreCallingIdentity(identity);
Malcolm Chen964682d2017-11-28 16:20:07 -08006746 }
6747 }
6748
6749 /**
Shuo Qian8ee4e882020-01-08 14:30:06 -08006750 * Checks if the device is capable of mobile data by considering whether whether the
6751 * user has enabled mobile data, whether the carrier has enabled mobile data, and
6752 * whether the network policy allows data connections.
Malcolm Chen964682d2017-11-28 16:20:07 -08006753 *
Shuo Qian8ee4e882020-01-08 14:30:06 -08006754 * @return {@code true} if the overall data connection is capable; {@code false} if not.
Malcolm Chen964682d2017-11-28 16:20:07 -08006755 */
6756 @Override
6757 public boolean isDataEnabled(int subId) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07006758 String functionName = "isDataEnabled";
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006759 try {
6760 try {
6761 mApp.enforceCallingOrSelfPermission(
6762 android.Manifest.permission.ACCESS_NETWORK_STATE,
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07006763 functionName);
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006764 } catch (Exception e) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07006765 try {
6766 mApp.enforceCallingOrSelfPermission(
6767 android.Manifest.permission.READ_PHONE_STATE,
6768 functionName);
6769 } catch (Exception e2) {
6770 mApp.enforceCallingOrSelfPermission(
6771 permission.READ_BASIC_PHONE_STATE, functionName);
6772 }
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006773 }
6774 } catch (Exception e) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07006775 enforceReadPrivilegedPermission(functionName);
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006776 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006777
6778 final long identity = Binder.clearCallingIdentity();
6779 try {
6780 int phoneId = mSubscriptionController.getPhoneId(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006781 Phone phone = PhoneFactory.getPhone(phoneId);
6782 if (phone != null) {
Jack Yu4ad64e52021-12-03 14:23:53 -08006783 boolean retVal;
6784 if (phone.isUsingNewDataStack()) {
6785 retVal = phone.getDataNetworkController().getDataSettingsManager()
6786 .isDataEnabled();
6787 } else {
6788 retVal = phone.getDataEnabledSettings().isDataEnabled();
6789 }
6790 if (DBG) log("isDataEnabled: " + retVal + ", subId=" + subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08006791 return retVal;
6792 } else {
6793 if (DBG) loge("isDataEnabled: no phone subId=" + subId + " retVal=false");
6794 return false;
6795 }
6796 } finally {
6797 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08006798 }
Robert Greenwalted86e582014-05-21 20:03:20 -07006799 }
Shishir Agrawal60f9c952014-06-23 12:00:43 -07006800
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006801 /**
6802 * Check if data is enabled for a specific reason
6803 * @param subId Subscription index
6804 * @param reason the reason the data enable change is taking place
6805 * @return {@code true} if the overall data is enabled; {@code false} if not.
6806 */
6807 @Override
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006808 public boolean isDataEnabledForReason(int subId,
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006809 @TelephonyManager.DataEnabledReason int reason) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07006810 String functionName = "isDataEnabledForReason";
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006811 try {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07006812 try {
6813 mApp.enforceCallingOrSelfPermission(
6814 android.Manifest.permission.ACCESS_NETWORK_STATE,
6815 functionName);
6816 } catch (Exception e) {
6817 mApp.enforceCallingOrSelfPermission(permission.READ_BASIC_PHONE_STATE,
6818 functionName);
6819 }
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006820 } catch (Exception e) {
Sooraj Sasindran0d909a02021-11-08 12:01:16 -08006821 try {
6822 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE,
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07006823 functionName);
Sooraj Sasindran0d909a02021-11-08 12:01:16 -08006824 } catch (Exception e2) {
6825 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07006826 mApp, subId, functionName);
Sooraj Sasindran0d909a02021-11-08 12:01:16 -08006827 }
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006828 }
6829
6830
6831 final long identity = Binder.clearCallingIdentity();
6832 try {
6833 int phoneId = mSubscriptionController.getPhoneId(subId);
6834 if (DBG) {
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006835 log("isDataEnabledForReason: subId=" + subId + " phoneId=" + phoneId
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006836 + " reason=" + reason);
6837 }
6838 Phone phone = PhoneFactory.getPhone(phoneId);
6839 if (phone != null) {
6840 boolean retVal;
Jack Yu99e87332021-12-17 23:14:15 -08006841 if (phone.isUsingNewDataStack()) {
6842 retVal = phone.getDataSettingsManager().isDataEnabledForReason(reason);
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006843 } else {
Jack Yu99e87332021-12-17 23:14:15 -08006844 if (reason == TelephonyManager.DATA_ENABLED_REASON_USER) {
6845 retVal = phone.isUserDataEnabled();
6846 } else {
6847 retVal = phone.getDataEnabledSettings().isDataEnabledForReason(reason);
6848 }
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006849 }
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006850 if (DBG) log("isDataEnabledForReason: retVal=" + retVal);
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006851 return retVal;
6852 } else {
6853 if (DBG) {
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07006854 loge("isDataEnabledForReason: no phone subId="
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00006855 + subId + " retVal=false");
6856 }
6857 return false;
6858 }
6859 } finally {
6860 Binder.restoreCallingIdentity(identity);
6861 }
6862 }
6863
Malcolm Chendf0b4cc2020-02-24 15:12:43 -08006864 private int getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, int uid,
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006865 Phone phone) {
Sarah Chin3394efe2021-04-09 10:37:15 -07006866 if (uid == Process.PHONE_UID) {
6867 // Skip the check if it's the phone UID (system UID removed in b/184713596)
6868 // TODO (b/184954344): Check for system/phone UID at call site instead of here
Hall Liu54a2a0c2020-07-13 12:13:03 -07006869 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
6870 }
6871
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006872 //load access rules from carrier configs, and check those as well: b/139133814
6873 SubscriptionController subController = SubscriptionController.getInstance();
6874 if (privilegeFromSim == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
6875 || subController == null) return privilegeFromSim;
6876
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006877 PackageManager pkgMgr = phone.getContext().getPackageManager();
6878 String[] packages = pkgMgr.getPackagesForUid(uid);
6879
6880 final long identity = Binder.clearCallingIdentity();
6881 try {
Jeff Davidson8ab02b22020-03-28 12:24:40 -07006882 int subId = phone.getSubId();
6883 if (mCarrierPrivilegeTestOverrideSubIds.contains(subId)) {
6884 // A test override is in place for the privileges for this subId, so don't try to
6885 // read the subscription privileges.
6886 return privilegeFromSim;
6887 }
6888 SubscriptionInfo subInfo = subController.getSubscriptionInfo(subId);
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006889 SubscriptionManager subManager = (SubscriptionManager)
6890 phone.getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
6891 for (String pkg : packages) {
6892 if (subManager.canManageSubscription(subInfo, pkg)) {
6893 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
6894 }
6895 }
6896 return privilegeFromSim;
6897 } finally {
6898 Binder.restoreCallingIdentity(identity);
6899 }
6900 }
6901
6902 private int getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, Phone phone,
6903 String pkgName) {
6904 //load access rules from carrier configs, and check those as well: b/139133814
6905 SubscriptionController subController = SubscriptionController.getInstance();
6906 if (privilegeFromSim == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
6907 || subController == null) return privilegeFromSim;
6908
6909 final long identity = Binder.clearCallingIdentity();
6910 try {
Jeff Davidson8ab02b22020-03-28 12:24:40 -07006911 int subId = phone.getSubId();
6912 if (mCarrierPrivilegeTestOverrideSubIds.contains(subId)) {
6913 // A test override is in place for the privileges for this subId, so don't try to
6914 // read the subscription privileges.
6915 return privilegeFromSim;
6916 }
6917 SubscriptionInfo subInfo = subController.getSubscriptionInfo(subId);
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006918 SubscriptionManager subManager = (SubscriptionManager)
6919 phone.getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
6920 return subManager.canManageSubscription(subInfo, pkgName)
6921 ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS : privilegeFromSim;
6922 } finally {
6923 Binder.restoreCallingIdentity(identity);
6924 }
6925 }
6926
Shishir Agrawal60f9c952014-06-23 12:00:43 -07006927 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08006928 public int getCarrierPrivilegeStatus(int subId) {
6929 final Phone phone = getPhone(subId);
6930 if (phone == null) {
6931 loge("getCarrierPrivilegeStatus: Invalid subId");
6932 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
6933 }
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00006934 UiccPort port = UiccController.getInstance().getUiccPort(phone.getPhoneId());
6935 if (port == null) {
Shishir Agrawal5e5becd2014-11-18 11:38:23 -08006936 loge("getCarrierPrivilegeStatus: No UICC");
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07006937 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
6938 }
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006939
6940 return getCarrierPrivilegeStatusFromCarrierConfigRules(
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00006941 port.getCarrierPrivilegeStatusForCurrentTransaction(
Malcolm Chendf0b4cc2020-02-24 15:12:43 -08006942 phone.getContext().getPackageManager()), Binder.getCallingUid(), phone);
Shishir Agrawal60f9c952014-06-23 12:00:43 -07006943 }
Junda Liu29340342014-07-10 15:23:27 -07006944
6945 @Override
Jeff Davidson7e17e312018-02-13 18:17:36 -08006946 public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08006947 enforceReadPrivilegedPermission("getCarrierPrivilegeStatusForUid");
Jeff Davidson7e17e312018-02-13 18:17:36 -08006948 final Phone phone = getPhone(subId);
6949 if (phone == null) {
Taesu Leef8fbed92019-10-07 18:47:02 +09006950 loge("getCarrierPrivilegeStatusForUid: Invalid subId");
Jeff Davidson7e17e312018-02-13 18:17:36 -08006951 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
6952 }
6953 UiccProfile profile =
6954 UiccController.getInstance().getUiccProfileForPhone(phone.getPhoneId());
6955 if (profile == null) {
Taesu Leef8fbed92019-10-07 18:47:02 +09006956 loge("getCarrierPrivilegeStatusForUid: No UICC");
Jeff Davidson7e17e312018-02-13 18:17:36 -08006957 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
6958 }
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006959 return getCarrierPrivilegeStatusFromCarrierConfigRules(
Shuo Qian2c0ae432019-12-05 11:40:37 -08006960 profile.getCarrierPrivilegeStatusForUid(
Malcolm Chendf0b4cc2020-02-24 15:12:43 -08006961 phone.getContext().getPackageManager(), uid), uid, phone);
Jeff Davidson7e17e312018-02-13 18:17:36 -08006962 }
6963
6964 @Override
chen xuf7e9fe82019-05-09 19:31:02 -07006965 public int checkCarrierPrivilegesForPackage(int subId, String pkgName) {
Nazanin1adf4562021-03-29 15:35:30 -07006966 enforceReadPrivilegedPermission("checkCarrierPrivilegesForPackage");
chen xuf7e9fe82019-05-09 19:31:02 -07006967 if (TextUtils.isEmpty(pkgName)) {
Junda Liu317d70b2016-03-08 09:33:53 -08006968 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
chen xuf7e9fe82019-05-09 19:31:02 -07006969 }
6970
6971 int phoneId = SubscriptionManager.getPhoneId(subId);
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00006972 UiccPort port = UiccController.getInstance().getUiccPort(phoneId);
6973 if (port == null) {
chen xuf7e9fe82019-05-09 19:31:02 -07006974 loge("checkCarrierPrivilegesForPackage: No UICC on subId " + subId);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07006975 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
6976 }
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006977 return getCarrierPrivilegeStatusFromCarrierConfigRules(
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00006978 port.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName),
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006979 getPhone(phoneId), pkgName);
Zach Johnson50ecba32015-05-19 00:24:21 -07006980 }
6981
6982 @Override
6983 public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
Sarah Chinfc3169b2021-04-28 20:21:03 -07006984 // TODO(b/186774706): Remove @RequiresPermission from TelephonyManager API
Junda Liu317d70b2016-03-08 09:33:53 -08006985 if (TextUtils.isEmpty(pkgName))
6986 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Zach Johnson50ecba32015-05-19 00:24:21 -07006987 int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
6988 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00006989 UiccPort port = UiccController.getInstance().getUiccPort(i);
6990 if (port == null) {
Jonathan Basseri7d320df2015-06-16 12:17:08 -07006991 // No UICC in that slot.
Zach Johnson50ecba32015-05-19 00:24:21 -07006992 continue;
6993 }
6994
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006995 result = getCarrierPrivilegeStatusFromCarrierConfigRules(
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00006996 port.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName),
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07006997 getPhone(i), pkgName);
Zach Johnson50ecba32015-05-19 00:24:21 -07006998 if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
6999 break;
7000 }
7001 }
7002
7003 return result;
Junda Liu29340342014-07-10 15:23:27 -07007004 }
Derek Tan89e89d42014-07-08 17:00:10 -07007005
7006 @Override
Junda Liue64de782015-04-16 17:19:16 -07007007 public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
Nazanin1adf4562021-03-29 15:35:30 -07007008 enforceReadPrivilegedPermission("getCarrierPackageNamesForIntentAndPhone");
Junda Liue64de782015-04-16 17:19:16 -07007009 if (!SubscriptionManager.isValidPhoneId(phoneId)) {
7010 loge("phoneId " + phoneId + " is not valid.");
7011 return null;
7012 }
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00007013 UiccPort port = UiccController.getInstance().getUiccPort(phoneId);
7014 if (port == null) {
Taesu Leef8fbed92019-10-07 18:47:02 +09007015 loge("getCarrierPackageNamesForIntentAndPhone: No UICC");
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07007016 return null ;
7017 }
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00007018 return port.getCarrierPackageNamesForIntent(mApp.getPackageManager(), intent);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07007019 }
7020
Amith Yamasani6e118872016-02-19 12:53:51 -08007021 @Override
chen xuf7e9fe82019-05-09 19:31:02 -07007022 public List<String> getPackagesWithCarrierPrivileges(int phoneId) {
Nazanin1adf4562021-03-29 15:35:30 -07007023 enforceReadPrivilegedPermission("getPackagesWithCarrierPrivileges");
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007024 PackageManager pm = mApp.getPackageManager();
Amith Yamasani6e118872016-02-19 12:53:51 -08007025 List<String> privilegedPackages = new ArrayList<>();
7026 List<PackageInfo> packages = null;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00007027 UiccPort port = UiccController.getInstance().getUiccPort(phoneId);
chen xuf7e9fe82019-05-09 19:31:02 -07007028 // has UICC in that slot.
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00007029 if (port != null) {
7030 if (port.hasCarrierPrivilegeRules()) {
Amith Yamasani6e118872016-02-19 12:53:51 -08007031 if (packages == null) {
7032 // Only check packages in user 0 for now
7033 packages = pm.getInstalledPackagesAsUser(
Nazanin Bakhshi5d0636e2019-08-19 16:29:37 -07007034 PackageManager.MATCH_DISABLED_COMPONENTS
7035 | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
Cheonho Park17089c62019-08-01 15:23:12 +09007036 | PackageManager.GET_SIGNING_CERTIFICATES,
Amit Mahajanb8f13202020-01-27 18:16:07 -08007037 UserHandle.SYSTEM.getIdentifier());
Amith Yamasani6e118872016-02-19 12:53:51 -08007038 }
7039 for (int p = packages.size() - 1; p >= 0; p--) {
7040 PackageInfo pkgInfo = packages.get(p);
7041 if (pkgInfo != null && pkgInfo.packageName != null
Sooraj Sasindran97bce6f2021-09-28 21:37:29 +00007042 && getCarrierPrivilegeStatusFromCarrierConfigRules(
7043 port.getCarrierPrivilegeStatus(pkgInfo),
7044 getPhone(phoneId), pkgInfo.packageName)
chen xuf7e9fe82019-05-09 19:31:02 -07007045 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
Amith Yamasani6e118872016-02-19 12:53:51 -08007046 privilegedPackages.add(pkgInfo.packageName);
7047 }
7048 }
7049 }
7050 }
7051 return privilegedPackages;
7052 }
7053
chen xuf7e9fe82019-05-09 19:31:02 -07007054 @Override
7055 public List<String> getPackagesWithCarrierPrivilegesForAllPhones() {
Shuo Qian067a06d2019-12-03 23:40:18 +00007056 enforceReadPrivilegedPermission("getPackagesWithCarrierPrivilegesForAllPhones");
7057
7058 final long identity = Binder.clearCallingIdentity();
7059
chen xuf7e9fe82019-05-09 19:31:02 -07007060 List<String> privilegedPackages = new ArrayList<>();
Shuo Qian067a06d2019-12-03 23:40:18 +00007061 try {
7062 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
7063 privilegedPackages.addAll(getPackagesWithCarrierPrivileges(i));
7064 }
7065 } finally {
7066 Binder.restoreCallingIdentity(identity);
chen xuf7e9fe82019-05-09 19:31:02 -07007067 }
7068 return privilegedPackages;
7069 }
7070
Wink Savilleb564aae2014-10-23 10:18:09 -07007071 private String getIccId(int subId) {
Sanket Padawe356d7632015-06-22 14:03:32 -07007072 final Phone phone = getPhone(subId);
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00007073 UiccPort port = phone == null ? null : phone.getUiccPort();
7074 if (port == null) {
Derek Tan97ebb422014-09-05 16:55:38 -07007075 return null;
7076 }
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00007077 String iccId = port.getIccId();
Derek Tan97ebb422014-09-05 16:55:38 -07007078 if (TextUtils.isEmpty(iccId)) {
Derek Tan97ebb422014-09-05 16:55:38 -07007079 return null;
7080 }
7081 return iccId;
7082 }
7083
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07007084 @Override
Shuo Qiane4e11672020-12-15 22:15:33 -08007085 public void setCallComposerStatus(int subId, int status) {
7086 enforceModifyPermission();
7087
7088 final long identity = Binder.clearCallingIdentity();
7089 try {
7090 Phone phone = getPhone(subId);
7091 if (phone != null) {
7092 Phone defaultPhone = phone.getImsPhone();
7093 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
7094 ImsPhone imsPhone = (ImsPhone) defaultPhone;
7095 imsPhone.setCallComposerStatus(status);
Shuo Qian284ae752020-12-22 19:10:14 -08007096 ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
7097 .updateImsServiceConfig();
Shuo Qiane4e11672020-12-15 22:15:33 -08007098 }
7099 }
Shuo Qian284ae752020-12-22 19:10:14 -08007100 } catch (ImsException e) {
7101 throw new ServiceSpecificException(e.getCode());
7102 } finally {
Shuo Qiane4e11672020-12-15 22:15:33 -08007103 Binder.restoreCallingIdentity(identity);
7104 }
7105 }
7106
7107 @Override
7108 public int getCallComposerStatus(int subId) {
7109 enforceReadPrivilegedPermission("getCallComposerStatus");
7110
7111 final long identity = Binder.clearCallingIdentity();
7112 try {
7113 Phone phone = getPhone(subId);
7114 if (phone != null) {
7115 Phone defaultPhone = phone.getImsPhone();
7116 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
7117 ImsPhone imsPhone = (ImsPhone) defaultPhone;
7118 return imsPhone.getCallComposerStatus();
7119 }
7120 }
7121 } finally {
7122 Binder.restoreCallingIdentity(identity);
7123 }
7124 return TelephonyManager.CALL_COMPOSER_STATUS_OFF;
7125 }
7126
7127 @Override
Jeff Sharkey85190e62014-12-05 09:40:12 -08007128 public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
7129 String number) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08007130 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
Jeff Davidson7e17e312018-02-13 18:17:36 -08007131 subId, "setLine1NumberForDisplayForSubscriber");
Derek Tan97ebb422014-09-05 16:55:38 -07007132
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007133 final long identity = Binder.clearCallingIdentity();
7134 try {
7135 final String iccId = getIccId(subId);
7136 final Phone phone = getPhone(subId);
7137 if (phone == null) {
7138 return false;
7139 }
7140 final String subscriberId = phone.getSubscriberId();
7141
7142 if (DBG_MERGE) {
Amit Mahajanb8f13202020-01-27 18:16:07 -08007143 Rlog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId="
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007144 + subscriberId + " to " + number);
7145 }
7146
7147 if (TextUtils.isEmpty(iccId)) {
7148 return false;
7149 }
7150
7151 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
7152
7153 final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
7154 if (alphaTag == null) {
7155 editor.remove(alphaTagPrefKey);
7156 } else {
7157 editor.putString(alphaTagPrefKey, alphaTag);
7158 }
7159
7160 // Record both the line number and IMSI for this ICCID, since we need to
7161 // track all merged IMSIs based on line number
7162 final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
7163 final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
7164 if (number == null) {
7165 editor.remove(numberPrefKey);
7166 editor.remove(subscriberPrefKey);
7167 } else {
7168 editor.putString(numberPrefKey, number);
7169 editor.putString(subscriberPrefKey, subscriberId);
7170 }
7171
7172 editor.commit();
7173 return true;
7174 } finally {
7175 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07007176 }
Derek Tan7226c842014-07-02 17:42:23 -07007177 }
7178
7179 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007180 public String getLine1NumberForDisplay(int subId, String callingPackage,
7181 String callingFeatureId) {
Makoto Onukifee69342015-06-29 14:44:50 -07007182 // This is open to apps with WRITE_SMS.
Jeff Davidson7e17e312018-02-13 18:17:36 -08007183 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007184 mApp, subId, callingPackage, callingFeatureId, "getLine1NumberForDisplay")) {
Amit Mahajan9cf11512015-11-09 11:40:48 -08007185 if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
Svet Ganovb320e182015-04-16 12:30:10 -07007186 return null;
7187 }
Derek Tan97ebb422014-09-05 16:55:38 -07007188
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007189 final long identity = Binder.clearCallingIdentity();
7190 try {
7191 String iccId = getIccId(subId);
7192 if (iccId != null) {
7193 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
7194 if (DBG_MERGE) {
7195 log("getLine1NumberForDisplay returning "
7196 + mTelephonySharedPreferences.getString(numberPrefKey, null));
7197 }
7198 return mTelephonySharedPreferences.getString(numberPrefKey, null);
Amit Mahajan9cf11512015-11-09 11:40:48 -08007199 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007200 if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null");
7201 return null;
7202 } finally {
7203 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07007204 }
Derek Tan7226c842014-07-02 17:42:23 -07007205 }
7206
7207 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007208 public String getLine1AlphaTagForDisplay(int subId, String callingPackage,
7209 String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08007210 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007211 mApp, subId, callingPackage, callingFeatureId, "getLine1AlphaTagForDisplay")) {
Svet Ganovb320e182015-04-16 12:30:10 -07007212 return null;
7213 }
Derek Tan97ebb422014-09-05 16:55:38 -07007214
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007215 final long identity = Binder.clearCallingIdentity();
7216 try {
7217 String iccId = getIccId(subId);
7218 if (iccId != null) {
7219 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
7220 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null);
7221 }
7222 return null;
7223 } finally {
7224 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07007225 }
Derek Tan7226c842014-07-02 17:42:23 -07007226 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07007227
7228 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007229 public String[] getMergedSubscriberIds(int subId, String callingPackage,
7230 String callingFeatureId) {
Jeff Davidson913390f2018-02-23 17:11:49 -08007231 // This API isn't public, so no need to provide a valid subscription ID - we're not worried
7232 // about carrier-privileged callers not having access.
Jeff Davidson7e17e312018-02-13 18:17:36 -08007233 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08007234 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007235 callingFeatureId, "getMergedSubscriberIds")) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07007236 return null;
7237 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08007238
Jordan Liub49b04b2019-05-06 14:45:15 -07007239 // Clear calling identity, when calling TelephonyManager, because callerUid must be
7240 // the process, where TelephonyManager was instantiated.
7241 // Otherwise AppOps check will fail.
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07007242 final long identity = Binder.clearCallingIdentity();
7243 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007244 final Context context = mApp;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007245 final TelephonyManager tele = TelephonyManager.from(context);
7246 final SubscriptionManager sub = SubscriptionManager.from(context);
7247
7248 // Figure out what subscribers are currently active
7249 final ArraySet<String> activeSubscriberIds = new ArraySet<>();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007250
Jordan Liub49b04b2019-05-06 14:45:15 -07007251 // Only consider subs which match the current subId
7252 // This logic can be simplified. See b/131189269 for progress.
7253 if (isActiveSubscription(subId)) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07007254 activeSubscriberIds.add(tele.getSubscriberId(subId));
7255 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007256
7257 // First pass, find a number override for an active subscriber
7258 String mergeNumber = null;
7259 final Map<String, ?> prefs = mTelephonySharedPreferences.getAll();
7260 for (String key : prefs.keySet()) {
7261 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) {
7262 final String subscriberId = (String) prefs.get(key);
7263 if (activeSubscriberIds.contains(subscriberId)) {
7264 final String iccId = key.substring(
7265 PREF_CARRIERS_SUBSCRIBER_PREFIX.length());
7266 final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
7267 mergeNumber = (String) prefs.get(numberKey);
7268 if (DBG_MERGE) {
Amit Mahajanb8f13202020-01-27 18:16:07 -08007269 Rlog.d(LOG_TAG, "Found line number " + mergeNumber
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007270 + " for active subscriber " + subscriberId);
7271 }
7272 if (!TextUtils.isEmpty(mergeNumber)) {
7273 break;
7274 }
7275 }
7276 }
7277 }
7278
7279 // Shortcut when no active merged subscribers
7280 if (TextUtils.isEmpty(mergeNumber)) {
7281 return null;
7282 }
7283
7284 // Second pass, find all subscribers under that line override
7285 final ArraySet<String> result = new ArraySet<>();
7286 for (String key : prefs.keySet()) {
7287 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) {
7288 final String number = (String) prefs.get(key);
7289 if (mergeNumber.equals(number)) {
7290 final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length());
7291 final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
7292 final String subscriberId = (String) prefs.get(subscriberKey);
7293 if (!TextUtils.isEmpty(subscriberId)) {
7294 result.add(subscriberId);
7295 }
7296 }
7297 }
7298 }
7299
7300 final String[] resultArray = result.toArray(new String[result.size()]);
7301 Arrays.sort(resultArray);
7302 if (DBG_MERGE) {
Amit Mahajanb8f13202020-01-27 18:16:07 -08007303 Rlog.d(LOG_TAG,
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007304 "Found subscribers " + Arrays.toString(resultArray) + " after merge");
7305 }
7306 return resultArray;
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07007307 } finally {
7308 Binder.restoreCallingIdentity(identity);
Jeff Sharkey85190e62014-12-05 09:40:12 -08007309 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08007310 }
7311
7312 @Override
zoey chen38003472019-12-13 17:16:31 +08007313 public String[] getMergedImsisFromGroup(int subId, String callingPackage) {
7314 enforceReadPrivilegedPermission("getMergedImsisFromGroup");
Malcolm Chen6ca97372019-07-01 16:28:21 -07007315
7316 final long identity = Binder.clearCallingIdentity();
7317 try {
7318 final TelephonyManager telephonyManager = mApp.getSystemService(
7319 TelephonyManager.class);
7320 String subscriberId = telephonyManager.getSubscriberId(subId);
7321 if (subscriberId == null) {
7322 if (DBG) {
zoey chen38003472019-12-13 17:16:31 +08007323 log("getMergedImsisFromGroup can't find subscriberId for subId "
Malcolm Chen6ca97372019-07-01 16:28:21 -07007324 + subId);
7325 }
7326 return null;
7327 }
7328
7329 final SubscriptionInfo info = SubscriptionController.getInstance()
7330 .getSubscriptionInfo(subId);
7331 final ParcelUuid groupUuid = info.getGroupUuid();
7332 // If it doesn't belong to any group, return just subscriberId of itself.
7333 if (groupUuid == null) {
7334 return new String[]{subscriberId};
7335 }
7336
7337 // Get all subscriberIds from the group.
7338 final List<String> mergedSubscriberIds = new ArrayList<>();
7339 final List<SubscriptionInfo> groupInfos = SubscriptionController.getInstance()
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007340 .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName(),
Philip P. Moltmann8d34f0c2020-03-05 16:24:02 -08007341 mApp.getAttributionTag());
Malcolm Chen6ca97372019-07-01 16:28:21 -07007342 for (SubscriptionInfo subInfo : groupInfos) {
7343 subscriberId = telephonyManager.getSubscriberId(subInfo.getSubscriptionId());
7344 if (subscriberId != null) {
7345 mergedSubscriberIds.add(subscriberId);
7346 }
7347 }
7348
7349 return mergedSubscriberIds.toArray(new String[mergedSubscriberIds.size()]);
7350 } finally {
7351 Binder.restoreCallingIdentity(identity);
7352
7353 }
7354 }
7355
7356 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08007357 public boolean setOperatorBrandOverride(int subId, String brand) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08007358 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
Jeff Davidson7e17e312018-02-13 18:17:36 -08007359 subId, "setOperatorBrandOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007360
7361 final long identity = Binder.clearCallingIdentity();
7362 try {
7363 final Phone phone = getPhone(subId);
7364 return phone == null ? false : phone.setOperatorBrandOverride(brand);
7365 } finally {
7366 Binder.restoreCallingIdentity(identity);
7367 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07007368 }
Steven Liu4bf01bc2014-07-17 11:05:29 -05007369
7370 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08007371 public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
Shishir Agrawal621a47c2014-12-01 10:25:09 -08007372 List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
7373 List<String> cdmaNonRoamingList) {
Shuo Qian2c0ae432019-12-05 11:40:37 -08007374 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
7375 mApp, subId, "setRoamingOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007376
7377 final long identity = Binder.clearCallingIdentity();
7378 try {
7379 final Phone phone = getPhone(subId);
7380 if (phone == null) {
7381 return false;
7382 }
7383 return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList,
7384 cdmaNonRoamingList);
7385 } finally {
7386 Binder.restoreCallingIdentity(identity);
Shishir Agrawalc04d9752016-02-19 10:41:00 -08007387 }
Shishir Agrawal621a47c2014-12-01 10:25:09 -08007388 }
7389
7390 @Override
Shuo Qian850e4d6a2018-04-25 21:02:08 +00007391 @Deprecated
7392 public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
7393 enforceModifyPermission();
7394
7395 int returnValue = 0;
7396 try {
vagdeviaf9a5b92018-08-15 16:01:53 -07007397 AsyncResult result = (AsyncResult) sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
Shuo Qian850e4d6a2018-04-25 21:02:08 +00007398 if(result.exception == null) {
7399 if (result.result != null) {
7400 byte[] responseData = (byte[])(result.result);
7401 if(responseData.length > oemResp.length) {
7402 Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +
7403 responseData.length + "bytes. Buffer Size is " +
7404 oemResp.length + "bytes.");
7405 }
7406 System.arraycopy(responseData, 0, oemResp, 0, responseData.length);
7407 returnValue = responseData.length;
7408 }
7409 } else {
7410 CommandException ex = (CommandException) result.exception;
7411 returnValue = ex.getCommandError().ordinal();
7412 if(returnValue > 0) returnValue *= -1;
7413 }
7414 } catch (RuntimeException e) {
7415 Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");
7416 returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());
7417 if(returnValue > 0) returnValue *= -1;
7418 }
7419
7420 return returnValue;
7421 }
7422
7423 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07007424 public int getRadioAccessFamily(int phoneId, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08007425 Phone phone = PhoneFactory.getPhone(phoneId);
Shuo Qiandee53402020-05-29 14:08:15 -07007426 try {
7427 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07007428 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Shuo Qiandee53402020-05-29 14:08:15 -07007429 mApp, phone.getSubId(), "getRadioAccessFamily");
7430 } catch (SecurityException e) {
7431 EventLog.writeEvent(0x534e4554, "150857259", -1, "Missing Permission");
7432 throw e;
7433 }
chen xub97461a2018-10-26 14:17:57 -07007434 int raf = RadioAccessFamily.RAF_UNKNOWN;
Jeff Davidson913390f2018-02-23 17:11:49 -08007435 if (phone == null) {
chen xub97461a2018-10-26 14:17:57 -07007436 return raf;
Jeff Davidson913390f2018-02-23 17:11:49 -08007437 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007438 final long identity = Binder.clearCallingIdentity();
7439 try {
chen xub97461a2018-10-26 14:17:57 -07007440 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07007441 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
chen xub97461a2018-10-26 14:17:57 -07007442 mApp, phone.getSubId(), "getRadioAccessFamily");
7443 raf = ProxyController.getInstance().getRadioAccessFamily(phoneId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007444 } finally {
7445 Binder.restoreCallingIdentity(identity);
7446 }
chen xub97461a2018-10-26 14:17:57 -07007447 return raf;
Wink Saville5d475dd2014-10-17 15:00:58 -07007448 }
Andrew Leedf14ead2014-10-17 14:22:52 -07007449
7450 @Override
Hall Liu82694d52020-12-11 18:22:04 -08007451 public void uploadCallComposerPicture(int subscriptionId, String callingPackage,
Hall Liue31bac62020-12-23 19:16:10 -08007452 String contentType, ParcelFileDescriptor fd, ResultReceiver callback) {
Hall Liu82694d52020-12-11 18:22:04 -08007453 try {
7454 if (!Objects.equals(mApp.getPackageManager().getPackageUid(callingPackage, 0),
7455 Binder.getCallingUid())) {
Tyler Gunnb87925a2021-06-10 14:54:27 -07007456 throw new SecurityException("Invalid package:" + callingPackage);
Hall Liu82694d52020-12-11 18:22:04 -08007457 }
7458 } catch (PackageManager.NameNotFoundException e) {
Tyler Gunnb87925a2021-06-10 14:54:27 -07007459 throw new SecurityException("Invalid package:" + callingPackage);
Hall Liu82694d52020-12-11 18:22:04 -08007460 }
7461 RoleManager rm = mApp.getSystemService(RoleManager.class);
7462 List<String> dialerRoleHolders = rm.getRoleHolders(RoleManager.ROLE_DIALER);
7463 if (!dialerRoleHolders.contains(callingPackage)) {
7464 throw new SecurityException("App must be the dialer role holder to"
7465 + " upload a call composer pic");
7466 }
7467
7468 Executors.newSingleThreadExecutor().execute(() -> {
7469 ByteArrayOutputStream output = new ByteArrayOutputStream(
7470 (int) TelephonyManager.getMaximumCallComposerPictureSize());
7471 InputStream input = new ParcelFileDescriptor.AutoCloseInputStream(fd);
7472 boolean readUntilEnd = false;
7473 int totalBytesRead = 0;
7474 byte[] buffer = new byte[16 * 1024];
7475 while (true) {
7476 int numRead;
7477 try {
7478 numRead = input.read(buffer);
7479 } catch (IOException e) {
7480 try {
7481 fd.checkError();
7482 callback.send(TelephonyManager.CallComposerException.ERROR_INPUT_CLOSED,
7483 null);
7484 } catch (IOException e1) {
7485 // This means that the other side closed explicitly with an error. If this
7486 // happens, log and ignore.
7487 loge("Remote end of call composer picture pipe closed: " + e1);
7488 }
7489 break;
7490 }
7491 if (numRead == -1) {
7492 readUntilEnd = true;
7493 break;
7494 }
7495 totalBytesRead += numRead;
7496 if (totalBytesRead > TelephonyManager.getMaximumCallComposerPictureSize()) {
7497 loge("Too many bytes read for call composer picture: " + totalBytesRead);
7498 try {
7499 input.close();
7500 } catch (IOException e) {
7501 // ignore
7502 }
7503 break;
7504 }
7505 output.write(buffer, 0, numRead);
7506 }
7507 // Generally, the remote end will close the file descriptors. The only case where we
7508 // close is above, where the picture size is too big.
7509
7510 try {
7511 fd.checkError();
7512 } catch (IOException e) {
7513 loge("Remote end for call composer closed with an error: " + e);
7514 return;
7515 }
7516
Hall Liuaa4211e2021-01-20 15:43:39 -08007517 if (!readUntilEnd) {
7518 loge("Did not finish reading entire image; aborting");
7519 return;
7520 }
Hall Liu82694d52020-12-11 18:22:04 -08007521
Hall Liuaa4211e2021-01-20 15:43:39 -08007522 ImageData imageData = new ImageData(output.toByteArray(), contentType, null);
7523 CallComposerPictureManager.getInstance(mApp, subscriptionId).handleUploadToServer(
7524 new CallComposerPictureTransfer.Factory() {},
7525 imageData,
7526 (result) -> {
7527 if (result.first != null) {
7528 ParcelUuid parcelUuid = new ParcelUuid(result.first);
7529 Bundle outputResult = new Bundle();
7530 outputResult.putParcelable(
7531 TelephonyManager.KEY_CALL_COMPOSER_PICTURE_HANDLE, parcelUuid);
7532 callback.send(TelephonyManager.CallComposerException.SUCCESS,
7533 outputResult);
7534 } else {
7535 callback.send(result.second, null);
7536 }
7537 }
7538 );
Hall Liu82694d52020-12-11 18:22:04 -08007539 });
7540 }
7541
7542 @Override
Andrew Leedf14ead2014-10-17 14:22:52 -07007543 public void enableVideoCalling(boolean enable) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007544 final Phone defaultPhone = getDefaultPhone();
Andrew Leedf14ead2014-10-17 14:22:52 -07007545 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007546
7547 final long identity = Binder.clearCallingIdentity();
7548 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007549 ImsManager.getInstance(defaultPhone.getContext(),
7550 defaultPhone.getPhoneId()).setVtSetting(enable);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007551 } finally {
7552 Binder.restoreCallingIdentity(identity);
7553 }
Andrew Leedf14ead2014-10-17 14:22:52 -07007554 }
7555
7556 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007557 public boolean isVideoCallingEnabled(String callingPackage, String callingFeatureId) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007558 final Phone defaultPhone = getDefaultPhone();
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007559 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
7560 callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
Amit Mahajan578e53d2018-03-20 16:18:38 +00007561 return false;
7562 }
Svet Ganovb320e182015-04-16 12:30:10 -07007563
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007564 final long identity = Binder.clearCallingIdentity();
7565 try {
7566 // Check the user preference and the system-level IMS setting. Even if the user has
7567 // enabled video calling, if IMS is disabled we aren't able to support video calling.
7568 // In the long run, we may instead need to check if there exists a connection service
7569 // which can support video calling.
7570 ImsManager imsManager =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007571 ImsManager.getInstance(defaultPhone.getContext(), defaultPhone.getPhoneId());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007572 return imsManager.isVtEnabledByPlatform()
7573 && imsManager.isEnhanced4gLteModeSettingEnabledByUser()
7574 && imsManager.isVtEnabledByUser();
7575 } finally {
7576 Binder.restoreCallingIdentity(identity);
7577 }
Andrew Leedf14ead2014-10-17 14:22:52 -07007578 }
Libin.Tang@motorola.comafe82642014-12-18 13:27:53 -06007579
Andrew Leea1239f22015-03-02 17:44:07 -08007580 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007581 public boolean canChangeDtmfToneLength(int subId, String callingPackage,
7582 String callingFeatureId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007583 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007584 mApp, subId, callingPackage, callingFeatureId,
7585 "isVideoCallingEnabled")) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007586 return false;
7587 }
7588
7589 final long identity = Binder.clearCallingIdentity();
7590 try {
7591 CarrierConfigManager configManager =
7592 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007593 return configManager.getConfigForSubId(subId)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007594 .getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL);
7595 } finally {
7596 Binder.restoreCallingIdentity(identity);
7597 }
Andrew Leea1239f22015-03-02 17:44:07 -08007598 }
7599
7600 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007601 public boolean isWorldPhone(int subId, String callingPackage, String callingFeatureId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007602 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007603 mApp, subId, callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007604 return false;
7605 }
7606
7607 final long identity = Binder.clearCallingIdentity();
7608 try {
7609 CarrierConfigManager configManager =
7610 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007611 return configManager.getConfigForSubId(subId)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007612 .getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL);
7613 } finally {
7614 Binder.restoreCallingIdentity(identity);
7615 }
Andrew Leea1239f22015-03-02 17:44:07 -08007616 }
7617
Andrew Lee9431b832015-03-09 18:46:45 -07007618 @Override
7619 public boolean isTtyModeSupported() {
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07007620 TelecomManager telecomManager = mApp.getSystemService(TelecomManager.class);
Wooki Wu1f82f7a2016-02-15 15:59:58 +08007621 return telecomManager.isTtySupported();
Andrew Lee9431b832015-03-09 18:46:45 -07007622 }
7623
7624 @Override
7625 public boolean isHearingAidCompatibilitySupported() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007626 final long identity = Binder.clearCallingIdentity();
7627 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007628 return mApp.getResources().getBoolean(R.bool.hac_enabled);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007629 } finally {
7630 Binder.restoreCallingIdentity(identity);
7631 }
Andrew Lee9431b832015-03-09 18:46:45 -07007632 }
7633
Hall Liuf6668912018-10-31 17:05:23 -07007634 /**
7635 * Determines whether the device currently supports RTT (Real-time text). Based both on carrier
7636 * support for the feature and device firmware support.
7637 *
7638 * @return {@code true} if the device and carrier both support RTT, {@code false} otherwise.
7639 */
7640 @Override
7641 public boolean isRttSupported(int subscriptionId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007642 final long identity = Binder.clearCallingIdentity();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007643 final Phone phone = getPhone(subscriptionId);
7644 if (phone == null) {
7645 loge("isRttSupported: no Phone found. Invalid subId:" + subscriptionId);
7646 return false;
7647 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007648 try {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007649 boolean isCarrierSupported = mApp.getCarrierConfigForSubId(subscriptionId).getBoolean(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007650 CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
7651 boolean isDeviceSupported =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007652 phone.getContext().getResources().getBoolean(R.bool.config_support_rtt);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007653 return isCarrierSupported && isDeviceSupported;
7654 } finally {
7655 Binder.restoreCallingIdentity(identity);
7656 }
Hall Liu98187582018-01-22 19:15:32 -08007657 }
7658
Hall Liuf6668912018-10-31 17:05:23 -07007659 /**
Hall Liuf2daa022019-07-23 18:39:00 -07007660 * Determines whether the user has turned on RTT. If the carrier wants to ignore the user-set
7661 * RTT setting, will return true if the device and carrier both support RTT.
7662 * Otherwise. only returns true if the device and carrier both also support RTT.
Hall Liuf6668912018-10-31 17:05:23 -07007663 */
7664 public boolean isRttEnabled(int subscriptionId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007665 final long identity = Binder.clearCallingIdentity();
7666 try {
Hall Liu5bab75c2019-12-11 23:58:20 +00007667 boolean isRttSupported = isRttSupported(subscriptionId);
7668 boolean isUserRttSettingOn = Settings.Secure.getInt(
7669 mApp.getContentResolver(), Settings.Secure.RTT_CALLING_MODE, 0) != 0;
7670 boolean shouldIgnoreUserRttSetting = mApp.getCarrierConfigForSubId(subscriptionId)
7671 .getBoolean(CarrierConfigManager.KEY_IGNORE_RTT_MODE_SETTING_BOOL);
7672 return isRttSupported && (isUserRttSettingOn || shouldIgnoreUserRttSetting);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007673 } finally {
7674 Binder.restoreCallingIdentity(identity);
7675 }
Hall Liu3ad5f012018-04-06 16:23:39 -07007676 }
7677
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007678 @Deprecated
7679 @Override
7680 public String getDeviceId(String callingPackage) {
7681 return getDeviceIdWithFeature(callingPackage, null);
7682 }
7683
Sanket Padawe7310cc72015-01-14 09:53:20 -08007684 /**
7685 * Returns the unique device ID of phone, for example, the IMEI for
7686 * GSM and the MEID for CDMA phones. Return null if device ID is not available.
7687 *
7688 * <p>Requires Permission:
7689 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
7690 */
7691 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007692 public String getDeviceIdWithFeature(String callingPackage, String callingFeatureId) {
Shuo Qian13d89152021-05-10 23:58:11 -07007693 try {
7694 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
7695 } catch (SecurityException se) {
7696 EventLog.writeEvent(0x534e4554, "186530889", Binder.getCallingUid());
7697 throw new SecurityException("Package " + callingPackage + " does not belong to "
7698 + Binder.getCallingUid());
7699 }
Sanket Padawe7310cc72015-01-14 09:53:20 -08007700 final Phone phone = PhoneFactory.getPhone(0);
Jeff Davidson913390f2018-02-23 17:11:49 -08007701 if (phone == null) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08007702 return null;
7703 }
Jeff Davidson913390f2018-02-23 17:11:49 -08007704 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07007705 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007706 callingPackage, callingFeatureId, "getDeviceId")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08007707 return null;
7708 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007709
7710 final long identity = Binder.clearCallingIdentity();
7711 try {
7712 return phone.getDeviceId();
7713 } finally {
7714 Binder.restoreCallingIdentity(identity);
7715 }
Sanket Padawe7310cc72015-01-14 09:53:20 -08007716 }
7717
Ping Sunc67b7c22016-03-02 19:16:45 +08007718 /**
7719 * {@hide}
7720 * Returns the IMS Registration Status on a particular subid
7721 *
7722 * @param subId
7723 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007724 public boolean isImsRegistered(int subId) {
Ping Sunc67b7c22016-03-02 19:16:45 +08007725 Phone phone = getPhone(subId);
7726 if (phone != null) {
7727 return phone.isImsRegistered();
7728 } else {
7729 return false;
7730 }
7731 }
7732
Santos Cordon7a1885b2015-02-03 11:15:19 -08007733 @Override
Shuo Qian6e6137d2019-10-30 16:33:31 -07007734 public int getSubIdForPhoneAccountHandle(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007735 PhoneAccountHandle phoneAccountHandle, String callingPackage, String callingFeatureId) {
Shuo Qian6e6137d2019-10-30 16:33:31 -07007736 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, getDefaultSubscription(),
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007737 callingPackage, callingFeatureId, "getSubIdForPhoneAccountHandle")) {
Shuo Qian6e6137d2019-10-30 16:33:31 -07007738 throw new SecurityException("Requires READ_PHONE_STATE permission.");
7739 }
7740 final long identity = Binder.clearCallingIdentity();
7741 try {
7742 return PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle);
7743 } finally {
7744 Binder.restoreCallingIdentity(identity);
7745 }
7746 }
7747
7748 @Override
Tyler Gunnf70ed162019-04-03 15:28:53 -07007749 public @Nullable PhoneAccountHandle getPhoneAccountHandleForSubscriptionId(int subscriptionId) {
Alireza Forouzan4ac4f982021-03-16 22:18:52 -07007750 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07007751 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Alireza Forouzan4ac4f982021-03-16 22:18:52 -07007752 mApp,
7753 subscriptionId,
7754 "getPhoneAccountHandleForSubscriptionId, " + "subscriptionId: " + subscriptionId);
Tyler Gunnf70ed162019-04-03 15:28:53 -07007755 final long identity = Binder.clearCallingIdentity();
7756 try {
7757 Phone phone = getPhone(subscriptionId);
7758 if (phone == null) {
7759 return null;
7760 }
7761 return PhoneUtils.makePstnPhoneAccountHandle(phone);
7762 } finally {
7763 Binder.restoreCallingIdentity(identity);
7764 }
7765 }
7766
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007767 /**
7768 * @return the VoWiFi calling availability.
Nathan Haroldc55097a2015-03-11 18:14:50 -07007769 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007770 public boolean isWifiCallingAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007771 final long identity = Binder.clearCallingIdentity();
7772 try {
7773 Phone phone = getPhone(subId);
7774 if (phone != null) {
7775 return phone.isWifiCallingEnabled();
7776 } else {
7777 return false;
7778 }
7779 } finally {
7780 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007781 }
Nathan Haroldc55097a2015-03-11 18:14:50 -07007782 }
7783
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007784 /**
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007785 * @return the VT calling availability.
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07007786 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007787 public boolean isVideoTelephonyAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007788 final long identity = Binder.clearCallingIdentity();
7789 try {
7790 Phone phone = getPhone(subId);
7791 if (phone != null) {
7792 return phone.isVideoEnabled();
7793 } else {
7794 return false;
7795 }
7796 } finally {
7797 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007798 }
7799 }
7800
7801 /**
7802 * @return the IMS registration technology for the MMTEL feature. Valid return values are
7803 * defined in {@link ImsRegistrationImplBase}.
7804 */
7805 public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007806 final long identity = Binder.clearCallingIdentity();
7807 try {
7808 Phone phone = getPhone(subId);
7809 if (phone != null) {
7810 return phone.getImsRegistrationTech();
7811 } else {
7812 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
7813 }
7814 } finally {
7815 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08007816 }
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07007817 }
7818
Stuart Scott8eef64f2015-04-08 15:13:54 -07007819 @Override
7820 public void factoryReset(int subId) {
paulhu5a773602019-08-23 19:17:33 +08007821 enforceSettingsPermission();
Stuart Scott981d8582015-04-21 14:09:50 -07007822 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
7823 return;
7824 }
Kai Shif70f46f2021-03-03 13:59:46 -08007825 Phone defaultPhone = getDefaultPhone();
7826 if (defaultPhone != null) {
7827 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7828 mApp, getDefaultPhone().getSubId(), "factoryReset");
7829 }
Svet Ganovcc087f82015-05-12 20:35:54 -07007830 final long identity = Binder.clearCallingIdentity();
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007831
Svet Ganovcc087f82015-05-12 20:35:54 -07007832 try {
Stuart Scott981d8582015-04-21 14:09:50 -07007833 if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
7834 UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07007835 setDataEnabledForReason(subId, TelephonyManager.DATA_ENABLED_REASON_USER,
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00007836 getDefaultDataEnabled());
Svet Ganovcc087f82015-05-12 20:35:54 -07007837 setNetworkSelectionModeAutomatic(subId);
SongFerngWang8c6e82e2021-03-02 22:09:29 +08007838 Phone phone = getPhone(subId);
SongFerngWangfd89b102021-05-27 22:44:54 +08007839 cleanUpAllowedNetworkTypes(phone, subId);
Nazanin Bakhshif782e562018-12-11 15:15:39 -08007840 setDataRoamingEnabled(subId, getDefaultDataRoamingEnabled(subId));
Jordan Liu857e73a2021-03-05 16:24:04 -08007841 getPhone(subId).resetCarrierKeysForImsiEncryption();
Svet Ganovcc087f82015-05-12 20:35:54 -07007842 }
Amit Mahajan7dbbd822019-03-13 17:33:47 -07007843 // There has been issues when Sms raw table somehow stores orphan
7844 // fragments. They lead to garbled message when new fragments come
7845 // in and combined with those stale ones. In case this happens again,
7846 // user can reset all network settings which will clean up this table.
7847 cleanUpSmsRawTable(getDefaultPhone().getContext());
Brad Ebingerbc7dd582019-10-17 17:03:22 -07007848 // Clean up IMS settings as well here.
7849 int slotId = getSlotIndex(subId);
7850 if (slotId > SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
7851 ImsManager.getInstance(mApp, slotId).factoryReset();
7852 }
Naina Nallurid63128d2019-09-17 14:10:30 -07007853
Kai Shif70f46f2021-03-03 13:59:46 -08007854 if (defaultPhone == null) {
7855 return;
7856 }
Naina Nallurid63128d2019-09-17 14:10:30 -07007857 // Erase modem config if erase modem on network setting is enabled.
7858 String configValue = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_TELEPHONY,
7859 RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED);
7860 if (configValue != null && Boolean.parseBoolean(configValue)) {
Kai Shif70f46f2021-03-03 13:59:46 -08007861 sendEraseModemConfig(defaultPhone);
Naina Nallurid63128d2019-09-17 14:10:30 -07007862 }
Kai Shif70f46f2021-03-03 13:59:46 -08007863
7864 sendEraseDataInSharedPreferences(defaultPhone);
Svet Ganovcc087f82015-05-12 20:35:54 -07007865 } finally {
7866 Binder.restoreCallingIdentity(identity);
Stuart Scott8eef64f2015-04-08 15:13:54 -07007867 }
7868 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01007869
SongFerngWangfd89b102021-05-27 22:44:54 +08007870 @VisibleForTesting
7871 void cleanUpAllowedNetworkTypes(Phone phone, int subId) {
7872 if (phone == null || !SubscriptionManager.isUsableSubscriptionId(subId)) {
7873 return;
7874 }
7875 long defaultNetworkType = RadioAccessFamily.getRafFromNetworkType(
7876 RILConstants.PREFERRED_NETWORK_MODE);
7877 SubscriptionManager.setSubscriptionProperty(subId,
7878 SubscriptionManager.ALLOWED_NETWORK_TYPES,
7879 "user=" + defaultNetworkType);
7880 phone.loadAllowedNetworksFromSubscriptionDatabase();
7881 phone.setAllowedNetworkTypes(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER,
7882 defaultNetworkType, null);
7883 }
7884
Amit Mahajan7dbbd822019-03-13 17:33:47 -07007885 private void cleanUpSmsRawTable(Context context) {
7886 ContentResolver resolver = context.getContentResolver();
7887 Uri uri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete");
7888 resolver.delete(uri, null, null);
7889 }
7890
Narayan Kamath1c496c22015-04-16 14:40:19 +01007891 @Override
chen xu5d3637b2019-01-21 23:31:38 -08007892 public String getSimLocaleForSubscriber(int subId) {
7893 enforceReadPrivilegedPermission("getSimLocaleForSubscriber, subId: " + subId);
7894 final Phone phone = getPhone(subId);
7895 if (phone == null) {
7896 log("getSimLocaleForSubscriber, invalid subId");
chen xu2bb91e42019-01-24 14:35:54 -08007897 return null;
chen xu5d3637b2019-01-21 23:31:38 -08007898 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007899 final long identity = Binder.clearCallingIdentity();
7900 try {
chen xu5d3637b2019-01-21 23:31:38 -08007901 final SubscriptionInfo info = mSubscriptionController.getActiveSubscriptionInfo(subId,
Philip P. Moltmann8d34f0c2020-03-05 16:24:02 -08007902 phone.getContext().getOpPackageName(), phone.getContext().getAttributionTag());
chen xu6291c472019-02-04 12:55:53 -08007903 if (info == null) {
7904 log("getSimLocaleForSubscriber, inactive subId: " + subId);
7905 return null;
7906 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007907 // Try and fetch the locale from the carrier properties or from the SIM language
7908 // preferences (EF-PL and EF-LI)...
7909 final int mcc = info.getMcc();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007910 String simLanguage = null;
chen xu5d3637b2019-01-21 23:31:38 -08007911 final Locale localeFromDefaultSim = phone.getLocaleFromSimAndCarrierPrefs();
7912 if (localeFromDefaultSim != null) {
7913 if (!localeFromDefaultSim.getCountry().isEmpty()) {
7914 if (DBG) log("Using locale from subId: " + subId + " locale: "
7915 + localeFromDefaultSim);
7916 return localeFromDefaultSim.toLanguageTag();
7917 } else {
7918 simLanguage = localeFromDefaultSim.getLanguage();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007919 }
7920 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01007921
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007922 // The SIM language preferences only store a language (e.g. fr = French), not an
7923 // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
7924 // the SIM and carrier preferences does not include a country we add the country
7925 // determined from the SIM MCC to provide an exact locale.
zoey chenc730df82019-12-18 17:07:20 +08007926 final Locale mccLocale = LocaleUtils.getLocaleFromMcc(mApp, mcc, simLanguage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007927 if (mccLocale != null) {
chen xu5d3637b2019-01-21 23:31:38 -08007928 if (DBG) log("No locale from SIM, using mcc locale:" + mccLocale);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007929 return mccLocale.toLanguageTag();
7930 }
7931
7932 if (DBG) log("No locale found - returning null");
7933 return null;
7934 } finally {
7935 Binder.restoreCallingIdentity(identity);
7936 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01007937 }
7938
7939 private List<SubscriptionInfo> getAllSubscriptionInfoList() {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007940 return mSubscriptionController.getAllSubInfoList(mApp.getOpPackageName(),
Philip P. Moltmann8d34f0c2020-03-05 16:24:02 -08007941 mApp.getAttributionTag());
Narayan Kamath1c496c22015-04-16 14:40:19 +01007942 }
7943
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007944 /**
7945 * NOTE: this method assumes permission checks are done and caller identity has been cleared.
7946 */
7947 private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07007948 return mSubscriptionController.getActiveSubscriptionInfoList(mApp.getOpPackageName(),
Philip P. Moltmann8d34f0c2020-03-05 16:24:02 -08007949 mApp.getAttributionTag());
Narayan Kamath1c496c22015-04-16 14:40:19 +01007950 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07007951
Chenjie Yu1ba97252018-01-11 18:16:20 -08007952 private final ModemActivityInfo mLastModemActivityInfo =
Hall Liu49656c02020-10-09 19:00:11 -07007953 new ModemActivityInfo(0, 0, 0, new int[ModemActivityInfo.getNumTxPowerLevels()], 0);
Chenjie Yu1ba97252018-01-11 18:16:20 -08007954
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07007955 /**
Adam Lesinski903a54c2016-04-11 14:49:52 -07007956 * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
7957 * representing the state of the modem.
7958 *
Chenjie Yu1ba97252018-01-11 18:16:20 -08007959 * NOTE: The underlying implementation clears the modem state, so there should only ever be one
7960 * caller to it. Everyone should call this class to get cumulative data.
Adam Lesinski903a54c2016-04-11 14:49:52 -07007961 * @hide
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07007962 */
7963 @Override
Adam Lesinski903a54c2016-04-11 14:49:52 -07007964 public void requestModemActivityInfo(ResultReceiver result) {
7965 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07007966 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007967
7968 final long identity = Binder.clearCallingIdentity();
7969 try {
Shuo Qian8f4750a2020-02-20 17:12:10 -08007970 sendRequestAsync(CMD_GET_MODEM_ACTIVITY_INFO, result, null, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08007971 } finally {
7972 Binder.restoreCallingIdentity(identity);
Chenjie Yu1ba97252018-01-11 18:16:20 -08007973 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07007974 }
Jack Yu85bd38a2015-11-09 11:34:32 -08007975
Siddharth Rayb8114062018-06-17 15:02:38 -07007976 // Checks that ModemActivityInfo is valid. Sleep time, Idle time, Rx time and Tx time should be
7977 // less than total activity duration.
7978 private boolean isModemActivityInfoValid(ModemActivityInfo info) {
7979 if (info == null) {
7980 return false;
7981 }
7982 int activityDurationMs =
Hall Liu49656c02020-10-09 19:00:11 -07007983 (int) (info.getTimestampMillis() - mLastModemActivityInfo.getTimestampMillis());
7984 int totalTxTimeMs = Arrays.stream(info.getTransmitTimeMillis()).sum();
7985
Siddharth Rayb8114062018-06-17 15:02:38 -07007986 return (info.isValid()
7987 && (info.getSleepTimeMillis() <= activityDurationMs)
7988 && (info.getIdleTimeMillis() <= activityDurationMs)
Chen Xud78231e2019-09-10 18:49:52 -07007989 && (info.getReceiveTimeMillis() <= activityDurationMs)
Siddharth Rayb8114062018-06-17 15:02:38 -07007990 && (totalTxTimeMs <= activityDurationMs));
7991 }
7992
Jack Yu85bd38a2015-11-09 11:34:32 -08007993 /**
Jack Yu85bd38a2015-11-09 11:34:32 -08007994 * Returns the service state information on specified subscription.
7995 */
7996 @Override
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08007997 public ServiceState getServiceStateForSubscriber(int subId,
7998 boolean renounceFineLocationAccess, boolean renounceCoarseLocationAccess,
7999 String callingPackage, String callingFeatureId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08008000 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008001 mApp, subId, callingPackage, callingFeatureId, "getServiceStateForSubscriber")) {
Jack Yu85bd38a2015-11-09 11:34:32 -08008002 return null;
8003 }
8004
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08008005 boolean hasFinePermission = false;
8006 boolean hasCoarsePermission = false;
8007 if (!renounceFineLocationAccess) {
8008 LocationAccessPolicy.LocationPermissionResult fineLocationResult =
8009 LocationAccessPolicy.checkLocationPermission(mApp,
8010 new LocationAccessPolicy.LocationPermissionQuery.Builder()
8011 .setCallingPackage(callingPackage)
8012 .setCallingFeatureId(callingFeatureId)
8013 .setCallingPid(Binder.getCallingPid())
8014 .setCallingUid(Binder.getCallingUid())
8015 .setMethod("getServiceStateForSubscriber")
8016 .setLogAsInfo(true)
8017 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
8018 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
8019 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
8020 .build());
8021 hasFinePermission =
8022 fineLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
8023 }
Hall Liuf19c44f2018-11-27 14:38:17 -08008024
Sooraj Sasindran2250dc02021-11-10 16:42:01 -08008025 if (!renounceCoarseLocationAccess) {
8026 LocationAccessPolicy.LocationPermissionResult coarseLocationResult =
8027 LocationAccessPolicy.checkLocationPermission(mApp,
8028 new LocationAccessPolicy.LocationPermissionQuery.Builder()
8029 .setCallingPackage(callingPackage)
8030 .setCallingFeatureId(callingFeatureId)
8031 .setCallingPid(Binder.getCallingPid())
8032 .setCallingUid(Binder.getCallingUid())
8033 .setMethod("getServiceStateForSubscriber")
8034 .setLogAsInfo(true)
8035 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
8036 .setMinSdkVersionForFine(Integer.MAX_VALUE)
8037 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
8038 .build());
8039 hasCoarsePermission =
8040 coarseLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
8041 }
Hall Liuf19c44f2018-11-27 14:38:17 -08008042
Jack Yu479f40e2020-10-27 21:29:25 -07008043 final Phone phone = getPhone(subId);
8044 if (phone == null) {
8045 return null;
8046 }
8047
Jordan Liu0f2bc442020-11-18 16:47:37 -08008048 final long identity = Binder.clearCallingIdentity();
8049
Jack Yu479f40e2020-10-27 21:29:25 -07008050 boolean isCallingPackageDataService = phone.getDataServicePackages()
8051 .contains(callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008052 try {
Jordan Liuc437b192020-08-17 10:59:12 -07008053 // isActiveSubId requires READ_PHONE_STATE, which we already check for above
8054 if (!mSubscriptionController.isActiveSubId(subId, callingPackage, callingFeatureId)) {
8055 Rlog.d(LOG_TAG,
8056 "getServiceStateForSubscriber returning null for inactive subId=" + subId);
8057 return null;
8058 }
8059
Hall Liuf19c44f2018-11-27 14:38:17 -08008060 ServiceState ss = phone.getServiceState();
8061
8062 // Scrub out the location info in ServiceState depending on what level of access
8063 // the caller has.
Jack Yu479f40e2020-10-27 21:29:25 -07008064 if (hasFinePermission || isCallingPackageDataService) return ss;
Malcolm Chen5052de62019-12-30 13:56:38 -08008065 if (hasCoarsePermission) return ss.createLocationInfoSanitizedCopy(false);
8066 return ss.createLocationInfoSanitizedCopy(true);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008067 } finally {
8068 Binder.restoreCallingIdentity(identity);
8069 }
Jack Yu85bd38a2015-11-09 11:34:32 -08008070 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08008071
8072 /**
8073 * Returns the URI for the per-account voicemail ringtone set in Phone settings.
8074 *
8075 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
8076 * voicemail ringtone.
8077 * @return The URI for the ringtone to play when receiving a voicemail from a specific
8078 * PhoneAccount.
8079 */
8080 @Override
8081 public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008082 final long identity = Binder.clearCallingIdentity();
8083 try {
8084 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
8085 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008086 phone = getDefaultPhone();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008087 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08008088
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008089 return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext());
8090 } finally {
8091 Binder.restoreCallingIdentity(identity);
8092 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08008093 }
8094
8095 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008096 * Sets the per-account voicemail ringtone.
8097 *
8098 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
8099 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
8100 *
8101 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
8102 * voicemail ringtone.
8103 * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
8104 * PhoneAccount.
8105 */
8106 @Override
8107 public void setVoicemailRingtoneUri(String callingPackage,
8108 PhoneAccountHandle phoneAccountHandle, Uri uri) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008109 final Phone defaultPhone = getDefaultPhone();
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008110 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07008111 TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
8112 if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08008113 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8114 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
8115 "setVoicemailRingtoneUri");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008116 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008117
8118 final long identity = Binder.clearCallingIdentity();
8119 try {
8120 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
8121 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008122 phone = defaultPhone;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008123 }
8124 VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri);
8125 } finally {
8126 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008127 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008128 }
8129
8130 /**
Nancy Chen31f9ba12016-01-06 11:42:12 -08008131 * Returns whether vibration is set for voicemail notification in Phone settings.
8132 *
8133 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
8134 * voicemail vibration setting.
8135 * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
8136 */
8137 @Override
8138 public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008139 final long identity = Binder.clearCallingIdentity();
8140 try {
8141 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
8142 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008143 phone = getDefaultPhone();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008144 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08008145
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008146 return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext());
8147 } finally {
8148 Binder.restoreCallingIdentity(identity);
8149 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08008150 }
8151
Youhan Wange64578a2016-05-02 15:32:42 -07008152 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008153 * Sets the per-account voicemail vibration.
8154 *
8155 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
8156 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
8157 *
8158 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
8159 * voicemail vibration setting.
8160 * @param enabled Whether to enable or disable vibration for voicemail notifications from a
8161 * specific PhoneAccount.
8162 */
8163 @Override
8164 public void setVoicemailVibrationEnabled(String callingPackage,
8165 PhoneAccountHandle phoneAccountHandle, boolean enabled) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008166 final Phone defaultPhone = getDefaultPhone();
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008167 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Tyler Gunn5ddfdc92019-10-31 13:08:23 -07008168 TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
8169 if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08008170 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8171 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
8172 "setVoicemailVibrationEnabled");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008173 }
8174
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008175 final long identity = Binder.clearCallingIdentity();
8176 try {
8177 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
8178 if (phone == null) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008179 phone = defaultPhone;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008180 }
8181 VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled);
8182 } finally {
8183 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008184 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08008185 }
8186
8187 /**
Youhan Wange64578a2016-05-02 15:32:42 -07008188 * Make sure either called from same process as self (phone) or IPC caller has read privilege.
8189 *
8190 * @throws SecurityException if the caller does not have the required permission
8191 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07008192 private void enforceReadPrivilegedPermission(String message) {
Youhan Wange64578a2016-05-02 15:32:42 -07008193 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
Brad Ebinger35c841c2018-10-01 10:40:55 -07008194 message);
Youhan Wange64578a2016-05-02 15:32:42 -07008195 }
8196
8197 /**
Ta-wei Yen30a69c82016-12-27 14:52:32 -08008198 * Make sure either called from same process as self (phone) or IPC caller has send SMS
8199 * permission.
8200 *
8201 * @throws SecurityException if the caller does not have the required permission
8202 */
8203 private void enforceSendSmsPermission() {
8204 mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null);
8205 }
8206
8207 /**
Ta-wei Yen527a9c02017-01-06 15:29:25 -08008208 * Make sure called from the package in charge of visual voicemail.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08008209 *
Ta-wei Yen527a9c02017-01-06 15:29:25 -08008210 * @throws SecurityException if the caller is not the visual voicemail package.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08008211 */
Ta-wei Yen527a9c02017-01-06 15:29:25 -08008212 private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008213 final long identity = Binder.clearCallingIdentity();
8214 try {
8215 ComponentName componentName =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008216 RemoteVvmTaskManager.getRemotePackage(mApp, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008217 if (componentName == null) {
8218 throw new SecurityException(
8219 "Caller not current active visual voicemail package[null]");
8220 }
8221 String vvmPackage = componentName.getPackageName();
8222 if (!callingPackage.equals(vvmPackage)) {
8223 throw new SecurityException("Caller not current active visual voicemail package["
8224 + vvmPackage + "]");
8225 }
8226 } finally {
8227 Binder.restoreCallingIdentity(identity);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08008228 }
8229 }
8230
8231 /**
Youhan Wange64578a2016-05-02 15:32:42 -07008232 * Return the application ID for the app type.
8233 *
8234 * @param subId the subscription ID that this request applies to.
8235 * @param appType the uicc app type.
8236 * @return Application ID for specificied app type, or null if no uicc.
8237 */
8238 @Override
8239 public String getAidForAppType(int subId, int appType) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07008240 enforceReadPrivilegedPermission("getAidForAppType");
Youhan Wange64578a2016-05-02 15:32:42 -07008241 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008242
8243 final long identity = Binder.clearCallingIdentity();
Youhan Wange64578a2016-05-02 15:32:42 -07008244 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008245 if (phone == null) {
8246 return null;
8247 }
8248 String aid = null;
8249 try {
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00008250 aid = UiccController.getInstance().getUiccPort(phone.getPhoneId())
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008251 .getApplicationByType(appType).getAid();
8252 } catch (Exception e) {
8253 Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e);
8254 }
8255 return aid;
8256 } finally {
8257 Binder.restoreCallingIdentity(identity);
Youhan Wange64578a2016-05-02 15:32:42 -07008258 }
Youhan Wange64578a2016-05-02 15:32:42 -07008259 }
8260
Youhan Wang4001d252016-05-11 10:29:41 -07008261 /**
8262 * Return the Electronic Serial Number.
8263 *
8264 * @param subId the subscription ID that this request applies to.
8265 * @return ESN or null if error.
8266 */
8267 @Override
8268 public String getEsn(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07008269 enforceReadPrivilegedPermission("getEsn");
Youhan Wang4001d252016-05-11 10:29:41 -07008270 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008271
8272 final long identity = Binder.clearCallingIdentity();
Youhan Wang4001d252016-05-11 10:29:41 -07008273 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008274 if (phone == null) {
8275 return null;
8276 }
8277 String esn = null;
8278 try {
8279 esn = phone.getEsn();
8280 } catch (Exception e) {
8281 Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e);
8282 }
8283 return esn;
8284 } finally {
8285 Binder.restoreCallingIdentity(identity);
Youhan Wang4001d252016-05-11 10:29:41 -07008286 }
Youhan Wang4001d252016-05-11 10:29:41 -07008287 }
8288
Sanket Padawe99ef1e32016-05-18 16:12:33 -07008289 /**
Youhan Wang66ad5d72016-07-18 17:56:58 -07008290 * Return the Preferred Roaming List Version.
8291 *
8292 * @param subId the subscription ID that this request applies to.
8293 * @return PRLVersion or null if error.
8294 */
8295 @Override
8296 public String getCdmaPrlVersion(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07008297 enforceReadPrivilegedPermission("getCdmaPrlVersion");
Youhan Wang66ad5d72016-07-18 17:56:58 -07008298 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008299
8300 final long identity = Binder.clearCallingIdentity();
Youhan Wang66ad5d72016-07-18 17:56:58 -07008301 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008302 if (phone == null) {
8303 return null;
8304 }
8305 String cdmaPrlVersion = null;
8306 try {
8307 cdmaPrlVersion = phone.getCdmaPrlVersion();
8308 } catch (Exception e) {
8309 Log.e(LOG_TAG, "Not getting PRLVersion", e);
8310 }
8311 return cdmaPrlVersion;
8312 } finally {
8313 Binder.restoreCallingIdentity(identity);
Youhan Wang66ad5d72016-07-18 17:56:58 -07008314 }
Youhan Wang66ad5d72016-07-18 17:56:58 -07008315 }
8316
8317 /**
Sanket Padawe99ef1e32016-05-18 16:12:33 -07008318 * Get snapshot of Telephony histograms
8319 * @return List of Telephony histograms
8320 * @hide
8321 */
8322 @Override
8323 public List<TelephonyHistogram> getTelephonyHistograms() {
Jeff Davidson7e17e312018-02-13 18:17:36 -08008324 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8325 mApp, getDefaultSubscription(), "getTelephonyHistograms");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008326
8327 final long identity = Binder.clearCallingIdentity();
8328 try {
8329 return RIL.getTelephonyRILTimingHistograms();
8330 } finally {
8331 Binder.restoreCallingIdentity(identity);
8332 }
Sanket Padawe99ef1e32016-05-18 16:12:33 -07008333 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07008334
8335 /**
8336 * {@hide}
Michele Berionne482f8202018-11-27 18:57:59 -08008337 * Set the allowed carrier list and the excluded carrier list, indicating the priority between
8338 * the two lists.
Meng Wang1a7c35a2016-05-05 20:56:15 -07008339 * Require system privileges. In the future we may add this to carrier APIs.
8340 *
Michele Berionne482f8202018-11-27 18:57:59 -08008341 * @return Integer with the result of the operation, as defined in {@link TelephonyManager}.
Meng Wang1a7c35a2016-05-05 20:56:15 -07008342 */
8343 @Override
Michele Berionne482f8202018-11-27 18:57:59 -08008344 @TelephonyManager.SetCarrierRestrictionResult
8345 public int setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules) {
Meng Wang1a7c35a2016-05-05 20:56:15 -07008346 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07008347 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Sanket Padawe13bac7b2017-03-20 15:04:47 -07008348
Michele Berionne482f8202018-11-27 18:57:59 -08008349 if (carrierRestrictionRules == null) {
8350 throw new NullPointerException("carrier restriction cannot be null");
Meng Wang9b7c4e92017-02-17 11:41:27 -08008351 }
Sanket Padawe13bac7b2017-03-20 15:04:47 -07008352
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008353 final long identity = Binder.clearCallingIdentity();
8354 try {
Michele Berionne482f8202018-11-27 18:57:59 -08008355 return (int) sendRequest(CMD_SET_ALLOWED_CARRIERS, carrierRestrictionRules,
vagdeviaf9a5b92018-08-15 16:01:53 -07008356 workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008357 } finally {
8358 Binder.restoreCallingIdentity(identity);
8359 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07008360 }
8361
8362 /**
8363 * {@hide}
Michele Berionne482f8202018-11-27 18:57:59 -08008364 * Get the allowed carrier list and the excluded carrier list, including the priority between
8365 * the two lists.
Meng Wang1a7c35a2016-05-05 20:56:15 -07008366 * Require system privileges. In the future we may add this to carrier APIs.
8367 *
Michele Berionne482f8202018-11-27 18:57:59 -08008368 * @return {@link android.telephony.CarrierRestrictionRules}
Meng Wang1a7c35a2016-05-05 20:56:15 -07008369 */
8370 @Override
Michele Berionne482f8202018-11-27 18:57:59 -08008371 public CarrierRestrictionRules getAllowedCarriers() {
Brad Ebinger35c841c2018-10-01 10:40:55 -07008372 enforceReadPrivilegedPermission("getAllowedCarriers");
vagdeviaf9a5b92018-08-15 16:01:53 -07008373 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008374
8375 final long identity = Binder.clearCallingIdentity();
8376 try {
Michele Berionne482f8202018-11-27 18:57:59 -08008377 Object response = sendRequest(CMD_GET_ALLOWED_CARRIERS, null, workSource);
8378 if (response instanceof CarrierRestrictionRules) {
8379 return (CarrierRestrictionRules) response;
8380 }
8381 // Response is an Exception of some kind,
8382 // which is signalled to the user as a NULL retval
8383 return null;
8384 } catch (Exception e) {
8385 Log.e(LOG_TAG, "getAllowedCarriers. Exception ex=" + e);
8386 return null;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008387 } finally {
8388 Binder.restoreCallingIdentity(identity);
8389 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07008390 }
8391
fionaxu59545b42016-05-25 15:53:37 -07008392 /**
fionaxu59545b42016-05-25 15:53:37 -07008393 * Action set from carrier signalling broadcast receivers to enable/disable radio
8394 * @param subId the subscription ID that this action applies to.
8395 * @param enabled control enable or disable radio.
8396 * {@hide}
8397 */
8398 @Override
8399 public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
8400 enforceModifyPermission();
8401 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008402
8403 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07008404 if (phone == null) {
8405 loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
8406 return;
8407 }
8408 try {
8409 phone.carrierActionSetRadioEnabled(enabled);
8410 } catch (Exception e) {
8411 Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008412 } finally {
8413 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07008414 }
8415 }
8416
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07008417 /**
Sooraj Sasindrandaf060f2021-06-15 14:52:55 -07008418 * Enable or disable Voice over NR (VoNR)
8419 * @param subId the subscription ID that this action applies to.
8420 * @param enabled enable or disable VoNR.
8421 * @return operation result.
8422 */
8423 @Override
8424 public int setVoNrEnabled(int subId, boolean enabled) {
8425 enforceModifyPermission();
8426 final Phone phone = getPhone(subId);
8427
8428 final long identity = Binder.clearCallingIdentity();
8429 if (phone == null) {
8430 loge("setVoNrEnabled fails with no phone object for subId: " + subId);
8431 return TelephonyManager.ENABLE_VONR_RADIO_NOT_AVAILABLE;
8432 }
8433
8434 WorkSource workSource = getWorkSource(Binder.getCallingUid());
8435 try {
8436 int result = (int) sendRequest(CMD_ENABLE_VONR, enabled, subId,
8437 workSource);
8438 if (DBG) log("setVoNrEnabled result: " + result);
Gary Jian8dd305f2021-10-14 16:31:35 +08008439
8440 if (result == TelephonyManager.ENABLE_VONR_SUCCESS) {
8441 if (DBG) {
8442 log("Set VoNR settings in siminfo db; subId=" + subId + ", value:" + enabled);
8443 }
8444 SubscriptionManager.setSubscriptionProperty(
8445 subId, SubscriptionManager.NR_ADVANCED_CALLING_ENABLED,
8446 (enabled ? "1" : "0"));
8447 }
8448
Sooraj Sasindrandaf060f2021-06-15 14:52:55 -07008449 return result;
8450 } finally {
8451 Binder.restoreCallingIdentity(identity);
8452 }
8453 }
8454
8455 /**
8456 * Is voice over NR enabled
8457 * @return true if VoNR is enabled else false
8458 */
8459 @Override
8460 public boolean isVoNrEnabled(int subId) {
8461 enforceReadPrivilegedPermission("isVoNrEnabled");
8462 WorkSource workSource = getWorkSource(Binder.getCallingUid());
8463 final long identity = Binder.clearCallingIdentity();
8464 try {
8465 boolean isEnabled = (boolean) sendRequest(CMD_IS_VONR_ENABLED,
8466 null, subId, workSource);
8467 if (DBG) log("isVoNrEnabled: " + isEnabled);
8468 return isEnabled;
8469 } finally {
8470 Binder.restoreCallingIdentity(identity);
8471 }
8472 }
8473
8474 /**
fionaxu8da9cb12017-05-23 15:02:46 -07008475 * Action set from carrier signalling broadcast receivers to start/stop reporting the default
8476 * network status based on which carrier apps could apply actions accordingly,
8477 * enable/disable default url handler for example.
8478 *
8479 * @param subId the subscription ID that this action applies to.
8480 * @param report control start/stop reporting the default network status.
8481 * {@hide}
8482 */
8483 @Override
8484 public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
8485 enforceModifyPermission();
8486 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008487
8488 final long identity = Binder.clearCallingIdentity();
fionaxu8da9cb12017-05-23 15:02:46 -07008489 if (phone == null) {
8490 loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId);
8491 return;
8492 }
8493 try {
8494 phone.carrierActionReportDefaultNetworkStatus(report);
8495 } catch (Exception e) {
8496 Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008497 } finally {
8498 Binder.restoreCallingIdentity(identity);
fionaxu8da9cb12017-05-23 15:02:46 -07008499 }
8500 }
8501
8502 /**
fionaxud9622282017-07-17 17:51:30 -07008503 * Action set from carrier signalling broadcast receivers to reset all carrier actions
8504 * @param subId the subscription ID that this action applies to.
8505 * {@hide}
8506 */
8507 @Override
8508 public void carrierActionResetAll(int subId) {
8509 enforceModifyPermission();
8510 final Phone phone = getPhone(subId);
8511 if (phone == null) {
8512 loge("carrierAction: ResetAll fails with invalid sibId: " + subId);
8513 return;
8514 }
8515 try {
8516 phone.carrierActionResetAll();
8517 } catch (Exception e) {
8518 Log.e(LOG_TAG, "carrierAction: ResetAll fails. Exception ex=" + e);
8519 }
8520 }
8521
8522 /**
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07008523 * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a
8524 * bug report is being generated.
8525 */
8526 @Override
Ta-wei Yen99282e02016-06-21 18:19:35 -07008527 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008528 if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
8529 != PackageManager.PERMISSION_GRANTED) {
dcashman22b950d2016-06-27 11:39:02 -07008530 writer.println("Permission Denial: can't dump Phone from pid="
8531 + Binder.getCallingPid()
8532 + ", uid=" + Binder.getCallingUid()
8533 + "without permission "
8534 + android.Manifest.permission.DUMP);
8535 return;
8536 }
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008537 DumpsysHandler.dump(mApp, fd, writer, args);
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07008538 }
Jack Yueb89b242016-06-22 13:27:47 -07008539
Brad Ebingerdac2f002018-04-03 15:17:52 -07008540 @Override
Hall Liua1548bd2019-12-24 14:14:12 -08008541 public int handleShellCommand(@NonNull ParcelFileDescriptor in,
8542 @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
8543 @NonNull String[] args) {
8544 return new TelephonyShellCommand(this, getDefaultPhone().getContext()).exec(
8545 this, in.getFileDescriptor(), out.getFileDescriptor(),
8546 err.getFileDescriptor(), args);
Brad Ebingerdac2f002018-04-03 15:17:52 -07008547 }
8548
Jack Yueb89b242016-06-22 13:27:47 -07008549 /**
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00008550 * Policy control of data connection with reason {@@TelephonyManager.DataEnabledReason}
Greg Kaiser17f41752020-05-05 16:47:47 +00008551 * @param subId Subscription index
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00008552 * @param reason the reason the data enable change is taking place
8553 * @param enabled True if enabling the data, otherwise disabling.
8554 * @hide
Jack Yu75ab2952016-07-08 14:29:33 -07008555 */
8556 @Override
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07008557 public void setDataEnabledForReason(int subId, @TelephonyManager.DataEnabledReason int reason,
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00008558 boolean enabled) {
8559 if (reason == TelephonyManager.DATA_ENABLED_REASON_USER
8560 || reason == TelephonyManager.DATA_ENABLED_REASON_CARRIER) {
8561 try {
8562 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
Sooraj Sasindran95c07a92020-07-15 01:35:24 -07008563 mApp, subId, "setDataEnabledForReason");
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00008564 } catch (SecurityException se) {
8565 enforceModifyPermission();
8566 }
8567 } else {
8568 enforceModifyPermission();
8569 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008570
8571 final long identity = Binder.clearCallingIdentity();
8572 try {
8573 Phone phone = getPhone(subId);
8574 if (phone != null) {
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00008575 if (reason == TelephonyManager.DATA_ENABLED_REASON_CARRIER) {
8576 phone.carrierActionSetMeteredApnsEnabled(enabled);
8577 } else {
Jack Yu99e87332021-12-17 23:14:15 -08008578 if (phone.isUsingNewDataStack()) {
8579 phone.getDataSettingsManager().setDataEnabled(reason, enabled);
8580 } else {
8581 phone.getDataEnabledSettings().setDataEnabled(reason, enabled);
8582 }
Sooraj Sasindranaf1b5132020-05-05 21:06:20 +00008583 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008584 }
8585 } finally {
8586 Binder.restoreCallingIdentity(identity);
Jack Yu75ab2952016-07-08 14:29:33 -07008587 }
8588 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07008589
8590 /**
8591 * Get Client request stats
8592 * @return List of Client Request Stats
8593 * @hide
8594 */
8595 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008596 public List<ClientRequestStats> getClientRequestStats(String callingPackage,
8597 String callingFeatureId, int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08008598 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008599 mApp, subId, callingPackage, callingFeatureId, "getClientRequestStats")) {
Sooraj Sasindran9a909312016-07-18 11:57:25 -07008600 return null;
8601 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07008602 Phone phone = getPhone(subId);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07008603
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008604 final long identity = Binder.clearCallingIdentity();
8605 try {
8606 if (phone != null) {
8607 return phone.getClientRequestStats();
8608 }
8609
8610 return null;
8611 } finally {
8612 Binder.restoreCallingIdentity(identity);
8613 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07008614 }
8615
Narayan Kamathf04b5a12018-01-09 11:47:15 +00008616 private WorkSource getWorkSource(int uid) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008617 String packageName = mApp.getPackageManager().getNameForUid(uid);
Narayan Kamathf04b5a12018-01-09 11:47:15 +00008618 return new WorkSource(uid, packageName);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07008619 }
Jack Yueb4124c2017-02-16 15:32:43 -08008620
8621 /**
Grace Chen70990072017-03-24 17:21:30 -07008622 * Set SIM card power state.
Jack Yueb4124c2017-02-16 15:32:43 -08008623 *
Sanket Padawe13bac7b2017-03-20 15:04:47 -07008624 * @param slotIndex SIM slot id.
Grace Chen70990072017-03-24 17:21:30 -07008625 * @param state State of SIM (power down, power up, pass through)
8626 * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
8627 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
8628 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
Jack Yueb4124c2017-02-16 15:32:43 -08008629 *
8630 **/
8631 @Override
Grace Chen70990072017-03-24 17:21:30 -07008632 public void setSimPowerStateForSlot(int slotIndex, int state) {
Jack Yueb4124c2017-02-16 15:32:43 -08008633 enforceModifyPermission();
Sanket Padawe13bac7b2017-03-20 15:04:47 -07008634 Phone phone = PhoneFactory.getPhone(slotIndex);
8635
vagdeviaf9a5b92018-08-15 16:01:53 -07008636 WorkSource workSource = getWorkSource(Binder.getCallingUid());
8637
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008638 final long identity = Binder.clearCallingIdentity();
8639 try {
8640 if (phone != null) {
Jordan Liu109698e2020-11-24 14:50:34 -08008641 phone.setSimPowerState(state, null, workSource);
8642 }
8643 } finally {
8644 Binder.restoreCallingIdentity(identity);
8645 }
8646 }
8647
8648 /**
8649 * Set SIM card power state.
8650 *
8651 * @param slotIndex SIM slot id.
8652 * @param state State of SIM (power down, power up, pass through)
8653 * @param callback callback to trigger after success or failure
8654 * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
8655 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
8656 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
8657 *
8658 **/
8659 @Override
8660 public void setSimPowerStateForSlotWithCallback(int slotIndex, int state,
8661 IIntegerConsumer callback) {
8662 enforceModifyPermission();
8663 Phone phone = PhoneFactory.getPhone(slotIndex);
8664
8665 WorkSource workSource = getWorkSource(Binder.getCallingUid());
8666
8667 final long identity = Binder.clearCallingIdentity();
8668 try {
8669 if (phone != null) {
8670 Pair<Integer, IIntegerConsumer> arguments = Pair.create(state, callback);
8671 sendRequestAsync(CMD_SET_SIM_POWER, arguments, phone, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008672 }
8673 } finally {
8674 Binder.restoreCallingIdentity(identity);
Jack Yueb4124c2017-02-16 15:32:43 -08008675 }
8676 }
Shuo Qiandd210312017-04-12 22:11:33 +00008677
Tyler Gunn65d45c22017-06-05 11:22:26 -07008678 private boolean isUssdApiAllowed(int subId) {
8679 CarrierConfigManager configManager =
Nazanin Bakhshif782e562018-12-11 15:15:39 -08008680 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Tyler Gunn65d45c22017-06-05 11:22:26 -07008681 if (configManager == null) {
8682 return false;
8683 }
8684 PersistableBundle pb = configManager.getConfigForSubId(subId);
8685 if (pb == null) {
8686 return false;
8687 }
8688 return pb.getBoolean(
8689 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL);
8690 }
8691
Shuo Qiandd210312017-04-12 22:11:33 +00008692 /**
8693 * Check if phone is in emergency callback mode
8694 * @return true if phone is in emergency callback mode
8695 * @param subId sub id
8696 */
goneil9c5f4872017-12-05 14:07:56 -08008697 @Override
Shuo Qiandd210312017-04-12 22:11:33 +00008698 public boolean getEmergencyCallbackMode(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07008699 enforceReadPrivilegedPermission("getEmergencyCallbackMode");
Shuo Qiandd210312017-04-12 22:11:33 +00008700 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008701
8702 final long identity = Binder.clearCallingIdentity();
8703 try {
8704 if (phone != null) {
8705 return phone.isInEcm();
8706 } else {
8707 return false;
8708 }
8709 } finally {
8710 Binder.restoreCallingIdentity(identity);
Shuo Qiandd210312017-04-12 22:11:33 +00008711 }
8712 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08008713
8714 /**
8715 * Get the current signal strength information for the given subscription.
8716 * Because this information is not updated when the device is in a low power state
8717 * it should not be relied-upon to be current.
8718 * @param subId Subscription index
8719 * @return the most recent cached signal strength info from the modem
8720 */
8721 @Override
8722 public SignalStrength getSignalStrength(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008723 final long identity = Binder.clearCallingIdentity();
8724 try {
8725 Phone p = getPhone(subId);
8726 if (p == null) {
8727 return null;
8728 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08008729
Malcolm Chenaa4a8532018-02-28 15:00:40 -08008730 return p.getSignalStrength();
8731 } finally {
8732 Binder.restoreCallingIdentity(identity);
8733 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08008734 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00008735
Pengquan Meng77b7f132018-08-22 14:49:57 -07008736 /**
Chen Xuf792fd62018-10-17 17:54:36 +00008737 * Get the current modem radio state for the given slot.
8738 * @param slotIndex slot index.
8739 * @param callingPackage the name of the package making the call.
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008740 * @param callingFeatureId The feature in the package.
Chen Xuf792fd62018-10-17 17:54:36 +00008741 * @return the current radio power state from the modem
8742 */
8743 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008744 public int getRadioPowerState(int slotIndex, String callingPackage, String callingFeatureId) {
Chen Xuf792fd62018-10-17 17:54:36 +00008745 Phone phone = PhoneFactory.getPhone(slotIndex);
8746 if (phone != null) {
Philip P. Moltmann700a9592019-10-03 11:53:50 -07008747 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, phone.getSubId(),
8748 callingPackage, callingFeatureId, "getRadioPowerState")) {
Chen Xuf792fd62018-10-17 17:54:36 +00008749 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
8750 }
8751
8752 final long identity = Binder.clearCallingIdentity();
8753 try {
8754 return phone.getRadioPowerState();
8755 } finally {
8756 Binder.restoreCallingIdentity(identity);
8757 }
8758 }
8759 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
8760 }
8761
8762 /**
Pengquan Meng77b7f132018-08-22 14:49:57 -07008763 * Checks if data roaming is enabled on the subscription with id {@code subId}.
8764 *
8765 * <p>Requires one of the following permissions:
8766 * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07008767 * {@link android.Manifest.permission#READ_BASIC_PHONE_STATE},
Pengquan Meng77b7f132018-08-22 14:49:57 -07008768 * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
8769 * privileges.
8770 *
8771 * @param subId subscription id
8772 * @return {@code true} if data roaming is enabled on this subscription, otherwise return
8773 * {@code false}.
8774 */
8775 @Override
8776 public boolean isDataRoamingEnabled(int subId) {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07008777 String functionName = "isDataRoamingEnabled";
Shuo Qian093013d2020-08-13 15:42:55 -07008778 try {
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07008779 try {
8780 mApp.enforceCallingOrSelfPermission(
8781 android.Manifest.permission.ACCESS_NETWORK_STATE,
8782 functionName);
8783 } catch (Exception e) {
8784 mApp.enforceCallingOrSelfPermission(
8785 permission.READ_BASIC_PHONE_STATE, functionName);
8786 }
Shuo Qian093013d2020-08-13 15:42:55 -07008787 } catch (Exception e) {
Nathan Harold62c68512021-04-06 11:26:02 -07008788 TelephonyPermissions.enforceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
Sooraj Sasindran5d051bf2021-11-05 13:14:15 -07008789 mApp, subId, functionName);
Shuo Qian093013d2020-08-13 15:42:55 -07008790 }
Pengquan Meng44e66f12019-04-01 10:48:20 -07008791
Pengquan Menga1bb6272018-09-06 09:59:22 -07008792 boolean isEnabled = false;
8793 final long identity = Binder.clearCallingIdentity();
Pengquan Meng77b7f132018-08-22 14:49:57 -07008794 try {
Pengquan Menga1bb6272018-09-06 09:59:22 -07008795 Phone phone = getPhone(subId);
8796 isEnabled = phone != null ? phone.getDataRoamingEnabled() : false;
Pengquan Menga1bb6272018-09-06 09:59:22 -07008797 } finally {
8798 Binder.restoreCallingIdentity(identity);
Pengquan Meng77b7f132018-08-22 14:49:57 -07008799 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07008800 return isEnabled;
Pengquan Meng77b7f132018-08-22 14:49:57 -07008801 }
8802
8803
8804 /**
8805 * Enables/Disables the data roaming on the subscription with id {@code subId}.
8806 *
8807 * <p> Requires permission:
8808 * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier
8809 * privileges.
8810 *
8811 * @param subId subscription id
8812 * @param isEnabled {@code true} means enable, {@code false} means disable.
8813 */
8814 @Override
8815 public void setDataRoamingEnabled(int subId, boolean isEnabled) {
Pengquan Meng44e66f12019-04-01 10:48:20 -07008816 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8817 mApp, subId, "setDataRoamingEnabled");
8818
Pengquan Menga1bb6272018-09-06 09:59:22 -07008819 final long identity = Binder.clearCallingIdentity();
8820 try {
Pengquan Menga1bb6272018-09-06 09:59:22 -07008821 Phone phone = getPhone(subId);
8822 if (phone != null) {
8823 phone.setDataRoamingEnabled(isEnabled);
8824 }
8825 } finally {
8826 Binder.restoreCallingIdentity(identity);
Pengquan Meng77b7f132018-08-22 14:49:57 -07008827 }
8828 }
8829
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00008830 @Override
Pengquan Meng6884a2c2018-10-03 12:19:13 -07008831 public boolean isManualNetworkSelectionAllowed(int subId) {
tom hsuc91afc72020-01-06 23:46:07 +08008832 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07008833 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Pengquan Meng44e66f12019-04-01 10:48:20 -07008834 mApp, subId, "isManualNetworkSelectionAllowed");
8835
Pengquan Meng6884a2c2018-10-03 12:19:13 -07008836 boolean isAllowed = true;
8837 final long identity = Binder.clearCallingIdentity();
8838 try {
Pengquan Meng6884a2c2018-10-03 12:19:13 -07008839 Phone phone = getPhone(subId);
8840 if (phone != null) {
8841 isAllowed = phone.isCspPlmnEnabled();
8842 }
8843 } finally {
8844 Binder.restoreCallingIdentity(identity);
8845 }
8846 return isAllowed;
8847 }
8848
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00008849 private boolean haveCarrierPrivilegeAccess(UiccPort port, String callingPackage) {
8850 UiccProfile profile = port.getUiccProfile();
8851 if (profile == null ||
8852 profile.getCarrierPrivilegeStatus(mApp.getPackageManager(), callingPackage)
8853 != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
8854 return false;
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00008855 }
8856 return true;
8857 }
8858
Pengquan Meng6884a2c2018-10-03 12:19:13 -07008859 @Override
Jordan Liu75f43ea2019-01-17 16:56:37 -08008860 public List<UiccCardInfo> getUiccCardsInfo(String callingPackage) {
sandeepjsa208e3b2021-11-17 04:05:58 +00008861 // Verify that the callingPackage belongs to the calling UID
Jordan Liu4cda4552020-03-23 11:55:07 -07008862 mApp.getSystemService(AppOpsManager.class)
8863 .checkPackage(Binder.getCallingUid(), callingPackage);
8864
Jordan Liu1e142fc2019-04-22 15:10:43 -07008865 boolean hasReadPermission = false;
sandeepjsb6c87872021-09-27 15:34:44 +00008866 boolean isIccIdAccessRestricted = false;
Jordan Liuc65bc952019-02-12 17:54:02 -08008867 try {
8868 enforceReadPrivilegedPermission("getUiccCardsInfo");
Jordan Liu1e142fc2019-04-22 15:10:43 -07008869 hasReadPermission = true;
Jordan Liuc65bc952019-02-12 17:54:02 -08008870 } catch (SecurityException e) {
8871 // even without READ_PRIVILEGED_PHONE_STATE, we allow the call to continue if the caller
8872 // has carrier privileges on an active UICC
8873 if (checkCarrierPrivilegesForPackageAnyPhone(callingPackage)
8874 != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
Jordan Liu1e142fc2019-04-22 15:10:43 -07008875 throw new SecurityException("Caller does not have permission.");
Jordan Liuc65bc952019-02-12 17:54:02 -08008876 }
Jordan Liu75f43ea2019-01-17 16:56:37 -08008877 }
sandeepjsb6c87872021-09-27 15:34:44 +00008878 // checking compatibility, if calling app's target SDK is T and beyond.
8879 if (CompatChanges.isChangeEnabled(GET_API_SIGNATURES_FROM_UICC_PORT_INFO,
8880 Binder.getCallingUid())) {
8881 isIccIdAccessRestricted = true;
8882 }
Jordan Liu5aa07002018-12-18 15:44:48 -08008883 final long identity = Binder.clearCallingIdentity();
8884 try {
Jordan Liu75f43ea2019-01-17 16:56:37 -08008885 UiccController uiccController = UiccController.getInstance();
8886 ArrayList<UiccCardInfo> cardInfos = uiccController.getAllUiccCardInfos();
Jordan Liu1e142fc2019-04-22 15:10:43 -07008887 if (hasReadPermission) {
8888 return cardInfos;
Jordan Liu75f43ea2019-01-17 16:56:37 -08008889 }
Jordan Liu1e142fc2019-04-22 15:10:43 -07008890
8891 // Remove private info if the caller doesn't have access
8892 ArrayList<UiccCardInfo> filteredInfos = new ArrayList<>();
8893 for (UiccCardInfo cardInfo : cardInfos) {
sandeepjsb6c87872021-09-27 15:34:44 +00008894 //setting the value after compatibility check
8895 cardInfo.setIccIdAccessRestricted(isIccIdAccessRestricted);
Jordan Liu1e142fc2019-04-22 15:10:43 -07008896 // For an inactive eUICC, the UiccCard will be null even though the UiccCardInfo
8897 // is available
sandeepjsb6c87872021-09-27 15:34:44 +00008898 UiccCard card = uiccController.getUiccCardForSlot(cardInfo.getPhysicalSlotIndex());
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00008899 if (card == null) {
8900 // assume no access if the card is unavailable
sandeepjsb6c87872021-09-27 15:34:44 +00008901 filteredInfos.add(getUiccCardInfoUnPrivileged(cardInfo));
Jordan Liu1e142fc2019-04-22 15:10:43 -07008902 continue;
8903 }
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00008904 Collection<UiccPortInfo> portInfos = cardInfo.getPorts();
8905 if (portInfos.isEmpty()) {
sandeepjsb6c87872021-09-27 15:34:44 +00008906 filteredInfos.add(getUiccCardInfoUnPrivileged(cardInfo));
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00008907 continue;
Jordan Liu1e142fc2019-04-22 15:10:43 -07008908 }
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00008909 List<UiccPortInfo> uiccPortInfos = new ArrayList<>();
8910 for (UiccPortInfo portInfo : portInfos) {
8911 UiccPort port = uiccController.getUiccPortForSlot(
8912 cardInfo.getPhysicalSlotIndex(), portInfo.getPortIndex());
8913 if (port == null) {
8914 // assume no access if port is null
8915 uiccPortInfos.add(getUiccPortInfoUnPrivileged(portInfo));
8916 continue;
8917 }
8918 if (haveCarrierPrivilegeAccess(port, callingPackage)) {
8919 uiccPortInfos.add(portInfo);
8920 } else {
8921 uiccPortInfos.add(getUiccPortInfoUnPrivileged(portInfo));
8922 }
8923 }
8924 filteredInfos.add(new UiccCardInfo(
8925 cardInfo.isEuicc(),
8926 cardInfo.getCardId(),
8927 null,
8928 cardInfo.getPhysicalSlotIndex(),
8929 cardInfo.isRemovable(),
8930 cardInfo.isMultipleEnabledProfilesSupported(),
8931 uiccPortInfos));
Jordan Liu1e142fc2019-04-22 15:10:43 -07008932 }
8933 return filteredInfos;
Jordan Liu5aa07002018-12-18 15:44:48 -08008934 } finally {
8935 Binder.restoreCallingIdentity(identity);
8936 }
8937 }
8938
sandeepjsb6c87872021-09-27 15:34:44 +00008939 /**
8940 * Returns a copy of the UiccCardinfo with the EID and ICCID set to null. These values are
8941 * generally private and require carrier privileges to view.
8942 *
8943 * @hide
8944 */
8945 @NonNull
8946 public UiccCardInfo getUiccCardInfoUnPrivileged(UiccCardInfo cardInfo) {
8947 List<UiccPortInfo> portinfo = new ArrayList<>();
8948 for (UiccPortInfo portinfos : cardInfo.getPorts()) {
8949 portinfo.add(getUiccPortInfoUnPrivileged(portinfos));
8950 }
8951 return new UiccCardInfo(
8952 cardInfo.isEuicc(),
8953 cardInfo.getCardId(),
8954 null,
8955 cardInfo.getPhysicalSlotIndex(),
8956 cardInfo.isRemovable(),
8957 cardInfo.isMultipleEnabledProfilesSupported(),
8958 portinfo
8959 );
8960 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00008961
sandeepjsb6c87872021-09-27 15:34:44 +00008962 /**
8963 * @hide
8964 * @return a copy of the UiccPortInfo with ICCID set to {@link UiccPortInfo#ICCID_REDACTED}.
8965 * These values are generally private and require carrier privileges to view.
8966 */
8967 @NonNull
8968 public UiccPortInfo getUiccPortInfoUnPrivileged(UiccPortInfo portInfo) {
8969 return new UiccPortInfo(
8970 UiccPortInfo.ICCID_REDACTED,
8971 portInfo.getPortIndex(),
8972 portInfo.getLogicalSlotIndex(),
8973 portInfo.isActive()
8974 );
8975 }
8976 @Override
8977 public UiccSlotInfo[] getUiccSlotsInfo(String callingPackage) {
sandeepjsa208e3b2021-11-17 04:05:58 +00008978 // Verify that the callingPackage belongs to the calling UID
sandeepjsb6c87872021-09-27 15:34:44 +00008979 mApp.getSystemService(AppOpsManager.class)
8980 .checkPackage(Binder.getCallingUid(), callingPackage);
8981
8982 boolean hasReadPermission = false;
8983 boolean isLogicalSlotAccessRestricted = false;
sandeepjsb6c87872021-09-27 15:34:44 +00008984
8985 try {
8986 enforceReadPrivilegedPermission("getUiccSlotsInfo");
8987 hasReadPermission = true;
8988 } catch (SecurityException e) {
8989 // even without READ_PRIVILEGED_PHONE_STATE, we allow the call to continue if the caller
8990 // has carrier privileges on an active UICC
8991 if (checkCarrierPrivilegesForPackageAnyPhone(callingPackage)
8992 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
8993 hasReadPermission = true;
8994 }
8995 }
8996
8997 // checking compatibility, if calling app's target SDK is T and beyond.
8998 if (CompatChanges.isChangeEnabled(GET_API_SIGNATURES_FROM_UICC_PORT_INFO,
8999 Binder.getCallingUid())) {
9000 isLogicalSlotAccessRestricted = true;
9001 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009002 final long identity = Binder.clearCallingIdentity();
9003 try {
9004 UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
9005 if (slots == null) {
9006 Rlog.i(LOG_TAG, "slots is null.");
9007 return null;
9008 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009009 UiccSlotInfo[] infos = new UiccSlotInfo[slots.length];
9010 for (int i = 0; i < slots.length; i++) {
9011 UiccSlot slot = slots[i];
9012 if (slot == null) {
9013 continue;
9014 }
9015
Jordan Liu7be7e652019-05-06 18:55:02 +00009016 String cardId;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009017 UiccCard card = slot.getUiccCard();
9018 if (card != null) {
9019 cardId = card.getCardId();
Jordan Liu7be7e652019-05-06 18:55:02 +00009020 } else {
Jordan Liu01bd00d2019-09-12 16:19:43 -07009021 cardId = slot.getEid();
9022 if (TextUtils.isEmpty(cardId)) {
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009023 // If cardId is null, use iccId of default port as cardId. Check if has
9024 // read permission otherwise set to null.(card is null which means no
9025 // carrier permission)
9026 cardId = hasReadPermission ? slot.getIccId(
9027 TelephonyManager.DEFAULT_PORT_INDEX) : null;
Jordan Liu01bd00d2019-09-12 16:19:43 -07009028 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009029 }
9030
Jordan Liu857451f2019-05-09 16:35:35 -07009031 if (cardId != null) {
9032 // if cardId is an ICCID, strip off trailing Fs before exposing to user
9033 // if cardId is an EID, it's all digits so this is fine
9034 cardId = IccUtils.stripTrailingFs(cardId);
9035 }
9036
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009037 int cardState = 0;
9038 switch (slot.getCardState()) {
9039 case CARDSTATE_ABSENT:
9040 cardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
9041 break;
9042 case CARDSTATE_PRESENT:
9043 cardState = UiccSlotInfo.CARD_STATE_INFO_PRESENT;
9044 break;
9045 case CARDSTATE_ERROR:
9046 cardState = UiccSlotInfo.CARD_STATE_INFO_ERROR;
9047 break;
9048 case CARDSTATE_RESTRICTED:
9049 cardState = UiccSlotInfo.CARD_STATE_INFO_RESTRICTED;
9050 break;
9051 default:
9052 break;
9053
9054 }
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009055 List<UiccPortInfo> portInfos = new ArrayList<>();
9056 int[] portIndexes = slot.getPortList();
9057 for (int portIdx : portIndexes) {
9058 String iccId = IccUtils.stripTrailingFs(getIccId(slot, portIdx,
9059 callingPackage, hasReadPermission));
9060 if (slot.isPortActive(portIdx)) {
9061 UiccPort port = slot.getUiccCard().getUiccPort(portIdx);
9062 portInfos.add(new UiccPortInfo(iccId, port.getPortIdx(),
9063 port.getPhoneId(), true));
9064 } else {
9065 portInfos.add(new UiccPortInfo(iccId, portIdx, -1, false));
9066 }
9067 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009068 infos[i] = new UiccSlotInfo(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009069 slot.isEuicc(),
9070 cardId,
9071 cardState,
Jordan Liua2619582019-02-14 12:56:40 -08009072 slot.isExtendedApduSupported(),
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009073 slot.isRemovable(), portInfos);
sandeepjsb6c87872021-09-27 15:34:44 +00009074 //setting the value after compatibility check
9075 infos[i].setLogicalSlotAccessRestricted(isLogicalSlotAccessRestricted);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009076 }
9077 return infos;
9078 } finally {
9079 Binder.restoreCallingIdentity(identity);
Holly Jiuyu Sun1d957c52018-04-04 13:52:42 -07009080 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00009081 }
9082
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009083 /* Returns null if doesn't have read permission or carrier privilege access. */
9084 private String getIccId(UiccSlot slot, int portIndex, String callingPackage,
9085 boolean hasReadPermission) {
9086 String iccId = slot.getIccId(portIndex);
9087 if (hasReadPermission) { // if has read permission
9088 return iccId;
9089 } else {
9090 if (slot.getUiccCard() != null && slot.getUiccCard().getUiccPort(portIndex) != null) {
9091 UiccPort port = slot.getUiccCard().getUiccPort(portIndex);
9092 // if no read permission, checking carrier privilege access
9093 if (haveCarrierPrivilegeAccess(port, callingPackage)) {
9094 return iccId;
9095 }
9096 }
9097 }
9098 // No read permission or carrier privilege access.
9099 return UiccPortInfo.ICCID_REDACTED;
9100 }
9101
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00009102 @Override
sandeepjsb6c87872021-09-27 15:34:44 +00009103 @Deprecated
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00009104 public boolean switchSlots(int[] physicalSlots) {
9105 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009106
9107 final long identity = Binder.clearCallingIdentity();
9108 try {
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009109 List<UiccSlotMapping> slotMappings = new ArrayList<>();
9110 for (int i = 0; i < physicalSlots.length; i++) {
9111 // Deprecated API, hence MEP is not supported. Adding default portIndex 0.
9112 slotMappings.add(new UiccSlotMapping(TelephonyManager.DEFAULT_PORT_INDEX,
9113 physicalSlots[i], i));
9114 }
9115 return (Boolean) sendRequest(CMD_SWITCH_SLOTS, slotMappings);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009116 } finally {
9117 Binder.restoreCallingIdentity(identity);
9118 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00009119 }
Jack Yu4c988042018-02-27 15:30:01 -08009120
9121 @Override
sandeepjsb6c87872021-09-27 15:34:44 +00009122 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
9123 public boolean setSimSlotMapping(@NonNull List<UiccSlotMapping> slotMapping) {
9124 enforceModifyPermission();
9125
9126 final long identity = Binder.clearCallingIdentity();
9127 try {
Muralidhar Reddyeb809e32021-11-19 03:07:54 +00009128 return (Boolean) sendRequest(CMD_SWITCH_SLOTS, slotMapping);
sandeepjsb6c87872021-09-27 15:34:44 +00009129 } finally {
9130 Binder.restoreCallingIdentity(identity);
9131 }
9132 }
9133
9134 @Override
Jordan Liu7de49fa2018-12-06 14:48:49 -08009135 public int getCardIdForDefaultEuicc(int subId, String callingPackage) {
Jordan Liu7de49fa2018-12-06 14:48:49 -08009136 final long identity = Binder.clearCallingIdentity();
9137 try {
9138 return UiccController.getInstance().getCardIdForDefaultEuicc();
9139 } finally {
9140 Binder.restoreCallingIdentity(identity);
9141 }
9142 }
9143
Pengquan Meng85728fb2018-03-12 16:31:21 -07009144 /**
goneil47ffb6e2018-04-06 15:40:58 -07009145 * A test API to reload the UICC profile.
9146 *
9147 * <p>Requires that the calling app has permission
9148 * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
9149 * @hide
9150 */
9151 @Override
9152 public void refreshUiccProfile(int subId) {
9153 enforceModifyPermission();
9154
9155 final long identity = Binder.clearCallingIdentity();
9156 try {
9157 Phone phone = getPhone(subId);
9158 if (phone == null) {
9159 return;
9160 }
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00009161 UiccPort uiccPort = phone.getUiccPort();
9162 if (uiccPort == null) {
goneil47ffb6e2018-04-06 15:40:58 -07009163 return;
9164 }
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00009165 UiccProfile uiccProfile = uiccPort.getUiccProfile();
goneil47ffb6e2018-04-06 15:40:58 -07009166 if (uiccProfile == null) {
9167 return;
9168 }
9169 uiccProfile.refresh();
9170 } finally {
9171 Binder.restoreCallingIdentity(identity);
9172 }
9173 }
9174
9175 /**
Pengquan Meng85728fb2018-03-12 16:31:21 -07009176 * Returns false if the mobile data is disabled by default, otherwise return true.
9177 */
9178 private boolean getDefaultDataEnabled() {
Inseob Kim14bb3d02018-12-13 17:11:34 +09009179 return TelephonyProperties.mobile_data().orElse(true);
Pengquan Meng85728fb2018-03-12 16:31:21 -07009180 }
9181
9182 /**
9183 * Returns true if the data roaming is enabled by default, i.e the system property
9184 * of {@link #DEFAULT_DATA_ROAMING_PROPERTY_NAME} is true or the config of
9185 * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} is true.
9186 */
9187 private boolean getDefaultDataRoamingEnabled(int subId) {
9188 final CarrierConfigManager configMgr = (CarrierConfigManager)
Nazanin Bakhshif782e562018-12-11 15:15:39 -08009189 mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Shuo Qian1d84a0e2020-07-15 12:36:44 -07009190 boolean isDataRoamingEnabled = TelephonyProperties.data_roaming().orElse(false);
Pengquan Meng85728fb2018-03-12 16:31:21 -07009191 isDataRoamingEnabled |= configMgr.getConfigForSubId(subId).getBoolean(
9192 CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
9193 return isDataRoamingEnabled;
9194 }
9195
9196 /**
9197 * Returns the default network type for the given {@code subId}, if the default network type is
9198 * not set, return {@link Phone#PREFERRED_NT_MODE}.
9199 */
9200 private int getDefaultNetworkType(int subId) {
Inseob Kim14bb3d02018-12-13 17:11:34 +09009201 List<Integer> list = TelephonyProperties.default_network();
9202 int phoneId = mSubscriptionController.getPhoneId(subId);
9203 if (phoneId >= 0 && phoneId < list.size() && list.get(phoneId) != null) {
9204 return list.get(phoneId);
9205 }
9206 return Phone.PREFERRED_NT_MODE;
Pengquan Meng85728fb2018-03-12 16:31:21 -07009207 }
fionaxua13278b2018-03-21 00:08:13 -07009208
9209 @Override
9210 public void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String
chen xueaba88a2019-03-15 13:15:10 -07009211 gid1, String gid2, String plmn, String spn, String carrierPrivilegeRules, String apn) {
fionaxua13278b2018-03-21 00:08:13 -07009212 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009213
9214 final long identity = Binder.clearCallingIdentity();
9215 try {
9216 final Phone phone = getPhone(subId);
9217 if (phone == null) {
9218 loge("setCarrierTestOverride fails with invalid subId: " + subId);
9219 return;
9220 }
chen xueaba88a2019-03-15 13:15:10 -07009221 phone.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, plmn, spn,
9222 carrierPrivilegeRules, apn);
Jeff Davidson8ab02b22020-03-28 12:24:40 -07009223 if (carrierPrivilegeRules == null) {
9224 mCarrierPrivilegeTestOverrideSubIds.remove(subId);
9225 } else {
9226 mCarrierPrivilegeTestOverrideSubIds.add(subId);
9227 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009228 } finally {
9229 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07009230 }
fionaxua13278b2018-03-21 00:08:13 -07009231 }
9232
9233 @Override
9234 public int getCarrierIdListVersion(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07009235 enforceReadPrivilegedPermission("getCarrierIdListVersion");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08009236
9237 final long identity = Binder.clearCallingIdentity();
9238 try {
9239 final Phone phone = getPhone(subId);
9240 if (phone == null) {
9241 loge("getCarrierIdListVersion fails with invalid subId: " + subId);
9242 return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
9243 }
9244 return phone.getCarrierIdListVersion();
9245 } finally {
9246 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07009247 }
fionaxua13278b2018-03-21 00:08:13 -07009248 }
Malcolm Chen2c63d402018-08-14 16:00:53 -07009249
9250 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009251 public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage,
9252 String callingFeatureId) {
Malcolm Chen2c63d402018-08-14 16:00:53 -07009253 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009254 mApp, subId, callingPackage, callingFeatureId,
9255 "getNumberOfModemsWithSimultaneousDataConnections")) {
Malcolm Chen2c63d402018-08-14 16:00:53 -07009256 return -1;
9257 }
9258
9259 final long identity = Binder.clearCallingIdentity();
9260 try {
9261 return mPhoneConfigurationManager.getNumberOfModemsWithSimultaneousDataConnections();
9262 } finally {
9263 Binder.restoreCallingIdentity(identity);
9264 }
9265 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07009266
9267 @Override
9268 public int getCdmaRoamingMode(int subId) {
zoey chen7e6d4e52019-12-17 18:18:59 +08009269 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07009270 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Pengquan Menga1bb6272018-09-06 09:59:22 -07009271 mApp, subId, "getCdmaRoamingMode");
9272
9273 final long identity = Binder.clearCallingIdentity();
9274 try {
9275 return (int) sendRequest(CMD_GET_CDMA_ROAMING_MODE, null /* argument */, subId);
9276 } finally {
9277 Binder.restoreCallingIdentity(identity);
9278 }
9279 }
9280
9281 @Override
9282 public boolean setCdmaRoamingMode(int subId, int mode) {
9283 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
9284 mApp, subId, "setCdmaRoamingMode");
9285
9286 final long identity = Binder.clearCallingIdentity();
9287 try {
9288 return (boolean) sendRequest(CMD_SET_CDMA_ROAMING_MODE, mode, subId);
9289 } finally {
9290 Binder.restoreCallingIdentity(identity);
9291 }
9292 }
9293
9294 @Override
Sarah Chinbaab1432020-10-28 13:46:24 -07009295 public int getCdmaSubscriptionMode(int subId) {
9296 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07009297 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Sarah Chinbaab1432020-10-28 13:46:24 -07009298 mApp, subId, "getCdmaSubscriptionMode");
9299
9300 final long identity = Binder.clearCallingIdentity();
9301 try {
9302 return (int) sendRequest(CMD_GET_CDMA_SUBSCRIPTION_MODE, null /* argument */, subId);
9303 } finally {
9304 Binder.restoreCallingIdentity(identity);
9305 }
9306 }
9307
9308 @Override
Pengquan Menga1bb6272018-09-06 09:59:22 -07009309 public boolean setCdmaSubscriptionMode(int subId, int mode) {
9310 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
9311 mApp, subId, "setCdmaSubscriptionMode");
9312
9313 final long identity = Binder.clearCallingIdentity();
9314 try {
9315 return (boolean) sendRequest(CMD_SET_CDMA_SUBSCRIPTION_MODE, mode, subId);
9316 } finally {
9317 Binder.restoreCallingIdentity(identity);
9318 }
9319 }
Makoto Onukida3bf792018-09-18 16:06:29 -07009320
sqianc5eccab2018-10-19 18:46:41 -07009321 @Override
sqian8c685422019-02-22 15:55:18 -08009322 public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009323 String callingPackage, String callingFeatureId) {
sqian11b7a0e2018-12-05 18:48:28 -08009324 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009325 mApp, getDefaultSubscription(), callingPackage, callingFeatureId,
9326 "getEmergencyNumberList")) {
sqian11b7a0e2018-12-05 18:48:28 -08009327 throw new SecurityException("Requires READ_PHONE_STATE permission.");
9328 }
9329 final long identity = Binder.clearCallingIdentity();
9330 try {
sqian854d44b2018-12-12 16:48:18 -08009331 Map<Integer, List<EmergencyNumber>> emergencyNumberListInternal = new HashMap<>();
9332 for (Phone phone: PhoneFactory.getPhones()) {
9333 if (phone.getEmergencyNumberTracker() != null
9334 && phone.getEmergencyNumberTracker().getEmergencyNumberList() != null) {
9335 emergencyNumberListInternal.put(
9336 phone.getSubId(),
9337 phone.getEmergencyNumberTracker().getEmergencyNumberList());
9338 }
sqian11b7a0e2018-12-05 18:48:28 -08009339 }
sqian854d44b2018-12-12 16:48:18 -08009340 return emergencyNumberListInternal;
sqian11b7a0e2018-12-05 18:48:28 -08009341 } finally {
9342 Binder.restoreCallingIdentity(identity);
9343 }
sqianc5eccab2018-10-19 18:46:41 -07009344 }
9345
9346 @Override
sqian8c685422019-02-22 15:55:18 -08009347 public boolean isEmergencyNumber(String number, boolean exactMatch) {
Nazanin Bakhshif782e562018-12-11 15:15:39 -08009348 final Phone defaultPhone = getDefaultPhone();
sqian11b7a0e2018-12-05 18:48:28 -08009349 if (!exactMatch) {
9350 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07009351 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
sqian8c685422019-02-22 15:55:18 -08009352 mApp, defaultPhone.getSubId(), "isEmergencyNumber(Potential)");
sqian11b7a0e2018-12-05 18:48:28 -08009353 }
9354 final long identity = Binder.clearCallingIdentity();
9355 try {
sqian854d44b2018-12-12 16:48:18 -08009356 for (Phone phone: PhoneFactory.getPhones()) {
9357 if (phone.getEmergencyNumberTracker() != null
Taesu Leee050c002020-10-13 17:19:35 +09009358 && phone.getEmergencyNumberTracker()
9359 .isEmergencyNumber(number, exactMatch)) {
9360 return true;
sqian11b7a0e2018-12-05 18:48:28 -08009361 }
sqian11b7a0e2018-12-05 18:48:28 -08009362 }
9363 return false;
9364 } finally {
9365 Binder.restoreCallingIdentity(identity);
9366 }
9367 }
9368
sqianf4ca7ed2019-01-15 18:32:07 -08009369 /**
Shuo Qianccbaf742021-02-22 18:32:21 -08009370 * Start emergency callback mode for GsmCdmaPhone for testing.
9371 */
9372 @Override
9373 public void startEmergencyCallbackMode() {
9374 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
9375 "startEmergencyCallbackMode");
9376 enforceModifyPermission();
9377 final long identity = Binder.clearCallingIdentity();
9378 try {
9379 for (Phone phone : PhoneFactory.getPhones()) {
9380 Rlog.d(LOG_TAG, "startEmergencyCallbackMode phone type: " + phone.getPhoneType());
9381 if (phone != null && ((phone.getPhoneType() == PHONE_TYPE_GSM)
9382 || (phone.getPhoneType() == PHONE_TYPE_CDMA))) {
9383 GsmCdmaPhone gsmCdmaPhone = (GsmCdmaPhone) phone;
9384 gsmCdmaPhone.obtainMessage(
9385 GsmCdmaPhone.EVENT_EMERGENCY_CALLBACK_MODE_ENTER).sendToTarget();
9386 Rlog.d(LOG_TAG, "startEmergencyCallbackMode: triggered");
9387 }
9388 }
9389 } finally {
9390 Binder.restoreCallingIdentity(identity);
9391 }
9392 }
9393
9394 /**
sqianf4ca7ed2019-01-15 18:32:07 -08009395 * Update emergency number list for test mode.
9396 */
9397 @Override
9398 public void updateEmergencyNumberListTestMode(int action, EmergencyNumber num) {
9399 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
9400 "updateEmergencyNumberListTestMode");
9401
9402 final long identity = Binder.clearCallingIdentity();
9403 try {
9404 for (Phone phone: PhoneFactory.getPhones()) {
9405 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
9406 if (tracker != null) {
9407 tracker.executeEmergencyNumberTestModeCommand(action, num);
9408 }
9409 }
9410 } finally {
9411 Binder.restoreCallingIdentity(identity);
9412 }
9413 }
9414
9415 /**
9416 * Get the full emergency number list for test mode.
9417 */
9418 @Override
9419 public List<String> getEmergencyNumberListTestMode() {
9420 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
9421 "getEmergencyNumberListTestMode");
9422
9423 final long identity = Binder.clearCallingIdentity();
9424 try {
9425 Set<String> emergencyNumbers = new HashSet<>();
9426 for (Phone phone: PhoneFactory.getPhones()) {
9427 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
9428 if (tracker != null) {
9429 for (EmergencyNumber num : tracker.getEmergencyNumberList()) {
9430 emergencyNumbers.add(num.getNumber());
9431 }
9432 }
9433 }
9434 return new ArrayList<>(emergencyNumbers);
9435 } finally {
9436 Binder.restoreCallingIdentity(identity);
9437 }
9438 }
9439
chen xud6b45bd2018-10-30 22:27:10 -07009440 @Override
Shuo Qian3b6ee772019-11-13 17:43:31 -08009441 public int getEmergencyNumberDbVersion(int subId) {
9442 enforceReadPrivilegedPermission("getEmergencyNumberDbVersion");
9443
9444 final long identity = Binder.clearCallingIdentity();
9445 try {
9446 final Phone phone = getPhone(subId);
9447 if (phone == null) {
9448 loge("getEmergencyNumberDbVersion fails with invalid subId: " + subId);
9449 return TelephonyManager.INVALID_EMERGENCY_NUMBER_DB_VERSION;
9450 }
9451 return phone.getEmergencyNumberDbVersion();
9452 } finally {
9453 Binder.restoreCallingIdentity(identity);
9454 }
9455 }
9456
9457 @Override
9458 public void notifyOtaEmergencyNumberDbInstalled() {
9459 enforceModifyPermission();
9460
9461 final long identity = Binder.clearCallingIdentity();
9462 try {
9463 for (Phone phone: PhoneFactory.getPhones()) {
9464 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
9465 if (tracker != null) {
9466 tracker.updateOtaEmergencyNumberDatabase();
9467 }
9468 }
9469 } finally {
9470 Binder.restoreCallingIdentity(identity);
9471 }
9472 }
9473
9474 @Override
Shuo Qianc373f112020-03-05 17:55:34 -08009475 public void updateOtaEmergencyNumberDbFilePath(ParcelFileDescriptor otaParcelFileDescriptor) {
Shuo Qian3b6ee772019-11-13 17:43:31 -08009476 enforceActiveEmergencySessionPermission();
9477
9478 final long identity = Binder.clearCallingIdentity();
9479 try {
9480 for (Phone phone: PhoneFactory.getPhones()) {
9481 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
9482 if (tracker != null) {
Shuo Qianc373f112020-03-05 17:55:34 -08009483 tracker.updateOtaEmergencyNumberDbFilePath(otaParcelFileDescriptor);
9484 }
9485 }
9486 } finally {
9487 Binder.restoreCallingIdentity(identity);
9488 }
9489 }
9490
9491 @Override
9492 public void resetOtaEmergencyNumberDbFilePath() {
9493 enforceActiveEmergencySessionPermission();
9494
9495 final long identity = Binder.clearCallingIdentity();
9496 try {
9497 for (Phone phone: PhoneFactory.getPhones()) {
9498 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
9499 if (tracker != null) {
9500 tracker.resetOtaEmergencyNumberDbFilePath();
Shuo Qian3b6ee772019-11-13 17:43:31 -08009501 }
9502 }
9503 } finally {
9504 Binder.restoreCallingIdentity(identity);
9505 }
9506 }
9507
9508 @Override
chen xud6b45bd2018-10-30 22:27:10 -07009509 public List<String> getCertsFromCarrierPrivilegeAccessRules(int subId) {
9510 enforceReadPrivilegedPermission("getCertsFromCarrierPrivilegeAccessRules");
9511 Phone phone = getPhone(subId);
9512 if (phone == null) {
9513 return null;
9514 }
9515 final long identity = Binder.clearCallingIdentity();
9516 try {
9517 UiccProfile profile = UiccController.getInstance()
9518 .getUiccProfileForPhone(phone.getPhoneId());
9519 if (profile != null) {
9520 return profile.getCertsFromCarrierPrivilegeAccessRules();
9521 }
9522 } finally {
9523 Binder.restoreCallingIdentity(identity);
9524 }
9525 return null;
9526 }
Malcolm Chen8e4ed912019-01-15 20:22:16 -08009527
9528 /**
9529 * Enable or disable a modem stack.
9530 */
9531 @Override
9532 public boolean enableModemForSlot(int slotIndex, boolean enable) {
9533 enforceModifyPermission();
9534
9535 final long identity = Binder.clearCallingIdentity();
9536 try {
9537 Phone phone = PhoneFactory.getPhone(slotIndex);
9538 if (phone == null) {
9539 return false;
9540 } else {
9541 return (Boolean) sendRequest(CMD_REQUEST_ENABLE_MODEM, enable, phone, null);
9542 }
9543 } finally {
9544 Binder.restoreCallingIdentity(identity);
9545 }
9546 }
Michelecea4cf22018-12-21 15:00:11 -08009547
Malcolm Chen4bcd9822019-03-27 18:34:05 -07009548 /**
9549 * Whether a modem stack is enabled or not.
9550 */
9551 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009552 public boolean isModemEnabledForSlot(int slotIndex, String callingPackage,
9553 String callingFeatureId) {
Malcolm Chen4bcd9822019-03-27 18:34:05 -07009554 Phone phone = PhoneFactory.getPhone(slotIndex);
9555 if (phone == null) return false;
9556
9557 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009558 mApp, phone.getSubId(), callingPackage, callingFeatureId,
9559 "isModemEnabledForSlot")) {
Malcolm Chen4bcd9822019-03-27 18:34:05 -07009560 throw new SecurityException("Requires READ_PHONE_STATE permission.");
9561 }
9562
9563 final long identity = Binder.clearCallingIdentity();
9564 try {
Nazanin Bakhshif71371d2019-04-29 17:29:44 -07009565 try {
9566 return mPhoneConfigurationManager.getPhoneStatusFromCache(phone.getPhoneId());
9567 } catch (NoSuchElementException ex) {
9568 return (Boolean) sendRequest(CMD_GET_MODEM_STATUS, null, phone, null);
9569 }
Malcolm Chen4bcd9822019-03-27 18:34:05 -07009570 } finally {
9571 Binder.restoreCallingIdentity(identity);
9572 }
9573 }
9574
Michelecea4cf22018-12-21 15:00:11 -08009575 @Override
Michele0ea7d782019-03-19 14:58:42 -07009576 public void setMultiSimCarrierRestriction(boolean isMultiSimCarrierRestricted) {
Michelecea4cf22018-12-21 15:00:11 -08009577 enforceModifyPermission();
9578
9579 final long identity = Binder.clearCallingIdentity();
9580 try {
9581 mTelephonySharedPreferences.edit()
Michele0ea7d782019-03-19 14:58:42 -07009582 .putBoolean(PREF_MULTI_SIM_RESTRICTED, isMultiSimCarrierRestricted)
Michelecea4cf22018-12-21 15:00:11 -08009583 .commit();
9584 } finally {
9585 Binder.restoreCallingIdentity(identity);
9586 }
9587 }
9588
9589 @Override
Michele0ea7d782019-03-19 14:58:42 -07009590 @TelephonyManager.IsMultiSimSupportedResult
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009591 public int isMultiSimSupported(String callingPackage, String callingFeatureId) {
Michele4245e952019-02-04 11:36:23 -08009592 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp,
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009593 getDefaultPhone().getSubId(), callingPackage, callingFeatureId,
9594 "isMultiSimSupported")) {
Michele0ea7d782019-03-19 14:58:42 -07009595 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele4245e952019-02-04 11:36:23 -08009596 }
Michelecea4cf22018-12-21 15:00:11 -08009597
9598 final long identity = Binder.clearCallingIdentity();
9599 try {
Michele0ea7d782019-03-19 14:58:42 -07009600 return isMultiSimSupportedInternal();
Michelecea4cf22018-12-21 15:00:11 -08009601 } finally {
9602 Binder.restoreCallingIdentity(identity);
9603 }
9604 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08009605
Michele0ea7d782019-03-19 14:58:42 -07009606 @TelephonyManager.IsMultiSimSupportedResult
9607 private int isMultiSimSupportedInternal() {
Michele30b57b22019-03-01 12:01:14 -08009608 // If the device has less than 2 SIM cards, indicate that multisim is restricted.
9609 int numPhysicalSlots = UiccController.getInstance().getUiccSlots().length;
9610 if (numPhysicalSlots < 2) {
Michele0ea7d782019-03-19 14:58:42 -07009611 loge("isMultiSimSupportedInternal: requires at least 2 cards");
9612 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -08009613 }
9614 // Check if the hardware supports multisim functionality. If usage of multisim is not
9615 // supported by the modem, indicate that it is restricted.
9616 PhoneCapability staticCapability =
9617 mPhoneConfigurationManager.getStaticPhoneCapability();
9618 if (staticCapability == null) {
Michele0ea7d782019-03-19 14:58:42 -07009619 loge("isMultiSimSupportedInternal: no static configuration available");
9620 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -08009621 }
SongFerngWang8236caa2021-01-17 21:51:44 +08009622 if (staticCapability.getLogicalModemList().size() < 2) {
Michele0ea7d782019-03-19 14:58:42 -07009623 loge("isMultiSimSupportedInternal: maximum number of modem is < 2");
9624 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
Michele30b57b22019-03-01 12:01:14 -08009625 }
9626 // Check if support of multiple SIMs is restricted by carrier
9627 if (mTelephonySharedPreferences.getBoolean(PREF_MULTI_SIM_RESTRICTED, false)) {
Michele0ea7d782019-03-19 14:58:42 -07009628 return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_CARRIER;
Michele30b57b22019-03-01 12:01:14 -08009629 }
9630
Michele0ea7d782019-03-19 14:58:42 -07009631 return TelephonyManager.MULTISIM_ALLOWED;
Michele30b57b22019-03-01 12:01:14 -08009632 }
9633
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08009634 /**
9635 * Switch configs to enable multi-sim or switch back to single-sim
Nazanin Bakhshi17318782019-03-01 11:56:08 -08009636 * Note: Switch from multi-sim to single-sim is only possible with MODIFY_PHONE_STATE
9637 * permission, but the other way around is possible with either MODIFY_PHONE_STATE
9638 * or carrier privileges
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08009639 * @param numOfSims number of active sims we want to switch to
9640 */
9641 @Override
9642 public void switchMultiSimConfig(int numOfSims) {
Nazanin Bakhshi17318782019-03-01 11:56:08 -08009643 if (numOfSims == 1) {
9644 enforceModifyPermission();
9645 } else {
9646 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
9647 mApp, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, "switchMultiSimConfig");
9648 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08009649 final long identity = Binder.clearCallingIdentity();
Michele30b57b22019-03-01 12:01:14 -08009650
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08009651 try {
Michele30b57b22019-03-01 12:01:14 -08009652 //only proceed if multi-sim is not restricted
Michele0ea7d782019-03-19 14:58:42 -07009653 if (isMultiSimSupportedInternal() != TelephonyManager.MULTISIM_ALLOWED) {
Michele30b57b22019-03-01 12:01:14 -08009654 loge("switchMultiSimConfig not possible. It is restricted or not supported.");
9655 return;
9656 }
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08009657 mPhoneConfigurationManager.switchMultiSimConfig(numOfSims);
9658 } finally {
9659 Binder.restoreCallingIdentity(identity);
9660 }
9661 }
9662
Hyungjun Parkbb07fde2019-01-10 15:28:51 +09009663 @Override
9664 public boolean isApplicationOnUicc(int subId, int appType) {
9665 enforceReadPrivilegedPermission("isApplicationOnUicc");
9666 Phone phone = getPhone(subId);
9667 if (phone == null) {
9668 return false;
9669 }
9670 final long identity = Binder.clearCallingIdentity();
9671 try {
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00009672 UiccPort uiccPort = phone.getUiccPort();
9673 if (uiccPort == null) {
Hyungjun Parkbb07fde2019-01-10 15:28:51 +09009674 return false;
9675 }
Muralidhar Reddy472c2ae2021-09-29 19:38:40 +00009676 UiccProfile uiccProfile = uiccPort.getUiccProfile();
Hyungjun Parkbb07fde2019-01-10 15:28:51 +09009677 if (uiccProfile == null) {
9678 return false;
9679 }
9680 if (TelephonyManager.APPTYPE_SIM <= appType
9681 && appType <= TelephonyManager.APPTYPE_ISIM) {
9682 return uiccProfile.isApplicationOnIcc(AppType.values()[appType]);
9683 }
9684 return false;
9685 } finally {
9686 Binder.restoreCallingIdentity(identity);
9687 }
9688 }
9689
Nazanin Bakhshi628473f2019-01-29 17:37:52 -08009690 /**
chen xub4baa772019-04-03 10:23:41 -07009691 * Get whether making changes to modem configurations will trigger reboot.
9692 * Return value defaults to true.
Nazanin Bakhshi5fe5ef22019-01-30 10:52:09 -08009693 */
9694 @Override
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009695 public boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage,
9696 String callingFeatureId) {
chen xub4baa772019-04-03 10:23:41 -07009697 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Philip P. Moltmann700a9592019-10-03 11:53:50 -07009698 mApp, subId, callingPackage, callingFeatureId,
9699 "doesSwitchMultiSimConfigTriggerReboot")) {
chen xub4baa772019-04-03 10:23:41 -07009700 return false;
9701 }
Nazanin Bakhshi5fe5ef22019-01-30 10:52:09 -08009702 final long identity = Binder.clearCallingIdentity();
9703 try {
9704 return mPhoneConfigurationManager.isRebootRequiredForModemConfigChange();
9705 } finally {
9706 Binder.restoreCallingIdentity(identity);
9707 }
9708 }
9709
Nathan Harold29f5f052019-02-15 13:41:57 -08009710 private void updateModemStateMetrics() {
9711 TelephonyMetrics metrics = TelephonyMetrics.getInstance();
9712 // TODO: check the state for each modem if the api is ready.
9713 metrics.updateEnabledModemBitmap((1 << TelephonyManager.from(mApp).getPhoneCount()) - 1);
9714 }
9715
Pengquan Meng3889a572019-01-23 11:16:29 -08009716 @Override
sandeepjsa208e3b2021-11-17 04:05:58 +00009717 public List<UiccSlotMapping> getSlotsMapping(String callingPackage) {
Pengquan Meng3889a572019-01-23 11:16:29 -08009718 enforceReadPrivilegedPermission("getSlotsMapping");
sandeepjsa208e3b2021-11-17 04:05:58 +00009719 // Verify that the callingPackage belongs to the calling UID
9720 mApp.getSystemService(AppOpsManager.class)
9721 .checkPackage(Binder.getCallingUid(), callingPackage);
Pengquan Meng3889a572019-01-23 11:16:29 -08009722 final long identity = Binder.clearCallingIdentity();
sandeepjsa208e3b2021-11-17 04:05:58 +00009723 List<UiccSlotMapping> slotMap = new ArrayList<>();
Pengquan Meng3889a572019-01-23 11:16:29 -08009724 try {
sandeepjsa208e3b2021-11-17 04:05:58 +00009725 UiccSlotInfo[] slotInfos = getUiccSlotsInfo(mApp.getOpPackageName());
9726 if (slotInfos != null) {
9727 for (int i = 0; i < slotInfos.length; i++) {
9728 for (UiccPortInfo portInfo : slotInfos[i].getPorts()) {
9729 if (SubscriptionManager.isValidPhoneId(portInfo.getLogicalSlotIndex())) {
9730 slotMap.add(new UiccSlotMapping(portInfo.getPortIndex(), i,
9731 portInfo.getLogicalSlotIndex()));
9732 }
9733 }
Pengquan Meng3889a572019-01-23 11:16:29 -08009734 }
9735 }
sandeepjsa208e3b2021-11-17 04:05:58 +00009736 return slotMap;
Pengquan Meng3889a572019-01-23 11:16:29 -08009737 } finally {
9738 Binder.restoreCallingIdentity(identity);
9739 }
9740 }
Nathan Harold48d6fd52019-02-06 19:01:40 -08009741
9742 /**
9743 * Get the IRadio HAL Version
9744 */
9745 @Override
9746 public int getRadioHalVersion() {
9747 Phone phone = getDefaultPhone();
9748 if (phone == null) return -1;
9749 HalVersion hv = phone.getHalVersion();
9750 if (hv.equals(HalVersion.UNKNOWN)) return -1;
9751 return hv.major * 100 + hv.minor;
9752 }
Malcolm Chendc8c10e2019-04-10 18:25:07 -07009753
9754 /**
Shuo Qianda2d6ec2020-01-14 15:18:28 -08009755 * Get the current calling package name.
9756 * @return the current calling package name
9757 */
9758 @Override
9759 public String getCurrentPackageName() {
9760 return mApp.getPackageManager().getPackagesForUid(Binder.getCallingUid())[0];
9761 }
9762
9763 /**
Malcolm Chene5ad5792019-04-18 13:51:02 -07009764 * Return whether data is enabled for certain APN type. This will tell if framework will accept
9765 * corresponding network requests on a subId.
9766 *
9767 * Data is enabled if:
Malcolm Chendc8c10e2019-04-10 18:25:07 -07009768 * 1) user data is turned on, or
Malcolm Chene5ad5792019-04-18 13:51:02 -07009769 * 2) APN is un-metered for this subscription, or
9770 * 3) APN type is whitelisted. E.g. MMS is whitelisted if
Hall Liu746e03c2020-09-25 11:13:49 -07009771 * {@link TelephonyManager#MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED} is enabled.
Malcolm Chene5ad5792019-04-18 13:51:02 -07009772 *
9773 * @return whether data is allowed for a apn type.
9774 *
9775 * @hide
Malcolm Chendc8c10e2019-04-10 18:25:07 -07009776 */
9777 @Override
Malcolm Chene5ad5792019-04-18 13:51:02 -07009778 public boolean isDataEnabledForApn(int apnType, int subId, String callingPackage) {
Amit Mahajan5d4e1922019-10-07 16:20:43 -07009779 enforceReadPrivilegedPermission("Needs READ_PRIVILEGED_PHONE_STATE for "
9780 + "isDataEnabledForApn");
Malcolm Chendc8c10e2019-04-10 18:25:07 -07009781
9782 // Now that all security checks passes, perform the operation as ourselves.
9783 final long identity = Binder.clearCallingIdentity();
9784 try {
9785 Phone phone = getPhone(subId);
9786 if (phone == null) return false;
9787
Jack Yu41407ee2019-05-13 16:54:09 -07009788 boolean isMetered = ApnSettingUtils.isMeteredApnType(apnType, phone);
Jack Yu99e87332021-12-17 23:14:15 -08009789 boolean isDataEnabled;
9790 if (phone.isUsingNewDataStack()) {
9791 isDataEnabled = phone.getDataSettingsManager().isDataEnabled(apnType);
9792 } else {
9793 isDataEnabled = phone.getDataEnabledSettings().isDataEnabled(apnType);
9794 }
9795 return !isMetered || isDataEnabled;
Malcolm Chene5ad5792019-04-18 13:51:02 -07009796 } finally {
9797 Binder.restoreCallingIdentity(identity);
9798 }
9799 }
9800
9801 @Override
Jack Yu41407ee2019-05-13 16:54:09 -07009802 public boolean isApnMetered(@ApnType int apnType, int subId) {
Malcolm Chene5ad5792019-04-18 13:51:02 -07009803 enforceReadPrivilegedPermission("isApnMetered");
9804
9805 // Now that all security checks passes, perform the operation as ourselves.
9806 final long identity = Binder.clearCallingIdentity();
9807 try {
9808 Phone phone = getPhone(subId);
9809 if (phone == null) return true; // By default return true.
9810
Jack Yu41407ee2019-05-13 16:54:09 -07009811 return ApnSettingUtils.isMeteredApnType(apnType, phone);
Malcolm Chendc8c10e2019-04-10 18:25:07 -07009812 } finally {
9813 Binder.restoreCallingIdentity(identity);
9814 }
9815 }
Brad Ebingera63db5f2019-04-23 16:31:13 -07009816
9817 @Override
Hall Liu73f5d362020-01-20 13:42:00 -08009818 public void setSystemSelectionChannels(List<RadioAccessSpecifier> specifiers,
9819 int subscriptionId, IBooleanConsumer resultCallback) {
9820 enforceModifyPermission();
9821 long token = Binder.clearCallingIdentity();
9822 try {
9823 Phone phone = getPhone(subscriptionId);
9824 if (phone == null) {
9825 try {
9826 if (resultCallback != null) {
9827 resultCallback.accept(false);
9828 }
9829 } catch (RemoteException e) {
9830 // ignore
9831 }
9832 return;
9833 }
9834 Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> argument =
9835 Pair.create(specifiers, (x) -> {
9836 try {
9837 if (resultCallback != null) {
9838 resultCallback.accept(x);
9839 }
9840 } catch (RemoteException e) {
9841 // ignore
9842 }
9843 });
9844 sendRequestAsync(CMD_SET_SYSTEM_SELECTION_CHANNELS, argument, phone, null);
9845 } finally {
9846 Binder.restoreCallingIdentity(token);
9847 }
9848 }
9849
9850 @Override
Sarah Chin679c08a2020-11-18 13:39:35 -08009851 public List<RadioAccessSpecifier> getSystemSelectionChannels(int subId) {
9852 TelephonyPermissions
Nathan Harold62c68512021-04-06 11:26:02 -07009853 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
Sarah Chin679c08a2020-11-18 13:39:35 -08009854 mApp, subId, "getSystemSelectionChannels");
9855 WorkSource workSource = getWorkSource(Binder.getCallingUid());
9856 final long identity = Binder.clearCallingIdentity();
9857 try {
Sarah Chin428d1d62021-03-13 03:17:40 -08009858 Object result = sendRequest(CMD_GET_SYSTEM_SELECTION_CHANNELS, null, subId, workSource);
9859 if (result instanceof IllegalStateException) {
9860 throw (IllegalStateException) result;
9861 }
9862 List<RadioAccessSpecifier> specifiers = (List<RadioAccessSpecifier>) result;
Sarah Chin679c08a2020-11-18 13:39:35 -08009863 if (DBG) log("getSystemSelectionChannels: " + specifiers);
9864 return specifiers;
9865 } finally {
9866 Binder.restoreCallingIdentity(identity);
9867 }
9868 }
9869
9870 @Override
changbetty7157e9e2019-12-06 18:16:37 +08009871 public boolean isMvnoMatched(int subId, int mvnoType, @NonNull String mvnoMatchData) {
changbettyca3d40d2020-03-03 16:27:31 +08009872 enforceReadPrivilegedPermission("isMvnoMatched");
changbetty7157e9e2019-12-06 18:16:37 +08009873 IccRecords iccRecords = UiccController.getInstance().getIccRecords(
9874 SubscriptionManager.getPhoneId(subId), UiccController.APP_FAM_3GPP);
9875 if (iccRecords == null) {
9876 Log.d(LOG_TAG, "isMvnoMatched# IccRecords is null");
9877 return false;
9878 }
9879 return ApnSettingUtils.mvnoMatches(iccRecords, mvnoType, mvnoMatchData);
9880 }
9881
9882 @Override
Philip P. Moltmannd02b7372020-03-18 17:06:12 -07009883 public void enqueueSmsPickResult(String callingPackage, String callingAttributionTag,
9884 IIntegerConsumer pendingSubIdResult) {
Shuo Qianda2d6ec2020-01-14 15:18:28 -08009885 if (callingPackage == null) {
9886 callingPackage = getCurrentPackageName();
9887 }
Brad Ebingera63db5f2019-04-23 16:31:13 -07009888 SmsPermissions permissions = new SmsPermissions(getDefaultPhone(), mApp,
9889 (AppOpsManager) mApp.getSystemService(Context.APP_OPS_SERVICE));
Philip P. Moltmannd02b7372020-03-18 17:06:12 -07009890 if (!permissions.checkCallingCanSendSms(callingPackage, callingAttributionTag,
9891 "Sending message")) {
Brad Ebingera63db5f2019-04-23 16:31:13 -07009892 throw new SecurityException("Requires SEND_SMS permission to perform this operation");
9893 }
9894 PickSmsSubscriptionActivity.addPendingResult(pendingSubIdResult);
9895 Intent intent = new Intent();
9896 intent.setClass(mApp, PickSmsSubscriptionActivity.class);
9897 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9898 // Bring up choose default SMS subscription dialog right now
9899 intent.putExtra(PickSmsSubscriptionActivity.DIALOG_TYPE_KEY,
9900 PickSmsSubscriptionActivity.SMS_PICK_FOR_MESSAGE);
9901 mApp.startActivity(intent);
9902 }
chen xud5ca2d52019-05-28 15:20:57 -07009903
9904 @Override
9905 public String getMmsUAProfUrl(int subId) {
9906 //TODO investigate if this API should require proper permission check in R b/133791609
9907 final long identity = Binder.clearCallingIdentity();
9908 try {
Guoqiang.Qiu171383d2020-07-13 09:38:32 +08009909 String carrierUAProfUrl = mApp.getCarrierConfigForSubId(subId).getString(
9910 CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING);
9911 if (!TextUtils.isEmpty(carrierUAProfUrl)) {
9912 return carrierUAProfUrl;
9913 }
Daniel Brightebb4eb72020-02-18 15:16:33 -08009914 return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
9915 .getString(com.android.internal.R.string.config_mms_user_agent_profile_url);
chen xud5ca2d52019-05-28 15:20:57 -07009916 } finally {
9917 Binder.restoreCallingIdentity(identity);
9918 }
9919 }
9920
9921 @Override
9922 public String getMmsUserAgent(int subId) {
9923 //TODO investigate if this API should require proper permission check in R b/133791609
9924 final long identity = Binder.clearCallingIdentity();
9925 try {
Guoqiang.Qiu171383d2020-07-13 09:38:32 +08009926 String carrierUserAgent = mApp.getCarrierConfigForSubId(subId).getString(
9927 CarrierConfigManager.KEY_MMS_USER_AGENT_STRING);
9928 if (!TextUtils.isEmpty(carrierUserAgent)) {
9929 return carrierUserAgent;
9930 }
Daniel Brightebb4eb72020-02-18 15:16:33 -08009931 return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
9932 .getString(com.android.internal.R.string.config_mms_user_agent);
chen xud5ca2d52019-05-28 15:20:57 -07009933 } finally {
9934 Binder.restoreCallingIdentity(identity);
9935 }
9936 }
Jack Yub07d4972019-05-28 16:12:25 -07009937
9938 @Override
Hall Liua62f5da2020-09-25 10:42:19 -07009939 public boolean isMobileDataPolicyEnabled(int subscriptionId, int policy) {
9940 enforceReadPrivilegedPermission("isMobileDataPolicyEnabled");
Jack Yub07d4972019-05-28 16:12:25 -07009941
Jack Yub07d4972019-05-28 16:12:25 -07009942 final long identity = Binder.clearCallingIdentity();
9943 try {
Hall Liua62f5da2020-09-25 10:42:19 -07009944 Phone phone = getPhone(subscriptionId);
Jack Yub07d4972019-05-28 16:12:25 -07009945 if (phone == null) return false;
9946
Hall Liua62f5da2020-09-25 10:42:19 -07009947 switch (policy) {
9948 case TelephonyManager.MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL:
Jack Yu99e87332021-12-17 23:14:15 -08009949 if (phone.isUsingNewDataStack()) {
9950 return phone.getDataSettingsManager().isDataAllowedInVoiceCall();
9951 } else {
9952 return phone.getDataEnabledSettings().isDataAllowedInVoiceCall();
9953 }
Hall Liua62f5da2020-09-25 10:42:19 -07009954 case TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED:
Jack Yu99e87332021-12-17 23:14:15 -08009955 if (phone.isUsingNewDataStack()) {
9956 return phone.getDataSettingsManager().isMmsAlwaysAllowed();
9957 } else {
9958 return phone.getDataEnabledSettings().isMmsAlwaysAllowed();
9959 }
Hall Liua62f5da2020-09-25 10:42:19 -07009960 default:
9961 throw new IllegalArgumentException(policy + " is not a valid policy");
9962 }
Jack Yub07d4972019-05-28 16:12:25 -07009963 } finally {
9964 Binder.restoreCallingIdentity(identity);
9965 }
9966 }
9967
9968 @Override
Hall Liuc66bb112021-02-02 12:09:32 -08009969 public void setMobileDataPolicyEnabled(int subscriptionId, int policy,
Hall Liua62f5da2020-09-25 10:42:19 -07009970 boolean enabled) {
changbettyd5c246e2019-12-24 15:40:37 +08009971 enforceModifyPermission();
9972
changbettyd5c246e2019-12-24 15:40:37 +08009973 final long identity = Binder.clearCallingIdentity();
9974 try {
Hall Liua62f5da2020-09-25 10:42:19 -07009975 Phone phone = getPhone(subscriptionId);
9976 if (phone == null) return;
changbettyd5c246e2019-12-24 15:40:37 +08009977
Hall Liua62f5da2020-09-25 10:42:19 -07009978 switch (policy) {
9979 case TelephonyManager.MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL:
Jack Yu99e87332021-12-17 23:14:15 -08009980 if (phone.isUsingNewDataStack()) {
9981 phone.getDataSettingsManager().setAllowDataDuringVoiceCall(enabled);
9982 } else {
9983 phone.getDataEnabledSettings().setAllowDataDuringVoiceCall(enabled);
9984 }
Hall Liua62f5da2020-09-25 10:42:19 -07009985 break;
9986 case TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED:
Jack Yu99e87332021-12-17 23:14:15 -08009987 if (phone.isUsingNewDataStack()) {
9988 phone.getDataSettingsManager().setAlwaysAllowMmsData(enabled);
9989 } else {
9990 phone.getDataEnabledSettings().setAlwaysAllowMmsData(enabled);
9991 }
Hall Liua62f5da2020-09-25 10:42:19 -07009992 break;
9993 default:
9994 throw new IllegalArgumentException(policy + " is not a valid policy");
9995 }
changbettyd5c246e2019-12-24 15:40:37 +08009996 } finally {
9997 Binder.restoreCallingIdentity(identity);
9998 }
9999 }
10000
Tyler Gunn7bcdc742019-10-04 15:56:59 -070010001 /**
Hall Liu746e03c2020-09-25 11:13:49 -070010002 * Updates whether conference event package handling is enabled.
Tyler Gunn7bcdc742019-10-04 15:56:59 -070010003 * @param isCepEnabled {@code true} if CEP handling is enabled (default), or {@code false}
10004 * otherwise.
10005 */
10006 @Override
10007 public void setCepEnabled(boolean isCepEnabled) {
10008 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setCepEnabled");
10009
10010 final long identity = Binder.clearCallingIdentity();
10011 try {
10012 Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled);
10013 for (Phone phone : PhoneFactory.getPhones()) {
10014 Phone defaultPhone = phone.getImsPhone();
10015 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
10016 ImsPhone imsPhone = (ImsPhone) defaultPhone;
10017 ImsPhoneCallTracker imsPhoneCallTracker =
10018 (ImsPhoneCallTracker) imsPhone.getCallTracker();
10019 imsPhoneCallTracker.setConferenceEventPackageEnabled(isCepEnabled);
10020 Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled + ", for imsPhone "
10021 + imsPhone.getMsisdn());
10022 }
10023 }
10024 } finally {
10025 Binder.restoreCallingIdentity(identity);
10026 }
10027 }
allenwtsu46dcc572020-01-08 18:24:03 +080010028
10029 /**
10030 * Notify that an RCS autoconfiguration XML file has been received for provisioning.
10031 *
10032 * @param config The XML file to be read. ASCII/UTF8 encoded text if not compressed.
10033 * @param isCompressed The XML file is compressed in gzip format and must be decompressed
10034 * before being read.
10035 */
10036 @Override
10037 public void notifyRcsAutoConfigurationReceived(int subId, @NonNull byte[] config, boolean
10038 isCompressed) {
10039 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
10040 mApp, subId, "notifyRcsAutoConfigurationReceived");
Hui Wang761a6682020-10-31 05:12:53 +000010041 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
10042 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
10043 }
10044 if (!isImsAvailableOnDevice()) {
10045 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
10046 "IMS not available on device.");
10047 }
10048
10049 final long identity = Binder.clearCallingIdentity();
allenwtsu46dcc572020-01-08 18:24:03 +080010050 try {
Hui Wang761a6682020-10-31 05:12:53 +000010051 RcsProvisioningMonitor.getInstance().updateConfig(subId, config, isCompressed);
10052 } finally {
10053 Binder.restoreCallingIdentity(identity);
allenwtsu46dcc572020-01-08 18:24:03 +080010054 }
10055 }
zoey chene02881a2019-12-30 16:11:23 +080010056
10057 @Override
10058 public boolean isIccLockEnabled(int subId) {
10059 enforceReadPrivilegedPermission("isIccLockEnabled");
10060
10061 // Now that all security checks passes, perform the operation as ourselves.
10062 final long identity = Binder.clearCallingIdentity();
10063 try {
10064 Phone phone = getPhone(subId);
10065 if (phone != null && phone.getIccCard() != null) {
10066 return phone.getIccCard().getIccLockEnabled();
10067 } else {
10068 return false;
10069 }
10070 } finally {
10071 Binder.restoreCallingIdentity(identity);
10072 }
10073 }
10074
10075 /**
10076 * Set the ICC pin lock enabled or disabled.
10077 *
10078 * @return an integer representing the status of IccLock enabled or disabled in the following
10079 * three cases:
10080 * - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if enabled or disabled IccLock
10081 * successfully.
10082 * - Positive number and zero for remaining password attempts.
10083 * - Negative number for other failure cases (such like enabling/disabling PIN failed).
10084 *
10085 */
10086 @Override
10087 public int setIccLockEnabled(int subId, boolean enabled, String password) {
10088 enforceModifyPermission();
10089
10090 Phone phone = getPhone(subId);
10091 if (phone == null) {
10092 return 0;
10093 }
10094 // Now that all security checks passes, perform the operation as ourselves.
10095 final long identity = Binder.clearCallingIdentity();
10096 try {
10097 int attemptsRemaining = (int) sendRequest(CMD_SET_ICC_LOCK_ENABLED,
10098 new Pair<Boolean, String>(enabled, password), phone, null);
10099 return attemptsRemaining;
10100
10101 } catch (Exception e) {
10102 Log.e(LOG_TAG, "setIccLockEnabled. Exception e =" + e);
10103 } finally {
10104 Binder.restoreCallingIdentity(identity);
10105 }
10106 return 0;
10107 }
10108
10109 /**
10110 * Change the ICC password used in ICC pin lock.
10111 *
10112 * @return an integer representing the status of IccLock changed in the following three cases:
10113 * - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if changed IccLock successfully.
10114 * - Positive number and zero for remaining password attempts.
10115 * - Negative number for other failure cases (such like enabling/disabling PIN failed).
10116 *
10117 */
10118 @Override
10119 public int changeIccLockPassword(int subId, String oldPassword, String newPassword) {
10120 enforceModifyPermission();
10121
10122 Phone phone = getPhone(subId);
10123 if (phone == null) {
10124 return 0;
10125 }
10126 // Now that all security checks passes, perform the operation as ourselves.
10127 final long identity = Binder.clearCallingIdentity();
10128 try {
10129 int attemptsRemaining = (int) sendRequest(CMD_CHANGE_ICC_LOCK_PASSWORD,
10130 new Pair<String, String>(oldPassword, newPassword), phone, null);
10131 return attemptsRemaining;
10132
10133 } catch (Exception e) {
10134 Log.e(LOG_TAG, "changeIccLockPassword. Exception e =" + e);
10135 } finally {
10136 Binder.restoreCallingIdentity(identity);
10137 }
10138 return 0;
10139 }
Peter Wangdafb9ac2020-01-15 14:13:38 -080010140
10141 /**
10142 * Request for receiving user activity notification
10143 */
10144 @Override
10145 public void requestUserActivityNotification() {
10146 if (!mNotifyUserActivity.get()
10147 && !mMainThreadHandler.hasMessages(MSG_NOTIFY_USER_ACTIVITY)) {
10148 mNotifyUserActivity.set(true);
10149 }
10150 }
10151
10152 /**
10153 * Called when userActivity is signalled in the power manager.
10154 * This is safe to call from any thread, with any window manager locks held or not.
10155 */
10156 @Override
10157 public void userActivity() {
10158 // ***************************************
10159 // * Inherited from PhoneWindowManager *
10160 // ***************************************
10161 // THIS IS CALLED FROM DEEP IN THE POWER MANAGER
10162 // WITH ITS LOCKS HELD.
10163 //
10164 // This code must be VERY careful about the locks
10165 // it acquires.
10166 // In fact, the current code acquires way too many,
10167 // and probably has lurking deadlocks.
10168
10169 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10170 throw new SecurityException("Only the OS may call notifyUserActivity()");
10171 }
10172
10173 if (mNotifyUserActivity.getAndSet(false)) {
10174 mMainThreadHandler.sendEmptyMessageDelayed(MSG_NOTIFY_USER_ACTIVITY,
10175 USER_ACTIVITY_NOTIFICATION_DELAY);
10176 }
10177 }
Malcolm Chen4639c562020-04-13 11:59:40 -070010178
10179 @Override
10180 public boolean canConnectTo5GInDsdsMode() {
10181 return mApp.getResources().getBoolean(R.bool.config_5g_connection_in_dsds_mode);
10182 }
Jack Yud10cdd42020-09-28 20:28:01 -070010183
10184 @Override
10185 public @NonNull List<String> getEquivalentHomePlmns(int subId, String callingPackage,
10186 String callingFeatureId) {
10187 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
10188 mApp, subId, callingPackage, callingFeatureId, "getEquivalentHomePlmns")) {
10189 throw new SecurityException("Requires READ_PHONE_STATE permission.");
10190 }
10191
10192 Phone phone = getPhone(subId);
10193 if (phone == null) {
10194 throw new RuntimeException("phone is not available");
10195 }
10196 // Now that all security checks passes, perform the operation as ourselves.
10197 final long identity = Binder.clearCallingIdentity();
10198 try {
10199 return phone.getEquivalentHomePlmns();
10200 } finally {
10201 Binder.restoreCallingIdentity(identity);
10202 }
10203 }
Daniel Bright59e67312020-11-13 11:49:37 -080010204
10205 @Override
10206 public boolean isRadioInterfaceCapabilitySupported(
Daniel Bright95a4c1f2021-02-11 09:57:16 -080010207 final @NonNull @TelephonyManager.RadioInterfaceCapability String capability) {
10208 Set<String> radioInterfaceCapabilities =
Daniel Bright94f43662021-03-01 14:43:40 -080010209 mRadioInterfaceCapabilities.getCapabilities();
Daniel Bright59e67312020-11-13 11:49:37 -080010210 if (radioInterfaceCapabilities == null) {
10211 throw new RuntimeException("radio interface capabilities are not available");
Daniel Bright59e67312020-11-13 11:49:37 -080010212 }
Daniel Bright95a4c1f2021-02-11 09:57:16 -080010213 return radioInterfaceCapabilities.contains(capability);
Daniel Bright59e67312020-11-13 11:49:37 -080010214 }
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010215
Hui Wang641e81c2020-10-12 12:14:23 -070010216 @Override
10217 public void bootstrapAuthenticationRequest(int subId, int appType, Uri nafUrl,
10218 UaSecurityProtocolIdentifier securityProtocol,
Brad Ebinger34c09a52021-02-17 23:23:21 +000010219 boolean forceBootStrapping, IBootstrapAuthenticationCallback callback) {
10220 TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
10221 Binder.getCallingUid(), "bootstrapAuthenticationRequest",
10222 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
10223 Manifest.permission.MODIFY_PHONE_STATE);
Hui Wang641e81c2020-10-12 12:14:23 -070010224 if (DBG) {
10225 log("bootstrapAuthenticationRequest, subId:" + subId + ", appType:"
10226 + appType + ", NAF:" + nafUrl + ", sp:" + securityProtocol
10227 + ", forceBootStrapping:" + forceBootStrapping + ", callback:" + callback);
10228 }
10229
10230 if (!SubscriptionManager.isValidSubscriptionId(subId)
10231 || appType < TelephonyManager.APPTYPE_UNKNOWN
10232 || appType > TelephonyManager.APPTYPE_ISIM
10233 || nafUrl == null || securityProtocol == null || callback == null) {
10234 Log.d(LOG_TAG, "bootstrapAuthenticationRequest failed due to invalid parameters");
10235 if (callback != null) {
10236 try {
10237 callback.onAuthenticationFailure(
10238 0, TelephonyManager.GBA_FAILURE_REASON_FEATURE_NOT_SUPPORTED);
10239 } catch (RemoteException exception) {
10240 log("Fail to notify onAuthenticationFailure due to " + exception);
10241 }
10242 return;
10243 }
10244 }
10245
10246 final long token = Binder.clearCallingIdentity();
10247 try {
10248 getGbaManager(subId).bootstrapAuthenticationRequest(
10249 new GbaAuthRequest(subId, appType, nafUrl, securityProtocol.toByteArray(),
10250 forceBootStrapping, callback));
10251 } finally {
10252 Binder.restoreCallingIdentity(token);
10253 }
10254 }
10255
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010256 /**
Sooraj Sasindran72cff492021-07-29 09:42:42 -070010257 * Attempts to set the radio power state for all phones for thermal reason.
10258 * This does not guarantee that the
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010259 * requested radio power state will actually be set. See {@link
10260 * PhoneInternalInterface#setRadioPowerForReason} for more details.
10261 *
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010262 * @param enable {@code true} if trying to turn radio on.
10263 * @return {@code true} if phone setRadioPowerForReason was called. Otherwise, returns {@code
10264 * false}.
10265 */
Sooraj Sasindran72cff492021-07-29 09:42:42 -070010266 private boolean setRadioPowerForThermal(boolean enable) {
10267 boolean isPhoneAvailable = false;
10268 for (int i = 0; i < TelephonyManager.getDefault().getActiveModemCount(); i++) {
10269 Phone phone = PhoneFactory.getPhone(i);
10270 if (phone != null) {
10271 phone.setRadioPowerForReason(enable, Phone.RADIO_POWER_REASON_THERMAL);
10272 isPhoneAvailable = true;
10273 }
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010274 }
Sooraj Sasindran72cff492021-07-29 09:42:42 -070010275
10276 // return true if successfully informed the phone object about the thermal radio power
10277 // request.
10278 return isPhoneAvailable;
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010279 }
10280
10281 private int handleDataThrottlingRequest(int subId,
10282 DataThrottlingRequest dataThrottlingRequest) {
Jack Nudelman5d6a98b2021-03-04 14:26:25 -080010283 boolean isDataThrottlingSupported = isRadioInterfaceCapabilitySupported(
10284 TelephonyManager.CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING);
10285 if (!isDataThrottlingSupported && dataThrottlingRequest.getDataThrottlingAction()
10286 != DataThrottlingRequest.DATA_THROTTLING_ACTION_NO_DATA_THROTTLING) {
10287 throw new IllegalArgumentException("modem does not support data throttling");
10288 }
10289
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010290 // Ensure that radio is on. If not able to power on due to phone being unavailable, return
10291 // THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
Sooraj Sasindran72cff492021-07-29 09:42:42 -070010292 if (!setRadioPowerForThermal(true)) {
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010293 return TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
10294 }
10295
10296 setDataEnabledForReason(subId, TelephonyManager.DATA_ENABLED_REASON_THERMAL, true);
10297
Jack Nudelman5d6a98b2021-03-04 14:26:25 -080010298 if (isDataThrottlingSupported) {
10299 int thermalMitigationResult =
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010300 (int) sendRequest(CMD_SET_DATA_THROTTLING, dataThrottlingRequest, subId);
Jack Nudelman5d6a98b2021-03-04 14:26:25 -080010301 if (thermalMitigationResult == SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS) {
10302 throw new IllegalArgumentException("modem returned INVALID_ARGUMENTS");
10303 } else if (thermalMitigationResult
10304 == MODEM_DOES_NOT_SUPPORT_DATA_THROTTLING_ERROR_CODE) {
Jack Nudelman760d0962021-05-20 13:57:30 -070010305 log("Modem likely does not support data throttling on secondary carrier. Data " +
10306 "throttling action = " + dataThrottlingRequest.getDataThrottlingAction());
10307 return TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
Jack Nudelman5d6a98b2021-03-04 14:26:25 -080010308 }
10309 return thermalMitigationResult;
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010310 }
Jack Nudelman5d6a98b2021-03-04 14:26:25 -080010311
10312 return TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010313 }
10314
Jack Nudelman644b91a2021-03-12 14:09:48 -080010315 private static List<String> getThermalMitigationAllowlist(Context context) {
10316 if (sThermalMitigationAllowlistedPackages.isEmpty()) {
10317 for (String pckg : context.getResources()
10318 .getStringArray(R.array.thermal_mitigation_allowlisted_packages)) {
10319 sThermalMitigationAllowlistedPackages.add(pckg);
10320 }
10321 }
10322
10323 return sThermalMitigationAllowlistedPackages;
10324 }
10325
Jack Nudelmane69bbc82021-05-13 10:00:15 -070010326 private boolean isAnyPhoneInEmergencyState() {
10327 TelecomManager tm = mApp.getSystemService(TelecomManager.class);
10328 if (tm.isInEmergencyCall()) {
10329 Log.e(LOG_TAG , "Phone state is not valid. One of the phones is in an emergency call");
10330 return true;
10331 }
10332 for (Phone phone : PhoneFactory.getPhones()) {
10333 if (phone.isInEmergencySmsMode() || phone.isInEcm()) {
10334 Log.e(LOG_TAG, "Phone state is not valid. isInEmergencySmsMode = "
10335 + phone.isInEmergencySmsMode() + " isInEmergencyCallbackMode = "
10336 + phone.isInEcm());
10337 return true;
10338 }
10339 }
10340
10341 return false;
10342 }
10343
Jack Nudelman644b91a2021-03-12 14:09:48 -080010344 /**
10345 * Used by shell commands to add an authorized package name for thermal mitigation.
10346 * @param packageName name of package to be allowlisted
10347 * @param context
10348 */
10349 static void addPackageToThermalMitigationAllowlist(String packageName, Context context) {
10350 sThermalMitigationAllowlistedPackages = getThermalMitigationAllowlist(context);
10351 sThermalMitigationAllowlistedPackages.add(packageName);
10352 }
10353
10354 /**
10355 * Used by shell commands to remove an authorized package name for thermal mitigation.
10356 * @param packageName name of package to remove from allowlist
10357 * @param context
10358 */
10359 static void removePackageFromThermalMitigationAllowlist(String packageName, Context context) {
10360 sThermalMitigationAllowlistedPackages = getThermalMitigationAllowlist(context);
10361 sThermalMitigationAllowlistedPackages.remove(packageName);
10362 }
10363
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010364 /**
10365 * Thermal mitigation request to control functionalities at modem.
10366 *
10367 * @param subId the id of the subscription.
10368 * @param thermalMitigationRequest holds all necessary information to be passed down to modem.
Jack Nudelman644b91a2021-03-12 14:09:48 -080010369 * @param callingPackage the package name of the calling package.
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010370 *
10371 * @return thermalMitigationResult enum as defined in android.telephony.Annotation.
10372 */
10373 @Override
10374 @ThermalMitigationResult
10375 public int sendThermalMitigationRequest(
10376 int subId,
Jack Nudelman644b91a2021-03-12 14:09:48 -080010377 ThermalMitigationRequest thermalMitigationRequest,
10378 String callingPackage) throws IllegalArgumentException {
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010379 enforceModifyPermission();
10380
Jack Nudelman644b91a2021-03-12 14:09:48 -080010381 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
10382 if (!getThermalMitigationAllowlist(getDefaultPhone().getContext())
10383 .contains(callingPackage)) {
10384 throw new SecurityException("Calling package must be configured in the device config. "
10385 + "calling package: " + callingPackage);
10386 }
10387
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010388 WorkSource workSource = getWorkSource(Binder.getCallingUid());
10389 final long identity = Binder.clearCallingIdentity();
10390
10391 int thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_UNKNOWN_ERROR;
10392 try {
10393 int thermalMitigationAction = thermalMitigationRequest.getThermalMitigationAction();
10394 switch (thermalMitigationAction) {
10395 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_DATA_THROTTLING:
10396 thermalMitigationResult =
10397 handleDataThrottlingRequest(subId,
10398 thermalMitigationRequest.getDataThrottlingRequest());
10399 break;
10400 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_VOICE_ONLY:
10401 if (thermalMitigationRequest.getDataThrottlingRequest() != null) {
10402 throw new IllegalArgumentException("dataThrottlingRequest must be null for "
10403 + "ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_VOICE_ONLY");
10404 }
10405
10406 // Ensure that radio is on. If not able to power on due to phone being
10407 // unavailable, return THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
Sooraj Sasindran72cff492021-07-29 09:42:42 -070010408 if (!setRadioPowerForThermal(true)) {
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010409 thermalMitigationResult =
10410 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
10411 break;
10412 }
10413
10414 setDataEnabledForReason(subId, TelephonyManager.DATA_ENABLED_REASON_THERMAL,
10415 false);
10416 thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
10417 break;
10418 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_RADIO_OFF:
10419 if (thermalMitigationRequest.getDataThrottlingRequest() != null) {
10420 throw new IllegalArgumentException("dataThrottlingRequest must be null for"
10421 + " ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_RADIO_OFF");
10422 }
10423
10424 TelecomAccountRegistry registry = TelecomAccountRegistry.getInstance(null);
10425 if (registry != null) {
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010426 Phone phone = getPhone(subId);
10427 if (phone == null) {
10428 thermalMitigationResult =
10429 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
10430 break;
10431 }
10432
Jack Nudelmane69bbc82021-05-13 10:00:15 -070010433 TelephonyConnectionService service =
10434 registry.getTelephonyConnectionService();
Jack Nudelmanb30ac302021-06-17 15:39:58 -070010435 if (service != null && service.isEmergencyCallPending()) {
Jack Nudelmane69bbc82021-05-13 10:00:15 -070010436 Log.e(LOG_TAG, "An emergency call is pending");
10437 thermalMitigationResult =
10438 TelephonyManager.THERMAL_MITIGATION_RESULT_INVALID_STATE;
10439 break;
10440 } else if (isAnyPhoneInEmergencyState()) {
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010441 thermalMitigationResult =
10442 TelephonyManager.THERMAL_MITIGATION_RESULT_INVALID_STATE;
10443 break;
10444 }
10445 } else {
10446 thermalMitigationResult =
10447 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
10448 break;
10449 }
10450
10451 // Turn radio off. If not able to power off due to phone being unavailable,
10452 // return THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
Sooraj Sasindran72cff492021-07-29 09:42:42 -070010453 if (!setRadioPowerForThermal(false)) {
Jack Nudelmanb0b87642020-11-12 15:04:39 -080010454 thermalMitigationResult =
10455 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
10456 break;
10457 }
10458 thermalMitigationResult =
10459 TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
10460 break;
10461 default:
10462 throw new IllegalArgumentException("the requested thermalMitigationAction does "
10463 + "not exist. Requested action: " + thermalMitigationAction);
10464 }
10465 } catch (IllegalArgumentException e) {
10466 throw e;
10467 } catch (Exception e) {
10468 Log.e(LOG_TAG, "thermalMitigationRequest. Exception e =" + e);
10469 thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
10470 } finally {
10471 Binder.restoreCallingIdentity(identity);
10472 }
10473
10474 if (DBG) {
10475 log("thermalMitigationRequest returning with thermalMitigationResult: "
10476 + thermalMitigationResult);
10477 }
10478
10479 return thermalMitigationResult;
10480 }
Hui Wang641e81c2020-10-12 12:14:23 -070010481
10482 /**
10483 * Set the GbaService Package Name that Telephony will bind to.
10484 *
10485 * @param subId The sim that the GbaService is associated with.
10486 * @param packageName The name of the package to be replaced with.
10487 * @return true if setting the GbaService to bind to succeeded, false if it did not.
10488 */
10489 @Override
10490 public boolean setBoundGbaServiceOverride(int subId, String packageName) {
10491 enforceModifyPermission();
10492
10493 final long identity = Binder.clearCallingIdentity();
10494 try {
10495 return getGbaManager(subId).overrideServicePackage(packageName);
10496 } finally {
10497 Binder.restoreCallingIdentity(identity);
10498 }
10499 }
10500
10501 /**
10502 * Return the package name of the currently bound GbaService.
10503 *
10504 * @param subId The sim that the GbaService is associated with.
10505 * @return the package name of the GbaService configuration, null if GBA is not supported.
10506 */
10507 @Override
10508 public String getBoundGbaService(int subId) {
10509 enforceReadPrivilegedPermission("getBoundGbaServicePackage");
10510
10511 final long identity = Binder.clearCallingIdentity();
10512 try {
10513 return getGbaManager(subId).getServicePackage();
10514 } finally {
10515 Binder.restoreCallingIdentity(identity);
10516 }
10517 }
10518
10519 /**
10520 * Set the release time for telephony to unbind GbaService.
10521 *
10522 * @param subId The sim that the GbaService is associated with.
10523 * @param interval The release time to unbind GbaService by millisecond.
10524 * @return true if setting the GbaService to bind to succeeded, false if it did not.
10525 */
10526 @Override
10527 public boolean setGbaReleaseTimeOverride(int subId, int interval) {
10528 enforceModifyPermission();
10529
10530 final long identity = Binder.clearCallingIdentity();
10531 try {
10532 return getGbaManager(subId).overrideReleaseTime(interval);
10533 } finally {
10534 Binder.restoreCallingIdentity(identity);
10535 }
10536 }
10537
10538 /**
10539 * Return the release time for telephony to unbind GbaService.
10540 *
10541 * @param subId The sim that the GbaService is associated with.
10542 * @return The release time to unbind GbaService by millisecond.
10543 */
10544 @Override
10545 public int getGbaReleaseTime(int subId) {
10546 enforceReadPrivilegedPermission("getGbaReleaseTime");
10547
10548 final long identity = Binder.clearCallingIdentity();
10549 try {
10550 return getGbaManager(subId).getReleaseTime();
10551 } finally {
10552 Binder.restoreCallingIdentity(identity);
10553 }
10554 }
10555
10556 private GbaManager getGbaManager(int subId) {
10557 GbaManager instance = GbaManager.getInstance(subId);
10558 if (instance == null) {
10559 String packageName = mApp.getResources().getString(R.string.config_gba_package);
10560 int releaseTime = mApp.getResources().getInteger(R.integer.config_gba_release_time);
10561 instance = GbaManager.make(mApp, subId, packageName, releaseTime);
10562 }
10563 return instance;
10564 }
Hui Wang761a6682020-10-31 05:12:53 +000010565
10566 /**
10567 * indicate whether the device and the carrier can support
10568 * RCS VoLTE single registration.
10569 */
10570 @Override
10571 public boolean isRcsVolteSingleRegistrationCapable(int subId) {
Brad Ebinger34c09a52021-02-17 23:23:21 +000010572 TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
10573 Binder.getCallingUid(), "isRcsVolteSingleRegistrationCapable",
10574 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
10575 permission.READ_PRIVILEGED_PHONE_STATE);
Hui Wang761a6682020-10-31 05:12:53 +000010576
10577 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
10578 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
10579 }
10580
10581 final long identity = Binder.clearCallingIdentity();
10582 try {
10583 RcsProvisioningMonitor rpm = RcsProvisioningMonitor.getInstance();
10584 if (rpm != null) {
Hui Wang67af90e2021-06-04 16:57:15 -070010585 Boolean isCapable = rpm.isRcsVolteSingleRegistrationEnabled(subId);
10586 if (isCapable != null) {
10587 return isCapable;
10588 }
Hui Wang761a6682020-10-31 05:12:53 +000010589 }
Hui Wang67af90e2021-06-04 16:57:15 -070010590 throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
10591 "service is temporarily unavailable.");
Hui Wang761a6682020-10-31 05:12:53 +000010592 } finally {
10593 Binder.restoreCallingIdentity(identity);
10594 }
10595 }
10596
10597 /**
10598 * Register RCS provisioning callback.
10599 */
10600 @Override
Hui Wang3cac7e52021-01-27 14:45:25 -080010601 public void registerRcsProvisioningCallback(int subId,
Hui Wang761a6682020-10-31 05:12:53 +000010602 IRcsConfigCallback callback) {
Brad Ebinger34c09a52021-02-17 23:23:21 +000010603 TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
Hui Wang3cac7e52021-01-27 14:45:25 -080010604 Binder.getCallingUid(), "registerRcsProvisioningCallback",
Brad Ebinger34c09a52021-02-17 23:23:21 +000010605 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
10606 permission.READ_PRIVILEGED_PHONE_STATE);
Hui Wang761a6682020-10-31 05:12:53 +000010607
10608 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
10609 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
10610 }
10611 if (!isImsAvailableOnDevice()) {
10612 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
10613 "IMS not available on device.");
10614 }
10615
10616 final long identity = Binder.clearCallingIdentity();
10617 try {
Hui Wang68cd3722021-01-11 20:04:53 -080010618 if (!RcsProvisioningMonitor.getInstance()
Hui Wang3cac7e52021-01-27 14:45:25 -080010619 .registerRcsProvisioningCallback(subId, callback)) {
Brad Ebinger919631e2021-06-02 17:46:35 -070010620 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
10621 "Active subscription not found.");
Hui Wang68cd3722021-01-11 20:04:53 -080010622 }
Hui Wang761a6682020-10-31 05:12:53 +000010623 } finally {
10624 Binder.restoreCallingIdentity(identity);
10625 }
10626 }
10627
10628 /**
10629 * Unregister RCS provisioning callback.
10630 */
10631 @Override
Hui Wang3cac7e52021-01-27 14:45:25 -080010632 public void unregisterRcsProvisioningCallback(int subId,
Hui Wang761a6682020-10-31 05:12:53 +000010633 IRcsConfigCallback callback) {
Brad Ebinger34c09a52021-02-17 23:23:21 +000010634 TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
Hui Wang3cac7e52021-01-27 14:45:25 -080010635 Binder.getCallingUid(), "unregisterRcsProvisioningCallback",
Brad Ebinger34c09a52021-02-17 23:23:21 +000010636 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
10637 permission.READ_PRIVILEGED_PHONE_STATE);
Hui Wang761a6682020-10-31 05:12:53 +000010638
10639 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
10640 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
10641 }
10642 if (!isImsAvailableOnDevice()) {
10643 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
10644 "IMS not available on device.");
10645 }
10646
10647 final long identity = Binder.clearCallingIdentity();
10648 try {
Hui Wang68cd3722021-01-11 20:04:53 -080010649 RcsProvisioningMonitor.getInstance()
Hui Wang3cac7e52021-01-27 14:45:25 -080010650 .unregisterRcsProvisioningCallback(subId, callback);
Hui Wang761a6682020-10-31 05:12:53 +000010651 } finally {
10652 Binder.restoreCallingIdentity(identity);
10653 }
10654 }
10655
10656 /**
10657 * trigger RCS reconfiguration.
10658 */
10659 public void triggerRcsReconfiguration(int subId) {
Brad Ebinger34c09a52021-02-17 23:23:21 +000010660 TelephonyPermissions.enforceAnyPermissionGranted(mApp, Binder.getCallingUid(),
10661 "triggerRcsReconfiguration",
10662 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION);
Hui Wang761a6682020-10-31 05:12:53 +000010663
10664 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
10665 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
10666 }
10667 if (!isImsAvailableOnDevice()) {
10668 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
10669 "IMS not available on device.");
10670 }
10671
10672 final long identity = Binder.clearCallingIdentity();
10673 try {
10674 RcsProvisioningMonitor.getInstance().requestReconfig(subId);
10675 } finally {
10676 Binder.restoreCallingIdentity(identity);
10677 }
10678 }
10679
10680 /**
10681 * Provide the client configuration parameters of the RCS application.
10682 */
10683 public void setRcsClientConfiguration(int subId, RcsClientConfiguration rcc) {
Brad Ebinger34c09a52021-02-17 23:23:21 +000010684 TelephonyPermissions.enforceAnyPermissionGranted(mApp, Binder.getCallingUid(),
10685 "setRcsClientConfiguration",
10686 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION);
Hui Wang761a6682020-10-31 05:12:53 +000010687
10688 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
10689 throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
10690 }
10691 if (!isImsAvailableOnDevice()) {
10692 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
10693 "IMS not available on device.");
10694 }
10695
10696 final long identity = Binder.clearCallingIdentity();
10697
10698 try {
10699 IImsConfig configBinder = getImsConfig(getSlotIndex(subId), ImsFeature.FEATURE_RCS);
10700 if (configBinder == null) {
10701 Rlog.e(LOG_TAG, "null result for setRcsClientConfiguration");
Brad Ebinger919631e2021-06-02 17:46:35 -070010702 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
10703 "could not find the requested subscription");
Hui Wang761a6682020-10-31 05:12:53 +000010704 } else {
10705 configBinder.setRcsClientConfiguration(rcc);
10706 }
joonhunshin3e154242021-09-17 06:33:39 +000010707
10708 RcsStats.getInstance().onRcsClientProvisioningStats(subId,
10709 RCS_CLIENT_PROVISIONING_STATS__EVENT__CLIENT_PARAMS_SENT);
Hui Wang761a6682020-10-31 05:12:53 +000010710 } catch (RemoteException e) {
10711 Rlog.e(LOG_TAG, "fail to setRcsClientConfiguration " + e.getMessage());
Brad Ebinger919631e2021-06-02 17:46:35 -070010712 throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
10713 "service is temporarily unavailable.");
Hui Wang761a6682020-10-31 05:12:53 +000010714 } finally {
10715 Binder.restoreCallingIdentity(identity);
10716 }
10717 }
10718
10719 /**
Hui Wangbaaee6a2021-02-19 20:45:36 -080010720 * Enables or disables the test mode for RCS VoLTE single registration.
10721 */
10722 @Override
10723 public void setRcsSingleRegistrationTestModeEnabled(boolean enabled) {
10724 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10725 "setRcsSingleRegistrationTestModeEnabled");
10726
10727 RcsProvisioningMonitor.getInstance().setTestModeEnabled(enabled);
10728 }
10729
10730 /**
10731 * Gets the test mode for RCS VoLTE single registration.
10732 */
10733 @Override
10734 public boolean getRcsSingleRegistrationTestModeEnabled() {
10735 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10736 "getRcsSingleRegistrationTestModeEnabled");
10737
10738 return RcsProvisioningMonitor.getInstance().getTestModeEnabled();
10739 }
10740
10741 /**
Hui Wang761a6682020-10-31 05:12:53 +000010742 * Overrides the config of RCS VoLTE single registration enabled for the device.
10743 */
10744 @Override
10745 public void setDeviceSingleRegistrationEnabledOverride(String enabledStr) {
10746 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10747 "setDeviceSingleRegistrationEnabledOverride");
10748 enforceModifyPermission();
10749
10750 Boolean enabled = "NULL".equalsIgnoreCase(enabledStr) ? null
10751 : Boolean.parseBoolean(enabledStr);
10752 RcsProvisioningMonitor.getInstance().overrideDeviceSingleRegistrationEnabled(enabled);
Brad Ebinger49a72b42021-01-29 00:55:24 +000010753 mApp.imsRcsController.setDeviceSingleRegistrationSupportOverride(enabled);
Hui Wang761a6682020-10-31 05:12:53 +000010754 }
10755
10756 /**
Tyler Gunn92479152021-01-20 16:30:10 -080010757 * Sends a device to device communication message. Only usable via shell.
10758 * @param message message to send.
10759 * @param value message value.
10760 */
10761 @Override
10762 public void sendDeviceToDeviceMessage(int message, int value) {
10763 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
Tyler Gunnbabbda02021-02-10 11:05:02 -080010764 "sendDeviceToDeviceMessage");
Tyler Gunn92479152021-01-20 16:30:10 -080010765 enforceModifyPermission();
10766
10767 final long identity = Binder.clearCallingIdentity();
10768 try {
10769 TelephonyConnectionService service =
10770 TelecomAccountRegistry.getInstance(null).getTelephonyConnectionService();
10771 if (service == null) {
10772 Rlog.e(LOG_TAG, "sendDeviceToDeviceMessage: not in a call.");
10773 return;
10774 }
10775 service.sendTestDeviceToDeviceMessage(message, value);
10776 } finally {
10777 Binder.restoreCallingIdentity(identity);
10778 }
10779 }
10780
Tyler Gunnbabbda02021-02-10 11:05:02 -080010781 /**
10782 * Sets the specified device to device transport active.
10783 * @param transport The transport to set active.
10784 */
10785 @Override
10786 public void setActiveDeviceToDeviceTransport(@NonNull String transport) {
10787 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10788 "setActiveDeviceToDeviceTransport");
10789 enforceModifyPermission();
10790
10791 final long identity = Binder.clearCallingIdentity();
10792 try {
10793 TelephonyConnectionService service =
10794 TelecomAccountRegistry.getInstance(null).getTelephonyConnectionService();
10795 if (service == null) {
10796 Rlog.e(LOG_TAG, "setActiveDeviceToDeviceTransport: not in a call.");
10797 return;
10798 }
10799 service.setActiveDeviceToDeviceTransport(transport);
10800 } finally {
10801 Binder.restoreCallingIdentity(identity);
10802 }
10803 }
Tyler Gunn92479152021-01-20 16:30:10 -080010804
Tyler Gunnd4339262021-05-03 14:46:49 -070010805 @Override
10806 public void setDeviceToDeviceForceEnabled(boolean isForceEnabled) {
10807 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10808 "setDeviceToDeviceForceEnabled");
10809
10810 final long identity = Binder.clearCallingIdentity();
10811 try {
10812 Arrays.stream(PhoneFactory.getPhones()).forEach(
10813 p -> {
10814 Phone thePhone = p.getImsPhone();
10815 if (thePhone != null && thePhone instanceof ImsPhone) {
10816 ImsPhone imsPhone = (ImsPhone) thePhone;
10817 CallTracker tracker = imsPhone.getCallTracker();
10818 if (tracker != null && tracker instanceof ImsPhoneCallTracker) {
10819 ImsPhoneCallTracker imsPhoneCallTracker =
10820 (ImsPhoneCallTracker) tracker;
10821 imsPhoneCallTracker.setDeviceToDeviceForceEnabled(isForceEnabled);
10822 }
10823 }
10824 }
10825 );
10826 } finally {
10827 Binder.restoreCallingIdentity(identity);
10828 }
10829 }
10830
Tyler Gunn92479152021-01-20 16:30:10 -080010831 /**
Hui Wang761a6682020-10-31 05:12:53 +000010832 * Gets the config of RCS VoLTE single registration enabled for the device.
10833 */
10834 @Override
10835 public boolean getDeviceSingleRegistrationEnabled() {
10836 enforceReadPrivilegedPermission("getDeviceSingleRegistrationEnabled");
10837 return RcsProvisioningMonitor.getInstance().getDeviceSingleRegistrationEnabled();
10838 }
10839
10840 /**
10841 * Overrides the config of RCS VoLTE single registration enabled for the carrier/subscription.
10842 */
10843 @Override
10844 public boolean setCarrierSingleRegistrationEnabledOverride(int subId, String enabledStr) {
10845 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10846 "setCarrierSingleRegistrationEnabledOverride");
10847 enforceModifyPermission();
10848
10849 Boolean enabled = "NULL".equalsIgnoreCase(enabledStr) ? null
10850 : Boolean.parseBoolean(enabledStr);
10851 return RcsProvisioningMonitor.getInstance().overrideCarrierSingleRegistrationEnabled(
10852 subId, enabled);
10853 }
10854
10855 /**
10856 * Gets the config of RCS VoLTE single registration enabled for the carrier/subscription.
10857 */
10858 @Override
10859 public boolean getCarrierSingleRegistrationEnabled(int subId) {
10860 enforceReadPrivilegedPermission("getCarrierSingleRegistrationEnabled");
10861 return RcsProvisioningMonitor.getInstance().getCarrierSingleRegistrationEnabled(subId);
10862 }
Chiachang Wangd6d34772020-12-22 11:38:27 +080010863
10864 /**
Hui Wangb647abe2021-02-26 09:33:38 -080010865 * Overrides the ims feature validation result
10866 */
10867 @Override
10868 public boolean setImsFeatureValidationOverride(int subId, String enabledStr) {
10869 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10870 "setImsFeatureValidationOverride");
10871
10872 Boolean enabled = "NULL".equalsIgnoreCase(enabledStr) ? null
10873 : Boolean.parseBoolean(enabledStr);
10874 return RcsProvisioningMonitor.getInstance().overrideImsFeatureValidation(
10875 subId, enabled);
10876 }
10877
10878 /**
10879 * Gets the ims feature validation override value
10880 */
10881 @Override
10882 public boolean getImsFeatureValidationOverride(int subId) {
10883 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10884 "getImsFeatureValidationOverride");
10885 return RcsProvisioningMonitor.getInstance().getImsFeatureValidationOverride(subId);
10886 }
10887
10888 /**
Chiachang Wangd6d34772020-12-22 11:38:27 +080010889 * Get the mobile provisioning url that is used to launch a browser to allow users to manage
10890 * their mobile plan.
10891 */
10892 @Override
10893 public String getMobileProvisioningUrl() {
10894 enforceReadPrivilegedPermission("getMobileProvisioningUrl");
10895 final long identity = Binder.clearCallingIdentity();
10896 try {
10897 return getDefaultPhone().getMobileProvisioningUrl();
10898 } finally {
10899 Binder.restoreCallingIdentity(identity);
10900 }
10901 }
Rambo Wanga5cc9b72021-01-07 10:51:54 -080010902
James.cf Linbcdf8b32021-01-14 16:44:13 +080010903 /**
calvinpane4a8a1d2021-01-25 13:51:18 +080010904 * Get the EAB contact from the EAB database.
10905 */
10906 @Override
10907 public String getContactFromEab(String contact) {
10908 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getContactFromEab");
10909 enforceModifyPermission();
10910 final long identity = Binder.clearCallingIdentity();
10911 try {
10912 return EabUtil.getContactFromEab(getDefaultPhone().getContext(), contact);
10913 } finally {
10914 Binder.restoreCallingIdentity(identity);
10915 }
10916 }
10917
10918 /**
Calvin Pana1434322021-07-01 19:27:01 +080010919 * Get the EAB capability from the EAB database.
10920 */
10921 @Override
10922 public String getCapabilityFromEab(String contact) {
10923 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getCapabilityFromEab");
10924 enforceModifyPermission();
10925 final long identity = Binder.clearCallingIdentity();
10926 try {
10927 return EabUtil.getCapabilityFromEab(getDefaultPhone().getContext(), contact);
10928 } finally {
10929 Binder.restoreCallingIdentity(identity);
10930 }
10931 }
10932
10933 /**
James.cf Linbcdf8b32021-01-14 16:44:13 +080010934 * Remove the EAB contacts from the EAB database.
10935 */
10936 @Override
10937 public int removeContactFromEab(int subId, String contacts) {
10938 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "removeCapabilitiesFromEab");
10939 enforceModifyPermission();
10940 final long identity = Binder.clearCallingIdentity();
10941 try {
10942 return EabUtil.removeContactFromEab(subId, contacts, getDefaultPhone().getContext());
10943 } finally {
10944 Binder.restoreCallingIdentity(identity);
10945 }
10946 }
10947
Rambo Wanga5cc9b72021-01-07 10:51:54 -080010948 @Override
James.cf Lin4b784aa2021-01-31 03:25:15 +080010949 public boolean getDeviceUceEnabled() {
10950 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getDeviceUceEnabled");
10951 final long identity = Binder.clearCallingIdentity();
10952 try {
10953 return mApp.getDeviceUceEnabled();
10954 } finally {
10955 Binder.restoreCallingIdentity(identity);
10956 }
10957 }
10958
10959 @Override
10960 public void setDeviceUceEnabled(boolean isEnabled) {
10961 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setDeviceUceEnabled");
10962 final long identity = Binder.clearCallingIdentity();
10963 try {
10964 mApp.setDeviceUceEnabled(isEnabled);
10965 } finally {
10966 Binder.restoreCallingIdentity(identity);
10967 }
10968 }
10969
Brad Ebinger14d467f2021-02-12 06:18:28 +000010970 /**
10971 * Add new feature tags to the Set used to calculate the capabilities in PUBLISH.
10972 * @return current RcsContactUceCapability instance that will be used for PUBLISH.
10973 */
10974 // Used for SHELL command only right now.
10975 @Override
10976 public RcsContactUceCapability addUceRegistrationOverrideShell(int subId,
10977 List<String> featureTags) {
10978 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10979 "addUceRegistrationOverrideShell");
10980 final long identity = Binder.clearCallingIdentity();
10981 try {
10982 return mApp.imsRcsController.addUceRegistrationOverrideShell(subId,
10983 new ArraySet<>(featureTags));
10984 } catch (ImsException e) {
10985 throw new ServiceSpecificException(e.getCode(), e.getMessage());
10986 } finally {
10987 Binder.restoreCallingIdentity(identity);
10988 }
10989 }
10990
10991 /**
10992 * Remove existing feature tags to the Set used to calculate the capabilities in PUBLISH.
10993 * @return current RcsContactUceCapability instance that will be used for PUBLISH.
10994 */
10995 // Used for SHELL command only right now.
10996 @Override
10997 public RcsContactUceCapability removeUceRegistrationOverrideShell(int subId,
10998 List<String> featureTags) {
10999 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11000 "removeUceRegistrationOverrideShell");
11001 final long identity = Binder.clearCallingIdentity();
11002 try {
11003 return mApp.imsRcsController.removeUceRegistrationOverrideShell(subId,
11004 new ArraySet<>(featureTags));
11005 } catch (ImsException e) {
11006 throw new ServiceSpecificException(e.getCode(), e.getMessage());
11007 } finally {
11008 Binder.restoreCallingIdentity(identity);
11009 }
11010 }
11011
11012 /**
11013 * Clear all overrides in the Set used to calculate the capabilities in PUBLISH.
11014 * @return current RcsContactUceCapability instance that will be used for PUBLISH.
11015 */
11016 // Used for SHELL command only right now.
11017 @Override
11018 public RcsContactUceCapability clearUceRegistrationOverrideShell(int subId) {
11019 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11020 "clearUceRegistrationOverrideShell");
11021 final long identity = Binder.clearCallingIdentity();
11022 try {
11023 return mApp.imsRcsController.clearUceRegistrationOverrideShell(subId);
11024 } catch (ImsException e) {
11025 throw new ServiceSpecificException(e.getCode(), e.getMessage());
11026 } finally {
11027 Binder.restoreCallingIdentity(identity);
11028 }
11029 }
11030
11031 /**
11032 * @return current RcsContactUceCapability instance that will be used for PUBLISH.
11033 */
11034 // Used for SHELL command only right now.
11035 @Override
11036 public RcsContactUceCapability getLatestRcsContactUceCapabilityShell(int subId) {
11037 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11038 "getLatestRcsContactUceCapabilityShell");
11039 final long identity = Binder.clearCallingIdentity();
11040 try {
11041 return mApp.imsRcsController.getLatestRcsContactUceCapabilityShell(subId);
11042 } catch (ImsException e) {
11043 throw new ServiceSpecificException(e.getCode(), e.getMessage());
11044 } finally {
11045 Binder.restoreCallingIdentity(identity);
11046 }
11047 }
11048
11049 /**
11050 * Returns the last PIDF XML sent to the network during the last PUBLISH or "none" if the
11051 * device does not have an active PUBLISH.
11052 */
11053 // Used for SHELL command only right now.
11054 @Override
11055 public String getLastUcePidfXmlShell(int subId) {
11056 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "uceGetLastPidfXml");
11057 final long identity = Binder.clearCallingIdentity();
11058 try {
11059 return mApp.imsRcsController.getLastUcePidfXmlShell(subId);
11060 } catch (ImsException e) {
11061 throw new ServiceSpecificException(e.getCode(), e.getMessage());
11062 } finally {
11063 Binder.restoreCallingIdentity(identity);
11064 }
11065 }
11066
James.cf Line8713a42021-04-29 16:04:26 +080011067 /**
11068 * Remove UCE requests cannot be sent to the network status.
11069 */
11070 // Used for SHELL command only right now.
11071 @Override
11072 public boolean removeUceRequestDisallowedStatus(int subId) {
11073 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "uceRemoveDisallowedStatus");
11074 final long identity = Binder.clearCallingIdentity();
11075 try {
11076 return mApp.imsRcsController.removeUceRequestDisallowedStatus(subId);
11077 } catch (ImsException e) {
11078 throw new ServiceSpecificException(e.getCode(), e.getMessage());
11079 } finally {
11080 Binder.restoreCallingIdentity(identity);
11081 }
11082 }
11083
James.cf Lin18bb9002021-05-25 01:37:38 +080011084 /**
11085 * Remove UCE requests cannot be sent to the network status.
11086 */
11087 // Used for SHELL command only.
11088 @Override
11089 public boolean setCapabilitiesRequestTimeout(int subId, long timeoutAfterMs) {
11090 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setCapRequestTimeout");
11091 final long identity = Binder.clearCallingIdentity();
11092 try {
11093 return mApp.imsRcsController.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
11094 } catch (ImsException e) {
11095 throw new ServiceSpecificException(e.getCode(), e.getMessage());
11096 } finally {
11097 Binder.restoreCallingIdentity(identity);
11098 }
11099 }
Brad Ebinger14d467f2021-02-12 06:18:28 +000011100
James.cf Lin4b784aa2021-01-31 03:25:15 +080011101 @Override
Rambo Wanga5cc9b72021-01-07 10:51:54 -080011102 public void setSignalStrengthUpdateRequest(int subId, SignalStrengthUpdateRequest request,
11103 String callingPackage) {
11104 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
11105 mApp, subId, "setSignalStrengthUpdateRequest");
11106
11107 final int callingUid = Binder.getCallingUid();
11108 // Verify that tha callingPackage belongs to the calling UID
11109 mApp.getSystemService(AppOpsManager.class)
11110 .checkPackage(callingUid, callingPackage);
11111
Rambo Wang3607f502021-02-01 21:51:40 -080011112 validateSignalStrengthUpdateRequest(mApp, request, callingUid);
Rambo Wanga5cc9b72021-01-07 10:51:54 -080011113
11114 final long identity = Binder.clearCallingIdentity();
11115 try {
11116 Object result = sendRequest(CMD_SET_SIGNAL_STRENGTH_UPDATE_REQUEST,
11117 new Pair<Integer, SignalStrengthUpdateRequest>(callingUid, request), subId);
11118
11119 if (result instanceof IllegalStateException) {
11120 throw (IllegalStateException) result;
11121 }
11122 } finally {
11123 Binder.restoreCallingIdentity(identity);
11124 }
11125 }
11126
11127 @Override
11128 public void clearSignalStrengthUpdateRequest(int subId, SignalStrengthUpdateRequest request,
11129 String callingPackage) {
11130 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
11131 mApp, subId, "clearSignalStrengthUpdateRequest");
11132
11133 final int callingUid = Binder.getCallingUid();
11134 // Verify that tha callingPackage belongs to the calling UID
11135 mApp.getSystemService(AppOpsManager.class)
11136 .checkPackage(callingUid, callingPackage);
11137
11138 final long identity = Binder.clearCallingIdentity();
11139 try {
11140 Object result = sendRequest(CMD_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST,
11141 new Pair<Integer, SignalStrengthUpdateRequest>(callingUid, request), subId);
11142
11143 if (result instanceof IllegalStateException) {
11144 throw (IllegalStateException) result;
11145 }
11146 } finally {
11147 Binder.restoreCallingIdentity(identity);
11148 }
11149 }
11150
Rambo Wang3607f502021-02-01 21:51:40 -080011151 private static void validateSignalStrengthUpdateRequest(Context context,
11152 SignalStrengthUpdateRequest request, int callingUid) {
Rambo Wanga5cc9b72021-01-07 10:51:54 -080011153 if (callingUid == Process.PHONE_UID || callingUid == Process.SYSTEM_UID) {
11154 // phone/system process do not have further restriction on request
11155 return;
11156 }
11157
11158 // Applications has restrictions on how to use the request:
Rambo Wang3607f502021-02-01 21:51:40 -080011159 // Non-system callers need permission to set mIsSystemThresholdReportingRequestedWhileIdle
Rambo Wanga5cc9b72021-01-07 10:51:54 -080011160 if (request.isSystemThresholdReportingRequestedWhileIdle()) {
Rambo Wang3607f502021-02-01 21:51:40 -080011161 context.enforceCallingOrSelfPermission(
11162 android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH,
11163 "validateSignalStrengthUpdateRequest");
Rambo Wanga5cc9b72021-01-07 10:51:54 -080011164 }
11165
11166 for (SignalThresholdInfo info : request.getSignalThresholdInfos()) {
11167 // Only system caller can set mHysteresisMs/mHysteresisDb/mIsEnabled.
11168 if (info.getHysteresisMs() != SignalThresholdInfo.HYSTERESIS_MS_DISABLED
11169 || info.getHysteresisDb() != SignalThresholdInfo.HYSTERESIS_DB_DISABLED
11170 || info.isEnabled()) {
11171 throw new IllegalArgumentException(
11172 "Only system can set hide fields in SignalThresholdInfo");
11173 }
11174
11175 // Thresholds length for each RAN need in range. This has been validated in
11176 // SignalThresholdInfo#Builder#setThreshold. Here we prevent apps calling hide method
11177 // setThresholdUnlimited (e.g. through reflection) with too short or too long thresholds
11178 final int[] thresholds = info.getThresholds();
11179 Objects.requireNonNull(thresholds);
11180 if (thresholds.length < SignalThresholdInfo.getMinimumNumberOfThresholdsAllowed()
11181 || thresholds.length
11182 > SignalThresholdInfo.getMaximumNumberOfThresholdsAllowed()) {
11183 throw new IllegalArgumentException(
11184 "thresholds length is out of range: " + thresholds.length);
11185 }
11186 }
11187 }
SongFerngWang8236caa2021-01-17 21:51:44 +080011188
11189 /**
11190 * Gets the current phone capability.
11191 *
11192 * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
11193 * @return the PhoneCapability which describes the data connection capability of modem.
11194 * It's used to evaluate possible phone config change, for example from single
11195 * SIM device to multi-SIM device.
11196 */
11197 @Override
11198 public PhoneCapability getPhoneCapability() {
11199 enforceReadPrivilegedPermission("getPhoneCapability");
11200 final long identity = Binder.clearCallingIdentity();
11201 try {
11202 return mPhoneConfigurationManager.getCurrentPhoneCapability();
11203 } finally {
11204 Binder.restoreCallingIdentity(identity);
11205 }
11206 }
Michele Berionne5e411512020-11-13 02:36:59 +000011207
11208 /**
11209 * Prepare TelephonyManager for an unattended reboot. The reboot is
11210 * required to be done shortly after the API is invoked.
11211 */
11212 @Override
11213 @TelephonyManager.PrepareUnattendedRebootResult
11214 public int prepareForUnattendedReboot() {
Rafael Higuera Silvad9630642021-09-20 15:32:01 +000011215 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Michele Berionne5e411512020-11-13 02:36:59 +000011216 enforceRebootPermission();
11217
11218 final long identity = Binder.clearCallingIdentity();
11219 try {
Rafael Higuera Silvad9630642021-09-20 15:32:01 +000011220 return (int) sendRequest(CMD_PREPARE_UNATTENDED_REBOOT, null, workSource);
Michele Berionne5e411512020-11-13 02:36:59 +000011221 } finally {
11222 Binder.restoreCallingIdentity(identity);
11223 }
11224 }
Hongbo Zeng156aa4a2021-02-08 21:50:28 +080011225
11226 /**
11227 * Request to get the current slicing configuration including URSP rules and
11228 * NSSAIs (configured, allowed and rejected).
11229 *
11230 * Requires carrier privileges or READ_PRIVILEGED_PHONE_STATE permission.
11231 */
11232 @Override
11233 public void getSlicingConfig(ResultReceiver callback) {
11234 enforceReadPrivilegedPermission("getSlicingConfig");
11235
11236 final long identity = Binder.clearCallingIdentity();
11237 try {
11238 Phone phone = getDefaultPhone();
11239 sendRequestAsync(CMD_GET_SLICING_CONFIG, callback, phone, null);
11240 } finally {
11241 Binder.restoreCallingIdentity(identity);
11242 }
11243 }
Hunsuk Choi3b742d62021-10-25 19:48:34 +000011244
11245 /**
11246 * Register an IMS connection state callback
11247 */
11248 @Override
Hunsuk Choi89bd22c2021-11-01 13:04:54 +000011249 public void registerImsStateCallback(int subId, int feature, IImsStateCallback cb,
11250 String callingPackage) {
Hunsuk Choi3b742d62021-10-25 19:48:34 +000011251 if (feature == ImsFeature.FEATURE_MMTEL) {
11252 // ImsMmTelManager
11253 // The following also checks READ_PRIVILEGED_PHONE_STATE.
11254 TelephonyPermissions
11255 .enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
11256 mApp, subId, "registerImsStateCallback");
11257 } else if (feature == ImsFeature.FEATURE_RCS) {
11258 // ImsRcsManager or SipDelegateManager
11259 TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
11260 Binder.getCallingUid(), "registerImsStateCallback",
11261 Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
11262 Manifest.permission.READ_PRECISE_PHONE_STATE,
11263 Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE,
11264 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION);
11265 }
11266
11267 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
11268 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
11269 "IMS not available on device.");
11270 }
11271
11272 if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
11273 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
11274 }
11275
11276 ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
11277 if (controller == null) {
11278 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
11279 "IMS not available on device.");
11280 }
11281
Hunsuk Choi89bd22c2021-11-01 13:04:54 +000011282 if (callingPackage == null) {
11283 callingPackage = getCurrentPackageName();
11284 }
11285
Hunsuk Choi3b742d62021-10-25 19:48:34 +000011286 final long token = Binder.clearCallingIdentity();
11287 try {
11288 int slotId = getSlotIndexOrException(subId);
Hunsuk Choi89bd22c2021-11-01 13:04:54 +000011289 controller.registerImsStateCallback(subId, feature, cb, callingPackage);
Hunsuk Choi3b742d62021-10-25 19:48:34 +000011290 } catch (ImsException e) {
11291 throw new ServiceSpecificException(e.getCode());
11292 } finally {
11293 Binder.restoreCallingIdentity(token);
11294 }
11295 }
11296
11297 /**
11298 * Unregister an IMS connection state callback
11299 */
11300 @Override
11301 public void unregisterImsStateCallback(IImsStateCallback cb) {
11302 final long token = Binder.clearCallingIdentity();
11303 ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
11304 if (controller == null) {
11305 return;
11306 }
11307 try {
11308 controller.unregisterImsStateCallback(cb);
11309 } finally {
11310 Binder.restoreCallingIdentity(token);
11311 }
11312 }
Sooraj Sasindranfae41b32021-10-26 02:10:05 -070011313
11314 /**
11315 * @return {@CellIdentity} last known cell identity {@CellIdentity}.
11316 *
11317 * Require {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and
11318 * com.android.phone.permission.ACCESS_LAST_KNOWN_CELL_ID, otherwise throws
11319 * SecurityException.
11320 * If there is current registered network this value will be same as the registered cell
11321 * identity. If the device goes out of service the previous cell identity is cached and
11322 * will be returned. If the cache age of the Cell identity is more than 24 hours
11323 * it will be cleared and null will be returned.
11324 *
11325 */
11326 @Override
11327 public @Nullable CellIdentity getLastKnownCellIdentity(int subId, String callingPackage,
11328 String callingFeatureId) {
11329 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
11330 LocationAccessPolicy.LocationPermissionResult fineLocationResult =
11331 LocationAccessPolicy.checkLocationPermission(mApp,
11332 new LocationAccessPolicy.LocationPermissionQuery.Builder()
11333 .setCallingPackage(callingPackage)
11334 .setCallingFeatureId(callingFeatureId)
11335 .setCallingPid(Binder.getCallingPid())
11336 .setCallingUid(Binder.getCallingUid())
11337 .setMethod("getLastKnownCellIdentity")
11338 .setLogAsInfo(true)
11339 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
11340 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
11341 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
11342 .build());
11343
11344 boolean hasFinePermission =
11345 fineLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
11346 if (!hasFinePermission
11347 || !TelephonyPermissions.checkLastKnownCellIdAccessPermission(mApp)) {
11348 throw new SecurityException("getLastKnownCellIdentity need ACCESS_FINE_LOCATION "
11349 + "and BIND_CONNECTION_SERVICE permission.");
11350 }
11351
11352 final long identity = Binder.clearCallingIdentity();
11353 try {
11354 Phone phone = getPhone(subId);
11355 if (phone == null) return null;
11356 ServiceStateTracker sst = phone.getServiceStateTracker();
11357 if (sst == null) return null;
11358 return sst.getLastKnownCellIdentity();
11359 } finally {
11360 Binder.restoreCallingIdentity(identity);
11361 }
11362 }
Jack Yu4c0a5502021-12-03 23:58:26 -080011363
11364 @Override
11365 public boolean isUsingNewDataStack() {
11366 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "isUsingNewDataStack");
11367 return getDefaultPhone().isUsingNewDataStack();
11368 }
jimsun3b9ccac2021-10-26 15:01:23 +080011369
11370 /**
11371 * Sets the modem service class Name that Telephony will bind to.
11372 *
11373 * @param serviceName The class name of the modem service.
11374 * @return true if the operation is succeed, otherwise false.
11375 */
11376 public boolean setModemService(String serviceName) {
11377 Log.d(LOG_TAG, "setModemService - " + serviceName);
11378 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setModemService");
11379 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
11380 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
11381 "setModemService");
11382 return mPhoneConfigurationManager.setModemService(serviceName);
11383 }
11384
11385 /**
11386 * Return the class name of the currently bounded modem service.
11387 *
11388 * @return the class name of the modem service.
11389 */
11390 public String getModemService() {
11391 String result;
11392 Log.d(LOG_TAG, "getModemService");
11393 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getModemService");
11394 TelephonyPermissions
11395 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
11396 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
11397 "getModemService");
11398 result = mPhoneConfigurationManager.getModemService();
11399 Log.d(LOG_TAG, "result = " + result);
11400 return result;
11401 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -070011402}