blob: e31f68796339bd2cc0171a5aab270a568e9b0f45 [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
Ta-wei Yen87c49842016-05-13 21:19:52 -070019import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
20
Ta-wei Yen30a69c82016-12-27 14:52:32 -080021import android.Manifest.permission;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070022import android.app.AppOpsManager;
Ta-wei Yen30a69c82016-12-27 14:52:32 -080023import android.app.PendingIntent;
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -070024import android.content.ComponentName;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070025import android.content.Context;
26import android.content.Intent;
Derek Tan97ebb422014-09-05 16:55:38 -070027import android.content.SharedPreferences;
Nathan Harold31d7ff32018-10-15 20:20:30 -070028import android.content.pm.ApplicationInfo;
Derek Tan740e1672017-06-27 14:56:27 -070029import android.content.pm.ComponentInfo;
Amith Yamasani6e118872016-02-19 12:53:51 -080030import android.content.pm.PackageInfo;
Shishir Agrawal60f9c952014-06-23 12:00:43 -070031import android.content.pm.PackageManager;
Jack Yu84291ec2017-05-26 16:07:50 -070032import android.net.NetworkStats;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070033import android.net.Uri;
34import android.os.AsyncResult;
35import android.os.Binder;
36import android.os.Bundle;
37import android.os.Handler;
yinxu504e1392017-04-12 16:03:22 -070038import android.os.IBinder;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070039import android.os.Looper;
40import android.os.Message;
yinxu504e1392017-04-12 16:03:22 -070041import android.os.Messenger;
Tyler Gunn65d45c22017-06-05 11:22:26 -070042import android.os.PersistableBundle;
Brad Ebinger5f64b052017-12-14 14:26:15 -080043import android.os.RemoteException;
Adam Lesinski903a54c2016-04-11 14:49:52 -070044import android.os.ResultReceiver;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070045import android.os.ServiceManager;
Brad Ebingerdac2f002018-04-03 15:17:52 -070046import android.os.ShellCallback;
Pengquan Meng85728fb2018-03-12 16:31:21 -070047import android.os.SystemProperties;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070048import android.os.UserHandle;
Stuart Scott981d8582015-04-21 14:09:50 -070049import android.os.UserManager;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070050import android.os.WorkSource;
Derek Tan97ebb422014-09-05 16:55:38 -070051import android.preference.PreferenceManager;
Ihab Awadf2177b72013-11-25 13:33:23 -080052import android.provider.Settings;
Meng Wang1a7c35a2016-05-05 20:56:15 -070053import android.service.carrier.CarrierIdentifier;
Santos Cordon7a1885b2015-02-03 11:15:19 -080054import android.telecom.PhoneAccount;
Nancy Chen31f9ba12016-01-06 11:42:12 -080055import android.telecom.PhoneAccountHandle;
Andrew Lee9431b832015-03-09 18:46:45 -070056import android.telecom.TelecomManager;
Junda Liu12f7d802015-05-01 12:06:44 -070057import android.telephony.CarrierConfigManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070058import android.telephony.CellInfo;
Nathan Haroldf180aac2018-06-01 18:43:55 -070059import android.telephony.CellInfoGsm;
60import android.telephony.CellInfoWcdma;
Nathan Harold3ff88932018-08-14 10:19:49 -070061import android.telephony.CellLocation;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070062import android.telephony.ClientRequestStats;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -070063import android.telephony.ICellInfoCallback;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -070064import android.telephony.IccOpenLogicalChannelResponse;
Hall Liu1aa510f2017-11-22 17:40:08 -080065import android.telephony.LocationAccessPolicy;
Ta-wei Yen87c49842016-05-13 21:19:52 -070066import android.telephony.ModemActivityInfo;
Jake Hambye994d462014-02-03 13:10:13 -080067import android.telephony.NeighboringCellInfo;
yinxu504e1392017-04-12 16:03:22 -070068import android.telephony.NetworkScanRequest;
Wink Saville5d475dd2014-10-17 15:00:58 -070069import android.telephony.RadioAccessFamily;
Tyler Gunn65d45c22017-06-05 11:22:26 -070070import android.telephony.Rlog;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070071import android.telephony.ServiceState;
Nathan Harold46b42aa2017-03-10 19:38:22 -080072import android.telephony.SignalStrength;
Jack Yu84291ec2017-05-26 16:07:50 -070073import android.telephony.SmsManager;
Wink Saville0f3b5fc2014-11-11 08:40:49 -080074import android.telephony.SubscriptionInfo;
Jeff Sharkey85190e62014-12-05 09:40:12 -080075import android.telephony.SubscriptionManager;
Sanket Padawe99ef1e32016-05-18 16:12:33 -070076import android.telephony.TelephonyHistogram;
Ta-wei Yenb6929602016-05-24 15:48:27 -070077import android.telephony.TelephonyManager;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +000078import android.telephony.UiccSlotInfo;
Tyler Gunn65d45c22017-06-05 11:22:26 -070079import android.telephony.UssdResponse;
Ta-wei Yenb6929602016-05-24 15:48:27 -070080import android.telephony.VisualVoicemailSmsFilterSettings;
Nathan Harold3ff88932018-08-14 10:19:49 -070081import android.telephony.cdma.CdmaCellLocation;
Jack Yub5d8f642018-11-26 11:20:48 -080082import android.telephony.data.ApnSetting;
83import android.telephony.emergency.EmergencyNumber;
Nathan Harold3ff88932018-08-14 10:19:49 -070084import android.telephony.gsm.GsmCellLocation;
Brad Ebinger35c841c2018-10-01 10:40:55 -070085import android.telephony.ims.aidl.IImsCapabilityCallback;
Brad Ebinger22bc3e42018-01-16 09:39:35 -080086import android.telephony.ims.aidl.IImsConfig;
Brad Ebingerdf5b4f02018-10-31 11:24:17 -070087import android.telephony.ims.aidl.IImsConfigCallback;
Brad Ebinger22bc3e42018-01-16 09:39:35 -080088import android.telephony.ims.aidl.IImsMmTelFeature;
89import android.telephony.ims.aidl.IImsRcsFeature;
90import android.telephony.ims.aidl.IImsRegistration;
Brad Ebinger35c841c2018-10-01 10:40:55 -070091import android.telephony.ims.aidl.IImsRegistrationCallback;
Brad Ebinger1f2b5082018-02-08 16:11:32 -080092import android.telephony.ims.stub.ImsRegistrationImplBase;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070093import android.text.TextUtils;
Jeff Sharkey85190e62014-12-05 09:40:12 -080094import android.util.ArraySet;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070095import android.util.Log;
Jake Hambye994d462014-02-03 13:10:13 -080096import android.util.Pair;
Jeff Sharkey85190e62014-12-05 09:40:12 -080097import android.util.Slog;
Ta-wei Yen30a69c82016-12-27 14:52:32 -080098
Brad Ebinger35c841c2018-10-01 10:40:55 -070099import com.android.ims.ImsException;
Andrew Lee312e8172014-10-23 17:01:36 -0700100import com.android.ims.ImsManager;
Brad Ebinger34bef922017-11-09 10:27:08 -0800101import com.android.ims.internal.IImsServiceFeatureCallback;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700102import com.android.internal.telephony.CallManager;
Tyler Gunn52dcf772017-04-26 11:30:31 -0700103import com.android.internal.telephony.CallStateException;
pkanwar79ec0542017-07-31 14:10:01 -0700104import com.android.internal.telephony.CarrierInfoManager;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700105import com.android.internal.telephony.CellNetworkScanResult;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700106import com.android.internal.telephony.CommandException;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700107import com.android.internal.telephony.DefaultPhoneNotifier;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700108import com.android.internal.telephony.ITelephony;
Jake Hambye994d462014-02-03 13:10:13 -0800109import com.android.internal.telephony.IccCard;
Jack Yu5f7092c2018-04-13 14:05:37 -0700110import com.android.internal.telephony.LocaleTracker;
Narayan Kamath1c496c22015-04-16 14:40:19 +0100111import com.android.internal.telephony.MccTable;
yinxub1bed742017-04-17 11:45:04 -0700112import com.android.internal.telephony.NetworkScanRequestTracker;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700113import com.android.internal.telephony.OperatorInfo;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700114import com.android.internal.telephony.Phone;
Malcolm Chen2c63d402018-08-14 16:00:53 -0700115import com.android.internal.telephony.PhoneConfigurationManager;
Nathan Harolda667c152016-12-14 11:27:20 -0800116import com.android.internal.telephony.PhoneConstantConversions;
Ta-wei Yen87c49842016-05-13 21:19:52 -0700117import com.android.internal.telephony.PhoneConstants;
Wink Saville36469e72014-06-11 15:17:00 -0700118import com.android.internal.telephony.PhoneFactory;
Wink Saville5d475dd2014-10-17 15:00:58 -0700119import com.android.internal.telephony.ProxyController;
Sanket Padawe99ef1e32016-05-18 16:12:33 -0700120import com.android.internal.telephony.RIL;
Svet Ganovb320e182015-04-16 12:30:10 -0700121import com.android.internal.telephony.RILConstants;
Jack Yu5f7092c2018-04-13 14:05:37 -0700122import com.android.internal.telephony.ServiceStateTracker;
Makoto Onukida3bf792018-09-18 16:06:29 -0700123import com.android.internal.telephony.SmsApplication;
124import com.android.internal.telephony.SmsApplication.SmsApplicationData;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800125import com.android.internal.telephony.SubscriptionController;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800126import com.android.internal.telephony.TelephonyPermissions;
Derek Tan740e1672017-06-27 14:56:27 -0700127import com.android.internal.telephony.euicc.EuiccConnector;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700128import com.android.internal.telephony.uicc.IccIoResult;
129import com.android.internal.telephony.uicc.IccUtils;
Nathan Haroldb3014052017-01-25 15:57:32 -0800130import com.android.internal.telephony.uicc.SIMRecords;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700131import com.android.internal.telephony.uicc.UiccCard;
Nathan Haroldb3014052017-01-25 15:57:32 -0800132import com.android.internal.telephony.uicc.UiccCardApplication;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700133import com.android.internal.telephony.uicc.UiccController;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800134import com.android.internal.telephony.uicc.UiccProfile;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000135import com.android.internal.telephony.uicc.UiccSlot;
fionaxu7ed723d2017-05-30 18:58:54 -0700136import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
Jake Hambye994d462014-02-03 13:10:13 -0800137import com.android.internal.util.HexDump;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700138import com.android.phone.vvm.PhoneAccountHandleConverter;
Ta-wei Yen527a9c02017-01-06 15:29:25 -0800139import com.android.phone.vvm.RemoteVvmTaskManager;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700140import com.android.phone.vvm.VisualVoicemailSettingsUtil;
Ta-wei Yenc8905312017-03-28 11:14:45 -0700141import com.android.phone.vvm.VisualVoicemailSmsFilterConfig;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800142
Ta-wei Yenc236d6b2016-06-21 13:33:12 -0700143import java.io.FileDescriptor;
144import java.io.PrintWriter;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800145import java.nio.charset.StandardCharsets;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700146import java.util.ArrayList;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800147import java.util.Arrays;
Makoto Onukida3bf792018-09-18 16:06:29 -0700148import java.util.Collection;
Jake Hambye994d462014-02-03 13:10:13 -0800149import java.util.List;
Narayan Kamath1c496c22015-04-16 14:40:19 +0100150import java.util.Locale;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800151import java.util.Map;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700152
153/**
154 * Implementation of the ITelephony interface.
155 */
Santos Cordon117fee72014-05-16 17:56:12 -0700156public class PhoneInterfaceManager extends ITelephony.Stub {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700157 private static final String LOG_TAG = "PhoneInterfaceManager";
158 private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
159 private static final boolean DBG_LOC = false;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800160 private static final boolean DBG_MERGE = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700161
162 // Message codes used with mMainThreadHandler
163 private static final int CMD_HANDLE_PIN_MMI = 1;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700164 private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7;
165 private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700166 private static final int CMD_OPEN_CHANNEL = 9;
167 private static final int EVENT_OPEN_CHANNEL_DONE = 10;
168 private static final int CMD_CLOSE_CHANNEL = 11;
169 private static final int EVENT_CLOSE_CHANNEL_DONE = 12;
Jake Hambye994d462014-02-03 13:10:13 -0800170 private static final int CMD_NV_READ_ITEM = 13;
171 private static final int EVENT_NV_READ_ITEM_DONE = 14;
172 private static final int CMD_NV_WRITE_ITEM = 15;
173 private static final int EVENT_NV_WRITE_ITEM_DONE = 16;
174 private static final int CMD_NV_WRITE_CDMA_PRL = 17;
175 private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18;
chen xu6dac5ab2018-10-26 17:39:23 -0700176 private static final int CMD_RESET_MODEM_CONFIG = 19;
177 private static final int EVENT_RESET_MODEM_CONFIG_DONE = 20;
Jake Hamby7c27be32014-03-03 13:25:59 -0800178 private static final int CMD_GET_PREFERRED_NETWORK_TYPE = 21;
179 private static final int EVENT_GET_PREFERRED_NETWORK_TYPE_DONE = 22;
180 private static final int CMD_SET_PREFERRED_NETWORK_TYPE = 23;
181 private static final int EVENT_SET_PREFERRED_NETWORK_TYPE_DONE = 24;
Sailesh Nepal35b59452014-03-06 09:26:56 -0800182 private static final int CMD_SEND_ENVELOPE = 25;
183 private static final int EVENT_SEND_ENVELOPE_DONE = 26;
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000184 private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27;
185 private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28;
Derek Tan6b088ee2014-09-05 14:15:18 -0700186 private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29;
187 private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30;
188 private static final int CMD_EXCHANGE_SIM_IO = 31;
189 private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800190 private static final int CMD_SET_VOICEMAIL_NUMBER = 33;
191 private static final int EVENT_SET_VOICEMAIL_NUMBER_DONE = 34;
Stuart Scott54788802015-03-30 13:18:01 -0700192 private static final int CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC = 35;
193 private static final int EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE = 36;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700194 private static final int CMD_GET_MODEM_ACTIVITY_INFO = 37;
195 private static final int EVENT_GET_MODEM_ACTIVITY_INFO_DONE = 38;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700196 private static final int CMD_PERFORM_NETWORK_SCAN = 39;
197 private static final int EVENT_PERFORM_NETWORK_SCAN_DONE = 40;
198 private static final int CMD_SET_NETWORK_SELECTION_MODE_MANUAL = 41;
199 private static final int EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE = 42;
Meng Wang1a7c35a2016-05-05 20:56:15 -0700200 private static final int CMD_SET_ALLOWED_CARRIERS = 43;
201 private static final int EVENT_SET_ALLOWED_CARRIERS_DONE = 44;
202 private static final int CMD_GET_ALLOWED_CARRIERS = 45;
203 private static final int EVENT_GET_ALLOWED_CARRIERS_DONE = 46;
pkanwar32d516d2016-10-14 19:37:38 -0700204 private static final int CMD_HANDLE_USSD_REQUEST = 47;
Nathan Haroldb3014052017-01-25 15:57:32 -0800205 private static final int CMD_GET_FORBIDDEN_PLMNS = 48;
206 private static final int EVENT_GET_FORBIDDEN_PLMNS_DONE = 49;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000207 private static final int CMD_SWITCH_SLOTS = 50;
208 private static final int EVENT_SWITCH_SLOTS_DONE = 51;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700209 private static final int CMD_GET_NETWORK_SELECTION_MODE = 52;
210 private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 53;
211 private static final int CMD_GET_CDMA_ROAMING_MODE = 54;
212 private static final int EVENT_GET_CDMA_ROAMING_MODE_DONE = 55;
213 private static final int CMD_SET_CDMA_ROAMING_MODE = 56;
214 private static final int EVENT_SET_CDMA_ROAMING_MODE_DONE = 57;
215 private static final int CMD_SET_CDMA_SUBSCRIPTION_MODE = 58;
216 private static final int EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE = 59;
Nathan Harold3ff88932018-08-14 10:19:49 -0700217 private static final int CMD_GET_ALL_CELL_INFO = 60;
218 private static final int EVENT_GET_ALL_CELL_INFO_DONE = 61;
219 private static final int CMD_GET_CELL_LOCATION = 62;
220 private static final int EVENT_GET_CELL_LOCATION_DONE = 63;
chen xu6dac5ab2018-10-26 17:39:23 -0700221 private static final int CMD_MODEM_REBOOT = 64;
222 private static final int EVENT_CMD_MODEM_REBOOT_DONE = 65;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -0700223 private static final int CMD_REQUEST_CELL_INFO_UPDATE = 66;
224 private static final int EVENT_REQUEST_CELL_INFO_UPDATE_DONE = 67;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700225
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -0800226 // Parameters of select command.
227 private static final int SELECT_COMMAND = 0xA4;
228 private static final int SELECT_P1 = 0x04;
229 private static final int SELECT_P2 = 0;
230 private static final int SELECT_P3 = 0x10;
231
Pengquan Meng85728fb2018-03-12 16:31:21 -0700232 private static final String DEFAULT_NETWORK_MODE_PROPERTY_NAME = "ro.telephony.default_network";
233 private static final String DEFAULT_DATA_ROAMING_PROPERTY_NAME = "ro.com.android.dataroaming";
234 private static final String DEFAULT_MOBILE_DATA_PROPERTY_NAME = "ro.com.android.mobiledata";
235
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700236 /** The singleton instance. */
237 private static PhoneInterfaceManager sInstance;
238
Wink Saville3ab207e2014-11-20 13:07:20 -0800239 private PhoneGlobals mApp;
240 private Phone mPhone;
241 private CallManager mCM;
Stuart Scott981d8582015-04-21 14:09:50 -0700242 private UserManager mUserManager;
Wink Saville3ab207e2014-11-20 13:07:20 -0800243 private AppOpsManager mAppOps;
244 private MainThreadHandler mMainThreadHandler;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800245 private SubscriptionController mSubscriptionController;
Wink Saville3ab207e2014-11-20 13:07:20 -0800246 private SharedPreferences mTelephonySharedPreferences;
Malcolm Chen2c63d402018-08-14 16:00:53 -0700247 private PhoneConfigurationManager mPhoneConfigurationManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700248
Derek Tan97ebb422014-09-05 16:55:38 -0700249 private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
250 private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
Jeff Sharkey85190e62014-12-05 09:40:12 -0800251 private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
Derek Tan89e89d42014-07-08 17:00:10 -0700252
Derek Tan740e1672017-06-27 14:56:27 -0700253 // The AID of ISD-R.
254 private static final String ISDR_AID = "A0000005591010FFFFFFFF8900000100";
255
yinxub1bed742017-04-17 11:45:04 -0700256 private NetworkScanRequestTracker mNetworkScanRequestTracker;
257
David Kelly5e06a7f2018-03-12 14:10:59 +0000258 private static final int TYPE_ALLOCATION_CODE_LENGTH = 8;
259 private static final int MANUFACTURER_CODE_LENGTH = 8;
260
Derek Tan89e89d42014-07-08 17:00:10 -0700261 /**
Shishir Agrawal566b7612013-10-28 14:41:00 -0700262 * A request object to use for transmitting data to an ICC.
263 */
264 private static final class IccAPDUArgument {
265 public int channel, cla, command, p1, p2, p3;
266 public String data;
267
268 public IccAPDUArgument(int channel, int cla, int command,
269 int p1, int p2, int p3, String data) {
270 this.channel = channel;
271 this.cla = cla;
272 this.command = command;
273 this.p1 = p1;
274 this.p2 = p2;
275 this.p3 = p3;
276 this.data = data;
277 }
278 }
279
280 /**
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700281 * A request object to use for transmitting data to an ICC.
282 */
283 private static final class ManualNetworkSelectionArgument {
284 public OperatorInfo operatorInfo;
285 public boolean persistSelection;
286
287 public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) {
288 this.operatorInfo = operatorInfo;
289 this.persistSelection = persistSelection;
290 }
291 }
292
293 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700294 * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
295 * request after sending. The main thread will notify the request when it is complete.
296 */
297 private static final class MainThreadRequest {
298 /** The argument to use for the request */
299 public Object argument;
300 /** The result of the request that is run on the main thread */
301 public Object result;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800302 // The subscriber id that this request applies to. Defaults to
303 // SubscriptionManager.INVALID_SUBSCRIPTION_ID
304 public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700305
Nathan Harold92bed182018-10-12 18:16:49 -0700306 // In cases where subId is unavailable, the caller needs to specify the phone.
307 public Phone phone;
308
vagdeviaf9a5b92018-08-15 16:01:53 -0700309 public WorkSource workSource;
310
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700311 public MainThreadRequest(Object argument) {
312 this.argument = argument;
313 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800314
Nathan Harold92bed182018-10-12 18:16:49 -0700315 MainThreadRequest(Object argument, Phone phone, WorkSource workSource) {
316 this.argument = argument;
317 if (phone != null) {
318 this.phone = phone;
319 }
320 this.workSource = workSource;
321 }
322
vagdeviaf9a5b92018-08-15 16:01:53 -0700323 MainThreadRequest(Object argument, Integer subId, WorkSource workSource) {
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800324 this.argument = argument;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800325 if (subId != null) {
326 this.subId = subId;
327 }
vagdeviaf9a5b92018-08-15 16:01:53 -0700328 this.workSource = workSource;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800329 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700330 }
331
Sailesh Nepalcc0375f2013-11-13 09:15:18 -0800332 private static final class IncomingThirdPartyCallArgs {
333 public final ComponentName component;
334 public final String callId;
335 public final String callerDisplayName;
336
337 public IncomingThirdPartyCallArgs(ComponentName component, String callId,
338 String callerDisplayName) {
339 this.component = component;
340 this.callId = callId;
341 this.callerDisplayName = callerDisplayName;
342 }
343 }
344
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700345 /**
346 * A handler that processes messages on the main thread in the phone process. Since many
347 * of the Phone calls are not thread safe this is needed to shuttle the requests from the
348 * inbound binder threads to the main thread in the phone process. The Binder thread
349 * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
350 * on, which will be notified when the operation completes and will contain the result of the
351 * request.
352 *
353 * <p>If a MainThreadRequest object is provided in the msg.obj field,
354 * note that request.result must be set to something non-null for the calling thread to
355 * unblock.
356 */
357 private final class MainThreadHandler extends Handler {
358 @Override
359 public void handleMessage(Message msg) {
360 MainThreadRequest request;
361 Message onCompleted;
362 AsyncResult ar;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800363 UiccCard uiccCard;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700364 IccAPDUArgument iccArgument;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700365
366 switch (msg.what) {
Pengquan Menga1bb6272018-09-06 09:59:22 -0700367 case CMD_HANDLE_USSD_REQUEST: {
368 request = (MainThreadRequest) msg.obj;
369 final Phone phone = getPhoneFromRequest(request);
370 Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
371 String ussdRequest = ussdObject.first;
372 ResultReceiver wrappedCallback = ussdObject.second;
Tyler Gunn65d45c22017-06-05 11:22:26 -0700373
Pengquan Menga1bb6272018-09-06 09:59:22 -0700374 if (!isUssdApiAllowed(request.subId)) {
375 // Carrier does not support use of this API, return failure.
376 Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
377 UssdResponse response = new UssdResponse(ussdRequest, null);
378 Bundle returnData = new Bundle();
379 returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
380 wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
Tyler Gunn65d45c22017-06-05 11:22:26 -0700381
Pengquan Menga1bb6272018-09-06 09:59:22 -0700382 request.result = true;
383 notifyRequester(request);
384 return;
385 }
Tyler Gunn65d45c22017-06-05 11:22:26 -0700386
Pengquan Menga1bb6272018-09-06 09:59:22 -0700387 try {
388 request.result = phone != null
389 ? phone.handleUssdRequest(ussdRequest, wrappedCallback) : false;
390 } catch (CallStateException cse) {
391 request.result = false;
392 }
393 // Wake up the requesting thread
394 notifyRequester(request);
395 break;
pkanwar32d516d2016-10-14 19:37:38 -0700396 }
397
Yorke Lee716f67e2015-06-17 15:39:16 -0700398 case CMD_HANDLE_PIN_MMI: {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700399 request = (MainThreadRequest) msg.obj;
Yorke Lee716f67e2015-06-17 15:39:16 -0700400 final Phone phone = getPhoneFromRequest(request);
401 request.result = phone != null ?
402 getPhoneFromRequest(request).handlePinMmi((String) request.argument)
403 : false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700404 // Wake up the requesting thread
Pengquan Menga1bb6272018-09-06 09:59:22 -0700405 notifyRequester(request);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700406 break;
Yorke Lee716f67e2015-06-17 15:39:16 -0700407 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700408
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700409 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700410 request = (MainThreadRequest) msg.obj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700411 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800412 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700413 if (uiccCard == null) {
414 loge("iccTransmitApduLogicalChannel: No UICC");
415 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700416 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700417 } else {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700418 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
419 request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700420 uiccCard.iccTransmitApduLogicalChannel(
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700421 iccArgument.channel, iccArgument.cla, iccArgument.command,
422 iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data,
Shishir Agrawal566b7612013-10-28 14:41:00 -0700423 onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700424 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700425 break;
426
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700427 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700428 ar = (AsyncResult) msg.obj;
429 request = (MainThreadRequest) ar.userObj;
430 if (ar.exception == null && ar.result != null) {
431 request.result = ar.result;
432 } else {
433 request.result = new IccIoResult(0x6F, 0, (byte[])null);
434 if (ar.result == null) {
435 loge("iccTransmitApduLogicalChannel: Empty response");
Jake Hambye994d462014-02-03 13:10:13 -0800436 } else if (ar.exception instanceof CommandException) {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700437 loge("iccTransmitApduLogicalChannel: CommandException: " +
Jake Hambye994d462014-02-03 13:10:13 -0800438 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700439 } else {
440 loge("iccTransmitApduLogicalChannel: Unknown exception");
441 }
442 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700443 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700444 break;
445
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700446 case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
447 request = (MainThreadRequest) msg.obj;
448 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800449 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700450 if (uiccCard == null) {
451 loge("iccTransmitApduBasicChannel: No UICC");
452 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700453 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700454 } else {
455 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
456 request);
457 uiccCard.iccTransmitApduBasicChannel(
458 iccArgument.cla, iccArgument.command, iccArgument.p1, iccArgument.p2,
459 iccArgument.p3, iccArgument.data, onCompleted);
460 }
461 break;
462
463 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
464 ar = (AsyncResult) msg.obj;
465 request = (MainThreadRequest) ar.userObj;
466 if (ar.exception == null && ar.result != null) {
467 request.result = ar.result;
468 } else {
469 request.result = new IccIoResult(0x6F, 0, (byte[])null);
470 if (ar.result == null) {
471 loge("iccTransmitApduBasicChannel: Empty response");
472 } else if (ar.exception instanceof CommandException) {
473 loge("iccTransmitApduBasicChannel: CommandException: " +
474 ar.exception);
475 } else {
476 loge("iccTransmitApduBasicChannel: Unknown exception");
477 }
478 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700479 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700480 break;
481
482 case CMD_EXCHANGE_SIM_IO:
483 request = (MainThreadRequest) msg.obj;
484 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800485 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700486 if (uiccCard == null) {
487 loge("iccExchangeSimIO: No UICC");
488 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700489 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700490 } else {
491 onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
492 request);
493 uiccCard.iccExchangeSimIO(iccArgument.cla, /* fileID */
494 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3,
495 iccArgument.data, onCompleted);
496 }
497 break;
498
499 case EVENT_EXCHANGE_SIM_IO_DONE:
500 ar = (AsyncResult) msg.obj;
501 request = (MainThreadRequest) ar.userObj;
502 if (ar.exception == null && ar.result != null) {
503 request.result = ar.result;
504 } else {
505 request.result = new IccIoResult(0x6f, 0, (byte[])null);
506 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700507 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700508 break;
509
Derek Tan4d5e5c12014-02-04 11:54:58 -0800510 case CMD_SEND_ENVELOPE:
511 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800512 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700513 if (uiccCard == null) {
514 loge("sendEnvelopeWithStatus: No UICC");
515 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700516 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700517 } else {
518 onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
519 uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted);
520 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800521 break;
522
523 case EVENT_SEND_ENVELOPE_DONE:
524 ar = (AsyncResult) msg.obj;
525 request = (MainThreadRequest) ar.userObj;
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700526 if (ar.exception == null && ar.result != null) {
527 request.result = ar.result;
Derek Tan4d5e5c12014-02-04 11:54:58 -0800528 } else {
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700529 request.result = new IccIoResult(0x6F, 0, (byte[])null);
530 if (ar.result == null) {
531 loge("sendEnvelopeWithStatus: Empty response");
532 } else if (ar.exception instanceof CommandException) {
533 loge("sendEnvelopeWithStatus: CommandException: " +
534 ar.exception);
535 } else {
536 loge("sendEnvelopeWithStatus: exception:" + ar.exception);
537 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800538 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700539 notifyRequester(request);
Derek Tan4d5e5c12014-02-04 11:54:58 -0800540 break;
541
Shishir Agrawal566b7612013-10-28 14:41:00 -0700542 case CMD_OPEN_CHANNEL:
543 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800544 uiccCard = getUiccCardFromRequest(request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800545 Pair<String, Integer> openChannelArgs = (Pair<String, Integer>) request.argument;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700546 if (uiccCard == null) {
547 loge("iccOpenLogicalChannel: No UICC");
Shishir Agrawalfc0492a2016-02-17 11:15:33 -0800548 request.result = new IccOpenLogicalChannelResponse(-1,
549 IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700550 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700551 } else {
552 onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800553 uiccCard.iccOpenLogicalChannel(openChannelArgs.first,
554 openChannelArgs.second, onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700555 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700556 break;
557
558 case EVENT_OPEN_CHANNEL_DONE:
559 ar = (AsyncResult) msg.obj;
560 request = (MainThreadRequest) ar.userObj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700561 IccOpenLogicalChannelResponse openChannelResp;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700562 if (ar.exception == null && ar.result != null) {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700563 int[] result = (int[]) ar.result;
564 int channelId = result[0];
565 byte[] selectResponse = null;
566 if (result.length > 1) {
567 selectResponse = new byte[result.length - 1];
568 for (int i = 1; i < result.length; ++i) {
569 selectResponse[i - 1] = (byte) result[i];
570 }
571 }
572 openChannelResp = new IccOpenLogicalChannelResponse(channelId,
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700573 IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700574 } else {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700575 if (ar.result == null) {
576 loge("iccOpenLogicalChannel: Empty response");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700577 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700578 if (ar.exception != null) {
579 loge("iccOpenLogicalChannel: Exception: " + ar.exception);
580 }
581
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700582 int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR;
Junda Liua754ba12015-05-20 01:17:52 -0700583 if (ar.exception instanceof CommandException) {
584 CommandException.Error error =
585 ((CommandException) (ar.exception)).getCommandError();
586 if (error == CommandException.Error.MISSING_RESOURCE) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700587 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE;
Junda Liua754ba12015-05-20 01:17:52 -0700588 } else if (error == CommandException.Error.NO_SUCH_ELEMENT) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700589 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700590 }
591 }
592 openChannelResp = new IccOpenLogicalChannelResponse(
593 IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700594 }
Shishir Agrawal82c8a462014-07-31 18:13:17 -0700595 request.result = openChannelResp;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700596 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700597 break;
598
599 case CMD_CLOSE_CHANNEL:
600 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800601 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700602 if (uiccCard == null) {
603 loge("iccCloseLogicalChannel: No UICC");
Yoshiaki Naka2e29d822016-09-02 19:27:39 +0900604 request.result = false;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700605 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700606 } else {
607 onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
608 uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
609 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700610 break;
611
612 case EVENT_CLOSE_CHANNEL_DONE:
Jake Hambye994d462014-02-03 13:10:13 -0800613 handleNullReturnEvent(msg, "iccCloseLogicalChannel");
614 break;
615
616 case CMD_NV_READ_ITEM:
617 request = (MainThreadRequest) msg.obj;
618 onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
vagdeviaf9a5b92018-08-15 16:01:53 -0700619 mPhone.nvReadItem((Integer) request.argument, onCompleted, request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800620 break;
621
622 case EVENT_NV_READ_ITEM_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700623 ar = (AsyncResult) msg.obj;
624 request = (MainThreadRequest) ar.userObj;
Jake Hambye994d462014-02-03 13:10:13 -0800625 if (ar.exception == null && ar.result != null) {
626 request.result = ar.result; // String
Shishir Agrawal566b7612013-10-28 14:41:00 -0700627 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800628 request.result = "";
629 if (ar.result == null) {
630 loge("nvReadItem: Empty response");
631 } else if (ar.exception instanceof CommandException) {
632 loge("nvReadItem: CommandException: " +
633 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700634 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800635 loge("nvReadItem: Unknown exception");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700636 }
637 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700638 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700639 break;
640
Jake Hambye994d462014-02-03 13:10:13 -0800641 case CMD_NV_WRITE_ITEM:
642 request = (MainThreadRequest) msg.obj;
643 onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
644 Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
vagdeviaf9a5b92018-08-15 16:01:53 -0700645 mPhone.nvWriteItem(idValue.first, idValue.second, onCompleted,
646 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800647 break;
648
649 case EVENT_NV_WRITE_ITEM_DONE:
650 handleNullReturnEvent(msg, "nvWriteItem");
651 break;
652
653 case CMD_NV_WRITE_CDMA_PRL:
654 request = (MainThreadRequest) msg.obj;
655 onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
656 mPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
657 break;
658
659 case EVENT_NV_WRITE_CDMA_PRL_DONE:
660 handleNullReturnEvent(msg, "nvWriteCdmaPrl");
661 break;
662
chen xu6dac5ab2018-10-26 17:39:23 -0700663 case CMD_RESET_MODEM_CONFIG:
Jake Hambye994d462014-02-03 13:10:13 -0800664 request = (MainThreadRequest) msg.obj;
chen xu6dac5ab2018-10-26 17:39:23 -0700665 onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
666 mPhone.resetModemConfig(onCompleted);
Jake Hambye994d462014-02-03 13:10:13 -0800667 break;
668
chen xu6dac5ab2018-10-26 17:39:23 -0700669 case EVENT_RESET_MODEM_CONFIG_DONE:
670 handleNullReturnEvent(msg, "resetModemConfig");
Jake Hambye994d462014-02-03 13:10:13 -0800671 break;
672
Jake Hamby7c27be32014-03-03 13:25:59 -0800673 case CMD_GET_PREFERRED_NETWORK_TYPE:
674 request = (MainThreadRequest) msg.obj;
675 onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request);
Stuart Scott54788802015-03-30 13:18:01 -0700676 getPhoneFromRequest(request).getPreferredNetworkType(onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800677 break;
678
679 case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE:
680 ar = (AsyncResult) msg.obj;
681 request = (MainThreadRequest) ar.userObj;
682 if (ar.exception == null && ar.result != null) {
683 request.result = ar.result; // Integer
684 } else {
Sanket Padawecfc2d352016-01-05 19:52:14 -0800685 request.result = null;
Jake Hamby7c27be32014-03-03 13:25:59 -0800686 if (ar.result == null) {
687 loge("getPreferredNetworkType: Empty response");
688 } else if (ar.exception instanceof CommandException) {
689 loge("getPreferredNetworkType: CommandException: " +
690 ar.exception);
691 } else {
692 loge("getPreferredNetworkType: Unknown exception");
693 }
694 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700695 notifyRequester(request);
Jake Hamby7c27be32014-03-03 13:25:59 -0800696 break;
697
698 case CMD_SET_PREFERRED_NETWORK_TYPE:
699 request = (MainThreadRequest) msg.obj;
700 onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request);
701 int networkType = (Integer) request.argument;
Stuart Scott54788802015-03-30 13:18:01 -0700702 getPhoneFromRequest(request).setPreferredNetworkType(networkType, onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800703 break;
704
705 case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE:
706 handleNullReturnEvent(msg, "setPreferredNetworkType");
707 break;
708
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000709 case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
710 request = (MainThreadRequest)msg.obj;
711 onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
vagdeviaf9a5b92018-08-15 16:01:53 -0700712 mPhone.invokeOemRilRequestRaw((byte[]) request.argument, onCompleted);
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000713 break;
714
715 case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
716 ar = (AsyncResult)msg.obj;
717 request = (MainThreadRequest)ar.userObj;
718 request.result = ar;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700719 notifyRequester(request);
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000720 break;
721
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800722 case CMD_SET_VOICEMAIL_NUMBER:
723 request = (MainThreadRequest) msg.obj;
724 onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
725 Pair<String, String> tagNum = (Pair<String, String>) request.argument;
Stuart Scott584921c2015-01-15 17:10:34 -0800726 getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
727 onCompleted);
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800728 break;
729
730 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
731 handleNullReturnEvent(msg, "setVoicemailNumber");
732 break;
733
Stuart Scott54788802015-03-30 13:18:01 -0700734 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC:
735 request = (MainThreadRequest) msg.obj;
736 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE,
737 request);
738 getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted);
739 break;
740
741 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE:
742 handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic");
743 break;
744
Shishir Agrawal302c8692015-06-19 13:49:39 -0700745 case CMD_PERFORM_NETWORK_SCAN:
746 request = (MainThreadRequest) msg.obj;
747 onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request);
748 getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
749 break;
750
751 case EVENT_PERFORM_NETWORK_SCAN_DONE:
752 ar = (AsyncResult) msg.obj;
753 request = (MainThreadRequest) ar.userObj;
754 CellNetworkScanResult cellScanResult;
755 if (ar.exception == null && ar.result != null) {
756 cellScanResult = new CellNetworkScanResult(
757 CellNetworkScanResult.STATUS_SUCCESS,
758 (List<OperatorInfo>) ar.result);
759 } else {
760 if (ar.result == null) {
761 loge("getCellNetworkScanResults: Empty response");
762 }
763 if (ar.exception != null) {
764 loge("getCellNetworkScanResults: Exception: " + ar.exception);
765 }
766 int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR;
767 if (ar.exception instanceof CommandException) {
768 CommandException.Error error =
769 ((CommandException) (ar.exception)).getCommandError();
770 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
771 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE;
772 } else if (error == CommandException.Error.GENERIC_FAILURE) {
773 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE;
774 }
775 }
776 cellScanResult = new CellNetworkScanResult(errorCode, null);
777 }
778 request.result = cellScanResult;
Pengquan Menga1bb6272018-09-06 09:59:22 -0700779 notifyRequester(request);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700780 break;
781
782 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
783 request = (MainThreadRequest) msg.obj;
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700784 ManualNetworkSelectionArgument selArg =
785 (ManualNetworkSelectionArgument) request.argument;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700786 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE,
787 request);
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700788 getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo,
789 selArg.persistSelection, onCompleted);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700790 break;
791
792 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
Pengquan Menge3d01e22018-09-20 15:25:35 -0700793 ar = (AsyncResult) msg.obj;
794 request = (MainThreadRequest) ar.userObj;
795 if (ar.exception == null) {
796 request.result = true;
797 } else {
798 request.result = false;
799 loge("setNetworkSelectionModeManual " + ar.exception);
800 }
801 notifyRequester(request);
802 mApp.onNetworkSelectionChanged(request.subId);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700803 break;
804
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700805 case CMD_GET_MODEM_ACTIVITY_INFO:
806 request = (MainThreadRequest) msg.obj;
807 onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
vagdeviaf9a5b92018-08-15 16:01:53 -0700808 mPhone.getModemActivityInfo(onCompleted, request.workSource);
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700809 break;
810
811 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE:
812 ar = (AsyncResult) msg.obj;
813 request = (MainThreadRequest) ar.userObj;
814 if (ar.exception == null && ar.result != null) {
815 request.result = ar.result;
816 } else {
817 if (ar.result == null) {
818 loge("queryModemActivityInfo: Empty response");
819 } else if (ar.exception instanceof CommandException) {
820 loge("queryModemActivityInfo: CommandException: " +
821 ar.exception);
822 } else {
823 loge("queryModemActivityInfo: Unknown exception");
824 }
825 }
Amit Mahajand4766222016-01-28 15:28:28 -0800826 // Result cannot be null. Return ModemActivityInfo with all fields set to 0.
827 if (request.result == null) {
828 request.result = new ModemActivityInfo(0, 0, 0, null, 0, 0);
829 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700830 notifyRequester(request);
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700831 break;
832
Meng Wang1a7c35a2016-05-05 20:56:15 -0700833 case CMD_SET_ALLOWED_CARRIERS:
834 request = (MainThreadRequest) msg.obj;
835 onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
836 mPhone.setAllowedCarriers(
837 (List<CarrierIdentifier>) request.argument,
vagdeviaf9a5b92018-08-15 16:01:53 -0700838 onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700839 break;
840
841 case EVENT_SET_ALLOWED_CARRIERS_DONE:
842 ar = (AsyncResult) msg.obj;
843 request = (MainThreadRequest) ar.userObj;
844 if (ar.exception == null && ar.result != null) {
845 request.result = ar.result;
846 } else {
847 if (ar.result == null) {
848 loge("setAllowedCarriers: Empty response");
849 } else if (ar.exception instanceof CommandException) {
850 loge("setAllowedCarriers: CommandException: " +
851 ar.exception);
852 } else {
853 loge("setAllowedCarriers: Unknown exception");
854 }
855 }
856 // Result cannot be null. Return -1 on error.
857 if (request.result == null) {
858 request.result = new int[]{-1};
859 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700860 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700861 break;
862
863 case CMD_GET_ALLOWED_CARRIERS:
864 request = (MainThreadRequest) msg.obj;
865 onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
vagdeviaf9a5b92018-08-15 16:01:53 -0700866 mPhone.getAllowedCarriers(onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700867 break;
868
869 case EVENT_GET_ALLOWED_CARRIERS_DONE:
870 ar = (AsyncResult) msg.obj;
871 request = (MainThreadRequest) ar.userObj;
872 if (ar.exception == null && ar.result != null) {
873 request.result = ar.result;
874 } else {
875 if (ar.result == null) {
876 loge("getAllowedCarriers: Empty response");
877 } else if (ar.exception instanceof CommandException) {
878 loge("getAllowedCarriers: CommandException: " +
879 ar.exception);
880 } else {
881 loge("getAllowedCarriers: Unknown exception");
882 }
883 }
884 // Result cannot be null. Return empty list of CarrierIdentifier.
885 if (request.result == null) {
886 request.result = new ArrayList<CarrierIdentifier>(0);
887 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700888 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700889 break;
890
Nathan Haroldb3014052017-01-25 15:57:32 -0800891 case EVENT_GET_FORBIDDEN_PLMNS_DONE:
892 ar = (AsyncResult) msg.obj;
893 request = (MainThreadRequest) ar.userObj;
894 if (ar.exception == null && ar.result != null) {
895 request.result = ar.result;
896 } else {
897 request.result = new IllegalArgumentException(
898 "Failed to retrieve Forbidden Plmns");
899 if (ar.result == null) {
900 loge("getForbiddenPlmns: Empty response");
901 } else {
902 loge("getForbiddenPlmns: Unknown exception");
903 }
904 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700905 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -0800906 break;
907
908 case CMD_GET_FORBIDDEN_PLMNS:
909 request = (MainThreadRequest) msg.obj;
910 uiccCard = getUiccCardFromRequest(request);
911 if (uiccCard == null) {
912 loge("getForbiddenPlmns() UiccCard is null");
913 request.result = new IllegalArgumentException(
914 "getForbiddenPlmns() UiccCard is null");
Pengquan Menga1bb6272018-09-06 09:59:22 -0700915 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -0800916 break;
917 }
918 Integer appType = (Integer) request.argument;
919 UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType);
920 if (uiccApp == null) {
921 loge("getForbiddenPlmns() no app with specified type -- "
922 + appType);
923 request.result = new IllegalArgumentException("Failed to get UICC App");
Pengquan Menga1bb6272018-09-06 09:59:22 -0700924 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -0800925 break;
926 } else {
927 if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
928 + " specified type -- " + appType);
929 }
930 onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
931 ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
932 onCompleted);
933 break;
934
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000935 case CMD_SWITCH_SLOTS:
936 request = (MainThreadRequest) msg.obj;
937 int[] physicalSlots = (int[]) request.argument;
938 onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
939 UiccController.getInstance().switchSlots(physicalSlots, onCompleted);
940 break;
941
942 case EVENT_SWITCH_SLOTS_DONE:
943 ar = (AsyncResult) msg.obj;
944 request = (MainThreadRequest) ar.userObj;
945 request.result = (ar.exception == null);
Pengquan Menga1bb6272018-09-06 09:59:22 -0700946 notifyRequester(request);
947 break;
948 case CMD_GET_NETWORK_SELECTION_MODE:
949 request = (MainThreadRequest) msg.obj;
950 onCompleted = obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE, request);
951 getPhoneFromRequest(request).getNetworkSelectionMode(onCompleted);
952 break;
953
954 case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
955 ar = (AsyncResult) msg.obj;
956 request = (MainThreadRequest) ar.userObj;
957 if (ar.exception != null) {
958 request.result = TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
959 } else {
960 int mode = ((int[]) ar.result)[0];
961 if (mode == 0) {
962 request.result = TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
963 } else {
964 request.result = TelephonyManager.NETWORK_SELECTION_MODE_MANUAL;
965 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000966 }
Pengquan Menga1bb6272018-09-06 09:59:22 -0700967 notifyRequester(request);
968 break;
969 case CMD_GET_CDMA_ROAMING_MODE:
970 request = (MainThreadRequest) msg.obj;
971 onCompleted = obtainMessage(EVENT_GET_CDMA_ROAMING_MODE_DONE, request);
972 getPhoneFromRequest(request).queryCdmaRoamingPreference(onCompleted);
973 break;
974 case EVENT_GET_CDMA_ROAMING_MODE_DONE:
975 ar = (AsyncResult) msg.obj;
976 request = (MainThreadRequest) ar.userObj;
977 if (ar.exception != null) {
978 request.result = TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT;
979 } else {
980 request.result = ((int[]) ar.result)[0];
981 }
982 notifyRequester(request);
983 break;
984 case CMD_SET_CDMA_ROAMING_MODE:
985 request = (MainThreadRequest) msg.obj;
986 onCompleted = obtainMessage(EVENT_SET_CDMA_ROAMING_MODE_DONE, request);
987 int mode = (int) request.argument;
988 getPhoneFromRequest(request).setCdmaRoamingPreference(mode, onCompleted);
989 break;
990 case EVENT_SET_CDMA_ROAMING_MODE_DONE:
991 ar = (AsyncResult) msg.obj;
992 request = (MainThreadRequest) ar.userObj;
993 request.result = ar.exception == null;
994 notifyRequester(request);
995 break;
996 case CMD_SET_CDMA_SUBSCRIPTION_MODE:
997 request = (MainThreadRequest) msg.obj;
998 onCompleted = obtainMessage(EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE, request);
999 int subscriptionMode = (int) request.argument;
1000 getPhoneFromRequest(request).setCdmaSubscription(subscriptionMode, onCompleted);
1001 break;
1002 case EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE:
1003 ar = (AsyncResult) msg.obj;
1004 request = (MainThreadRequest) ar.userObj;
1005 request.result = ar.exception == null;
1006 notifyRequester(request);
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00001007 break;
Nathan Harold3ff88932018-08-14 10:19:49 -07001008 case CMD_GET_ALL_CELL_INFO:
1009 request = (MainThreadRequest) msg.obj;
Nathan Harold3ff88932018-08-14 10:19:49 -07001010 onCompleted = obtainMessage(EVENT_GET_ALL_CELL_INFO_DONE, request);
Nathan Harold92bed182018-10-12 18:16:49 -07001011 request.phone.requestCellInfoUpdate(request.workSource, onCompleted);
Nathan Harold3ff88932018-08-14 10:19:49 -07001012 break;
Nathan Harold3ff88932018-08-14 10:19:49 -07001013 case EVENT_GET_ALL_CELL_INFO_DONE:
1014 ar = (AsyncResult) msg.obj;
1015 request = (MainThreadRequest) ar.userObj;
Nathan Harold8d0f1742018-10-02 12:14:47 -07001016 // If a timeout occurs, the response will be null
1017 request.result = (ar.exception == null && ar.result != null)
1018 ? ar.result : new ArrayList<CellInfo>();
Nathan Harold3ff88932018-08-14 10:19:49 -07001019 synchronized (request) {
1020 request.notifyAll();
1021 }
1022 break;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001023 case CMD_REQUEST_CELL_INFO_UPDATE:
1024 request = (MainThreadRequest) msg.obj;
1025 request.phone.requestCellInfoUpdate(request.workSource,
1026 obtainMessage(EVENT_REQUEST_CELL_INFO_UPDATE_DONE, request));
1027 break;
1028 case EVENT_REQUEST_CELL_INFO_UPDATE_DONE:
1029 ar = (AsyncResult) msg.obj;
1030 request = (MainThreadRequest) ar.userObj;
1031 ICellInfoCallback cb = (ICellInfoCallback) request.argument;
1032 try {
1033 if (ar.exception != null) {
1034 // something went wrong... the response is null
1035 Log.e(LOG_TAG, "Exception retrieving CellInfo=" + ar.exception);
1036 cb.onCellInfo(null);
1037 } else if (ar.result == null) {
1038 // timeout occurred, so force the result to non-null "empty"
1039 Log.w(LOG_TAG, "Timeout Waiting for CellInfo!");
1040 cb.onCellInfo(new ArrayList<CellInfo>());
1041 } else {
1042 // use the result as returned
1043 cb.onCellInfo((List<CellInfo>) ar.result);
1044 }
1045 } catch (RemoteException re) {
1046 Log.w(LOG_TAG, "Discarded CellInfo due to Callback RemoteException");
1047 }
1048 break;
1049 case CMD_GET_CELL_LOCATION:
Nathan Harold3ff88932018-08-14 10:19:49 -07001050 request = (MainThreadRequest) msg.obj;
1051 WorkSource ws = (WorkSource) request.argument;
1052 Phone phone = getPhoneFromRequest(request);
1053 phone.getCellLocation(ws, obtainMessage(EVENT_GET_CELL_LOCATION_DONE, request));
1054 break;
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001055 case EVENT_GET_CELL_LOCATION_DONE:
Nathan Harold3ff88932018-08-14 10:19:49 -07001056 ar = (AsyncResult) msg.obj;
1057 request = (MainThreadRequest) ar.userObj;
1058 if (ar.exception == null) {
1059 request.result = ar.result;
1060 } else {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001061 phone = getPhoneFromRequest(request);
Nathan Harold3ff88932018-08-14 10:19:49 -07001062 request.result = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
1063 ? new CdmaCellLocation() : new GsmCellLocation();
1064 }
1065
1066 synchronized (request) {
1067 request.notifyAll();
1068 }
1069 break;
chen xu6dac5ab2018-10-26 17:39:23 -07001070 case CMD_MODEM_REBOOT:
1071 request = (MainThreadRequest) msg.obj;
1072 onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
1073 mPhone.rebootModem(onCompleted);
1074 break;
chen xu6dac5ab2018-10-26 17:39:23 -07001075 case EVENT_CMD_MODEM_REBOOT_DONE:
1076 handleNullReturnEvent(msg, "rebootModem");
1077 break;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001078 default:
1079 Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
1080 break;
1081 }
1082 }
Jake Hambye994d462014-02-03 13:10:13 -08001083
Pengquan Menga1bb6272018-09-06 09:59:22 -07001084 private void notifyRequester(MainThreadRequest request) {
1085 synchronized (request) {
1086 request.notifyAll();
1087 }
1088 }
1089
Jake Hambye994d462014-02-03 13:10:13 -08001090 private void handleNullReturnEvent(Message msg, String command) {
1091 AsyncResult ar = (AsyncResult) msg.obj;
1092 MainThreadRequest request = (MainThreadRequest) ar.userObj;
1093 if (ar.exception == null) {
1094 request.result = true;
1095 } else {
1096 request.result = false;
1097 if (ar.exception instanceof CommandException) {
1098 loge(command + ": CommandException: " + ar.exception);
1099 } else {
1100 loge(command + ": Unknown exception");
1101 }
1102 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07001103 notifyRequester(request);
Jake Hambye994d462014-02-03 13:10:13 -08001104 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001105 }
1106
1107 /**
1108 * Posts the specified command to be executed on the main thread,
1109 * waits for the request to complete, and returns the result.
1110 * @see #sendRequestAsync
1111 */
1112 private Object sendRequest(int command, Object argument) {
Nathan Harold92bed182018-10-12 18:16:49 -07001113 return sendRequest(
1114 command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, null, null);
vagdeviaf9a5b92018-08-15 16:01:53 -07001115 }
1116
1117 /**
1118 * Posts the specified command to be executed on the main thread,
1119 * waits for the request to complete, and returns the result.
1120 * @see #sendRequestAsync
1121 */
1122 private Object sendRequest(int command, Object argument, WorkSource workSource) {
1123 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
Nathan Harold92bed182018-10-12 18:16:49 -07001124 null, workSource);
Wink Saville36469e72014-06-11 15:17:00 -07001125 }
1126
1127 /**
1128 * Posts the specified command to be executed on the main thread,
1129 * waits for the request to complete, and returns the result.
1130 * @see #sendRequestAsync
1131 */
Shishir Agrawal76d5da92014-11-09 16:17:25 -08001132 private Object sendRequest(int command, Object argument, Integer subId) {
Nathan Harold92bed182018-10-12 18:16:49 -07001133 return sendRequest(command, argument, subId, null, null);
vagdeviaf9a5b92018-08-15 16:01:53 -07001134 }
1135
1136 /**
1137 * Posts the specified command to be executed on the main thread,
1138 * waits for the request to complete, and returns the result.
1139 * @see #sendRequestAsync
1140 */
Nathan Harold92bed182018-10-12 18:16:49 -07001141 private Object sendRequest(int command, Object argument, int subId, WorkSource workSource) {
1142 return sendRequest(command, argument, subId, null, workSource);
1143 }
1144
1145 /**
1146 * Posts the specified command to be executed on the main thread,
1147 * waits for the request to complete, and returns the result.
1148 * @see #sendRequestAsync
1149 */
1150 private Object sendRequest(int command, Object argument, Phone phone, WorkSource workSource) {
1151 return sendRequest(
1152 command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phone, workSource);
1153 }
1154
1155 /**
1156 * Posts the specified command to be executed on the main thread,
1157 * waits for the request to complete, and returns the result.
1158 * @see #sendRequestAsync
1159 */
1160 private Object sendRequest(
1161 int command, Object argument, Integer subId, Phone phone, WorkSource workSource) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001162 if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
1163 throw new RuntimeException("This method will deadlock if called from the main thread.");
1164 }
1165
Nathan Harold92bed182018-10-12 18:16:49 -07001166 MainThreadRequest request = null;
1167 if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && phone != null) {
1168 throw new IllegalArgumentException("subId and phone cannot both be specified!");
1169 } else if (phone != null) {
1170 request = new MainThreadRequest(argument, phone, workSource);
1171 } else {
1172 request = new MainThreadRequest(argument, subId, workSource);
1173 }
1174
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001175 Message msg = mMainThreadHandler.obtainMessage(command, request);
1176 msg.sendToTarget();
1177
1178 // Wait for the request to complete
1179 synchronized (request) {
1180 while (request.result == null) {
1181 try {
1182 request.wait();
1183 } catch (InterruptedException e) {
1184 // Do nothing, go back and wait until the request is complete
1185 }
1186 }
1187 }
1188 return request.result;
1189 }
1190
1191 /**
1192 * Asynchronous ("fire and forget") version of sendRequest():
1193 * Posts the specified command to be executed on the main thread, and
1194 * returns immediately.
1195 * @see #sendRequest
1196 */
1197 private void sendRequestAsync(int command) {
1198 mMainThreadHandler.sendEmptyMessage(command);
1199 }
1200
1201 /**
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001202 * Same as {@link #sendRequestAsync(int)} except it takes an argument.
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001203 * @see {@link #sendRequest(int)}
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001204 */
1205 private void sendRequestAsync(int command, Object argument) {
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001206 sendRequestAsync(command, argument, null, null);
1207 }
1208
1209 /**
1210 * Same as {@link #sendRequestAsync(int,Object)} except it takes a Phone and WorkSource.
1211 * @see {@link #sendRequest(int,Object)}
1212 */
1213 private void sendRequestAsync(
1214 int command, Object argument, Phone phone, WorkSource workSource) {
1215 MainThreadRequest request = new MainThreadRequest(argument, phone, workSource);
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001216 Message msg = mMainThreadHandler.obtainMessage(command, request);
1217 msg.sendToTarget();
1218 }
1219
1220 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001221 * Initialize the singleton PhoneInterfaceManager instance.
1222 * This is only done once, at startup, from PhoneApp.onCreate().
1223 */
Sailesh Nepal194161e2014-07-03 08:57:44 -07001224 /* package */ static PhoneInterfaceManager init(PhoneGlobals app, Phone phone) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001225 synchronized (PhoneInterfaceManager.class) {
1226 if (sInstance == null) {
Sailesh Nepal194161e2014-07-03 08:57:44 -07001227 sInstance = new PhoneInterfaceManager(app, phone);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001228 } else {
1229 Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
1230 }
1231 return sInstance;
1232 }
1233 }
1234
1235 /** Private constructor; @see init() */
Sailesh Nepal194161e2014-07-03 08:57:44 -07001236 private PhoneInterfaceManager(PhoneGlobals app, Phone phone) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001237 mApp = app;
1238 mPhone = phone;
1239 mCM = PhoneGlobals.getInstance().mCM;
Stuart Scott981d8582015-04-21 14:09:50 -07001240 mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001241 mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
1242 mMainThreadHandler = new MainThreadHandler();
Andrew Leedf14ead2014-10-17 14:22:52 -07001243 mTelephonySharedPreferences =
Derek Tan97ebb422014-09-05 16:55:38 -07001244 PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
Wink Savilleac1bdfd2014-11-20 23:04:44 -08001245 mSubscriptionController = SubscriptionController.getInstance();
yinxub1bed742017-04-17 11:45:04 -07001246 mNetworkScanRequestTracker = new NetworkScanRequestTracker();
Malcolm Chen2c63d402018-08-14 16:00:53 -07001247 mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
Wink Saville3ab207e2014-11-20 13:07:20 -08001248
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001249 publish();
1250 }
1251
1252 private void publish() {
1253 if (DBG) log("publish: " + this);
1254
1255 ServiceManager.addService("phone", this);
1256 }
1257
Stuart Scott584921c2015-01-15 17:10:34 -08001258 private Phone getPhoneFromRequest(MainThreadRequest request) {
Sanket Padawe56e75a32016-02-08 12:18:19 -08001259 return (request.subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
1260 ? mPhone : getPhone(request.subId);
Stuart Scott584921c2015-01-15 17:10:34 -08001261 }
1262
Shishir Agrawalc04d9752016-02-19 10:41:00 -08001263 private UiccCard getUiccCardFromRequest(MainThreadRequest request) {
1264 Phone phone = getPhoneFromRequest(request);
1265 return phone == null ? null :
1266 UiccController.getInstance().getUiccCard(phone.getPhoneId());
1267 }
1268
Wink Saville36469e72014-06-11 15:17:00 -07001269 // returns phone associated with the subId.
Wink Savilleb564aae2014-10-23 10:18:09 -07001270 private Phone getPhone(int subId) {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08001271 return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId));
Wink Saville36469e72014-06-11 15:17:00 -07001272 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001273
1274 public void dial(String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001275 dialForSubscriber(getPreferredVoiceSubscription(), number);
Wink Saville36469e72014-06-11 15:17:00 -07001276 }
1277
Wink Savilleb564aae2014-10-23 10:18:09 -07001278 public void dialForSubscriber(int subId, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001279 if (DBG) log("dial: " + number);
1280 // No permission check needed here: This is just a wrapper around the
1281 // ACTION_DIAL intent, which is available to any app since it puts up
1282 // the UI before it does anything.
1283
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001284 final long identity = Binder.clearCallingIdentity();
1285 try {
1286 String url = createTelUrl(number);
1287 if (url == null) {
1288 return;
1289 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001290
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001291 // PENDING: should we just silently fail if phone is offhook or ringing?
1292 PhoneConstants.State state = mCM.getState(subId);
1293 if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
1294 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
1295 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1296 mApp.startActivity(intent);
1297 }
1298 } finally {
1299 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001300 }
1301 }
1302
1303 public void call(String callingPackage, String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001304 callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number);
Wink Saville36469e72014-06-11 15:17:00 -07001305 }
1306
Wink Savilleb564aae2014-10-23 10:18:09 -07001307 public void callForSubscriber(int subId, String callingPackage, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001308 if (DBG) log("call: " + number);
1309
1310 // This is just a wrapper around the ACTION_CALL intent, but we still
1311 // need to do a permission check since we're calling startActivity()
1312 // from the context of the phone app.
1313 enforceCallPermission();
1314
1315 if (mAppOps.noteOp(AppOpsManager.OP_CALL_PHONE, Binder.getCallingUid(), callingPackage)
1316 != AppOpsManager.MODE_ALLOWED) {
1317 return;
1318 }
1319
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001320 final long identity = Binder.clearCallingIdentity();
1321 try {
1322 String url = createTelUrl(number);
1323 if (url == null) {
1324 return;
1325 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001326
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001327 boolean isValid = false;
1328 final List<SubscriptionInfo> slist = getActiveSubscriptionInfoListPrivileged();
1329 if (slist != null) {
1330 for (SubscriptionInfo subInfoRecord : slist) {
1331 if (subInfoRecord.getSubscriptionId() == subId) {
1332 isValid = true;
1333 break;
1334 }
Wink Saville3ab207e2014-11-20 13:07:20 -08001335 }
Wink Saville08874612014-08-31 19:19:58 -07001336 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001337 if (!isValid) {
1338 return;
1339 }
Wink Saville08874612014-08-31 19:19:58 -07001340
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001341 Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
1342 intent.putExtra(SUBSCRIPTION_KEY, subId);
1343 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1344 mApp.startActivity(intent);
1345 } finally {
1346 Binder.restoreCallingIdentity(identity);
1347 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001348 }
1349
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001350 public boolean supplyPin(String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001351 return supplyPinForSubscriber(getDefaultSubscription(), pin);
Wink Saville36469e72014-06-11 15:17:00 -07001352 }
1353
Wink Savilleb564aae2014-10-23 10:18:09 -07001354 public boolean supplyPinForSubscriber(int subId, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001355 int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07001356 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1357 }
1358
1359 public boolean supplyPuk(String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001360 return supplyPukForSubscriber(getDefaultSubscription(), puk, pin);
Wink Saville36469e72014-06-11 15:17:00 -07001361 }
1362
Wink Savilleb564aae2014-10-23 10:18:09 -07001363 public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001364 int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07001365 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1366 }
1367
1368 /** {@hide} */
1369 public int[] supplyPinReportResult(String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001370 return supplyPinReportResultForSubscriber(getDefaultSubscription(), pin);
Wink Saville36469e72014-06-11 15:17:00 -07001371 }
1372
Wink Savilleb564aae2014-10-23 10:18:09 -07001373 public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001374 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001375
1376 final long identity = Binder.clearCallingIdentity();
1377 try {
1378 final UnlockSim checkSimPin = new UnlockSim(getPhone(subId).getIccCard());
1379 checkSimPin.start();
1380 return checkSimPin.unlockSim(null, pin);
1381 } finally {
1382 Binder.restoreCallingIdentity(identity);
1383 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001384 }
1385
Wink Saville9de0f752013-10-22 19:04:03 -07001386 /** {@hide} */
1387 public int[] supplyPukReportResult(String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001388 return supplyPukReportResultForSubscriber(getDefaultSubscription(), puk, pin);
Wink Saville36469e72014-06-11 15:17:00 -07001389 }
1390
Wink Savilleb564aae2014-10-23 10:18:09 -07001391 public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001392 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001393
1394 final long identity = Binder.clearCallingIdentity();
1395 try {
1396 final UnlockSim checkSimPuk = new UnlockSim(getPhone(subId).getIccCard());
1397 checkSimPuk.start();
1398 return checkSimPuk.unlockSim(puk, pin);
1399 } finally {
1400 Binder.restoreCallingIdentity(identity);
1401 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001402 }
1403
1404 /**
Wink Saville9de0f752013-10-22 19:04:03 -07001405 * Helper thread to turn async call to SimCard#supplyPin into
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001406 * a synchronous one.
1407 */
1408 private static class UnlockSim extends Thread {
1409
1410 private final IccCard mSimCard;
1411
1412 private boolean mDone = false;
Wink Saville9de0f752013-10-22 19:04:03 -07001413 private int mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1414 private int mRetryCount = -1;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001415
1416 // For replies from SimCard interface
1417 private Handler mHandler;
1418
1419 // For async handler to identify request type
1420 private static final int SUPPLY_PIN_COMPLETE = 100;
1421
1422 public UnlockSim(IccCard simCard) {
1423 mSimCard = simCard;
1424 }
1425
1426 @Override
1427 public void run() {
1428 Looper.prepare();
1429 synchronized (UnlockSim.this) {
1430 mHandler = new Handler() {
1431 @Override
1432 public void handleMessage(Message msg) {
1433 AsyncResult ar = (AsyncResult) msg.obj;
1434 switch (msg.what) {
1435 case SUPPLY_PIN_COMPLETE:
1436 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
1437 synchronized (UnlockSim.this) {
Wink Saville9de0f752013-10-22 19:04:03 -07001438 mRetryCount = msg.arg1;
1439 if (ar.exception != null) {
1440 if (ar.exception instanceof CommandException &&
1441 ((CommandException)(ar.exception)).getCommandError()
1442 == CommandException.Error.PASSWORD_INCORRECT) {
1443 mResult = PhoneConstants.PIN_PASSWORD_INCORRECT;
1444 } else {
1445 mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1446 }
1447 } else {
1448 mResult = PhoneConstants.PIN_RESULT_SUCCESS;
1449 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001450 mDone = true;
1451 UnlockSim.this.notifyAll();
1452 }
1453 break;
1454 }
1455 }
1456 };
1457 UnlockSim.this.notifyAll();
1458 }
1459 Looper.loop();
1460 }
1461
1462 /*
1463 * Use PIN or PUK to unlock SIM card
1464 *
1465 * If PUK is null, unlock SIM card with PIN
1466 *
1467 * If PUK is not null, unlock SIM card with PUK and set PIN code
1468 */
Wink Saville9de0f752013-10-22 19:04:03 -07001469 synchronized int[] unlockSim(String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001470
1471 while (mHandler == null) {
1472 try {
1473 wait();
1474 } catch (InterruptedException e) {
1475 Thread.currentThread().interrupt();
1476 }
1477 }
1478 Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
1479
1480 if (puk == null) {
1481 mSimCard.supplyPin(pin, callback);
1482 } else {
1483 mSimCard.supplyPuk(puk, pin, callback);
1484 }
1485
1486 while (!mDone) {
1487 try {
1488 Log.d(LOG_TAG, "wait for done");
1489 wait();
1490 } catch (InterruptedException e) {
1491 // Restore the interrupted status
1492 Thread.currentThread().interrupt();
1493 }
1494 }
1495 Log.d(LOG_TAG, "done");
Wink Saville9de0f752013-10-22 19:04:03 -07001496 int[] resultArray = new int[2];
1497 resultArray[0] = mResult;
1498 resultArray[1] = mRetryCount;
1499 return resultArray;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001500 }
1501 }
1502
1503 public void updateServiceLocation() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001504 updateServiceLocationForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001505
1506 }
1507
Wink Savilleb564aae2014-10-23 10:18:09 -07001508 public void updateServiceLocationForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001509 // No permission check needed here: this call is harmless, and it's
1510 // needed for the ServiceState.requestStateUpdate() call (which is
1511 // already intentionally exposed to 3rd parties.)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001512 final long identity = Binder.clearCallingIdentity();
1513 try {
1514 final Phone phone = getPhone(subId);
1515 if (phone != null) {
1516 phone.updateServiceLocation();
1517 }
1518 } finally {
1519 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001520 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001521 }
1522
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001523 @Override
1524 public boolean isRadioOn(String callingPackage) {
1525 return isRadioOnForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07001526 }
1527
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001528 @Override
1529 public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08001530 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08001531 mApp, subId, callingPackage, "isRadioOnForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001532 return false;
1533 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001534
1535 final long identity = Binder.clearCallingIdentity();
1536 try {
1537 return isRadioOnForSubscriber(subId);
1538 } finally {
1539 Binder.restoreCallingIdentity(identity);
1540 }
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001541 }
1542
1543 private boolean isRadioOnForSubscriber(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001544 final long identity = Binder.clearCallingIdentity();
1545 try {
1546 final Phone phone = getPhone(subId);
1547 if (phone != null) {
1548 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
1549 } else {
1550 return false;
1551 }
1552 } finally {
1553 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001554 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001555 }
1556
1557 public void toggleRadioOnOff() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001558 toggleRadioOnOffForSubscriber(getDefaultSubscription());
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001559 }
Wink Saville36469e72014-06-11 15:17:00 -07001560
Wink Savilleb564aae2014-10-23 10:18:09 -07001561 public void toggleRadioOnOffForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001562 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001563
1564 final long identity = Binder.clearCallingIdentity();
1565 try {
1566 final Phone phone = getPhone(subId);
1567 if (phone != null) {
1568 phone.setRadioPower(!isRadioOnForSubscriber(subId));
1569 }
1570 } finally {
1571 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001572 }
Wink Saville36469e72014-06-11 15:17:00 -07001573 }
1574
1575 public boolean setRadio(boolean turnOn) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001576 return setRadioForSubscriber(getDefaultSubscription(), turnOn);
Wink Saville36469e72014-06-11 15:17:00 -07001577 }
1578
Wink Savilleb564aae2014-10-23 10:18:09 -07001579 public boolean setRadioForSubscriber(int subId, boolean turnOn) {
Wink Saville36469e72014-06-11 15:17:00 -07001580 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001581
1582 final long identity = Binder.clearCallingIdentity();
1583 try {
1584 final Phone phone = getPhone(subId);
1585 if (phone == null) {
1586 return false;
1587 }
1588 if ((phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF) != turnOn) {
1589 toggleRadioOnOffForSubscriber(subId);
1590 }
1591 return true;
1592 } finally {
1593 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001594 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001595 }
Wink Saville36469e72014-06-11 15:17:00 -07001596
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001597 public boolean needMobileRadioShutdown() {
1598 /*
1599 * If any of the Radios are available, it will need to be
1600 * shutdown. So return true if any Radio is available.
1601 */
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001602 final long identity = Binder.clearCallingIdentity();
1603 try {
1604 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1605 Phone phone = PhoneFactory.getPhone(i);
1606 if (phone != null && phone.isRadioAvailable()) return true;
1607 }
1608 logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown.");
1609 return false;
1610 } finally {
1611 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001612 }
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001613 }
1614
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001615 @Override
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001616 public void shutdownMobileRadios() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001617 enforceModifyPermission();
1618
1619 final long identity = Binder.clearCallingIdentity();
1620 try {
1621 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1622 logv("Shutting down Phone " + i);
1623 shutdownRadioUsingPhoneId(i);
1624 }
1625 } finally {
1626 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001627 }
1628 }
1629
1630 private void shutdownRadioUsingPhoneId(int phoneId) {
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001631 Phone phone = PhoneFactory.getPhone(phoneId);
1632 if (phone != null && phone.isRadioAvailable()) {
1633 phone.shutdownRadio();
1634 }
1635 }
1636
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001637 public boolean setRadioPower(boolean turnOn) {
Jack Yub4e16162017-05-15 12:48:40 -07001638 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001639
1640 final long identity = Binder.clearCallingIdentity();
1641 try {
1642 final Phone defaultPhone = PhoneFactory.getDefaultPhone();
1643 if (defaultPhone != null) {
1644 defaultPhone.setRadioPower(turnOn);
1645 return true;
1646 } else {
1647 loge("There's no default phone.");
1648 return false;
1649 }
1650 } finally {
1651 Binder.restoreCallingIdentity(identity);
Wei Liu9ae2a062016-08-08 11:09:34 -07001652 }
Wink Saville36469e72014-06-11 15:17:00 -07001653 }
1654
Wink Savilleb564aae2014-10-23 10:18:09 -07001655 public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001656 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001657
1658 final long identity = Binder.clearCallingIdentity();
1659 try {
1660 final Phone phone = getPhone(subId);
1661 if (phone != null) {
1662 phone.setRadioPower(turnOn);
1663 return true;
1664 } else {
1665 return false;
1666 }
1667 } finally {
1668 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001669 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001670 }
1671
Wink Saville36469e72014-06-11 15:17:00 -07001672 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07001673 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001674 public boolean enableDataConnectivity() {
1675 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001676
1677 final long identity = Binder.clearCallingIdentity();
1678 try {
1679 int subId = mSubscriptionController.getDefaultDataSubId();
1680 final Phone phone = getPhone(subId);
1681 if (phone != null) {
1682 phone.setUserDataEnabled(true);
1683 return true;
1684 } else {
1685 return false;
1686 }
1687 } finally {
1688 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001689 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001690 }
1691
Wink Saville36469e72014-06-11 15:17:00 -07001692 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07001693 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001694 public boolean disableDataConnectivity() {
1695 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001696
1697 final long identity = Binder.clearCallingIdentity();
1698 try {
1699 int subId = mSubscriptionController.getDefaultDataSubId();
1700 final Phone phone = getPhone(subId);
1701 if (phone != null) {
1702 phone.setUserDataEnabled(false);
1703 return true;
1704 } else {
1705 return false;
1706 }
1707 } finally {
1708 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001709 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001710 }
1711
Sanket Padawe356d7632015-06-22 14:03:32 -07001712 @Override
Jack Yuacf8a132017-05-01 17:00:48 -07001713 public boolean isDataConnectivityPossible(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001714 final long identity = Binder.clearCallingIdentity();
1715 try {
1716 final Phone phone = getPhone(subId);
1717 if (phone != null) {
Jack Yub5d8f642018-11-26 11:20:48 -08001718 return phone.isDataAllowed(ApnSetting.TYPE_DEFAULT);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001719 } else {
1720 return false;
1721 }
1722 } finally {
1723 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001724 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001725 }
1726
1727 public boolean handlePinMmi(String dialString) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001728 return handlePinMmiForSubscriber(getDefaultSubscription(), dialString);
Wink Saville36469e72014-06-11 15:17:00 -07001729 }
1730
pkanwarae03a6b2016-11-06 20:37:09 -08001731 public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001732 enforceCallPermission();
1733
1734 final long identity = Binder.clearCallingIdentity();
1735 try {
1736 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1737 return;
1738 }
1739 Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback);
1740 sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId);
1741 } finally {
1742 Binder.restoreCallingIdentity(identity);
1743 }
pkanwar32d516d2016-10-14 19:37:38 -07001744 };
1745
Wink Savilleb564aae2014-10-23 10:18:09 -07001746 public boolean handlePinMmiForSubscriber(int subId, String dialString) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001747 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001748
1749 final long identity = Binder.clearCallingIdentity();
1750 try {
1751 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1752 return false;
1753 }
1754 return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
1755 } finally {
1756 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001757 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001758 }
1759
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001760 public int getCallState() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07001761 return getCallStateForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001762 }
1763
Sanket Padawe13bac7b2017-03-20 15:04:47 -07001764 public int getCallStateForSlot(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001765 final long identity = Binder.clearCallingIdentity();
1766 try {
1767 Phone phone = PhoneFactory.getPhone(slotIndex);
1768 return phone == null ? TelephonyManager.CALL_STATE_IDLE :
1769 PhoneConstantConversions.convertCallState(phone.getState());
1770 } finally {
1771 Binder.restoreCallingIdentity(identity);
1772 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001773 }
1774
Sanket Padawe356d7632015-06-22 14:03:32 -07001775 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001776 public int getDataState() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001777 final long identity = Binder.clearCallingIdentity();
1778 try {
1779 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1780 if (phone != null) {
1781 return PhoneConstantConversions.convertDataState(phone.getDataConnectionState());
1782 } else {
1783 return PhoneConstantConversions.convertDataState(
1784 PhoneConstants.DataState.DISCONNECTED);
1785 }
1786 } finally {
1787 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001788 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001789 }
1790
Sanket Padawe356d7632015-06-22 14:03:32 -07001791 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001792 public int getDataActivity() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001793 final long identity = Binder.clearCallingIdentity();
1794 try {
1795 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1796 if (phone != null) {
1797 return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState());
1798 } else {
1799 return TelephonyManager.DATA_ACTIVITY_NONE;
1800 }
1801 } finally {
1802 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001803 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001804 }
1805
1806 @Override
Svetoslav64fad262015-04-14 14:35:21 -07001807 public Bundle getCellLocation(String callingPackage) {
Hall Liu1aa510f2017-11-22 17:40:08 -08001808 mPhone.getContext().getSystemService(AppOpsManager.class)
1809 .checkPackage(Binder.getCallingUid(), callingPackage);
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001810 if (!LocationAccessPolicy.canAccessCellLocation(mPhone.getContext(),
Svet Ganov4af66282018-03-07 19:57:05 -08001811 callingPackage, Binder.getCallingUid(), Binder.getCallingPid(), true)) {
Svetoslav64fad262015-04-14 14:35:21 -07001812 return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001813 }
1814
Narayan Kamathf04b5a12018-01-09 11:47:15 +00001815 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001816 final long identity = Binder.clearCallingIdentity();
1817 try {
1818 if (DBG_LOC) log("getCellLocation: is active user");
1819 Bundle data = new Bundle();
Nathan Harold3ff88932018-08-14 10:19:49 -07001820 int subId = mSubscriptionController.getDefaultDataSubId();
1821 CellLocation cl = (CellLocation) sendRequest(CMD_GET_CELL_LOCATION, workSource, subId);
1822 cl.fillInNotifierBundle(data);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001823 return data;
1824 } finally {
1825 Binder.restoreCallingIdentity(identity);
1826 }
Svetoslav64fad262015-04-14 14:35:21 -07001827 }
1828
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001829 @Override
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001830 public String getNetworkCountryIsoForPhone(int phoneId) {
1831 // Reporting the correct network country is ambiguous when IWLAN could conflict with
1832 // registered cell info, so return a NULL country instead.
1833 final long identity = Binder.clearCallingIdentity();
1834 try {
Malcolm Chen3732c2b2018-07-18 20:15:24 -07001835 if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
1836 // Get default phone in this case.
1837 phoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
1838 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001839 final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
Jack Yu5f7092c2018-04-13 14:05:37 -07001840 // Todo: fix this when we can get the actual cellular network info when the device
1841 // is on IWLAN.
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001842 if (TelephonyManager.NETWORK_TYPE_IWLAN
1843 == getVoiceNetworkTypeForSubscriber(subId, mApp.getPackageName())) {
1844 return "";
1845 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001846 Phone phone = PhoneFactory.getPhone(phoneId);
1847 if (phone != null) {
1848 ServiceStateTracker sst = phone.getServiceStateTracker();
1849 if (sst != null) {
1850 LocaleTracker lt = sst.getLocaleTracker();
1851 if (lt != null) {
1852 return lt.getCurrentCountry();
1853 }
1854 }
1855 }
1856 return "";
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001857 } finally {
1858 Binder.restoreCallingIdentity(identity);
1859 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001860 }
1861
1862 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001863 public void enableLocationUpdates() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001864 enableLocationUpdatesForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001865 }
1866
Sanket Padawe356d7632015-06-22 14:03:32 -07001867 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07001868 public void enableLocationUpdatesForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001869 mApp.enforceCallingOrSelfPermission(
1870 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001871
1872 final long identity = Binder.clearCallingIdentity();
1873 try {
1874 final Phone phone = getPhone(subId);
1875 if (phone != null) {
1876 phone.enableLocationUpdates();
1877 }
1878 } finally {
1879 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001880 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001881 }
1882
1883 @Override
1884 public void disableLocationUpdates() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001885 disableLocationUpdatesForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001886 }
1887
Sanket Padawe356d7632015-06-22 14:03:32 -07001888 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07001889 public void disableLocationUpdatesForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001890 mApp.enforceCallingOrSelfPermission(
1891 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001892
1893 final long identity = Binder.clearCallingIdentity();
1894 try {
1895 final Phone phone = getPhone(subId);
1896 if (phone != null) {
1897 phone.disableLocationUpdates();
1898 }
1899 } finally {
1900 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001901 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001902 }
1903
Nathan Harold31d7ff32018-10-15 20:20:30 -07001904 /**
1905 * Returns the target SDK version number for a given package name.
1906 *
1907 * @return target SDK if the package is found or INT_MAX.
1908 */
1909 private int getTargetSdk(String packageName) {
1910 try {
1911 final ApplicationInfo ai =
1912 mPhone.getContext().getPackageManager().getApplicationInfo(packageName, 0);
1913 if (ai != null) return ai.targetSdkVersion;
1914 } catch (PackageManager.NameNotFoundException unexpected) {
1915 }
1916 return Integer.MAX_VALUE;
1917 }
1918
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001919 @Override
1920 @SuppressWarnings("unchecked")
Nathan Harold31d7ff32018-10-15 20:20:30 -07001921 public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage) {
1922 final int targetSdk = getTargetSdk(callingPackage);
Nathan Harolddbea45a2018-08-30 14:35:07 -07001923 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
1924 throw new SecurityException(
1925 "getNeighboringCellInfo() is unavailable to callers targeting Q+ SDK levels.");
1926 }
Nathan Haroldb4d55612018-07-20 13:13:08 -07001927
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001928 if (mAppOps.noteOp(AppOpsManager.OP_NEIGHBORING_CELLS, Binder.getCallingUid(),
1929 callingPackage) != AppOpsManager.MODE_ALLOWED) {
1930 return null;
1931 }
Svetoslav64fad262015-04-14 14:35:21 -07001932
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001933 if (DBG_LOC) log("getNeighboringCellInfo: is active user");
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001934
Nathan Haroldf180aac2018-06-01 18:43:55 -07001935 List<CellInfo> info = getAllCellInfo(callingPackage);
1936 if (info == null) return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001937
Nathan Haroldf180aac2018-06-01 18:43:55 -07001938 List<NeighboringCellInfo> neighbors = new ArrayList<NeighboringCellInfo>();
1939 for (CellInfo ci : info) {
1940 if (ci instanceof CellInfoGsm) {
1941 neighbors.add(new NeighboringCellInfo((CellInfoGsm) ci));
1942 } else if (ci instanceof CellInfoWcdma) {
1943 neighbors.add(new NeighboringCellInfo((CellInfoWcdma) ci));
1944 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001945 }
Nathan Haroldf180aac2018-06-01 18:43:55 -07001946 return (neighbors.size()) > 0 ? neighbors : null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001947 }
1948
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001949 private List<CellInfo> getCachedCellInfo() {
1950 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
1951 for (Phone phone : PhoneFactory.getPhones()) {
1952 List<CellInfo> info = phone.getAllCellInfo();
1953 if (info != null) cellInfos.addAll(info);
1954 }
1955 return cellInfos;
1956 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001957
1958 @Override
Svetoslav64fad262015-04-14 14:35:21 -07001959 public List<CellInfo> getAllCellInfo(String callingPackage) {
Hall Liu1aa510f2017-11-22 17:40:08 -08001960 mPhone.getContext().getSystemService(AppOpsManager.class)
1961 .checkPackage(Binder.getCallingUid(), callingPackage);
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001962 if (!LocationAccessPolicy.canAccessCellLocation(mPhone.getContext(),
Svet Ganov4af66282018-03-07 19:57:05 -08001963 callingPackage, Binder.getCallingUid(), Binder.getCallingPid(), true)) {
Svetoslav64fad262015-04-14 14:35:21 -07001964 return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001965 }
1966
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001967 final int targetSdk = getTargetSdk(callingPackage);
1968 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
1969 return getCachedCellInfo();
1970 }
1971
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001972 if (DBG_LOC) log("getAllCellInfo: is active user");
Narayan Kamathf04b5a12018-01-09 11:47:15 +00001973 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001974 final long identity = Binder.clearCallingIdentity();
1975 try {
1976 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
1977 for (Phone phone : PhoneFactory.getPhones()) {
Nathan Harold3ff88932018-08-14 10:19:49 -07001978 final List<CellInfo> info = (List<CellInfo>) sendRequest(
Nathan Harold92bed182018-10-12 18:16:49 -07001979 CMD_GET_ALL_CELL_INFO, null, phone, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001980 if (info != null) cellInfos.addAll(info);
1981 }
1982 return cellInfos;
1983 } finally {
1984 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001985 }
1986 }
1987
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001988 @Override
Nathan Haroldfa8da0f2018-09-27 18:51:29 -07001989 public void requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage) {
1990 requestCellInfoUpdateInternal(
1991 subId, cb, callingPackage, getWorkSource(Binder.getCallingUid()));
1992 }
1993
1994 @Override
1995 public void requestCellInfoUpdateWithWorkSource(
1996 int subId, ICellInfoCallback cb, String callingPackage, WorkSource workSource) {
1997 enforceModifyPermission();
1998 requestCellInfoUpdateInternal(subId, cb, callingPackage, workSource);
1999 }
2000
2001 private void requestCellInfoUpdateInternal(
2002 int subId, ICellInfoCallback cb, String callingPackage, WorkSource workSource) {
2003 mPhone.getContext().getSystemService(AppOpsManager.class)
2004 .checkPackage(Binder.getCallingUid(), callingPackage);
2005 if (!LocationAccessPolicy.canAccessCellLocation(mPhone.getContext(),
2006 callingPackage, Binder.getCallingUid(), Binder.getCallingPid(), true)) {
2007 return;
2008 }
2009
2010 final Phone phone = getPhone(subId);
2011 if (phone == null) throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
2012
2013 sendRequestAsync(CMD_REQUEST_CELL_INFO_UPDATE, cb, phone, workSource);
2014 }
2015
2016 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002017 public void setCellInfoListRate(int rateInMillis) {
Jack Yua8d8cb82017-01-16 10:15:34 -08002018 enforceModifyPermission();
Narayan Kamathf04b5a12018-01-09 11:47:15 +00002019 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002020
2021 final long identity = Binder.clearCallingIdentity();
2022 try {
2023 mPhone.setCellInfoListRate(rateInMillis, workSource);
2024 } finally {
2025 Binder.restoreCallingIdentity(identity);
2026 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002027 }
2028
Shishir Agrawala9f32182016-04-12 12:00:16 -07002029 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002030 public String getImeiForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002031 Phone phone = PhoneFactory.getPhone(slotIndex);
2032 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002033 return null;
2034 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002035 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07002036 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
2037 callingPackage, "getImeiForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002038 return null;
2039 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002040
2041 final long identity = Binder.clearCallingIdentity();
2042 try {
2043 return phone.getImei();
2044 } finally {
2045 Binder.restoreCallingIdentity(identity);
2046 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002047 }
2048
2049 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002050 public String getTypeAllocationCodeForSlot(int slotIndex) {
2051 Phone phone = PhoneFactory.getPhone(slotIndex);
2052 String tac = null;
2053 if (phone != null) {
2054 String imei = phone.getImei();
2055 tac = imei == null ? null : imei.substring(0, TYPE_ALLOCATION_CODE_LENGTH);
2056 }
2057 return tac;
2058 }
2059
2060 @Override
Jack Yu2af8d712017-03-15 17:14:14 -07002061 public String getMeidForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002062 Phone phone = PhoneFactory.getPhone(slotIndex);
2063 if (phone == null) {
Jack Yu2af8d712017-03-15 17:14:14 -07002064 return null;
2065 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002066 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07002067 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
2068 callingPackage, "getMeidForSlot")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002069 return null;
2070 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002071
2072 final long identity = Binder.clearCallingIdentity();
2073 try {
2074 return phone.getMeid();
2075 } finally {
2076 Binder.restoreCallingIdentity(identity);
2077 }
Jack Yu2af8d712017-03-15 17:14:14 -07002078 }
2079
2080 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002081 public String getManufacturerCodeForSlot(int slotIndex) {
2082 Phone phone = PhoneFactory.getPhone(slotIndex);
2083 String manufacturerCode = null;
2084 if (phone != null) {
2085 String meid = phone.getMeid();
2086 manufacturerCode = meid == null ? null : meid.substring(0, MANUFACTURER_CODE_LENGTH);
2087 }
2088 return manufacturerCode;
2089 }
2090
2091 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002092 public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002093 Phone phone = PhoneFactory.getPhone(slotIndex);
2094 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002095 return null;
2096 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002097 int subId = phone.getSubId();
2098 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2099 mApp, subId, callingPackage, "getDeviceSoftwareVersionForSlot")) {
2100 return null;
2101 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002102
2103 final long identity = Binder.clearCallingIdentity();
2104 try {
2105 return phone.getDeviceSvn();
2106 } finally {
2107 Binder.restoreCallingIdentity(identity);
2108 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002109 }
2110
fionaxu43304da2017-11-27 22:51:16 -08002111 @Override
2112 public int getSubscriptionCarrierId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002113 final long identity = Binder.clearCallingIdentity();
2114 try {
2115 final Phone phone = getPhone(subId);
2116 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getCarrierId();
2117 } finally {
2118 Binder.restoreCallingIdentity(identity);
2119 }
fionaxu43304da2017-11-27 22:51:16 -08002120 }
2121
2122 @Override
2123 public String getSubscriptionCarrierName(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002124 final long identity = Binder.clearCallingIdentity();
2125 try {
2126 final Phone phone = getPhone(subId);
2127 return phone == null ? null : phone.getCarrierName();
2128 } finally {
2129 Binder.restoreCallingIdentity(identity);
2130 }
fionaxu43304da2017-11-27 22:51:16 -08002131 }
2132
calvinpanffe225e2018-11-01 19:43:06 +08002133 @Override
2134 public int getSubscriptionMNOCarrierId(int subId) {
2135 final long identity = Binder.clearCallingIdentity();
2136 try {
2137 final Phone phone = getPhone(subId);
2138 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getMNOCarrierId();
2139 } finally {
2140 Binder.restoreCallingIdentity(identity);
2141 }
2142 }
2143
chen xu25637222018-11-04 17:17:00 -08002144 @Override
2145 public int getSubscriptionPreciseCarrierId(int subId) {
2146 final long identity = Binder.clearCallingIdentity();
2147 try {
2148 final Phone phone = getPhone(subId);
2149 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID
2150 : phone.getPreciseCarrierId();
2151 } finally {
2152 Binder.restoreCallingIdentity(identity);
2153 }
2154 }
2155
2156 @Override
2157 public String getSubscriptionPreciseCarrierName(int subId) {
2158 final long identity = Binder.clearCallingIdentity();
2159 try {
2160 final Phone phone = getPhone(subId);
2161 return phone == null ? null : phone.getPreciseCarrierName();
2162 } finally {
2163 Binder.restoreCallingIdentity(identity);
2164 }
2165 }
2166
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002167 //
2168 // Internal helper methods.
2169 //
2170
Sanket Padaweee13a9b2016-03-08 17:30:28 -08002171 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002172 * Make sure the caller has the MODIFY_PHONE_STATE permission.
2173 *
2174 * @throws SecurityException if the caller does not have the required permission
2175 */
2176 private void enforceModifyPermission() {
2177 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
2178 }
2179
2180 /**
2181 * Make sure the caller has the CALL_PHONE permission.
2182 *
2183 * @throws SecurityException if the caller does not have the required permission
2184 */
2185 private void enforceCallPermission() {
2186 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
2187 }
2188
Stuart Scott8eef64f2015-04-08 15:13:54 -07002189 private void enforceConnectivityInternalPermission() {
2190 mApp.enforceCallingOrSelfPermission(
2191 android.Manifest.permission.CONNECTIVITY_INTERNAL,
2192 "ConnectivityService");
2193 }
2194
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002195 private String createTelUrl(String number) {
2196 if (TextUtils.isEmpty(number)) {
2197 return null;
2198 }
2199
Jake Hambye994d462014-02-03 13:10:13 -08002200 return "tel:" + number;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002201 }
2202
Ihab Awadf9e92732013-12-05 18:02:52 -08002203 private static void log(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002204 Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg);
2205 }
2206
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002207 private static void logv(String msg) {
2208 Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg);
2209 }
2210
Ihab Awadf9e92732013-12-05 18:02:52 -08002211 private static void loge(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002212 Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg);
2213 }
2214
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002215 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002216 public int getActivePhoneType() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07002217 return getActivePhoneTypeForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002218 }
2219
Sanket Padawe356d7632015-06-22 14:03:32 -07002220 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002221 public int getActivePhoneTypeForSlot(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002222 final long identity = Binder.clearCallingIdentity();
2223 try {
2224 final Phone phone = PhoneFactory.getPhone(slotIndex);
2225 if (phone == null) {
2226 return PhoneConstants.PHONE_TYPE_NONE;
2227 } else {
2228 return phone.getPhoneType();
2229 }
2230 } finally {
2231 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002232 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002233 }
2234
2235 /**
2236 * Returns the CDMA ERI icon index to display
2237 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002238 @Override
2239 public int getCdmaEriIconIndex(String callingPackage) {
2240 return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002241 }
2242
Sanket Padawe356d7632015-06-22 14:03:32 -07002243 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002244 public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002245 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002246 mApp, subId, callingPackage, "getCdmaEriIconIndexForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002247 return -1;
2248 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002249
2250 final long identity = Binder.clearCallingIdentity();
2251 try {
2252 final Phone phone = getPhone(subId);
2253 if (phone != null) {
2254 return phone.getCdmaEriIconIndex();
2255 } else {
2256 return -1;
2257 }
2258 } finally {
2259 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002260 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002261 }
2262
2263 /**
2264 * Returns the CDMA ERI icon mode,
2265 * 0 - ON
2266 * 1 - FLASHING
2267 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002268 @Override
2269 public int getCdmaEriIconMode(String callingPackage) {
2270 return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002271 }
2272
Sanket Padawe356d7632015-06-22 14:03:32 -07002273 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002274 public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002275 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002276 mApp, subId, callingPackage, "getCdmaEriIconModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002277 return -1;
2278 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002279
2280 final long identity = Binder.clearCallingIdentity();
2281 try {
2282 final Phone phone = getPhone(subId);
2283 if (phone != null) {
2284 return phone.getCdmaEriIconMode();
2285 } else {
2286 return -1;
2287 }
2288 } finally {
2289 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002290 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002291 }
2292
2293 /**
2294 * Returns the CDMA ERI text,
2295 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002296 @Override
2297 public String getCdmaEriText(String callingPackage) {
2298 return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002299 }
2300
Sanket Padawe356d7632015-06-22 14:03:32 -07002301 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002302 public String getCdmaEriTextForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002303 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002304 mApp, subId, callingPackage, "getCdmaEriIconTextForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002305 return null;
2306 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002307
2308 final long identity = Binder.clearCallingIdentity();
2309 try {
2310 final Phone phone = getPhone(subId);
2311 if (phone != null) {
2312 return phone.getCdmaEriText();
2313 } else {
2314 return null;
2315 }
2316 } finally {
2317 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002318 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002319 }
2320
2321 /**
Junda Liuca05d5d2014-08-14 22:36:34 -07002322 * Returns the CDMA MDN.
2323 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002324 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002325 public String getCdmaMdn(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002326 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2327 mApp, subId, "getCdmaMdn");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002328
2329 final long identity = Binder.clearCallingIdentity();
2330 try {
2331 final Phone phone = getPhone(subId);
2332 if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA && phone != null) {
2333 return phone.getLine1Number();
2334 } else {
2335 return null;
2336 }
2337 } finally {
2338 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07002339 }
2340 }
2341
2342 /**
2343 * Returns the CDMA MIN.
2344 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002345 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002346 public String getCdmaMin(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002347 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2348 mApp, subId, "getCdmaMin");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002349
2350 final long identity = Binder.clearCallingIdentity();
2351 try {
2352 final Phone phone = getPhone(subId);
2353 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
2354 return phone.getCdmaMin();
2355 } else {
2356 return null;
2357 }
2358 } finally {
2359 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07002360 }
2361 }
2362
2363 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002364 * Returns true if CDMA provisioning needs to run.
2365 */
2366 public boolean needsOtaServiceProvisioning() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002367 final long identity = Binder.clearCallingIdentity();
2368 try {
2369 return mPhone.needsOtaServiceProvisioning();
2370 } finally {
2371 Binder.restoreCallingIdentity(identity);
2372 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002373 }
2374
2375 /**
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002376 * Sets the voice mail number of a given subId.
2377 */
2378 @Override
2379 public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002380 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setVoiceMailNumber");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002381
2382 final long identity = Binder.clearCallingIdentity();
2383 try {
2384 Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
2385 new Pair<String, String>(alphaTag, number), new Integer(subId));
2386 return success;
2387 } finally {
2388 Binder.restoreCallingIdentity(identity);
2389 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002390 }
2391
Ta-wei Yen87c49842016-05-13 21:19:52 -07002392 @Override
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002393 public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
2394 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2395 String systemDialer = TelecomManager.from(mPhone.getContext()).getSystemDialerPackage();
2396 if (!TextUtils.equals(callingPackage, systemDialer)) {
2397 throw new SecurityException("caller must be system dialer");
2398 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002399
2400 final long identity = Binder.clearCallingIdentity();
2401 try {
2402 PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
2403 if (phoneAccountHandle == null) {
2404 return null;
2405 }
2406 return VisualVoicemailSettingsUtil.dump(mPhone.getContext(), phoneAccountHandle);
2407 } finally {
2408 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002409 }
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002410 }
2411
2412 @Override
Ta-wei Yen409ac562017-03-06 16:00:44 -08002413 public String getVisualVoicemailPackageName(String callingPackage, int subId) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08002414 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jeff Davidson7e17e312018-02-13 18:17:36 -08002415 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002416 mApp, subId, callingPackage, "getVisualVoicemailPackageName")) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08002417 return null;
2418 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002419
Jeff Davidsona8e4e242018-03-15 17:16:18 -07002420 final long identity = Binder.clearCallingIdentity();
2421 try {
2422 return RemoteVvmTaskManager
2423 .getRemotePackage(mPhone.getContext(), subId).getPackageName();
2424 } finally {
2425 Binder.restoreCallingIdentity(identity);
2426 }
Ta-wei Yendca928f2017-01-10 16:17:08 -08002427 }
2428
2429 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002430 public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
2431 VisualVoicemailSmsFilterSettings settings) {
2432 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002433
2434 final long identity = Binder.clearCallingIdentity();
2435 try {
2436 VisualVoicemailSmsFilterConfig.enableVisualVoicemailSmsFilter(
2437 mPhone.getContext(), callingPackage, subId, settings);
2438 } finally {
2439 Binder.restoreCallingIdentity(identity);
2440 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002441 }
2442
2443 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002444 public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
2445 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002446
2447 final long identity = Binder.clearCallingIdentity();
2448 try {
2449 VisualVoicemailSmsFilterConfig.disableVisualVoicemailSmsFilter(
2450 mPhone.getContext(), callingPackage, subId);
2451 } finally {
2452 Binder.restoreCallingIdentity(identity);
2453 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002454 }
2455
2456 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002457 public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
2458 String callingPackage, int subId) {
2459 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002460
2461 final long identity = Binder.clearCallingIdentity();
2462 try {
2463 return VisualVoicemailSmsFilterConfig.getVisualVoicemailSmsFilterSettings(
2464 mPhone.getContext(), callingPackage, subId);
2465 } finally {
2466 Binder.restoreCallingIdentity(identity);
2467 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002468 }
2469
2470 @Override
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002471 public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002472 enforceReadPrivilegedPermission("getActiveVisualVoicemailSmsFilterSettings");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002473
2474 final long identity = Binder.clearCallingIdentity();
2475 try {
2476 return VisualVoicemailSmsFilterConfig.getActiveVisualVoicemailSmsFilterSettings(
2477 mPhone.getContext(), subId);
2478 } finally {
2479 Binder.restoreCallingIdentity(identity);
2480 }
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002481 }
2482
2483 @Override
2484 public void sendVisualVoicemailSmsForSubscriber(String callingPackage, int subId,
2485 String number, int port, String text, PendingIntent sentIntent) {
2486 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Ta-wei Yen527a9c02017-01-06 15:29:25 -08002487 enforceVisualVoicemailPackage(callingPackage, subId);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002488 enforceSendSmsPermission();
2489 // Make the calls as the phone process.
2490 final long identity = Binder.clearCallingIdentity();
2491 try {
2492 SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(subId);
2493 if (port == 0) {
2494 smsManager.sendTextMessageWithSelfPermissions(number, null, text,
2495 sentIntent, null, false);
2496 } else {
2497 byte[] data = text.getBytes(StandardCharsets.UTF_8);
2498 smsManager.sendDataMessageWithSelfPermissions(number, null,
2499 (short) port, data, sentIntent, null);
2500 }
2501 } finally {
2502 Binder.restoreCallingIdentity(identity);
2503 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002504 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002505 /**
fionaxu0152e512016-11-14 13:36:14 -08002506 * Sets the voice activation state of a given subId.
2507 */
2508 @Override
2509 public void setVoiceActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002510 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2511 mApp, subId, "setVoiceActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002512
2513 final long identity = Binder.clearCallingIdentity();
2514 try {
2515 final Phone phone = getPhone(subId);
2516 if (phone != null) {
2517 phone.setVoiceActivationState(activationState);
2518 } else {
2519 loge("setVoiceActivationState fails with invalid subId: " + subId);
2520 }
2521 } finally {
2522 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002523 }
2524 }
2525
2526 /**
2527 * Sets the data activation state of a given subId.
2528 */
2529 @Override
2530 public void setDataActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002531 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2532 mApp, subId, "setDataActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002533
2534 final long identity = Binder.clearCallingIdentity();
2535 try {
2536 final Phone phone = getPhone(subId);
2537 if (phone != null) {
2538 phone.setDataActivationState(activationState);
2539 } else {
2540 loge("setVoiceActivationState fails with invalid subId: " + subId);
2541 }
2542 } finally {
2543 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002544 }
2545 }
2546
2547 /**
2548 * Returns the voice activation state of a given subId.
2549 */
2550 @Override
2551 public int getVoiceActivationState(int subId, String callingPackage) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002552 enforceReadPrivilegedPermission("getVoiceActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002553
fionaxu0152e512016-11-14 13:36:14 -08002554 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002555 final long identity = Binder.clearCallingIdentity();
2556 try {
2557 if (phone != null) {
2558 return phone.getVoiceActivationState();
2559 } else {
2560 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2561 }
2562 } finally {
2563 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002564 }
2565 }
2566
2567 /**
2568 * Returns the data activation state of a given subId.
2569 */
2570 @Override
2571 public int getDataActivationState(int subId, String callingPackage) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07002572 enforceReadPrivilegedPermission("getDataActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002573
fionaxu0152e512016-11-14 13:36:14 -08002574 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002575 final long identity = Binder.clearCallingIdentity();
2576 try {
2577 if (phone != null) {
2578 return phone.getDataActivationState();
2579 } else {
2580 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2581 }
2582 } finally {
2583 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002584 }
2585 }
2586
2587 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002588 * Returns the unread count of voicemails
2589 */
2590 public int getVoiceMessageCount() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002591 return getVoiceMessageCountForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002592 }
2593
2594 /**
2595 * Returns the unread count of voicemails for a subId
2596 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002597 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002598 public int getVoiceMessageCountForSubscriber( int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002599 final long identity = Binder.clearCallingIdentity();
2600 try {
2601 final Phone phone = getPhone(subId);
2602 if (phone != null) {
2603 return phone.getVoiceMessageCount();
2604 } else {
2605 return 0;
2606 }
2607 } finally {
2608 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002609 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002610 }
2611
2612 /**
pkanwar8a4dcfb2017-01-19 13:43:16 -08002613 * returns true, if the device is in a state where both voice and data
2614 * are supported simultaneously. This can change based on location or network condition.
2615 */
2616 @Override
2617 public boolean isConcurrentVoiceAndDataAllowed(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002618 final long identity = Binder.clearCallingIdentity();
2619 try {
2620 final Phone phone = getPhone(subId);
2621 return (phone == null ? false : phone.isConcurrentVoiceAndDataAllowed());
2622 } finally {
2623 Binder.restoreCallingIdentity(identity);
2624 }
pkanwar8a4dcfb2017-01-19 13:43:16 -08002625 }
2626
2627 /**
fionaxu235cc5e2017-03-06 22:25:57 -08002628 * Send the dialer code if called from the current default dialer or the caller has
2629 * carrier privilege.
2630 * @param inputCode The dialer code to send
2631 */
2632 @Override
2633 public void sendDialerSpecialCode(String callingPackage, String inputCode) {
2634 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2635 String defaultDialer = TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage();
2636 if (!TextUtils.equals(callingPackage, defaultDialer)) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002637 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
2638 getDefaultSubscription(), "sendDialerSpecialCode");
fionaxu235cc5e2017-03-06 22:25:57 -08002639 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002640
2641 final long identity = Binder.clearCallingIdentity();
2642 try {
2643 mPhone.sendDialerSpecialCode(inputCode);
2644 } finally {
2645 Binder.restoreCallingIdentity(identity);
2646 }
fionaxu235cc5e2017-03-06 22:25:57 -08002647 }
2648
2649 /**
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002650 * Returns the data network type.
2651 * Legacy call, permission-free.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002652 *
2653 * @Deprecated to be removed Q3 2013 use {@link #getDataNetworkType}.
2654 */
2655 @Override
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002656 public int getNetworkType() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002657 final long identity = Binder.clearCallingIdentity();
2658 try {
2659 final Phone phone = getPhone(getDefaultSubscription());
2660 if (phone != null) {
2661 return phone.getServiceState().getDataNetworkType();
2662 } else {
2663 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2664 }
2665 } finally {
2666 Binder.restoreCallingIdentity(identity);
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002667 }
Wink Saville36469e72014-06-11 15:17:00 -07002668 }
2669
Pengquan Menga1bb6272018-09-06 09:59:22 -07002670 @Override
2671 public int getNetworkSelectionMode(int subId) {
Pengquan Menge92a50d2018-09-21 15:54:48 -07002672 if (!isActiveSubscription(subId)) {
2673 return TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
2674 }
2675
Pengquan Menga1bb6272018-09-06 09:59:22 -07002676 return (int) sendRequest(CMD_GET_NETWORK_SELECTION_MODE, null /* argument */, subId);
2677 }
2678
Brad Ebinger35c841c2018-10-01 10:40:55 -07002679 @Override
2680 public void addImsRegistrationCallback(int subId, IImsRegistrationCallback c,
2681 String callingPackage) throws RemoteException {
2682 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
2683 "addImsRegistrationCallback")) {
2684 return;
2685 }
2686 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2687 final long token = Binder.clearCallingIdentity();
2688 try {
2689 ImsManager.getInstance(mPhone.getContext(), getSlotIndexOrException(subId))
2690 .addRegistrationCallbackForSubscription(c, subId);
2691 } finally {
2692 Binder.restoreCallingIdentity(token);
2693 }
2694 }
2695
2696 @Override
2697 public void removeImsRegistrationCallback(int subId, IImsRegistrationCallback c,
2698 String callingPackage) {
2699 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
2700 "removeImsRegistrationCallback")) {
2701 return;
2702 }
2703 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2704 Binder.withCleanCallingIdentity(() ->
2705 ImsManager.getInstance(mPhone.getContext(), getSlotIndexOrException(subId))
2706 .removeRegistrationCallbackForSubscription(c, subId));
2707 }
2708
2709 @Override
2710 public void addMmTelCapabilityCallback(int subId, IImsCapabilityCallback c,
2711 String callingPackage) throws RemoteException {
2712 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
2713 "addMmTelCapabilityCallback")) {
2714 return;
2715 }
2716 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2717 final long token = Binder.clearCallingIdentity();
2718 try {
2719 ImsManager.getInstance(mPhone.getContext(), getSlotIndexOrException(subId))
2720 .addCapabilitiesCallbackForSubscription(c, subId);
2721 } finally {
2722 Binder.restoreCallingIdentity(token);
2723 }
2724 }
2725
2726 @Override
2727 public void removeMmTelCapabilityCallback(int subId, IImsCapabilityCallback c,
2728 String callingPackage) {
2729 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
2730 "removeMmTelCapabilityCallback")) {
2731 return;
2732 }
2733 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2734 Binder.withCleanCallingIdentity(() ->
2735 ImsManager.getInstance(mPhone.getContext(), getSlotIndexOrException(subId))
2736 .removeCapabilitiesCallbackForSubscription(c, subId));
2737 }
2738
2739 @Override
2740 public boolean isCapable(int subId, int capability, int regTech, String callingPackage) {
2741 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
2742 "isCapable")) {
2743 return false;
2744 }
2745 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2746 final long token = Binder.clearCallingIdentity();
2747 try {
2748 return ImsManager.getInstance(mPhone.getContext(),
2749 getSlotIndexOrException(subId)).queryMmTelCapability(capability, regTech);
2750 } catch (ImsException e) {
2751 Log.w(LOG_TAG, "IMS isCapable - service unavailable: " + e.getMessage());
2752 return false;
2753 } finally {
2754 Binder.restoreCallingIdentity(token);
2755 }
2756 }
2757
2758 @Override
2759 public boolean isAvailable(int subId, int capability, int regTech, String callingPackage) {
2760 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
2761 "isAvailable")) {
2762 return false;
2763 }
2764 final long token = Binder.clearCallingIdentity();
2765 try {
2766 Phone phone = getPhone(subId);
2767 if (phone == null) return false;
2768 return phone.isImsCapabilityAvailable(capability, regTech);
2769 } finally {
2770 Binder.restoreCallingIdentity(token);
2771 }
2772 }
2773
2774 @Override
2775 public boolean isAdvancedCallingSettingEnabled(int subId) {
2776 enforceReadPrivilegedPermission("enforceReadPrivilegedPermission");
2777 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2778 final long token = Binder.clearCallingIdentity();
2779 try {
2780 return ImsManager.getInstance(mPhone.getContext(),
2781 getSlotIndexOrException(subId)).isEnhanced4gLteModeSettingEnabledByUser();
2782 } finally {
2783 Binder.restoreCallingIdentity(token);
2784 }
2785 }
2786
2787 @Override
2788 public void setAdvancedCallingSetting(int subId, boolean isEnabled) {
2789 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
2790 "setAdvancedCallingSetting");
2791 final long identity = Binder.clearCallingIdentity();
2792 try {
2793 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2794 ImsManager.getInstance(mPhone.getContext(),
2795 getSlotIndexOrException(subId)).setEnhanced4gLteModeSetting(isEnabled);
2796 } finally {
2797 Binder.restoreCallingIdentity(identity);
2798 }
2799 }
2800
2801 @Override
2802 public boolean isVtSettingEnabled(int subId, String callingPackage) {
2803 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
2804 "isVtSettingEnabled")) {
2805 return false;
2806 }
2807 final long identity = Binder.clearCallingIdentity();
2808 try {
2809 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2810 return ImsManager.getInstance(mPhone.getContext(),
2811 getSlotIndexOrException(subId)).isVtEnabledByUser();
2812 } finally {
2813 Binder.restoreCallingIdentity(identity);
2814 }
2815 }
2816
2817 @Override
2818 public void setVtSetting(int subId, boolean isEnabled) {
2819 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
2820 "setVtSetting");
2821 final long identity = Binder.clearCallingIdentity();
2822 try {
2823 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2824 ImsManager.getInstance(mPhone.getContext(),
2825 getSlotIndexOrException(subId)).setVtSetting(isEnabled);
2826 } finally {
2827 Binder.restoreCallingIdentity(identity);
2828 }
2829 }
2830
2831 @Override
2832 public boolean isVoWiFiSettingEnabled(int subId) {
2833 enforceReadPrivilegedPermission("isVoWiFiSettingEnabled");
2834 final long identity = Binder.clearCallingIdentity();
2835 try {
2836 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2837 return ImsManager.getInstance(mPhone.getContext(),
2838 getSlotIndexOrException(subId)).isWfcEnabledByUser();
2839 } finally {
2840 Binder.restoreCallingIdentity(identity);
2841 }
2842 }
2843
2844 @Override
2845 public void setVoWiFiSetting(int subId, boolean isEnabled) {
2846 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
2847 "setVoWiFiSetting");
2848 final long identity = Binder.clearCallingIdentity();
2849 try {
2850 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2851 ImsManager.getInstance(mPhone.getContext(),
2852 getSlotIndexOrException(subId)).setWfcSetting(isEnabled);
2853 } finally {
2854 Binder.restoreCallingIdentity(identity);
2855 }
2856 }
2857
2858 @Override
2859 public boolean isVoWiFiRoamingSettingEnabled(int subId) {
2860 enforceReadPrivilegedPermission("isVoWiFiRoamingSettingEnabled");
2861 final long identity = Binder.clearCallingIdentity();
2862 try {
2863 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2864 return ImsManager.getInstance(mPhone.getContext(),
2865 getSlotIndexOrException(subId)).isWfcRoamingEnabledByUser();
2866 } finally {
2867 Binder.restoreCallingIdentity(identity);
2868 }
2869 }
2870
2871 @Override
2872 public void setVoWiFiRoamingSetting(int subId, boolean isEnabled) {
2873 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
2874 "setVoWiFiRoamingSetting");
2875 final long identity = Binder.clearCallingIdentity();
2876 try {
2877 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2878 ImsManager.getInstance(mPhone.getContext(),
2879 getSlotIndexOrException(subId)).setWfcRoamingSetting(isEnabled);
2880 } finally {
2881 Binder.restoreCallingIdentity(identity);
2882 }
2883 }
2884
2885 @Override
2886 public void setVoWiFiNonPersistent(int subId, boolean isCapable, int mode) {
2887 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
2888 "setVoWiFiNonPersistent");
2889 final long identity = Binder.clearCallingIdentity();
2890 try {
2891 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2892 ImsManager.getInstance(mPhone.getContext(),
2893 getSlotIndexOrException(subId)).setWfcNonPersistent(isCapable, mode);
2894 } finally {
2895 Binder.restoreCallingIdentity(identity);
2896 }
2897 }
2898
2899 @Override
2900 public int getVoWiFiModeSetting(int subId) {
2901 enforceReadPrivilegedPermission("getVoWiFiModeSetting");
2902 final long identity = Binder.clearCallingIdentity();
2903 try {
2904 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2905 return ImsManager.getInstance(mPhone.getContext(),
2906 getSlotIndexOrException(subId)).getWfcMode(false /*isRoaming*/);
2907 } finally {
2908 Binder.restoreCallingIdentity(identity);
2909 }
2910 }
2911
2912 @Override
2913 public void setVoWiFiModeSetting(int subId, int mode) {
2914 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
2915 "setVoWiFiModeSetting");
2916 final long identity = Binder.clearCallingIdentity();
2917 try {
2918 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2919 ImsManager.getInstance(mPhone.getContext(),
2920 getSlotIndexOrException(subId)).setWfcMode(mode, false /*isRoaming*/);
2921 } finally {
2922 Binder.restoreCallingIdentity(identity);
2923 }
2924 }
2925
2926 @Override
2927 public int getVoWiFiRoamingModeSetting(int subId) {
2928 enforceReadPrivilegedPermission("getVoWiFiRoamingModeSetting");
2929 final long identity = Binder.clearCallingIdentity();
2930 try {
2931 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2932 return ImsManager.getInstance(mPhone.getContext(),
2933 getSlotIndexOrException(subId)).getWfcMode(true /*isRoaming*/);
2934 } finally {
2935 Binder.restoreCallingIdentity(identity);
2936 }
2937 }
2938
2939 @Override
2940 public void setVoWiFiRoamingModeSetting(int subId, int mode) {
2941 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
2942 "setVoWiFiRoamingModeSetting");
2943 final long identity = Binder.clearCallingIdentity();
2944 try {
2945 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2946 ImsManager.getInstance(mPhone.getContext(),
2947 getSlotIndexOrException(subId)).setWfcMode(mode, true /*isRoaming*/);
2948 } finally {
2949 Binder.restoreCallingIdentity(identity);
2950 }
2951 }
2952
2953 @Override
2954 public void setRttCapabilitySetting(int subId, boolean isEnabled) {
2955 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
2956 "setRttCapabilityEnabled");
2957 final long identity = Binder.clearCallingIdentity();
2958 try {
2959 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2960 ImsManager.getInstance(mPhone.getContext(),
2961 getSlotIndexOrException(subId)).setRttEnabled(isEnabled);
2962 } finally {
2963 Binder.restoreCallingIdentity(identity);
2964 }
2965 }
2966
2967 @Override
2968 public boolean isTtyOverVolteEnabled(int subId) {
2969 enforceReadPrivilegedPermission("isTtyOverVolteEnabled");
2970 final long identity = Binder.clearCallingIdentity();
2971 try {
2972 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2973 return ImsManager.getInstance(mPhone.getContext(),
2974 getSlotIndexOrException(subId)).isTtyOnVoLteCapable();
2975 } finally {
2976 Binder.restoreCallingIdentity(identity);
2977 }
2978 }
2979
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07002980 @Override
2981 public void registerImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
2982 enforceReadPrivilegedPermission("registerImsProvisioningChangedCallback");
2983 final long identity = Binder.clearCallingIdentity();
2984 try {
2985 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2986 ImsManager.getInstance(mPhone.getContext(), getSlotIndexOrException(subId))
2987 .getConfigInterface().addConfigCallback(callback);
2988 } catch (ImsException e) {
2989 throw new IllegalArgumentException(e.getMessage());
2990 } finally {
2991 Binder.restoreCallingIdentity(identity);
2992 }
2993 }
2994
2995 @Override
2996 public void unregisterImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
2997 enforceReadPrivilegedPermission("unregisterImsProvisioningChangedCallback");
2998 final long identity = Binder.clearCallingIdentity();
2999 try {
3000 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3001 ImsManager.getInstance(mPhone.getContext(), getSlotIndexOrException(subId))
3002 .getConfigInterface().removeConfigCallback(callback);
3003 } catch (ImsException e) {
3004 throw new IllegalArgumentException(e.getMessage());
3005 } finally {
3006 Binder.restoreCallingIdentity(identity);
3007 }
3008 }
3009
3010 @Override
3011 public int getImsProvisioningInt(int subId, int key) {
3012 enforceReadPrivilegedPermission("getImsProvisioningInt");
3013 final long identity = Binder.clearCallingIdentity();
3014 try {
3015 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3016 return ImsManager.getInstance(mPhone.getContext(), getSlotIndexOrException(subId))
3017 .getConfigInterface().getConfigInt(key);
3018 } catch (ImsException e) {
3019 throw new IllegalArgumentException(e.getMessage());
3020 } finally {
3021 Binder.restoreCallingIdentity(identity);
3022 }
3023 }
3024
3025 @Override
3026 public String getImsProvisioningString(int subId, int key) {
3027 enforceReadPrivilegedPermission("getImsProvisioningString");
3028 final long identity = Binder.clearCallingIdentity();
3029 try {
3030 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3031 return ImsManager.getInstance(mPhone.getContext(), getSlotIndexOrException(subId))
3032 .getConfigInterface().getConfigString(key);
3033 } catch (ImsException e) {
3034 throw new IllegalArgumentException(e.getMessage());
3035 } finally {
3036 Binder.restoreCallingIdentity(identity);
3037 }
3038 }
3039
3040 @Override
3041 public int setImsProvisioningInt(int subId, int key, int value) {
Brad Ebinger3d0b34e2018-11-15 14:13:12 -08003042 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3043 "setImsProvisioningInt");
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003044 final long identity = Binder.clearCallingIdentity();
3045 try {
3046 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3047 return ImsManager.getInstance(mPhone.getContext(), getSlotIndexOrException(subId))
3048 .getConfigInterface().setConfig(key, value);
3049 } catch (ImsException e) {
3050 throw new IllegalArgumentException(e.getMessage());
3051 } finally {
3052 Binder.restoreCallingIdentity(identity);
3053 }
3054 }
3055
3056 @Override
3057 public int setImsProvisioningString(int subId, int key, String value) {
Brad Ebinger3d0b34e2018-11-15 14:13:12 -08003058 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3059 "setImsProvisioningString");
Brad Ebingerdf5b4f02018-10-31 11:24:17 -07003060 final long identity = Binder.clearCallingIdentity();
3061 try {
3062 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3063 return ImsManager.getInstance(mPhone.getContext(), getSlotIndexOrException(subId))
3064 .getConfigInterface().setConfig(key, value);
3065 } catch (ImsException e) {
3066 throw new IllegalArgumentException(e.getMessage());
3067 } finally {
3068 Binder.restoreCallingIdentity(identity);
3069 }
3070 }
3071
Brad Ebinger35c841c2018-10-01 10:40:55 -07003072 private int getSlotIndexOrException(int subId) throws IllegalArgumentException {
3073 int slotId = SubscriptionManager.getSlotIndex(subId);
3074 if (!SubscriptionManager.isValidSlotIndex(slotId)) {
3075 throw new IllegalArgumentException("Invalid Subscription Id.");
3076 }
3077 return slotId;
3078 }
3079
Wink Saville36469e72014-06-11 15:17:00 -07003080 /**
3081 * Returns the network type for a subId
3082 */
3083 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003084 public int getNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003085 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003086 mApp, subId, callingPackage, "getNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003087 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3088 }
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07003089
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003090 final long identity = Binder.clearCallingIdentity();
3091 try {
3092 final Phone phone = getPhone(subId);
3093 if (phone != null) {
3094 return phone.getServiceState().getDataNetworkType();
3095 } else {
3096 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3097 }
3098 } finally {
3099 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003100 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003101 }
3102
3103 /**
3104 * Returns the data network type
3105 */
3106 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003107 public int getDataNetworkType(String callingPackage) {
3108 return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07003109 }
3110
3111 /**
3112 * Returns the data network type for a subId
3113 */
3114 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003115 public int getDataNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003116 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003117 mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003118 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3119 }
3120
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003121 final long identity = Binder.clearCallingIdentity();
3122 try {
3123 final Phone phone = getPhone(subId);
3124 if (phone != null) {
3125 return phone.getServiceState().getDataNetworkType();
3126 } else {
3127 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3128 }
3129 } finally {
3130 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003131 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003132 }
3133
3134 /**
Wink Saville36469e72014-06-11 15:17:00 -07003135 * Returns the Voice network type for a subId
3136 */
3137 @Override
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07003138 public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003139 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003140 mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07003141 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3142 }
3143
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003144 final long identity = Binder.clearCallingIdentity();
3145 try {
3146 final Phone phone = getPhone(subId);
3147 if (phone != null) {
3148 return phone.getServiceState().getVoiceNetworkType();
3149 } else {
3150 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
3151 }
3152 } finally {
3153 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003154 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003155 }
3156
3157 /**
3158 * @return true if a ICC card is present
3159 */
3160 public boolean hasIccCard() {
Wink Saville36469e72014-06-11 15:17:00 -07003161 // FIXME Make changes to pass defaultSimId of type int
Sanket Padawe13bac7b2017-03-20 15:04:47 -07003162 return hasIccCardUsingSlotIndex(mSubscriptionController.getSlotIndex(
3163 getDefaultSubscription()));
Wink Saville36469e72014-06-11 15:17:00 -07003164 }
3165
3166 /**
Sanket Padawe13bac7b2017-03-20 15:04:47 -07003167 * @return true if a ICC card is present for a slotIndex
Wink Saville36469e72014-06-11 15:17:00 -07003168 */
Sanket Padawe356d7632015-06-22 14:03:32 -07003169 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07003170 public boolean hasIccCardUsingSlotIndex(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003171 final long identity = Binder.clearCallingIdentity();
3172 try {
3173 final Phone phone = PhoneFactory.getPhone(slotIndex);
3174 if (phone != null) {
3175 return phone.getIccCard().hasIccCard();
3176 } else {
3177 return false;
3178 }
3179 } finally {
3180 Binder.restoreCallingIdentity(identity);
Amit Mahajana6fc2a82015-01-06 11:53:51 -08003181 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003182 }
3183
3184 /**
3185 * Return if the current radio is LTE on CDMA. This
3186 * is a tri-state return value as for a period of time
3187 * the mode may be unknown.
3188 *
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003189 * @param callingPackage the name of the package making the call.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003190 * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
Jake Hambye994d462014-02-03 13:10:13 -08003191 * or {@link Phone#LTE_ON_CDMA_TRUE}
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003192 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003193 @Override
3194 public int getLteOnCdmaMode(String callingPackage) {
3195 return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07003196 }
3197
Sanket Padawe356d7632015-06-22 14:03:32 -07003198 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003199 public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003200 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003201 mApp, subId, callingPackage, "getLteOnCdmaModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003202 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
3203 }
3204
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003205 final long identity = Binder.clearCallingIdentity();
3206 try {
3207 final Phone phone = getPhone(subId);
3208 if (phone == null) {
3209 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
3210 } else {
3211 return phone.getLteOnCdmaMode();
3212 }
3213 } finally {
3214 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003215 }
Wink Saville36469e72014-06-11 15:17:00 -07003216 }
3217
3218 public void setPhone(Phone phone) {
3219 mPhone = phone;
3220 }
3221
3222 /**
3223 * {@hide}
3224 * Returns Default subId, 0 in the case of single standby.
3225 */
Wink Savilleb564aae2014-10-23 10:18:09 -07003226 private int getDefaultSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08003227 return mSubscriptionController.getDefaultSubId();
Wink Saville36469e72014-06-11 15:17:00 -07003228 }
3229
Shishir Agrawala9f32182016-04-12 12:00:16 -07003230 private int getSlotForDefaultSubscription() {
3231 return mSubscriptionController.getPhoneId(getDefaultSubscription());
3232 }
3233
Wink Savilleb564aae2014-10-23 10:18:09 -07003234 private int getPreferredVoiceSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08003235 return mSubscriptionController.getDefaultVoiceSubId();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003236 }
Ihab Awadf2177b72013-11-25 13:33:23 -08003237
Pengquan Menge92a50d2018-09-21 15:54:48 -07003238 private boolean isActiveSubscription(int subId) {
3239 return mSubscriptionController.isActiveSubId(subId);
3240 }
3241
Ihab Awadf2177b72013-11-25 13:33:23 -08003242 /**
3243 * @see android.telephony.TelephonyManager.WifiCallingChoices
3244 */
3245 public int getWhenToMakeWifiCalls() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003246 final long identity = Binder.clearCallingIdentity();
3247 try {
3248 return Settings.System.getInt(mPhone.getContext().getContentResolver(),
3249 Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
3250 getWhenToMakeWifiCallsDefaultPreference());
3251 } finally {
3252 Binder.restoreCallingIdentity(identity);
3253 }
Ihab Awadf2177b72013-11-25 13:33:23 -08003254 }
3255
3256 /**
3257 * @see android.telephony.TelephonyManager.WifiCallingChoices
3258 */
3259 public void setWhenToMakeWifiCalls(int preference) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003260 final long identity = Binder.clearCallingIdentity();
3261 try {
3262 if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference);
3263 Settings.System.putInt(mPhone.getContext().getContentResolver(),
3264 Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference);
3265 } finally {
3266 Binder.restoreCallingIdentity(identity);
3267 }
Ihab Awadf9e92732013-12-05 18:02:52 -08003268 }
3269
Sailesh Nepald1e68152013-12-12 19:08:02 -08003270 private static int getWhenToMakeWifiCallsDefaultPreference() {
Santos Cordonda120f42014-08-06 04:44:34 -07003271 // TODO: Use a build property to choose this value.
Evan Charlton9829e882013-12-19 15:30:38 -08003272 return TelephonyManager.WifiCallingChoices.ALWAYS_USE;
Ihab Awadf2177b72013-11-25 13:33:23 -08003273 }
Shishir Agrawal69f68122013-12-16 17:25:49 -08003274
Shishir Agrawal566b7612013-10-28 14:41:00 -07003275 @Override
Derek Tan740e1672017-06-27 14:56:27 -07003276 public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
3277 int subId, String callingPackage, String aid, int p2) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003278 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3279 mApp, subId, "iccOpenLogicalChannel");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003280 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Shishir Agrawal566b7612013-10-28 14:41:00 -07003281
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003282 final long identity = Binder.clearCallingIdentity();
3283 try {
3284 if (TextUtils.equals(ISDR_AID, aid)) {
3285 // Only allows LPA to open logical channel to ISD-R.
3286 ComponentInfo bestComponent =
3287 EuiccConnector.findBestComponent(mPhone.getContext().getPackageManager());
3288 if (bestComponent == null
3289 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
3290 loge("The calling package is not allowed to access ISD-R.");
3291 throw new SecurityException(
3292 "The calling package is not allowed to access ISD-R.");
3293 }
Derek Tan740e1672017-06-27 14:56:27 -07003294 }
Derek Tan740e1672017-06-27 14:56:27 -07003295
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003296 if (DBG) {
3297 log("iccOpenLogicalChannel: subId=" + subId + " aid=" + aid + " p2=" + p2);
3298 }
3299 IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse) sendRequest(
3300 CMD_OPEN_CHANNEL, new Pair<String, Integer>(aid, p2), subId);
3301 if (DBG) log("iccOpenLogicalChannel: " + response);
3302 return response;
3303 } finally {
3304 Binder.restoreCallingIdentity(identity);
3305 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003306 }
3307
3308 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003309 public boolean iccCloseLogicalChannel(int subId, int channel) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003310 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3311 mApp, subId, "iccCloseLogicalChannel");
Shishir Agrawal566b7612013-10-28 14:41:00 -07003312
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003313 final long identity = Binder.clearCallingIdentity();
3314 try {
3315 if (DBG) log("iccCloseLogicalChannel: subId=" + subId + " chnl=" + channel);
3316 if (channel < 0) {
3317 return false;
3318 }
3319 Boolean success = (Boolean) sendRequest(CMD_CLOSE_CHANNEL, channel, subId);
3320 if (DBG) log("iccCloseLogicalChannel: " + success);
3321 return success;
3322 } finally {
3323 Binder.restoreCallingIdentity(identity);
Shishir Agrawal566b7612013-10-28 14:41:00 -07003324 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003325 }
3326
3327 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003328 public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
Shishir Agrawal566b7612013-10-28 14:41:00 -07003329 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003330 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3331 mApp, subId, "iccTransmitApduLogicalChannel");
Shishir Agrawal566b7612013-10-28 14:41:00 -07003332
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003333 final long identity = Binder.clearCallingIdentity();
3334 try {
3335 if (DBG) {
3336 log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel
3337 + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
3338 + p3 + " data=" + data);
3339 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003340
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003341 if (channel < 0) {
3342 return "";
3343 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003344
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003345 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL,
3346 new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), subId);
3347 if (DBG) log("iccTransmitApduLogicalChannel: " + response);
Shishir Agrawal566b7612013-10-28 14:41:00 -07003348
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003349 // Append the returned status code to the end of the response payload.
3350 String s = Integer.toHexString(
3351 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
3352 if (response.payload != null) {
3353 s = IccUtils.bytesToHexString(response.payload) + s;
3354 }
3355 return s;
3356 } finally {
3357 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07003358 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003359 }
Jake Hambye994d462014-02-03 13:10:13 -08003360
Evan Charltonc66da362014-05-16 14:06:40 -07003361 @Override
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08003362 public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
3363 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003364 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3365 mApp, subId, "iccTransmitApduBasicChannel");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003366 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003367
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003368 final long identity = Binder.clearCallingIdentity();
3369 try {
3370 if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
3371 && TextUtils.equals(ISDR_AID, data)) {
3372 // Only allows LPA to select ISD-R.
3373 ComponentInfo bestComponent =
3374 EuiccConnector.findBestComponent(mPhone.getContext().getPackageManager());
3375 if (bestComponent == null
3376 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
3377 loge("The calling package is not allowed to select ISD-R.");
3378 throw new SecurityException(
3379 "The calling package is not allowed to select ISD-R.");
3380 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08003381 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08003382
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003383 if (DBG) {
3384 log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd="
3385 + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
3386 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003387
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003388 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL,
3389 new IccAPDUArgument(0, cla, command, p1, p2, p3, data), subId);
3390 if (DBG) log("iccTransmitApduBasicChannel: " + response);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003391
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003392 // Append the returned status code to the end of the response payload.
3393 String s = Integer.toHexString(
3394 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
3395 if (response.payload != null) {
3396 s = IccUtils.bytesToHexString(response.payload) + s;
3397 }
3398 return s;
3399 } finally {
3400 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07003401 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003402 }
3403
3404 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003405 public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003406 String filePath) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003407 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3408 mApp, subId, "iccExchangeSimIO");
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003409
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003410 final long identity = Binder.clearCallingIdentity();
3411 try {
3412 if (DBG) {
3413 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " "
3414 + p1 + " " + p2 + " " + p3 + ":" + filePath);
3415 }
3416
3417 IccIoResult response =
3418 (IccIoResult) sendRequest(CMD_EXCHANGE_SIM_IO,
3419 new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath),
3420 subId);
3421
3422 if (DBG) {
3423 log("Exchange SIM_IO [R]" + response);
3424 }
3425
3426 byte[] result = null;
3427 int length = 2;
3428 if (response.payload != null) {
3429 length = 2 + response.payload.length;
3430 result = new byte[length];
3431 System.arraycopy(response.payload, 0, result, 0, response.payload.length);
3432 } else {
3433 result = new byte[length];
3434 }
3435
3436 result[length - 1] = (byte) response.sw2;
3437 result[length - 2] = (byte) response.sw1;
3438 return result;
3439 } finally {
3440 Binder.restoreCallingIdentity(identity);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003441 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003442 }
3443
Nathan Haroldb3014052017-01-25 15:57:32 -08003444 /**
3445 * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
3446 * on a particular subscription
3447 */
sqianb6e41952018-03-12 14:54:01 -07003448 public String[] getForbiddenPlmns(int subId, int appType, String callingPackage) {
3449 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
3450 mApp, subId, callingPackage, "getForbiddenPlmns")) {
3451 return null;
3452 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003453
3454 final long identity = Binder.clearCallingIdentity();
3455 try {
3456 if (appType != TelephonyManager.APPTYPE_USIM
3457 && appType != TelephonyManager.APPTYPE_SIM) {
3458 loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
3459 return null;
3460 }
3461 Object response = sendRequest(
3462 CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
3463 if (response instanceof String[]) {
3464 return (String[]) response;
3465 }
3466 // Response is an Exception of some kind,
3467 // which is signalled to the user as a NULL retval
Nathan Haroldb3014052017-01-25 15:57:32 -08003468 return null;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003469 } finally {
3470 Binder.restoreCallingIdentity(identity);
Nathan Haroldb3014052017-01-25 15:57:32 -08003471 }
Nathan Haroldb3014052017-01-25 15:57:32 -08003472 }
3473
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003474 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003475 public String sendEnvelopeWithStatus(int subId, String content) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003476 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3477 mApp, subId, "sendEnvelopeWithStatus");
Evan Charltonc66da362014-05-16 14:06:40 -07003478
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003479 final long identity = Binder.clearCallingIdentity();
3480 try {
3481 IccIoResult response = (IccIoResult) sendRequest(CMD_SEND_ENVELOPE, content, subId);
3482 if (response.payload == null) {
3483 return "";
3484 }
Evan Charltonc66da362014-05-16 14:06:40 -07003485
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003486 // Append the returned status code to the end of the response payload.
3487 String s = Integer.toHexString(
3488 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
3489 s = IccUtils.bytesToHexString(response.payload) + s;
3490 return s;
3491 } finally {
3492 Binder.restoreCallingIdentity(identity);
3493 }
Evan Charltonc66da362014-05-16 14:06:40 -07003494 }
3495
Jake Hambye994d462014-02-03 13:10:13 -08003496 /**
3497 * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
3498 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
3499 *
3500 * @param itemID the ID of the item to read
3501 * @return the NV item as a String, or null on error.
3502 */
3503 @Override
3504 public String nvReadItem(int itemID) {
vagdeviaf9a5b92018-08-15 16:01:53 -07003505 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08003506 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3507 mApp, getDefaultSubscription(), "nvReadItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003508
3509 final long identity = Binder.clearCallingIdentity();
3510 try {
3511 if (DBG) log("nvReadItem: item " + itemID);
vagdeviaf9a5b92018-08-15 16:01:53 -07003512 String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003513 if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
3514 return value;
3515 } finally {
3516 Binder.restoreCallingIdentity(identity);
3517 }
Jake Hambye994d462014-02-03 13:10:13 -08003518 }
3519
3520 /**
3521 * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
3522 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
3523 *
3524 * @param itemID the ID of the item to read
3525 * @param itemValue the value to write, as a String
3526 * @return true on success; false on any failure
3527 */
3528 @Override
3529 public boolean nvWriteItem(int itemID, String itemValue) {
vagdeviaf9a5b92018-08-15 16:01:53 -07003530 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08003531 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3532 mApp, getDefaultSubscription(), "nvWriteItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003533
3534 final long identity = Binder.clearCallingIdentity();
3535 try {
3536 if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
3537 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
vagdeviaf9a5b92018-08-15 16:01:53 -07003538 new Pair<Integer, String>(itemID, itemValue), workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003539 if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
3540 return success;
3541 } finally {
3542 Binder.restoreCallingIdentity(identity);
3543 }
Jake Hambye994d462014-02-03 13:10:13 -08003544 }
3545
3546 /**
3547 * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
3548 * Used for device configuration by some CDMA operators.
3549 *
3550 * @param preferredRoamingList byte array containing the new PRL
3551 * @return true on success; false on any failure
3552 */
3553 @Override
3554 public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003555 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3556 mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003557
3558 final long identity = Binder.clearCallingIdentity();
3559 try {
3560 if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
3561 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
3562 if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
3563 return success;
3564 } finally {
3565 Binder.restoreCallingIdentity(identity);
3566 }
Jake Hambye994d462014-02-03 13:10:13 -08003567 }
3568
3569 /**
chen xu6dac5ab2018-10-26 17:39:23 -07003570 * Rollback modem configurations to factory default except some config which are in whitelist.
Jake Hambye994d462014-02-03 13:10:13 -08003571 * Used for device configuration by some CDMA operators.
3572 *
chen xu6dac5ab2018-10-26 17:39:23 -07003573 * @param slotIndex - device slot.
3574 *
Jake Hambye994d462014-02-03 13:10:13 -08003575 * @return true on success; false on any failure
3576 */
3577 @Override
chen xu6dac5ab2018-10-26 17:39:23 -07003578 public boolean resetModemConfig(int slotIndex) {
3579 Phone phone = PhoneFactory.getPhone(slotIndex);
3580 if (phone != null) {
3581 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3582 mApp, phone.getSubId(), "resetModemConfig");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003583
chen xu6dac5ab2018-10-26 17:39:23 -07003584 final long identity = Binder.clearCallingIdentity();
3585 try {
3586 Boolean success = (Boolean) sendRequest(CMD_RESET_MODEM_CONFIG, null);
3587 if (DBG) log("resetModemConfig:" + ' ' + (success ? "ok" : "fail"));
3588 return success;
3589 } finally {
3590 Binder.restoreCallingIdentity(identity);
3591 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003592 }
chen xu6dac5ab2018-10-26 17:39:23 -07003593 return false;
3594 }
3595
3596 /**
3597 * Generate a radio modem reset. Used for device configuration by some CDMA operators.
3598 *
3599 * @param slotIndex - device slot.
3600 *
3601 * @return true on success; false on any failure
3602 */
3603 @Override
3604 public boolean rebootModem(int slotIndex) {
3605 Phone phone = PhoneFactory.getPhone(slotIndex);
3606 if (phone != null) {
3607 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3608 mApp, phone.getSubId(), "rebootModem");
3609
3610 final long identity = Binder.clearCallingIdentity();
3611 try {
3612 Boolean success = (Boolean) sendRequest(CMD_MODEM_REBOOT, null);
3613 if (DBG) log("rebootModem:" + ' ' + (success ? "ok" : "fail"));
3614 return success;
3615 } finally {
3616 Binder.restoreCallingIdentity(identity);
3617 }
3618 }
3619 return false;
Jake Hambye994d462014-02-03 13:10:13 -08003620 }
Jake Hamby7c27be32014-03-03 13:25:59 -08003621
Svet Ganovb320e182015-04-16 12:30:10 -07003622 public String[] getPcscfAddress(String apnType, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003623 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003624 mApp, mPhone.getSubId(), callingPackage, "getPcscfAddress")) {
Svet Ganovb320e182015-04-16 12:30:10 -07003625 return new String[0];
3626 }
3627
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003628 final long identity = Binder.clearCallingIdentity();
3629 try {
3630 return mPhone.getPcscfAddress(apnType);
3631 } finally {
3632 Binder.restoreCallingIdentity(identity);
3633 }
Wink Saville36469e72014-06-11 15:17:00 -07003634 }
3635
Brad Ebinger51f743a2017-01-23 13:50:20 -08003636 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003637 * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
3638 * status updates, if not already enabled.
Brad Ebinger51f743a2017-01-23 13:50:20 -08003639 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003640 public void enableIms(int slotId) {
Brad Ebinger51f743a2017-01-23 13:50:20 -08003641 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003642
3643 final long identity = Binder.clearCallingIdentity();
3644 try {
3645 PhoneFactory.getImsResolver().enableIms(slotId);
3646 } finally {
3647 Binder.restoreCallingIdentity(identity);
3648 }
Brad Ebinger34bef922017-11-09 10:27:08 -08003649 }
3650
3651 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003652 * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
3653 * status updates to disabled.
Brad Ebinger34bef922017-11-09 10:27:08 -08003654 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003655 public void disableIms(int slotId) {
3656 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003657
3658 final long identity = Binder.clearCallingIdentity();
3659 try {
3660 PhoneFactory.getImsResolver().disableIms(slotId);
3661 } finally {
3662 Binder.restoreCallingIdentity(identity);
3663 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003664 }
3665
3666 /**
3667 * Returns the {@link IImsMmTelFeature} that corresponds to the given slot Id for the MMTel
3668 * feature or {@link null} if the service is not available. If the feature is available, the
3669 * {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates.
3670 */
3671 public IImsMmTelFeature getMmTelFeatureAndListen(int slotId,
Brad Ebinger34bef922017-11-09 10:27:08 -08003672 IImsServiceFeatureCallback callback) {
3673 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003674
3675 final long identity = Binder.clearCallingIdentity();
3676 try {
3677 return PhoneFactory.getImsResolver().getMmTelFeatureAndListen(slotId, callback);
3678 } finally {
3679 Binder.restoreCallingIdentity(identity);
3680 }
Brad Ebinger34bef922017-11-09 10:27:08 -08003681 }
3682
3683 /**
3684 * Returns the {@link IImsRcsFeature} that corresponds to the given slot Id for the RCS
3685 * feature during emergency calling or {@link null} if the service is not available. If the
3686 * feature is available, the {@link IImsServiceFeatureCallback} callback is registered as a
3687 * listener for feature updates.
3688 */
3689 public IImsRcsFeature getRcsFeatureAndListen(int slotId, IImsServiceFeatureCallback callback) {
3690 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003691
3692 final long identity = Binder.clearCallingIdentity();
3693 try {
3694 return PhoneFactory.getImsResolver().getRcsFeatureAndListen(slotId, callback);
3695 } finally {
3696 Binder.restoreCallingIdentity(identity);
3697 }
Brad Ebinger51f743a2017-01-23 13:50:20 -08003698 }
3699
Brad Ebinger5f64b052017-12-14 14:26:15 -08003700 /**
3701 * Returns the {@link IImsRegistration} structure associated with the slotId and feature
3702 * specified.
3703 */
3704 public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
3705 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003706
3707 final long identity = Binder.clearCallingIdentity();
3708 try {
3709 return PhoneFactory.getImsResolver().getImsRegistration(slotId, feature);
3710 } finally {
3711 Binder.restoreCallingIdentity(identity);
3712 }
Brad Ebinger5f64b052017-12-14 14:26:15 -08003713 }
3714
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003715 /**
3716 * Returns the {@link IImsConfig} structure associated with the slotId and feature
3717 * specified.
3718 */
3719 public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
3720 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003721
3722 final long identity = Binder.clearCallingIdentity();
3723 try {
3724 return PhoneFactory.getImsResolver().getImsConfig(slotId, feature);
3725 } finally {
3726 Binder.restoreCallingIdentity(identity);
3727 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003728 }
3729
Brad Ebinger884c07b2018-02-15 16:17:40 -08003730 /**
Brad Ebingerdac2f002018-04-03 15:17:52 -07003731 * Sets the ImsService Package Name that Telephony will bind to.
3732 *
3733 * @param slotId the slot ID that the ImsService should bind for.
3734 * @param isCarrierImsService true if the ImsService is the carrier override, false if the
3735 * ImsService is the device default ImsService.
3736 * @param packageName The package name of the application that contains the ImsService to bind
3737 * to.
3738 * @return true if setting the ImsService to bind to succeeded, false if it did not.
3739 * @hide
3740 */
3741 public boolean setImsService(int slotId, boolean isCarrierImsService, String packageName) {
Brad Ebingerde696de2018-04-06 09:56:40 -07003742 int[] subIds = SubscriptionManager.getSubId(slotId);
3743 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
3744 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
3745 "setImsService");
3746
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003747 final long identity = Binder.clearCallingIdentity();
3748 try {
3749 return PhoneFactory.getImsResolver().overrideImsServiceConfiguration(slotId,
3750 isCarrierImsService, packageName);
3751 } finally {
3752 Binder.restoreCallingIdentity(identity);
3753 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07003754 }
3755
3756 /**
3757 * Return the ImsService configuration.
3758 *
3759 * @param slotId The slot that the ImsService is associated with.
3760 * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
3761 * the device default.
3762 * @return the package name of the ImsService configuration.
3763 */
3764 public String getImsService(int slotId, boolean isCarrierImsService) {
Brad Ebingerde696de2018-04-06 09:56:40 -07003765 int[] subIds = SubscriptionManager.getSubId(slotId);
3766 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
3767 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
3768 "getImsService");
3769
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003770 final long identity = Binder.clearCallingIdentity();
3771 try {
3772 return PhoneFactory.getImsResolver().getImsServiceConfiguration(slotId,
3773 isCarrierImsService);
3774 } finally {
3775 Binder.restoreCallingIdentity(identity);
3776 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07003777 }
3778
Wink Saville36469e72014-06-11 15:17:00 -07003779 public void setImsRegistrationState(boolean registered) {
3780 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003781
3782 final long identity = Binder.clearCallingIdentity();
3783 try {
3784 mPhone.setImsRegistrationState(registered);
3785 } finally {
3786 Binder.restoreCallingIdentity(identity);
3787 }
Wink Saville36469e72014-06-11 15:17:00 -07003788 }
3789
3790 /**
Stuart Scott54788802015-03-30 13:18:01 -07003791 * Set the network selection mode to automatic.
3792 *
3793 */
3794 @Override
3795 public void setNetworkSelectionModeAutomatic(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003796 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3797 mApp, subId, "setNetworkSelectionModeAutomatic");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003798
Pengquan Menge92a50d2018-09-21 15:54:48 -07003799 if (!isActiveSubscription(subId)) {
3800 return;
3801 }
3802
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003803 final long identity = Binder.clearCallingIdentity();
3804 try {
3805 if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
3806 sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId);
3807 } finally {
3808 Binder.restoreCallingIdentity(identity);
3809 }
Stuart Scott54788802015-03-30 13:18:01 -07003810 }
3811
Pengquan Mengea84e042018-09-20 14:57:26 -07003812 /**
3813 * Ask the radio to connect to the input network and change selection mode to manual.
3814 *
3815 * @param subId the id of the subscription.
3816 * @param operatorInfo the operator information, included the PLMN, long name and short name of
3817 * the operator to attach to.
3818 * @param persistSelection whether the selection will persist until reboot. If true, only allows
3819 * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
3820 * normal network selection next time.
3821 * @return {@code true} on success; {@code true} on any failure.
Shishir Agrawal302c8692015-06-19 13:49:39 -07003822 */
3823 @Override
Pengquan Mengea84e042018-09-20 14:57:26 -07003824 public boolean setNetworkSelectionModeManual(
3825 int subId, OperatorInfo operatorInfo, boolean persistSelection) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003826 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3827 mApp, subId, "setNetworkSelectionModeManual");
Pengquan Menge92a50d2018-09-21 15:54:48 -07003828
3829 if (!isActiveSubscription(subId)) {
3830 return false;
3831 }
3832
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003833 final long identity = Binder.clearCallingIdentity();
3834 try {
Pengquan Mengea84e042018-09-20 14:57:26 -07003835 ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operatorInfo,
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003836 persistSelection);
Pengquan Mengea84e042018-09-20 14:57:26 -07003837 if (DBG) {
3838 log("setNetworkSelectionModeManual: subId: " + subId
3839 + " operator: " + operatorInfo);
3840 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003841 return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
3842 } finally {
3843 Binder.restoreCallingIdentity(identity);
3844 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07003845 }
3846
3847 /**
3848 * Scans for available networks.
3849 */
3850 @Override
3851 public CellNetworkScanResult getCellNetworkScanResults(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003852 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3853 mApp, subId, "getCellNetworkScanResults");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003854
Pengquan Menga1bb6272018-09-06 09:59:22 -07003855 long identity = Binder.clearCallingIdentity();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003856 try {
3857 if (DBG) log("getCellNetworkScanResults: subId " + subId);
Pengquan Menga1bb6272018-09-06 09:59:22 -07003858 return (CellNetworkScanResult) sendRequest(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003859 CMD_PERFORM_NETWORK_SCAN, null, subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003860 } finally {
3861 Binder.restoreCallingIdentity(identity);
3862 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07003863 }
3864
3865 /**
yinxub1bed742017-04-17 11:45:04 -07003866 * Starts a new network scan and returns the id of this scan.
yinxu504e1392017-04-12 16:03:22 -07003867 *
yinxub1bed742017-04-17 11:45:04 -07003868 * @param subId id of the subscription
3869 * @param request contains the radio access networks with bands/channels to scan
3870 * @param messenger callback messenger for scan results or errors
3871 * @param binder for the purpose of auto clean when the user thread crashes
yinxu504e1392017-04-12 16:03:22 -07003872 * @return the id of the requested scan which can be used to stop the scan.
3873 */
3874 @Override
3875 public int requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger,
3876 IBinder binder) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003877 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3878 mApp, subId, "requestNetworkScan");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003879
3880 final long identity = Binder.clearCallingIdentity();
3881 try {
3882 return mNetworkScanRequestTracker.startNetworkScan(
3883 request, messenger, binder, getPhone(subId));
3884 } finally {
3885 Binder.restoreCallingIdentity(identity);
3886 }
yinxu504e1392017-04-12 16:03:22 -07003887 }
3888
3889 /**
3890 * Stops an existing network scan with the given scanId.
yinxub1bed742017-04-17 11:45:04 -07003891 *
3892 * @param subId id of the subscription
3893 * @param scanId id of the scan that needs to be stopped
yinxu504e1392017-04-12 16:03:22 -07003894 */
3895 @Override
3896 public void stopNetworkScan(int subId, int scanId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003897 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3898 mApp, subId, "stopNetworkScan");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003899
3900 final long identity = Binder.clearCallingIdentity();
3901 try {
3902 mNetworkScanRequestTracker.stopNetworkScan(scanId);
3903 } finally {
3904 Binder.restoreCallingIdentity(identity);
3905 }
yinxu504e1392017-04-12 16:03:22 -07003906 }
3907
3908 /**
Junda Liu84d15a22014-07-02 11:21:04 -07003909 * Get the calculated preferred network type.
3910 * Used for debugging incorrect network type.
3911 *
3912 * @return the preferred network type, defined in RILConstants.java.
3913 */
3914 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07003915 public int getCalculatedPreferredNetworkType(String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003916 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003917 mApp, mPhone.getSubId(), callingPackage, "getCalculatedPreferredNetworkType")) {
Svet Ganovb320e182015-04-16 12:30:10 -07003918 return RILConstants.PREFERRED_NETWORK_MODE;
3919 }
3920
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003921 final long identity = Binder.clearCallingIdentity();
3922 try {
3923 // FIXME: need to get SubId from somewhere.
3924 return PhoneFactory.calculatePreferredNetworkType(mPhone.getContext(), 0);
3925 } finally {
3926 Binder.restoreCallingIdentity(identity);
3927 }
Junda Liu84d15a22014-07-02 11:21:04 -07003928 }
3929
3930 /**
Jake Hamby7c27be32014-03-03 13:25:59 -08003931 * Get the preferred network type.
3932 * Used for device configuration by some CDMA operators.
3933 *
3934 * @return the preferred network type, defined in RILConstants.java.
3935 */
3936 @Override
Stuart Scott54788802015-03-30 13:18:01 -07003937 public int getPreferredNetworkType(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003938 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3939 mApp, subId, "getPreferredNetworkType");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003940
3941 final long identity = Binder.clearCallingIdentity();
3942 try {
3943 if (DBG) log("getPreferredNetworkType");
3944 int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null, subId);
3945 int networkType = (result != null ? result[0] : -1);
3946 if (DBG) log("getPreferredNetworkType: " + networkType);
3947 return networkType;
3948 } finally {
3949 Binder.restoreCallingIdentity(identity);
3950 }
Jake Hamby7c27be32014-03-03 13:25:59 -08003951 }
3952
3953 /**
3954 * Set the preferred network type.
3955 * Used for device configuration by some CDMA operators.
3956 *
3957 * @param networkType the preferred network type, defined in RILConstants.java.
3958 * @return true on success; false on any failure.
3959 */
3960 @Override
Stuart Scott54788802015-03-30 13:18:01 -07003961 public boolean setPreferredNetworkType(int subId, int networkType) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003962 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3963 mApp, subId, "setPreferredNetworkType");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003964
3965 final long identity = Binder.clearCallingIdentity();
3966 try {
3967 if (DBG) log("setPreferredNetworkType: subId " + subId + " type " + networkType);
3968 Boolean success = (Boolean) sendRequest(
3969 CMD_SET_PREFERRED_NETWORK_TYPE, networkType, subId);
3970 if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail"));
3971 if (success) {
3972 Settings.Global.putInt(mPhone.getContext().getContentResolver(),
3973 Settings.Global.PREFERRED_NETWORK_MODE + subId, networkType);
3974 }
3975 return success;
3976 } finally {
3977 Binder.restoreCallingIdentity(identity);
Junda Liu80bc0d12014-07-14 16:36:44 -07003978 }
Jake Hamby7c27be32014-03-03 13:25:59 -08003979 }
Robert Greenwalted86e582014-05-21 20:03:20 -07003980
3981 /**
Junda Liu475951f2014-11-07 16:45:03 -08003982 * Check TETHER_DUN_REQUIRED and TETHER_DUN_APN settings, net.tethering.noprovisioning
Jack Yu3cda1cd2018-10-30 17:41:31 -07003983 * SystemProperty to decide whether DUN APN is required for
Junda Liu475951f2014-11-07 16:45:03 -08003984 * tethering.
3985 *
3986 * @return 0: Not required. 1: required. 2: Not set.
3987 * @hide
3988 */
3989 @Override
3990 public int getTetherApnRequired() {
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003991 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003992
3993 final long identity = Binder.clearCallingIdentity();
3994 try {
3995 int dunRequired = Settings.Global.getInt(mPhone.getContext().getContentResolver(),
3996 Settings.Global.TETHER_DUN_REQUIRED, 2);
Jack Yu3cda1cd2018-10-30 17:41:31 -07003997 // If not set, check net.tethering.noprovisioning, TETHER_DUN_APN setting
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003998 if (dunRequired == 2 && mPhone.hasMatchedTetherApnSetting()) {
3999 dunRequired = 1;
4000 }
4001 return dunRequired;
4002 } finally {
4003 Binder.restoreCallingIdentity(identity);
Junda Liu475951f2014-11-07 16:45:03 -08004004 }
Junda Liu475951f2014-11-07 16:45:03 -08004005 }
4006
4007 /**
Robert Greenwalted86e582014-05-21 20:03:20 -07004008 * Set mobile data enabled
4009 * Used by the user through settings etc to turn on/off mobile data
4010 *
4011 * @param enable {@code true} turn turn data on, else {@code false}
4012 */
4013 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08004014 public void setUserDataEnabled(int subId, boolean enable) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004015 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4016 mApp, subId, "setUserDataEnabled");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004017
4018 final long identity = Binder.clearCallingIdentity();
4019 try {
4020 int phoneId = mSubscriptionController.getPhoneId(subId);
4021 if (DBG) log("setUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
4022 Phone phone = PhoneFactory.getPhone(phoneId);
4023 if (phone != null) {
4024 if (DBG) log("setUserDataEnabled: subId=" + subId + " enable=" + enable);
4025 phone.setUserDataEnabled(enable);
4026 } else {
4027 loge("setUserDataEnabled: no phone for subId=" + subId);
4028 }
4029 } finally {
4030 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08004031 }
Robert Greenwalted86e582014-05-21 20:03:20 -07004032 }
4033
4034 /**
Malcolm Chen964682d2017-11-28 16:20:07 -08004035 * Get the user enabled state of Mobile Data.
4036 *
4037 * TODO: remove and use isUserDataEnabled.
4038 * This can't be removed now because some vendor codes
4039 * calls through ITelephony directly while they should
4040 * use TelephonyManager.
4041 *
4042 * @return true on enabled
4043 */
4044 @Override
4045 public boolean getDataEnabled(int subId) {
4046 return isUserDataEnabled(subId);
4047 }
4048
4049 /**
4050 * Get whether mobile data is enabled per user setting.
4051 *
4052 * There are other factors deciding whether mobile data is actually enabled, but they are
4053 * not considered here. See {@link #isDataEnabled(int)} for more details.
Robert Greenwalt646120a2014-05-23 11:54:03 -07004054 *
Jeff Davidsona1920712016-11-18 17:05:56 -08004055 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
Robert Greenwalted86e582014-05-21 20:03:20 -07004056 *
4057 * @return {@code true} if data is enabled else {@code false}
4058 */
4059 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08004060 public boolean isUserDataEnabled(int subId) {
Robert Greenwalt646120a2014-05-23 11:54:03 -07004061 try {
4062 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
4063 null);
4064 } catch (Exception e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004065 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4066 mApp, subId, "isUserDataEnabled");
Robert Greenwalt646120a2014-05-23 11:54:03 -07004067 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004068
4069 final long identity = Binder.clearCallingIdentity();
4070 try {
4071 int phoneId = mSubscriptionController.getPhoneId(subId);
4072 if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
4073 Phone phone = PhoneFactory.getPhone(phoneId);
4074 if (phone != null) {
4075 boolean retVal = phone.isUserDataEnabled();
4076 if (DBG) log("isUserDataEnabled: subId=" + subId + " retVal=" + retVal);
4077 return retVal;
4078 } else {
4079 if (DBG) loge("isUserDataEnabled: no phone subId=" + subId + " retVal=false");
4080 return false;
4081 }
4082 } finally {
4083 Binder.restoreCallingIdentity(identity);
Malcolm Chen964682d2017-11-28 16:20:07 -08004084 }
4085 }
4086
4087 /**
4088 * Get whether mobile data is enabled.
4089 *
4090 * Comparable to {@link #isUserDataEnabled(int)}, this considers all factors deciding
4091 * whether mobile data is actually enabled.
4092 *
4093 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
4094 *
4095 * @return {@code true} if data is enabled else {@code false}
4096 */
4097 @Override
4098 public boolean isDataEnabled(int subId) {
4099 try {
4100 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
4101 null);
4102 } catch (Exception e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004103 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4104 mApp, subId, "isDataEnabled");
Malcolm Chen964682d2017-11-28 16:20:07 -08004105 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004106
4107 final long identity = Binder.clearCallingIdentity();
4108 try {
4109 int phoneId = mSubscriptionController.getPhoneId(subId);
4110 if (DBG) log("isDataEnabled: subId=" + subId + " phoneId=" + phoneId);
4111 Phone phone = PhoneFactory.getPhone(phoneId);
4112 if (phone != null) {
4113 boolean retVal = phone.isDataEnabled();
4114 if (DBG) log("isDataEnabled: subId=" + subId + " retVal=" + retVal);
4115 return retVal;
4116 } else {
4117 if (DBG) loge("isDataEnabled: no phone subId=" + subId + " retVal=false");
4118 return false;
4119 }
4120 } finally {
4121 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08004122 }
Robert Greenwalted86e582014-05-21 20:03:20 -07004123 }
Shishir Agrawal60f9c952014-06-23 12:00:43 -07004124
4125 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004126 public int getCarrierPrivilegeStatus(int subId) {
4127 final Phone phone = getPhone(subId);
4128 if (phone == null) {
4129 loge("getCarrierPrivilegeStatus: Invalid subId");
4130 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
4131 }
4132 UiccCard card = UiccController.getInstance().getUiccCard(phone.getPhoneId());
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07004133 if (card == null) {
Shishir Agrawal5e5becd2014-11-18 11:38:23 -08004134 loge("getCarrierPrivilegeStatus: No UICC");
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07004135 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
4136 }
4137 return card.getCarrierPrivilegeStatusForCurrentTransaction(
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004138 phone.getContext().getPackageManager());
Shishir Agrawal60f9c952014-06-23 12:00:43 -07004139 }
Junda Liu29340342014-07-10 15:23:27 -07004140
4141 @Override
Jeff Davidson7e17e312018-02-13 18:17:36 -08004142 public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
4143 final Phone phone = getPhone(subId);
4144 if (phone == null) {
4145 loge("getCarrierPrivilegeStatus: Invalid subId");
4146 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
4147 }
4148 UiccProfile profile =
4149 UiccController.getInstance().getUiccProfileForPhone(phone.getPhoneId());
4150 if (profile == null) {
4151 loge("getCarrierPrivilegeStatus: No UICC");
4152 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
4153 }
4154 return profile.getCarrierPrivilegeStatusForUid(phone.getContext().getPackageManager(), uid);
4155 }
4156
4157 @Override
Zach Johnson50ecba32015-05-19 00:24:21 -07004158 public int checkCarrierPrivilegesForPackage(String pkgName) {
Junda Liu317d70b2016-03-08 09:33:53 -08004159 if (TextUtils.isEmpty(pkgName))
4160 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Shishir Agrawal21409252015-01-15 23:33:50 -08004161 UiccCard card = UiccController.getInstance().getUiccCard(mPhone.getPhoneId());
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07004162 if (card == null) {
4163 loge("checkCarrierPrivilegesForPackage: No UICC");
4164 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
4165 }
Zach Johnson50ecba32015-05-19 00:24:21 -07004166 return card.getCarrierPrivilegeStatus(mPhone.getContext().getPackageManager(), pkgName);
4167 }
4168
4169 @Override
4170 public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
Junda Liu317d70b2016-03-08 09:33:53 -08004171 if (TextUtils.isEmpty(pkgName))
4172 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Zach Johnson50ecba32015-05-19 00:24:21 -07004173 int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
4174 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
4175 UiccCard card = UiccController.getInstance().getUiccCard(i);
4176 if (card == null) {
Jonathan Basseri7d320df2015-06-16 12:17:08 -07004177 // No UICC in that slot.
Zach Johnson50ecba32015-05-19 00:24:21 -07004178 continue;
4179 }
4180
4181 result = card.getCarrierPrivilegeStatus(
4182 mPhone.getContext().getPackageManager(), pkgName);
4183 if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
4184 break;
4185 }
4186 }
4187
4188 return result;
Junda Liu29340342014-07-10 15:23:27 -07004189 }
Derek Tan89e89d42014-07-08 17:00:10 -07004190
4191 @Override
Junda Liue64de782015-04-16 17:19:16 -07004192 public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
4193 if (!SubscriptionManager.isValidPhoneId(phoneId)) {
4194 loge("phoneId " + phoneId + " is not valid.");
4195 return null;
4196 }
4197 UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07004198 if (card == null) {
Diego Pontorieroaf74c862014-08-28 11:51:16 -07004199 loge("getCarrierPackageNamesForIntent: No UICC");
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07004200 return null ;
4201 }
Diego Pontorieroaf74c862014-08-28 11:51:16 -07004202 return card.getCarrierPackageNamesForIntent(
Svetoslav483aff72015-04-21 14:16:07 -07004203 mPhone.getContext().getPackageManager(), intent);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07004204 }
4205
Amith Yamasani6e118872016-02-19 12:53:51 -08004206 @Override
4207 public List<String> getPackagesWithCarrierPrivileges() {
4208 PackageManager pm = mPhone.getContext().getPackageManager();
4209 List<String> privilegedPackages = new ArrayList<>();
4210 List<PackageInfo> packages = null;
4211 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
4212 UiccCard card = UiccController.getInstance().getUiccCard(i);
4213 if (card == null) {
4214 // No UICC in that slot.
4215 continue;
4216 }
4217 if (card.hasCarrierPrivilegeRules()) {
4218 if (packages == null) {
4219 // Only check packages in user 0 for now
4220 packages = pm.getInstalledPackagesAsUser(
4221 PackageManager.MATCH_DISABLED_COMPONENTS
4222 | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
4223 | PackageManager.GET_SIGNATURES, UserHandle.USER_SYSTEM);
4224 }
4225 for (int p = packages.size() - 1; p >= 0; p--) {
4226 PackageInfo pkgInfo = packages.get(p);
4227 if (pkgInfo != null && pkgInfo.packageName != null
4228 && card.getCarrierPrivilegeStatus(pkgInfo)
4229 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
4230 privilegedPackages.add(pkgInfo.packageName);
4231 }
4232 }
4233 }
4234 }
4235 return privilegedPackages;
4236 }
4237
Wink Savilleb564aae2014-10-23 10:18:09 -07004238 private String getIccId(int subId) {
Sanket Padawe356d7632015-06-22 14:03:32 -07004239 final Phone phone = getPhone(subId);
4240 UiccCard card = phone == null ? null : phone.getUiccCard();
Derek Tan97ebb422014-09-05 16:55:38 -07004241 if (card == null) {
4242 loge("getIccId: No UICC");
4243 return null;
4244 }
4245 String iccId = card.getIccId();
4246 if (TextUtils.isEmpty(iccId)) {
4247 loge("getIccId: ICC ID is null or empty.");
4248 return null;
4249 }
4250 return iccId;
4251 }
4252
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07004253 @Override
Jeff Sharkey85190e62014-12-05 09:40:12 -08004254 public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
4255 String number) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004256 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
4257 subId, "setLine1NumberForDisplayForSubscriber");
Derek Tan97ebb422014-09-05 16:55:38 -07004258
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004259 final long identity = Binder.clearCallingIdentity();
4260 try {
4261 final String iccId = getIccId(subId);
4262 final Phone phone = getPhone(subId);
4263 if (phone == null) {
4264 return false;
4265 }
4266 final String subscriberId = phone.getSubscriberId();
4267
4268 if (DBG_MERGE) {
4269 Slog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId="
4270 + subscriberId + " to " + number);
4271 }
4272
4273 if (TextUtils.isEmpty(iccId)) {
4274 return false;
4275 }
4276
4277 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
4278
4279 final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
4280 if (alphaTag == null) {
4281 editor.remove(alphaTagPrefKey);
4282 } else {
4283 editor.putString(alphaTagPrefKey, alphaTag);
4284 }
4285
4286 // Record both the line number and IMSI for this ICCID, since we need to
4287 // track all merged IMSIs based on line number
4288 final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
4289 final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
4290 if (number == null) {
4291 editor.remove(numberPrefKey);
4292 editor.remove(subscriberPrefKey);
4293 } else {
4294 editor.putString(numberPrefKey, number);
4295 editor.putString(subscriberPrefKey, subscriberId);
4296 }
4297
4298 editor.commit();
4299 return true;
4300 } finally {
4301 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004302 }
Derek Tan7226c842014-07-02 17:42:23 -07004303 }
4304
4305 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004306 public String getLine1NumberForDisplay(int subId, String callingPackage) {
Makoto Onukifee69342015-06-29 14:44:50 -07004307 // This is open to apps with WRITE_SMS.
Jeff Davidson7e17e312018-02-13 18:17:36 -08004308 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
Jeff Davidson913390f2018-02-23 17:11:49 -08004309 mApp, subId, callingPackage, "getLine1NumberForDisplay")) {
Amit Mahajan9cf11512015-11-09 11:40:48 -08004310 if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
Svet Ganovb320e182015-04-16 12:30:10 -07004311 return null;
4312 }
Derek Tan97ebb422014-09-05 16:55:38 -07004313
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004314 final long identity = Binder.clearCallingIdentity();
4315 try {
4316 String iccId = getIccId(subId);
4317 if (iccId != null) {
4318 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
4319 if (DBG_MERGE) {
4320 log("getLine1NumberForDisplay returning "
4321 + mTelephonySharedPreferences.getString(numberPrefKey, null));
4322 }
4323 return mTelephonySharedPreferences.getString(numberPrefKey, null);
Amit Mahajan9cf11512015-11-09 11:40:48 -08004324 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004325 if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null");
4326 return null;
4327 } finally {
4328 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07004329 }
Derek Tan7226c842014-07-02 17:42:23 -07004330 }
4331
4332 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004333 public String getLine1AlphaTagForDisplay(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004334 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08004335 mApp, subId, callingPackage, "getLine1AlphaTagForDisplay")) {
Svet Ganovb320e182015-04-16 12:30:10 -07004336 return null;
4337 }
Derek Tan97ebb422014-09-05 16:55:38 -07004338
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004339 final long identity = Binder.clearCallingIdentity();
4340 try {
4341 String iccId = getIccId(subId);
4342 if (iccId != null) {
4343 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
4344 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null);
4345 }
4346 return null;
4347 } finally {
4348 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07004349 }
Derek Tan7226c842014-07-02 17:42:23 -07004350 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07004351
4352 @Override
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07004353 public String[] getMergedSubscriberIds(String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08004354 // This API isn't public, so no need to provide a valid subscription ID - we're not worried
4355 // about carrier-privileged callers not having access.
Jeff Davidson7e17e312018-02-13 18:17:36 -08004356 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08004357 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
4358 "getMergedSubscriberIds")) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07004359 return null;
4360 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08004361
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07004362 final long identity = Binder.clearCallingIdentity();
4363 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004364 final Context context = mPhone.getContext();
4365 final TelephonyManager tele = TelephonyManager.from(context);
4366 final SubscriptionManager sub = SubscriptionManager.from(context);
4367
4368 // Figure out what subscribers are currently active
4369 final ArraySet<String> activeSubscriberIds = new ArraySet<>();
4370 // Clear calling identity, when calling TelephonyManager, because callerUid must be
4371 // the process, where TelephonyManager was instantiated.
4372 // Otherwise AppOps check will fail.
4373
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07004374 final int[] subIds = sub.getActiveSubscriptionIdList();
4375 for (int subId : subIds) {
4376 activeSubscriberIds.add(tele.getSubscriberId(subId));
4377 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004378
4379 // First pass, find a number override for an active subscriber
4380 String mergeNumber = null;
4381 final Map<String, ?> prefs = mTelephonySharedPreferences.getAll();
4382 for (String key : prefs.keySet()) {
4383 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) {
4384 final String subscriberId = (String) prefs.get(key);
4385 if (activeSubscriberIds.contains(subscriberId)) {
4386 final String iccId = key.substring(
4387 PREF_CARRIERS_SUBSCRIBER_PREFIX.length());
4388 final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
4389 mergeNumber = (String) prefs.get(numberKey);
4390 if (DBG_MERGE) {
4391 Slog.d(LOG_TAG, "Found line number " + mergeNumber
4392 + " for active subscriber " + subscriberId);
4393 }
4394 if (!TextUtils.isEmpty(mergeNumber)) {
4395 break;
4396 }
4397 }
4398 }
4399 }
4400
4401 // Shortcut when no active merged subscribers
4402 if (TextUtils.isEmpty(mergeNumber)) {
4403 return null;
4404 }
4405
4406 // Second pass, find all subscribers under that line override
4407 final ArraySet<String> result = new ArraySet<>();
4408 for (String key : prefs.keySet()) {
4409 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) {
4410 final String number = (String) prefs.get(key);
4411 if (mergeNumber.equals(number)) {
4412 final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length());
4413 final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
4414 final String subscriberId = (String) prefs.get(subscriberKey);
4415 if (!TextUtils.isEmpty(subscriberId)) {
4416 result.add(subscriberId);
4417 }
4418 }
4419 }
4420 }
4421
4422 final String[] resultArray = result.toArray(new String[result.size()]);
4423 Arrays.sort(resultArray);
4424 if (DBG_MERGE) {
4425 Slog.d(LOG_TAG,
4426 "Found subscribers " + Arrays.toString(resultArray) + " after merge");
4427 }
4428 return resultArray;
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07004429 } finally {
4430 Binder.restoreCallingIdentity(identity);
Jeff Sharkey85190e62014-12-05 09:40:12 -08004431 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08004432 }
4433
4434 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004435 public boolean setOperatorBrandOverride(int subId, String brand) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004436 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
4437 subId, "setOperatorBrandOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004438
4439 final long identity = Binder.clearCallingIdentity();
4440 try {
4441 final Phone phone = getPhone(subId);
4442 return phone == null ? false : phone.setOperatorBrandOverride(brand);
4443 } finally {
4444 Binder.restoreCallingIdentity(identity);
4445 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07004446 }
Steven Liu4bf01bc2014-07-17 11:05:29 -05004447
4448 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004449 public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
Shishir Agrawal621a47c2014-12-01 10:25:09 -08004450 List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
4451 List<String> cdmaNonRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004452 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setRoamingOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004453
4454 final long identity = Binder.clearCallingIdentity();
4455 try {
4456 final Phone phone = getPhone(subId);
4457 if (phone == null) {
4458 return false;
4459 }
4460 return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList,
4461 cdmaNonRoamingList);
4462 } finally {
4463 Binder.restoreCallingIdentity(identity);
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004464 }
Shishir Agrawal621a47c2014-12-01 10:25:09 -08004465 }
4466
4467 @Override
Shuo Qian850e4d6a2018-04-25 21:02:08 +00004468 @Deprecated
4469 public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
4470 enforceModifyPermission();
4471
4472 int returnValue = 0;
4473 try {
vagdeviaf9a5b92018-08-15 16:01:53 -07004474 AsyncResult result = (AsyncResult) sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
Shuo Qian850e4d6a2018-04-25 21:02:08 +00004475 if(result.exception == null) {
4476 if (result.result != null) {
4477 byte[] responseData = (byte[])(result.result);
4478 if(responseData.length > oemResp.length) {
4479 Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +
4480 responseData.length + "bytes. Buffer Size is " +
4481 oemResp.length + "bytes.");
4482 }
4483 System.arraycopy(responseData, 0, oemResp, 0, responseData.length);
4484 returnValue = responseData.length;
4485 }
4486 } else {
4487 CommandException ex = (CommandException) result.exception;
4488 returnValue = ex.getCommandError().ordinal();
4489 if(returnValue > 0) returnValue *= -1;
4490 }
4491 } catch (RuntimeException e) {
4492 Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");
4493 returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());
4494 if(returnValue > 0) returnValue *= -1;
4495 }
4496
4497 return returnValue;
4498 }
4499
4500 @Override
Wink Saville5d475dd2014-10-17 15:00:58 -07004501 public void setRadioCapability(RadioAccessFamily[] rafs) {
4502 try {
4503 ProxyController.getInstance().setRadioCapability(rafs);
4504 } catch (RuntimeException e) {
4505 Log.w(LOG_TAG, "setRadioCapability: Runtime Exception");
4506 }
4507 }
4508
4509 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004510 public int getRadioAccessFamily(int phoneId, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08004511 Phone phone = PhoneFactory.getPhone(phoneId);
chen xub97461a2018-10-26 14:17:57 -07004512 int raf = RadioAccessFamily.RAF_UNKNOWN;
Jeff Davidson913390f2018-02-23 17:11:49 -08004513 if (phone == null) {
chen xub97461a2018-10-26 14:17:57 -07004514 return raf;
Jeff Davidson913390f2018-02-23 17:11:49 -08004515 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004516 final long identity = Binder.clearCallingIdentity();
4517 try {
chen xub97461a2018-10-26 14:17:57 -07004518 TelephonyPermissions
4519 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
4520 mApp, phone.getSubId(), "getRadioAccessFamily");
4521 raf = ProxyController.getInstance().getRadioAccessFamily(phoneId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004522 } finally {
4523 Binder.restoreCallingIdentity(identity);
4524 }
chen xub97461a2018-10-26 14:17:57 -07004525 return raf;
Wink Saville5d475dd2014-10-17 15:00:58 -07004526 }
Andrew Leedf14ead2014-10-17 14:22:52 -07004527
4528 @Override
4529 public void enableVideoCalling(boolean enable) {
4530 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004531
4532 final long identity = Binder.clearCallingIdentity();
4533 try {
4534 ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId()).setVtSetting(enable);
4535 } finally {
4536 Binder.restoreCallingIdentity(identity);
4537 }
Andrew Leedf14ead2014-10-17 14:22:52 -07004538 }
4539
4540 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004541 public boolean isVideoCallingEnabled(String callingPackage) {
Amit Mahajan578e53d2018-03-20 16:18:38 +00004542 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4543 mApp, mPhone.getSubId(), callingPackage, "isVideoCallingEnabled")) {
4544 return false;
4545 }
Svet Ganovb320e182015-04-16 12:30:10 -07004546
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004547 final long identity = Binder.clearCallingIdentity();
4548 try {
4549 // Check the user preference and the system-level IMS setting. Even if the user has
4550 // enabled video calling, if IMS is disabled we aren't able to support video calling.
4551 // In the long run, we may instead need to check if there exists a connection service
4552 // which can support video calling.
4553 ImsManager imsManager =
4554 ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId());
4555 return imsManager.isVtEnabledByPlatform()
4556 && imsManager.isEnhanced4gLteModeSettingEnabledByUser()
4557 && imsManager.isVtEnabledByUser();
4558 } finally {
4559 Binder.restoreCallingIdentity(identity);
4560 }
Andrew Leedf14ead2014-10-17 14:22:52 -07004561 }
Libin.Tang@motorola.comafe82642014-12-18 13:27:53 -06004562
Andrew Leea1239f22015-03-02 17:44:07 -08004563 @Override
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004564 public boolean canChangeDtmfToneLength(int subId, String callingPackage) {
4565 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4566 mApp, subId, callingPackage, "isVideoCallingEnabled")) {
4567 return false;
4568 }
4569
4570 final long identity = Binder.clearCallingIdentity();
4571 try {
4572 CarrierConfigManager configManager =
4573 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
4574 return configManager.getConfigForSubId(mPhone.getSubId())
4575 .getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL);
4576 } finally {
4577 Binder.restoreCallingIdentity(identity);
4578 }
Andrew Leea1239f22015-03-02 17:44:07 -08004579 }
4580
4581 @Override
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004582 public boolean isWorldPhone(int subId, String callingPackage) {
4583 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4584 mApp, subId, callingPackage, "isVideoCallingEnabled")) {
4585 return false;
4586 }
4587
4588 final long identity = Binder.clearCallingIdentity();
4589 try {
4590 CarrierConfigManager configManager =
4591 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
4592 return configManager.getConfigForSubId(mPhone.getSubId())
4593 .getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL);
4594 } finally {
4595 Binder.restoreCallingIdentity(identity);
4596 }
Andrew Leea1239f22015-03-02 17:44:07 -08004597 }
4598
Andrew Lee9431b832015-03-09 18:46:45 -07004599 @Override
4600 public boolean isTtyModeSupported() {
4601 TelecomManager telecomManager = TelecomManager.from(mPhone.getContext());
Wooki Wu1f82f7a2016-02-15 15:59:58 +08004602 return telecomManager.isTtySupported();
Andrew Lee9431b832015-03-09 18:46:45 -07004603 }
4604
4605 @Override
4606 public boolean isHearingAidCompatibilitySupported() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004607 final long identity = Binder.clearCallingIdentity();
4608 try {
4609 return mPhone.getContext().getResources().getBoolean(R.bool.hac_enabled);
4610 } finally {
4611 Binder.restoreCallingIdentity(identity);
4612 }
Andrew Lee9431b832015-03-09 18:46:45 -07004613 }
4614
Hall Liuf6668912018-10-31 17:05:23 -07004615 /**
4616 * Determines whether the device currently supports RTT (Real-time text). Based both on carrier
4617 * support for the feature and device firmware support.
4618 *
4619 * @return {@code true} if the device and carrier both support RTT, {@code false} otherwise.
4620 */
4621 @Override
4622 public boolean isRttSupported(int subscriptionId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004623 final long identity = Binder.clearCallingIdentity();
4624 try {
4625 boolean isCarrierSupported = mApp.getCarrierConfigForSubId(
4626 mPhone.getSubId()).getBoolean(
4627 CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
4628 boolean isDeviceSupported =
4629 mPhone.getContext().getResources().getBoolean(R.bool.config_support_rtt);
4630 return isCarrierSupported && isDeviceSupported;
4631 } finally {
4632 Binder.restoreCallingIdentity(identity);
4633 }
Hall Liu98187582018-01-22 19:15:32 -08004634 }
4635
Hall Liuf6668912018-10-31 17:05:23 -07004636 /**
4637 * Determines whether the user has turned on RTT. Only returns true if the device and carrier
4638 * both also support RTT.
4639 */
4640 public boolean isRttEnabled(int subscriptionId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004641 final long identity = Binder.clearCallingIdentity();
4642 try {
Hall Liuf6668912018-10-31 17:05:23 -07004643 return isRttSupported(subscriptionId) && Settings.Secure.getInt(
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004644 mPhone.getContext().getContentResolver(),
4645 Settings.Secure.RTT_CALLING_MODE, 0) != 0;
4646 } finally {
4647 Binder.restoreCallingIdentity(identity);
4648 }
Hall Liu3ad5f012018-04-06 16:23:39 -07004649 }
4650
Sanket Padawe7310cc72015-01-14 09:53:20 -08004651 /**
4652 * Returns the unique device ID of phone, for example, the IMEI for
4653 * GSM and the MEID for CDMA phones. Return null if device ID is not available.
4654 *
4655 * <p>Requires Permission:
4656 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
4657 */
4658 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004659 public String getDeviceId(String callingPackage) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08004660 final Phone phone = PhoneFactory.getPhone(0);
Jeff Davidson913390f2018-02-23 17:11:49 -08004661 if (phone == null) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08004662 return null;
4663 }
Jeff Davidson913390f2018-02-23 17:11:49 -08004664 int subId = phone.getSubId();
Michael Groover70af6dc2018-10-01 16:23:15 -07004665 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
4666 callingPackage, "getDeviceId")) {
Jeff Davidson913390f2018-02-23 17:11:49 -08004667 return null;
4668 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004669
4670 final long identity = Binder.clearCallingIdentity();
4671 try {
4672 return phone.getDeviceId();
4673 } finally {
4674 Binder.restoreCallingIdentity(identity);
4675 }
Sanket Padawe7310cc72015-01-14 09:53:20 -08004676 }
4677
Ping Sunc67b7c22016-03-02 19:16:45 +08004678 /**
4679 * {@hide}
4680 * Returns the IMS Registration Status on a particular subid
4681 *
4682 * @param subId
4683 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004684 public boolean isImsRegistered(int subId) {
Ping Sunc67b7c22016-03-02 19:16:45 +08004685 Phone phone = getPhone(subId);
4686 if (phone != null) {
4687 return phone.isImsRegistered();
4688 } else {
4689 return false;
4690 }
4691 }
4692
Santos Cordon7a1885b2015-02-03 11:15:19 -08004693 @Override
4694 public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004695 final long identity = Binder.clearCallingIdentity();
4696 try {
4697 return PhoneUtils.getSubIdForPhoneAccount(phoneAccount);
4698 } finally {
4699 Binder.restoreCallingIdentity(identity);
4700 }
Santos Cordon7a1885b2015-02-03 11:15:19 -08004701 }
Nathan Harolddcfc7932015-03-18 10:01:20 -07004702
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004703 /**
4704 * @return the VoWiFi calling availability.
Nathan Haroldc55097a2015-03-11 18:14:50 -07004705 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004706 public boolean isWifiCallingAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004707 final long identity = Binder.clearCallingIdentity();
4708 try {
4709 Phone phone = getPhone(subId);
4710 if (phone != null) {
4711 return phone.isWifiCallingEnabled();
4712 } else {
4713 return false;
4714 }
4715 } finally {
4716 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004717 }
Nathan Haroldc55097a2015-03-11 18:14:50 -07004718 }
4719
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004720 /**
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004721 * @return the VT calling availability.
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07004722 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004723 public boolean isVideoTelephonyAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004724 final long identity = Binder.clearCallingIdentity();
4725 try {
4726 Phone phone = getPhone(subId);
4727 if (phone != null) {
4728 return phone.isVideoEnabled();
4729 } else {
4730 return false;
4731 }
4732 } finally {
4733 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004734 }
4735 }
4736
4737 /**
4738 * @return the IMS registration technology for the MMTEL feature. Valid return values are
4739 * defined in {@link ImsRegistrationImplBase}.
4740 */
4741 public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004742 final long identity = Binder.clearCallingIdentity();
4743 try {
4744 Phone phone = getPhone(subId);
4745 if (phone != null) {
4746 return phone.getImsRegistrationTech();
4747 } else {
4748 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
4749 }
4750 } finally {
4751 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004752 }
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07004753 }
4754
Stuart Scott8eef64f2015-04-08 15:13:54 -07004755 @Override
4756 public void factoryReset(int subId) {
4757 enforceConnectivityInternalPermission();
Stuart Scott981d8582015-04-21 14:09:50 -07004758 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
4759 return;
4760 }
4761
Svet Ganovcc087f82015-05-12 20:35:54 -07004762 final long identity = Binder.clearCallingIdentity();
4763 try {
Stuart Scott981d8582015-04-21 14:09:50 -07004764 if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
4765 UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
Pengquan Meng85728fb2018-03-12 16:31:21 -07004766 setUserDataEnabled(subId, getDefaultDataEnabled());
Svet Ganovcc087f82015-05-12 20:35:54 -07004767 setNetworkSelectionModeAutomatic(subId);
Pengquan Meng85728fb2018-03-12 16:31:21 -07004768 setPreferredNetworkType(subId, getDefaultNetworkType(subId));
4769 mPhone.setDataRoamingEnabled(getDefaultDataRoamingEnabled(subId));
pkanwar79ec0542017-07-31 14:10:01 -07004770 CarrierInfoManager.deleteAllCarrierKeysForImsiEncryption(mPhone.getContext());
Svet Ganovcc087f82015-05-12 20:35:54 -07004771 }
4772 } finally {
4773 Binder.restoreCallingIdentity(identity);
Stuart Scott8eef64f2015-04-08 15:13:54 -07004774 }
4775 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004776
4777 @Override
4778 public String getLocaleFromDefaultSim() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004779 final long identity = Binder.clearCallingIdentity();
4780 try {
4781 // We query all subscriptions instead of just the active ones, because
4782 // this might be called early on in the provisioning flow when the
4783 // subscriptions potentially aren't active yet.
4784 final List<SubscriptionInfo> slist = getAllSubscriptionInfoList();
4785 if (slist == null || slist.isEmpty()) {
Narayan Kamath1c496c22015-04-16 14:40:19 +01004786 return null;
4787 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004788
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004789 // This function may be called very early, say, from the setup wizard, at
4790 // which point we won't have a default subscription set. If that's the case
4791 // we just choose the first, which will be valid in "most cases".
4792 final int defaultSubId = getDefaultSubscription();
4793 SubscriptionInfo info = null;
4794 if (defaultSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
4795 info = slist.get(0);
4796 } else {
4797 for (SubscriptionInfo item : slist) {
4798 if (item.getSubscriptionId() == defaultSubId) {
4799 info = item;
4800 break;
4801 }
4802 }
4803
4804 if (info == null) {
4805 return null;
Tony Hill183b2de2015-06-24 14:53:58 +01004806 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004807 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004808
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004809 // Try and fetch the locale from the carrier properties or from the SIM language
4810 // preferences (EF-PL and EF-LI)...
4811 final int mcc = info.getMcc();
4812 final Phone defaultPhone = getPhone(info.getSubscriptionId());
4813 String simLanguage = null;
4814 if (defaultPhone != null) {
4815 final Locale localeFromDefaultSim = defaultPhone.getLocaleFromSimAndCarrierPrefs();
4816 if (localeFromDefaultSim != null) {
4817 if (!localeFromDefaultSim.getCountry().isEmpty()) {
4818 if (DBG) log("Using locale from default SIM:" + localeFromDefaultSim);
4819 return localeFromDefaultSim.toLanguageTag();
4820 } else {
4821 simLanguage = localeFromDefaultSim.getLanguage();
4822 }
4823 }
4824 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004825
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004826 // The SIM language preferences only store a language (e.g. fr = French), not an
4827 // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
4828 // the SIM and carrier preferences does not include a country we add the country
4829 // determined from the SIM MCC to provide an exact locale.
4830 final Locale mccLocale = MccTable.getLocaleFromMcc(mPhone.getContext(), mcc,
4831 simLanguage);
4832 if (mccLocale != null) {
4833 if (DBG) log("No locale from default SIM, using mcc locale:" + mccLocale);
4834 return mccLocale.toLanguageTag();
4835 }
4836
4837 if (DBG) log("No locale found - returning null");
4838 return null;
4839 } finally {
4840 Binder.restoreCallingIdentity(identity);
4841 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004842 }
4843
4844 private List<SubscriptionInfo> getAllSubscriptionInfoList() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004845 return mSubscriptionController.getAllSubInfoList(
4846 mPhone.getContext().getOpPackageName());
Narayan Kamath1c496c22015-04-16 14:40:19 +01004847 }
4848
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004849 /**
4850 * NOTE: this method assumes permission checks are done and caller identity has been cleared.
4851 */
4852 private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
4853 return mSubscriptionController.getActiveSubscriptionInfoList(
4854 mPhone.getContext().getOpPackageName());
Narayan Kamath1c496c22015-04-16 14:40:19 +01004855 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004856
Chenjie Yu1ba97252018-01-11 18:16:20 -08004857 private final ModemActivityInfo mLastModemActivityInfo =
4858 new ModemActivityInfo(0, 0, 0, new int[0], 0, 0);
4859
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004860 /**
Adam Lesinski903a54c2016-04-11 14:49:52 -07004861 * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
4862 * representing the state of the modem.
4863 *
Chenjie Yu1ba97252018-01-11 18:16:20 -08004864 * NOTE: The underlying implementation clears the modem state, so there should only ever be one
4865 * caller to it. Everyone should call this class to get cumulative data.
Adam Lesinski903a54c2016-04-11 14:49:52 -07004866 * @hide
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004867 */
4868 @Override
Adam Lesinski903a54c2016-04-11 14:49:52 -07004869 public void requestModemActivityInfo(ResultReceiver result) {
4870 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07004871 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004872
4873 final long identity = Binder.clearCallingIdentity();
4874 try {
4875 ModemActivityInfo ret = null;
4876 synchronized (mLastModemActivityInfo) {
4877 ModemActivityInfo info = (ModemActivityInfo) sendRequest(
4878 CMD_GET_MODEM_ACTIVITY_INFO,
vagdeviaf9a5b92018-08-15 16:01:53 -07004879 null, workSource);
Siddharth Rayb8114062018-06-17 15:02:38 -07004880 if (isModemActivityInfoValid(info)) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004881 int[] mergedTxTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
4882 for (int i = 0; i < mergedTxTimeMs.length; i++) {
4883 mergedTxTimeMs[i] =
4884 info.getTxTimeMillis()[i]
4885 + mLastModemActivityInfo.getTxTimeMillis()[i];
4886 }
4887 mLastModemActivityInfo.setTimestamp(info.getTimestamp());
4888 mLastModemActivityInfo.setSleepTimeMillis(
4889 info.getSleepTimeMillis()
4890 + mLastModemActivityInfo.getSleepTimeMillis());
4891 mLastModemActivityInfo.setIdleTimeMillis(
4892 info.getIdleTimeMillis() + mLastModemActivityInfo.getIdleTimeMillis());
4893 mLastModemActivityInfo.setTxTimeMillis(mergedTxTimeMs);
4894 mLastModemActivityInfo.setRxTimeMillis(
4895 info.getRxTimeMillis() + mLastModemActivityInfo.getRxTimeMillis());
4896 mLastModemActivityInfo.setEnergyUsed(
4897 info.getEnergyUsed() + mLastModemActivityInfo.getEnergyUsed());
Chenjie Yu1ba97252018-01-11 18:16:20 -08004898 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004899 ret = new ModemActivityInfo(mLastModemActivityInfo.getTimestamp(),
4900 mLastModemActivityInfo.getSleepTimeMillis(),
4901 mLastModemActivityInfo.getIdleTimeMillis(),
4902 mLastModemActivityInfo.getTxTimeMillis(),
4903 mLastModemActivityInfo.getRxTimeMillis(),
4904 mLastModemActivityInfo.getEnergyUsed());
Chenjie Yu1ba97252018-01-11 18:16:20 -08004905 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004906 Bundle bundle = new Bundle();
4907 bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, ret);
4908 result.send(0, bundle);
4909 } finally {
4910 Binder.restoreCallingIdentity(identity);
Chenjie Yu1ba97252018-01-11 18:16:20 -08004911 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004912 }
Jack Yu85bd38a2015-11-09 11:34:32 -08004913
Siddharth Rayb8114062018-06-17 15:02:38 -07004914 // Checks that ModemActivityInfo is valid. Sleep time, Idle time, Rx time and Tx time should be
4915 // less than total activity duration.
4916 private boolean isModemActivityInfoValid(ModemActivityInfo info) {
4917 if (info == null) {
4918 return false;
4919 }
4920 int activityDurationMs =
4921 (int) (info.getTimestamp() - mLastModemActivityInfo.getTimestamp());
4922 int totalTxTimeMs = 0;
4923 for (int i = 0; i < info.getTxTimeMillis().length; i++) {
4924 totalTxTimeMs += info.getTxTimeMillis()[i];
4925 }
4926 return (info.isValid()
4927 && (info.getSleepTimeMillis() <= activityDurationMs)
4928 && (info.getIdleTimeMillis() <= activityDurationMs)
4929 && (info.getRxTimeMillis() <= activityDurationMs)
4930 && (totalTxTimeMs <= activityDurationMs));
4931 }
4932
Jack Yu85bd38a2015-11-09 11:34:32 -08004933 /**
4934 * {@hide}
4935 * Returns the service state information on specified subscription.
4936 */
4937 @Override
4938 public ServiceState getServiceStateForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004939 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08004940 mApp, subId, callingPackage, "getServiceStateForSubscriber")) {
Jack Yu85bd38a2015-11-09 11:34:32 -08004941 return null;
4942 }
4943
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004944 final long identity = Binder.clearCallingIdentity();
4945 try {
4946 final Phone phone = getPhone(subId);
4947 if (phone == null) {
4948 return null;
4949 }
Jack Yu85bd38a2015-11-09 11:34:32 -08004950
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004951 return phone.getServiceState();
4952 } finally {
4953 Binder.restoreCallingIdentity(identity);
4954 }
Jack Yu85bd38a2015-11-09 11:34:32 -08004955 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004956
4957 /**
4958 * Returns the URI for the per-account voicemail ringtone set in Phone settings.
4959 *
4960 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
4961 * voicemail ringtone.
4962 * @return The URI for the ringtone to play when receiving a voicemail from a specific
4963 * PhoneAccount.
4964 */
4965 @Override
4966 public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004967 final long identity = Binder.clearCallingIdentity();
4968 try {
4969 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
4970 if (phone == null) {
4971 phone = mPhone;
4972 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004973
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004974 return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext());
4975 } finally {
4976 Binder.restoreCallingIdentity(identity);
4977 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004978 }
4979
4980 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004981 * Sets the per-account voicemail ringtone.
4982 *
4983 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
4984 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
4985 *
4986 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
4987 * voicemail ringtone.
4988 * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
4989 * PhoneAccount.
4990 */
4991 @Override
4992 public void setVoicemailRingtoneUri(String callingPackage,
4993 PhoneAccountHandle phoneAccountHandle, Uri uri) {
4994 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4995 if (!TextUtils.equals(callingPackage,
4996 TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004997 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4998 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
4999 "setVoicemailRingtoneUri");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005000 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005001
5002 final long identity = Binder.clearCallingIdentity();
5003 try {
5004 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
5005 if (phone == null) {
5006 phone = mPhone;
5007 }
5008 VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri);
5009 } finally {
5010 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005011 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005012 }
5013
5014 /**
Nancy Chen31f9ba12016-01-06 11:42:12 -08005015 * Returns whether vibration is set for voicemail notification in Phone settings.
5016 *
5017 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
5018 * voicemail vibration setting.
5019 * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
5020 */
5021 @Override
5022 public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005023 final long identity = Binder.clearCallingIdentity();
5024 try {
5025 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
5026 if (phone == null) {
5027 phone = mPhone;
5028 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08005029
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005030 return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext());
5031 } finally {
5032 Binder.restoreCallingIdentity(identity);
5033 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08005034 }
5035
Youhan Wange64578a2016-05-02 15:32:42 -07005036 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005037 * Sets the per-account voicemail vibration.
5038 *
5039 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
5040 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
5041 *
5042 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
5043 * voicemail vibration setting.
5044 * @param enabled Whether to enable or disable vibration for voicemail notifications from a
5045 * specific PhoneAccount.
5046 */
5047 @Override
5048 public void setVoicemailVibrationEnabled(String callingPackage,
5049 PhoneAccountHandle phoneAccountHandle, boolean enabled) {
5050 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
5051 if (!TextUtils.equals(callingPackage,
5052 TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005053 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5054 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
5055 "setVoicemailVibrationEnabled");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005056 }
5057
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005058 final long identity = Binder.clearCallingIdentity();
5059 try {
5060 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
5061 if (phone == null) {
5062 phone = mPhone;
5063 }
5064 VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled);
5065 } finally {
5066 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005067 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08005068 }
5069
5070 /**
Youhan Wange64578a2016-05-02 15:32:42 -07005071 * Make sure either called from same process as self (phone) or IPC caller has read privilege.
5072 *
5073 * @throws SecurityException if the caller does not have the required permission
5074 */
Brad Ebinger35c841c2018-10-01 10:40:55 -07005075 private void enforceReadPrivilegedPermission(String message) {
Youhan Wange64578a2016-05-02 15:32:42 -07005076 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
Brad Ebinger35c841c2018-10-01 10:40:55 -07005077 message);
Youhan Wange64578a2016-05-02 15:32:42 -07005078 }
5079
5080 /**
Ta-wei Yen30a69c82016-12-27 14:52:32 -08005081 * Make sure either called from same process as self (phone) or IPC caller has send SMS
5082 * permission.
5083 *
5084 * @throws SecurityException if the caller does not have the required permission
5085 */
5086 private void enforceSendSmsPermission() {
5087 mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null);
5088 }
5089
5090 /**
Ta-wei Yen527a9c02017-01-06 15:29:25 -08005091 * Make sure called from the package in charge of visual voicemail.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08005092 *
Ta-wei Yen527a9c02017-01-06 15:29:25 -08005093 * @throws SecurityException if the caller is not the visual voicemail package.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08005094 */
Ta-wei Yen527a9c02017-01-06 15:29:25 -08005095 private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005096 final long identity = Binder.clearCallingIdentity();
5097 try {
5098 ComponentName componentName =
5099 RemoteVvmTaskManager.getRemotePackage(mPhone.getContext(), subId);
5100 if (componentName == null) {
5101 throw new SecurityException(
5102 "Caller not current active visual voicemail package[null]");
5103 }
5104 String vvmPackage = componentName.getPackageName();
5105 if (!callingPackage.equals(vvmPackage)) {
5106 throw new SecurityException("Caller not current active visual voicemail package["
5107 + vvmPackage + "]");
5108 }
5109 } finally {
5110 Binder.restoreCallingIdentity(identity);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08005111 }
5112 }
5113
5114 /**
Youhan Wange64578a2016-05-02 15:32:42 -07005115 * Return the application ID for the app type.
5116 *
5117 * @param subId the subscription ID that this request applies to.
5118 * @param appType the uicc app type.
5119 * @return Application ID for specificied app type, or null if no uicc.
5120 */
5121 @Override
5122 public String getAidForAppType(int subId, int appType) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005123 enforceReadPrivilegedPermission("getAidForAppType");
Youhan Wange64578a2016-05-02 15:32:42 -07005124 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005125
5126 final long identity = Binder.clearCallingIdentity();
Youhan Wange64578a2016-05-02 15:32:42 -07005127 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005128 if (phone == null) {
5129 return null;
5130 }
5131 String aid = null;
5132 try {
5133 aid = UiccController.getInstance().getUiccCard(phone.getPhoneId())
5134 .getApplicationByType(appType).getAid();
5135 } catch (Exception e) {
5136 Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e);
5137 }
5138 return aid;
5139 } finally {
5140 Binder.restoreCallingIdentity(identity);
Youhan Wange64578a2016-05-02 15:32:42 -07005141 }
Youhan Wange64578a2016-05-02 15:32:42 -07005142 }
5143
Youhan Wang4001d252016-05-11 10:29:41 -07005144 /**
5145 * Return the Electronic Serial Number.
5146 *
5147 * @param subId the subscription ID that this request applies to.
5148 * @return ESN or null if error.
5149 */
5150 @Override
5151 public String getEsn(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005152 enforceReadPrivilegedPermission("getEsn");
Youhan Wang4001d252016-05-11 10:29:41 -07005153 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005154
5155 final long identity = Binder.clearCallingIdentity();
Youhan Wang4001d252016-05-11 10:29:41 -07005156 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005157 if (phone == null) {
5158 return null;
5159 }
5160 String esn = null;
5161 try {
5162 esn = phone.getEsn();
5163 } catch (Exception e) {
5164 Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e);
5165 }
5166 return esn;
5167 } finally {
5168 Binder.restoreCallingIdentity(identity);
Youhan Wang4001d252016-05-11 10:29:41 -07005169 }
Youhan Wang4001d252016-05-11 10:29:41 -07005170 }
5171
Sanket Padawe99ef1e32016-05-18 16:12:33 -07005172 /**
Youhan Wang66ad5d72016-07-18 17:56:58 -07005173 * Return the Preferred Roaming List Version.
5174 *
5175 * @param subId the subscription ID that this request applies to.
5176 * @return PRLVersion or null if error.
5177 */
5178 @Override
5179 public String getCdmaPrlVersion(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005180 enforceReadPrivilegedPermission("getCdmaPrlVersion");
Youhan Wang66ad5d72016-07-18 17:56:58 -07005181 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005182
5183 final long identity = Binder.clearCallingIdentity();
Youhan Wang66ad5d72016-07-18 17:56:58 -07005184 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005185 if (phone == null) {
5186 return null;
5187 }
5188 String cdmaPrlVersion = null;
5189 try {
5190 cdmaPrlVersion = phone.getCdmaPrlVersion();
5191 } catch (Exception e) {
5192 Log.e(LOG_TAG, "Not getting PRLVersion", e);
5193 }
5194 return cdmaPrlVersion;
5195 } finally {
5196 Binder.restoreCallingIdentity(identity);
Youhan Wang66ad5d72016-07-18 17:56:58 -07005197 }
Youhan Wang66ad5d72016-07-18 17:56:58 -07005198 }
5199
5200 /**
Sanket Padawe99ef1e32016-05-18 16:12:33 -07005201 * Get snapshot of Telephony histograms
5202 * @return List of Telephony histograms
5203 * @hide
5204 */
5205 @Override
5206 public List<TelephonyHistogram> getTelephonyHistograms() {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005207 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5208 mApp, getDefaultSubscription(), "getTelephonyHistograms");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005209
5210 final long identity = Binder.clearCallingIdentity();
5211 try {
5212 return RIL.getTelephonyRILTimingHistograms();
5213 } finally {
5214 Binder.restoreCallingIdentity(identity);
5215 }
Sanket Padawe99ef1e32016-05-18 16:12:33 -07005216 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07005217
5218 /**
5219 * {@hide}
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005220 * Set the allowed carrier list for slotIndex
Meng Wang1a7c35a2016-05-05 20:56:15 -07005221 * Require system privileges. In the future we may add this to carrier APIs.
5222 *
5223 * @return The number of carriers set successfully, should match length of carriers
5224 */
5225 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005226 public int setAllowedCarriers(int slotIndex, List<CarrierIdentifier> carriers) {
Meng Wang1a7c35a2016-05-05 20:56:15 -07005227 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07005228 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005229
Meng Wang9b7c4e92017-02-17 11:41:27 -08005230 if (carriers == null) {
5231 throw new NullPointerException("carriers cannot be null");
5232 }
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005233
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005234 final long identity = Binder.clearCallingIdentity();
5235 try {
5236 int subId = SubscriptionManager.getSubId(slotIndex)[0];
vagdeviaf9a5b92018-08-15 16:01:53 -07005237 int[] retVal = (int[]) sendRequest(CMD_SET_ALLOWED_CARRIERS, carriers, subId,
5238 workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005239 return retVal[0];
5240 } finally {
5241 Binder.restoreCallingIdentity(identity);
5242 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07005243 }
5244
5245 /**
5246 * {@hide}
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005247 * Get the allowed carrier list for slotIndex.
Meng Wang1a7c35a2016-05-05 20:56:15 -07005248 * Require system privileges. In the future we may add this to carrier APIs.
5249 *
5250 * @return List of {@link android.service.telephony.CarrierIdentifier}; empty list
5251 * means all carriers are allowed.
5252 */
5253 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005254 public List<CarrierIdentifier> getAllowedCarriers(int slotIndex) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005255 enforceReadPrivilegedPermission("getAllowedCarriers");
vagdeviaf9a5b92018-08-15 16:01:53 -07005256 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005257
5258 final long identity = Binder.clearCallingIdentity();
5259 try {
5260 int subId = SubscriptionManager.getSubId(slotIndex)[0];
vagdeviaf9a5b92018-08-15 16:01:53 -07005261 return (List<CarrierIdentifier>) sendRequest(CMD_GET_ALLOWED_CARRIERS, null, subId,
5262 workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005263 } finally {
5264 Binder.restoreCallingIdentity(identity);
5265 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07005266 }
5267
fionaxu59545b42016-05-25 15:53:37 -07005268 /**
5269 * Action set from carrier signalling broadcast receivers to enable/disable metered apns
5270 * @param subId the subscription ID that this action applies to.
5271 * @param enabled control enable or disable metered apns.
5272 * {@hide}
5273 */
5274 @Override
5275 public void carrierActionSetMeteredApnsEnabled(int subId, boolean enabled) {
5276 enforceModifyPermission();
5277 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005278
5279 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07005280 if (phone == null) {
5281 loge("carrierAction: SetMeteredApnsEnabled fails with invalid subId: " + subId);
5282 return;
5283 }
5284 try {
5285 phone.carrierActionSetMeteredApnsEnabled(enabled);
5286 } catch (Exception e) {
5287 Log.e(LOG_TAG, "carrierAction: SetMeteredApnsEnabled fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005288 } finally {
5289 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07005290 }
5291 }
5292
5293 /**
5294 * Action set from carrier signalling broadcast receivers to enable/disable radio
5295 * @param subId the subscription ID that this action applies to.
5296 * @param enabled control enable or disable radio.
5297 * {@hide}
5298 */
5299 @Override
5300 public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
5301 enforceModifyPermission();
5302 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005303
5304 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07005305 if (phone == null) {
5306 loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
5307 return;
5308 }
5309 try {
5310 phone.carrierActionSetRadioEnabled(enabled);
5311 } catch (Exception e) {
5312 Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005313 } finally {
5314 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07005315 }
5316 }
5317
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07005318 /**
fionaxu8da9cb12017-05-23 15:02:46 -07005319 * Action set from carrier signalling broadcast receivers to start/stop reporting the default
5320 * network status based on which carrier apps could apply actions accordingly,
5321 * enable/disable default url handler for example.
5322 *
5323 * @param subId the subscription ID that this action applies to.
5324 * @param report control start/stop reporting the default network status.
5325 * {@hide}
5326 */
5327 @Override
5328 public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
5329 enforceModifyPermission();
5330 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005331
5332 final long identity = Binder.clearCallingIdentity();
fionaxu8da9cb12017-05-23 15:02:46 -07005333 if (phone == null) {
5334 loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId);
5335 return;
5336 }
5337 try {
5338 phone.carrierActionReportDefaultNetworkStatus(report);
5339 } catch (Exception e) {
5340 Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005341 } finally {
5342 Binder.restoreCallingIdentity(identity);
fionaxu8da9cb12017-05-23 15:02:46 -07005343 }
5344 }
5345
5346 /**
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07005347 * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a
5348 * bug report is being generated.
5349 */
5350 @Override
Ta-wei Yen99282e02016-06-21 18:19:35 -07005351 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
dcashman22b950d2016-06-27 11:39:02 -07005352 if (mPhone.getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
5353 != PackageManager.PERMISSION_GRANTED) {
5354 writer.println("Permission Denial: can't dump Phone from pid="
5355 + Binder.getCallingPid()
5356 + ", uid=" + Binder.getCallingUid()
5357 + "without permission "
5358 + android.Manifest.permission.DUMP);
5359 return;
5360 }
Ta-wei Yen99282e02016-06-21 18:19:35 -07005361 DumpsysHandler.dump(mPhone.getContext(), fd, writer, args);
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07005362 }
Jack Yueb89b242016-06-22 13:27:47 -07005363
Brad Ebingerdac2f002018-04-03 15:17:52 -07005364 @Override
5365 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
5366 String[] args, ShellCallback callback, ResultReceiver resultReceiver)
5367 throws RemoteException {
5368 (new TelephonyShellCommand(this)).exec(this, in, out, err, args, callback, resultReceiver);
5369 }
5370
Jack Yueb89b242016-06-22 13:27:47 -07005371 /**
Jack Yu84291ec2017-05-26 16:07:50 -07005372 * Get aggregated video call data usage since boot.
5373 *
5374 * @param perUidStats True if requesting data usage per uid, otherwise overall usage.
5375 * @return Snapshot of video call data usage
Jack Yueb89b242016-06-22 13:27:47 -07005376 * {@hide}
5377 */
5378 @Override
Jack Yu84291ec2017-05-26 16:07:50 -07005379 public NetworkStats getVtDataUsage(int subId, boolean perUidStats) {
Jack Yueb89b242016-06-22 13:27:47 -07005380 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_NETWORK_USAGE_HISTORY,
5381 null);
5382
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005383 final long identity = Binder.clearCallingIdentity();
5384 try {
5385 // NetworkStatsService keeps tracking the active network interface and identity. It
5386 // records the delta with the corresponding network identity.
5387 // We just return the total video call data usage snapshot since boot.
5388 Phone phone = getPhone(subId);
5389 if (phone != null) {
5390 return phone.getVtDataUsage(perUidStats);
5391 }
5392 return null;
5393 } finally {
5394 Binder.restoreCallingIdentity(identity);
Jack Yueb89b242016-06-22 13:27:47 -07005395 }
Jack Yueb89b242016-06-22 13:27:47 -07005396 }
Jack Yu75ab2952016-07-08 14:29:33 -07005397
5398 /**
5399 * Policy control of data connection. Usually used when data limit is passed.
5400 * @param enabled True if enabling the data, otherwise disabling.
5401 * @param subId Subscription index
5402 * {@hide}
5403 */
5404 @Override
5405 public void setPolicyDataEnabled(boolean enabled, int subId) {
5406 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005407
5408 final long identity = Binder.clearCallingIdentity();
5409 try {
5410 Phone phone = getPhone(subId);
5411 if (phone != null) {
5412 phone.setPolicyDataEnabled(enabled);
5413 }
5414 } finally {
5415 Binder.restoreCallingIdentity(identity);
Jack Yu75ab2952016-07-08 14:29:33 -07005416 }
5417 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07005418
5419 /**
5420 * Get Client request stats
5421 * @return List of Client Request Stats
5422 * @hide
5423 */
5424 @Override
5425 public List<ClientRequestStats> getClientRequestStats(String callingPackage, int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005426 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08005427 mApp, subId, callingPackage, "getClientRequestStats")) {
Sooraj Sasindran9a909312016-07-18 11:57:25 -07005428 return null;
5429 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07005430 Phone phone = getPhone(subId);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07005431
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005432 final long identity = Binder.clearCallingIdentity();
5433 try {
5434 if (phone != null) {
5435 return phone.getClientRequestStats();
5436 }
5437
5438 return null;
5439 } finally {
5440 Binder.restoreCallingIdentity(identity);
5441 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07005442 }
5443
Narayan Kamathf04b5a12018-01-09 11:47:15 +00005444 private WorkSource getWorkSource(int uid) {
Sooraj Sasindran9a909312016-07-18 11:57:25 -07005445 String packageName = mPhone.getContext().getPackageManager().getNameForUid(uid);
Narayan Kamathf04b5a12018-01-09 11:47:15 +00005446 return new WorkSource(uid, packageName);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07005447 }
Jack Yueb4124c2017-02-16 15:32:43 -08005448
5449 /**
Grace Chen70990072017-03-24 17:21:30 -07005450 * Set SIM card power state.
Jack Yueb4124c2017-02-16 15:32:43 -08005451 *
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005452 * @param slotIndex SIM slot id.
Grace Chen70990072017-03-24 17:21:30 -07005453 * @param state State of SIM (power down, power up, pass through)
5454 * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
5455 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
5456 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
Jack Yueb4124c2017-02-16 15:32:43 -08005457 *
5458 **/
5459 @Override
Grace Chen70990072017-03-24 17:21:30 -07005460 public void setSimPowerStateForSlot(int slotIndex, int state) {
Jack Yueb4124c2017-02-16 15:32:43 -08005461 enforceModifyPermission();
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005462 Phone phone = PhoneFactory.getPhone(slotIndex);
5463
vagdeviaf9a5b92018-08-15 16:01:53 -07005464 WorkSource workSource = getWorkSource(Binder.getCallingUid());
5465
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005466 final long identity = Binder.clearCallingIdentity();
5467 try {
5468 if (phone != null) {
vagdeviaf9a5b92018-08-15 16:01:53 -07005469 phone.setSimPowerState(state, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005470 }
5471 } finally {
5472 Binder.restoreCallingIdentity(identity);
Jack Yueb4124c2017-02-16 15:32:43 -08005473 }
5474 }
Shuo Qiandd210312017-04-12 22:11:33 +00005475
Tyler Gunn65d45c22017-06-05 11:22:26 -07005476 private boolean isUssdApiAllowed(int subId) {
5477 CarrierConfigManager configManager =
5478 (CarrierConfigManager) mPhone.getContext().getSystemService(
5479 Context.CARRIER_CONFIG_SERVICE);
5480 if (configManager == null) {
5481 return false;
5482 }
5483 PersistableBundle pb = configManager.getConfigForSubId(subId);
5484 if (pb == null) {
5485 return false;
5486 }
5487 return pb.getBoolean(
5488 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL);
5489 }
5490
Shuo Qiandd210312017-04-12 22:11:33 +00005491 /**
5492 * Check if phone is in emergency callback mode
5493 * @return true if phone is in emergency callback mode
5494 * @param subId sub id
5495 */
goneil9c5f4872017-12-05 14:07:56 -08005496 @Override
Shuo Qiandd210312017-04-12 22:11:33 +00005497 public boolean getEmergencyCallbackMode(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005498 enforceReadPrivilegedPermission("getEmergencyCallbackMode");
Shuo Qiandd210312017-04-12 22:11:33 +00005499 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005500
5501 final long identity = Binder.clearCallingIdentity();
5502 try {
5503 if (phone != null) {
5504 return phone.isInEcm();
5505 } else {
5506 return false;
5507 }
5508 } finally {
5509 Binder.restoreCallingIdentity(identity);
Shuo Qiandd210312017-04-12 22:11:33 +00005510 }
5511 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08005512
5513 /**
5514 * Get the current signal strength information for the given subscription.
5515 * Because this information is not updated when the device is in a low power state
5516 * it should not be relied-upon to be current.
5517 * @param subId Subscription index
5518 * @return the most recent cached signal strength info from the modem
5519 */
5520 @Override
5521 public SignalStrength getSignalStrength(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005522 final long identity = Binder.clearCallingIdentity();
5523 try {
5524 Phone p = getPhone(subId);
5525 if (p == null) {
5526 return null;
5527 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08005528
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005529 return p.getSignalStrength();
5530 } finally {
5531 Binder.restoreCallingIdentity(identity);
5532 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08005533 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005534
Pengquan Meng77b7f132018-08-22 14:49:57 -07005535 /**
Chen Xuf792fd62018-10-17 17:54:36 +00005536 * Get the current modem radio state for the given slot.
5537 * @param slotIndex slot index.
5538 * @param callingPackage the name of the package making the call.
5539 * @return the current radio power state from the modem
5540 */
5541 @Override
5542 public int getRadioPowerState(int slotIndex, String callingPackage) {
5543 Phone phone = PhoneFactory.getPhone(slotIndex);
5544 if (phone != null) {
5545 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5546 mApp, phone.getSubId(), callingPackage, "getRadioPowerState")) {
5547 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
5548 }
5549
5550 final long identity = Binder.clearCallingIdentity();
5551 try {
5552 return phone.getRadioPowerState();
5553 } finally {
5554 Binder.restoreCallingIdentity(identity);
5555 }
5556 }
5557 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
5558 }
5559
5560 /**
Pengquan Meng77b7f132018-08-22 14:49:57 -07005561 * Checks if data roaming is enabled on the subscription with id {@code subId}.
5562 *
5563 * <p>Requires one of the following permissions:
5564 * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
5565 * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
5566 * privileges.
5567 *
5568 * @param subId subscription id
5569 * @return {@code true} if data roaming is enabled on this subscription, otherwise return
5570 * {@code false}.
5571 */
5572 @Override
5573 public boolean isDataRoamingEnabled(int subId) {
Pengquan Menga1bb6272018-09-06 09:59:22 -07005574 boolean isEnabled = false;
5575 final long identity = Binder.clearCallingIdentity();
Pengquan Meng77b7f132018-08-22 14:49:57 -07005576 try {
5577 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
Pengquan Menga1bb6272018-09-06 09:59:22 -07005578 null /* message */);
5579 Phone phone = getPhone(subId);
5580 isEnabled = phone != null ? phone.getDataRoamingEnabled() : false;
Pengquan Meng77b7f132018-08-22 14:49:57 -07005581 } catch (Exception e) {
5582 TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
5583 mApp, subId, "isDataRoamingEnabled");
Pengquan Menga1bb6272018-09-06 09:59:22 -07005584 } finally {
5585 Binder.restoreCallingIdentity(identity);
Pengquan Meng77b7f132018-08-22 14:49:57 -07005586 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07005587 return isEnabled;
Pengquan Meng77b7f132018-08-22 14:49:57 -07005588 }
5589
5590
5591 /**
5592 * Enables/Disables the data roaming on the subscription with id {@code subId}.
5593 *
5594 * <p> Requires permission:
5595 * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier
5596 * privileges.
5597 *
5598 * @param subId subscription id
5599 * @param isEnabled {@code true} means enable, {@code false} means disable.
5600 */
5601 @Override
5602 public void setDataRoamingEnabled(int subId, boolean isEnabled) {
Pengquan Menga1bb6272018-09-06 09:59:22 -07005603 final long identity = Binder.clearCallingIdentity();
5604 try {
5605 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5606 mApp, subId, "setDataRoamingEnabled");
Pengquan Meng77b7f132018-08-22 14:49:57 -07005607
Pengquan Menga1bb6272018-09-06 09:59:22 -07005608 Phone phone = getPhone(subId);
5609 if (phone != null) {
5610 phone.setDataRoamingEnabled(isEnabled);
5611 }
5612 } finally {
5613 Binder.restoreCallingIdentity(identity);
Pengquan Meng77b7f132018-08-22 14:49:57 -07005614 }
5615 }
5616
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005617 @Override
Pengquan Meng6884a2c2018-10-03 12:19:13 -07005618 public boolean isManualNetworkSelectionAllowed(int subId) {
5619 boolean isAllowed = true;
5620 final long identity = Binder.clearCallingIdentity();
5621 try {
5622 TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
5623 mApp, subId, "isManualNetworkSelectionAllowed");
5624 Phone phone = getPhone(subId);
5625 if (phone != null) {
5626 isAllowed = phone.isCspPlmnEnabled();
5627 }
5628 } finally {
5629 Binder.restoreCallingIdentity(identity);
5630 }
5631 return isAllowed;
5632 }
5633
5634 @Override
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005635 public UiccSlotInfo[] getUiccSlotsInfo() {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005636 enforceReadPrivilegedPermission("getUiccSlotsInfo");
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005637
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005638 final long identity = Binder.clearCallingIdentity();
5639 try {
5640 UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
5641 if (slots == null) {
5642 Rlog.i(LOG_TAG, "slots is null.");
5643 return null;
5644 }
5645
5646 UiccSlotInfo[] infos = new UiccSlotInfo[slots.length];
5647 for (int i = 0; i < slots.length; i++) {
5648 UiccSlot slot = slots[i];
5649 if (slot == null) {
5650 continue;
5651 }
5652
5653 String cardId;
5654 UiccCard card = slot.getUiccCard();
5655 if (card != null) {
5656 cardId = card.getCardId();
5657 } else {
5658 cardId = slot.getIccId();
5659 }
5660
5661 int cardState = 0;
5662 switch (slot.getCardState()) {
5663 case CARDSTATE_ABSENT:
5664 cardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
5665 break;
5666 case CARDSTATE_PRESENT:
5667 cardState = UiccSlotInfo.CARD_STATE_INFO_PRESENT;
5668 break;
5669 case CARDSTATE_ERROR:
5670 cardState = UiccSlotInfo.CARD_STATE_INFO_ERROR;
5671 break;
5672 case CARDSTATE_RESTRICTED:
5673 cardState = UiccSlotInfo.CARD_STATE_INFO_RESTRICTED;
5674 break;
5675 default:
5676 break;
5677
5678 }
5679
5680 infos[i] = new UiccSlotInfo(
5681 slot.isActive(),
5682 slot.isEuicc(),
5683 cardId,
5684 cardState,
5685 slot.getPhoneId(),
5686 slot.isExtendedApduSupported());
5687 }
5688 return infos;
5689 } finally {
5690 Binder.restoreCallingIdentity(identity);
Holly Jiuyu Sun1d957c52018-04-04 13:52:42 -07005691 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005692 }
5693
5694 @Override
5695 public boolean switchSlots(int[] physicalSlots) {
5696 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005697
5698 final long identity = Binder.clearCallingIdentity();
5699 try {
5700 return (Boolean) sendRequest(CMD_SWITCH_SLOTS, physicalSlots);
5701 } finally {
5702 Binder.restoreCallingIdentity(identity);
5703 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005704 }
Jack Yu4c988042018-02-27 15:30:01 -08005705
5706 @Override
5707 public void setRadioIndicationUpdateMode(int subId, int filters, int mode) {
5708 enforceModifyPermission();
5709 final Phone phone = getPhone(subId);
5710 if (phone == null) {
5711 loge("setRadioIndicationUpdateMode fails with invalid subId: " + subId);
5712 return;
5713 }
5714
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005715 final long identity = Binder.clearCallingIdentity();
5716 try {
5717 phone.setRadioIndicationUpdateMode(filters, mode);
5718 } finally {
5719 Binder.restoreCallingIdentity(identity);
5720 }
Jack Yu4c988042018-02-27 15:30:01 -08005721 }
Pengquan Meng85728fb2018-03-12 16:31:21 -07005722
5723 /**
goneil47ffb6e2018-04-06 15:40:58 -07005724 * A test API to reload the UICC profile.
5725 *
5726 * <p>Requires that the calling app has permission
5727 * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
5728 * @hide
5729 */
5730 @Override
5731 public void refreshUiccProfile(int subId) {
5732 enforceModifyPermission();
5733
5734 final long identity = Binder.clearCallingIdentity();
5735 try {
5736 Phone phone = getPhone(subId);
5737 if (phone == null) {
5738 return;
5739 }
5740 UiccCard uiccCard = phone.getUiccCard();
5741 if (uiccCard == null) {
5742 return;
5743 }
5744 UiccProfile uiccProfile = uiccCard.getUiccProfile();
5745 if (uiccProfile == null) {
5746 return;
5747 }
5748 uiccProfile.refresh();
5749 } finally {
5750 Binder.restoreCallingIdentity(identity);
5751 }
5752 }
5753
5754 /**
Pengquan Meng85728fb2018-03-12 16:31:21 -07005755 * Returns false if the mobile data is disabled by default, otherwise return true.
5756 */
5757 private boolean getDefaultDataEnabled() {
5758 return "true".equalsIgnoreCase(
5759 SystemProperties.get(DEFAULT_MOBILE_DATA_PROPERTY_NAME, "true"));
5760 }
5761
5762 /**
5763 * Returns true if the data roaming is enabled by default, i.e the system property
5764 * of {@link #DEFAULT_DATA_ROAMING_PROPERTY_NAME} is true or the config of
5765 * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} is true.
5766 */
5767 private boolean getDefaultDataRoamingEnabled(int subId) {
5768 final CarrierConfigManager configMgr = (CarrierConfigManager)
5769 mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
5770 boolean isDataRoamingEnabled = "true".equalsIgnoreCase(
5771 SystemProperties.get(DEFAULT_DATA_ROAMING_PROPERTY_NAME, "false"));
5772 isDataRoamingEnabled |= configMgr.getConfigForSubId(subId).getBoolean(
5773 CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
5774 return isDataRoamingEnabled;
5775 }
5776
5777 /**
5778 * Returns the default network type for the given {@code subId}, if the default network type is
5779 * not set, return {@link Phone#PREFERRED_NT_MODE}.
5780 */
5781 private int getDefaultNetworkType(int subId) {
5782 return Integer.parseInt(
5783 TelephonyManager.getTelephonyProperty(
5784 mSubscriptionController.getPhoneId(subId),
5785 DEFAULT_NETWORK_MODE_PROPERTY_NAME,
5786 String.valueOf(Phone.PREFERRED_NT_MODE)));
5787 }
fionaxua13278b2018-03-21 00:08:13 -07005788
5789 @Override
5790 public void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String
5791 gid1, String gid2, String plmn, String spn) {
5792 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005793
5794 final long identity = Binder.clearCallingIdentity();
5795 try {
5796 final Phone phone = getPhone(subId);
5797 if (phone == null) {
5798 loge("setCarrierTestOverride fails with invalid subId: " + subId);
5799 return;
5800 }
5801 phone.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, plmn, spn);
5802 } finally {
5803 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07005804 }
fionaxua13278b2018-03-21 00:08:13 -07005805 }
5806
5807 @Override
5808 public int getCarrierIdListVersion(int subId) {
Brad Ebinger35c841c2018-10-01 10:40:55 -07005809 enforceReadPrivilegedPermission("getCarrierIdListVersion");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005810
5811 final long identity = Binder.clearCallingIdentity();
5812 try {
5813 final Phone phone = getPhone(subId);
5814 if (phone == null) {
5815 loge("getCarrierIdListVersion fails with invalid subId: " + subId);
5816 return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
5817 }
5818 return phone.getCarrierIdListVersion();
5819 } finally {
5820 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07005821 }
fionaxua13278b2018-03-21 00:08:13 -07005822 }
Malcolm Chen2c63d402018-08-14 16:00:53 -07005823
5824 @Override
5825 public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage) {
5826 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5827 mApp, subId, callingPackage, "getNumberOfModemsWithSimultaneousDataConnections")) {
5828 return -1;
5829 }
5830
5831 final long identity = Binder.clearCallingIdentity();
5832 try {
5833 return mPhoneConfigurationManager.getNumberOfModemsWithSimultaneousDataConnections();
5834 } finally {
5835 Binder.restoreCallingIdentity(identity);
5836 }
5837 }
Pengquan Menga1bb6272018-09-06 09:59:22 -07005838
5839 @Override
5840 public int getCdmaRoamingMode(int subId) {
5841 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5842 mApp, subId, "getCdmaRoamingMode");
5843
5844 final long identity = Binder.clearCallingIdentity();
5845 try {
5846 return (int) sendRequest(CMD_GET_CDMA_ROAMING_MODE, null /* argument */, subId);
5847 } finally {
5848 Binder.restoreCallingIdentity(identity);
5849 }
5850 }
5851
5852 @Override
5853 public boolean setCdmaRoamingMode(int subId, int mode) {
5854 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5855 mApp, subId, "setCdmaRoamingMode");
5856
5857 final long identity = Binder.clearCallingIdentity();
5858 try {
5859 return (boolean) sendRequest(CMD_SET_CDMA_ROAMING_MODE, mode, subId);
5860 } finally {
5861 Binder.restoreCallingIdentity(identity);
5862 }
5863 }
5864
5865 @Override
5866 public boolean setCdmaSubscriptionMode(int subId, int mode) {
5867 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5868 mApp, subId, "setCdmaSubscriptionMode");
5869
5870 final long identity = Binder.clearCallingIdentity();
5871 try {
5872 return (boolean) sendRequest(CMD_SET_CDMA_SUBSCRIPTION_MODE, mode, subId);
5873 } finally {
5874 Binder.restoreCallingIdentity(identity);
5875 }
5876 }
Makoto Onukida3bf792018-09-18 16:06:29 -07005877
5878 private void ensureUserRunning(int userId) {
5879 if (!mUserManager.isUserRunning(userId)) {
5880 throw new IllegalStateException("User " + userId + " does not exist or not running");
5881 }
5882 }
5883
5884 /**
5885 * Returns a list of SMS apps on a given user.
5886 *
5887 * Only the shell user (UID 2000 or 0) can call it.
5888 * Target user must be running.
5889 */
5890 @Override
5891 public String[] getSmsApps(int userId) {
5892 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getSmsApps");
5893 ensureUserRunning(userId);
5894
5895 final Collection<SmsApplicationData> apps =
5896 SmsApplication.getApplicationCollectionAsUser(mApp, userId);
5897
5898 String[] ret = new String[apps.size()];
5899 int i = 0;
5900 for (SmsApplicationData app : apps) {
5901 ret[i++] = app.mPackageName;
5902 }
5903 return ret;
5904 }
5905
5906 /**
5907 * Returns the default SMS app package name on a given user.
5908 *
5909 * Only the shell user (UID 2000 or 0) can call it.
5910 * Target user must be running.
5911 */
5912 @Override
5913 public String getDefaultSmsApp(int userId) {
5914 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getDefaultSmsApp");
5915 ensureUserRunning(userId);
5916
5917 final ComponentName cn = SmsApplication.getDefaultSmsApplicationAsUser(mApp,
5918 /* updateIfNeeded= */ true, userId);
5919 return cn == null ? null : cn.getPackageName();
5920 }
5921
5922 /**
5923 * Set a package as the default SMS app on a given user.
5924 *
5925 * Only the shell user (UID 2000 or 0) can call it.
5926 * Target user must be running.
5927 */
5928 @Override
5929 public void setDefaultSmsApp(int userId, String packageName) {
5930 TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setDefaultSmsApp");
5931 ensureUserRunning(userId);
5932
5933 boolean found = false;
5934 for (String pkg : getSmsApps(userId)) {
5935 if (TextUtils.equals(packageName, pkg)) {
5936 found = true;
5937 break;
5938 }
5939 }
5940 if (!found) {
5941 throw new IllegalArgumentException("Package " + packageName + " is not an SMS app");
5942 }
5943
5944 SmsApplication.setDefaultApplicationAsUser(packageName, mApp, userId);
5945 }
sqianc5eccab2018-10-19 18:46:41 -07005946
5947 @Override
5948 public Map<Integer, List<EmergencyNumber>> getCurrentEmergencyNumberList(
5949 String callingPackage) {
5950 // TODO connect with internal content
5951 return null;
5952 }
5953
5954 @Override
5955 public boolean isCurrentEmergencyNumber(String number) {
5956 // TODO connect with internal content
5957 return false;
5958 }
chen xud6b45bd2018-10-30 22:27:10 -07005959
5960 @Override
5961 public List<String> getCertsFromCarrierPrivilegeAccessRules(int subId) {
5962 enforceReadPrivilegedPermission("getCertsFromCarrierPrivilegeAccessRules");
5963 Phone phone = getPhone(subId);
5964 if (phone == null) {
5965 return null;
5966 }
5967 final long identity = Binder.clearCallingIdentity();
5968 try {
5969 UiccProfile profile = UiccController.getInstance()
5970 .getUiccProfileForPhone(phone.getPhoneId());
5971 if (profile != null) {
5972 return profile.getCertsFromCarrierPrivilegeAccessRules();
5973 }
5974 } finally {
5975 Binder.restoreCallingIdentity(identity);
5976 }
5977 return null;
5978 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005979}