blob: faa04a82f023f0c55308f4355834d5d4b3eea530 [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;
Derek Tan740e1672017-06-27 14:56:27 -070028import android.content.pm.ComponentInfo;
Amith Yamasani6e118872016-02-19 12:53:51 -080029import android.content.pm.PackageInfo;
Shishir Agrawal60f9c952014-06-23 12:00:43 -070030import android.content.pm.PackageManager;
Jack Yu84291ec2017-05-26 16:07:50 -070031import android.net.NetworkStats;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070032import android.net.Uri;
33import android.os.AsyncResult;
34import android.os.Binder;
35import android.os.Bundle;
36import android.os.Handler;
yinxu504e1392017-04-12 16:03:22 -070037import android.os.IBinder;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070038import android.os.Looper;
39import android.os.Message;
yinxu504e1392017-04-12 16:03:22 -070040import android.os.Messenger;
Tyler Gunn65d45c22017-06-05 11:22:26 -070041import android.os.PersistableBundle;
Brad Ebinger5f64b052017-12-14 14:26:15 -080042import android.os.RemoteException;
Adam Lesinski903a54c2016-04-11 14:49:52 -070043import android.os.ResultReceiver;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070044import android.os.ServiceManager;
Brad Ebingerdac2f002018-04-03 15:17:52 -070045import android.os.ShellCallback;
Pengquan Meng85728fb2018-03-12 16:31:21 -070046import android.os.SystemProperties;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070047import android.os.UserHandle;
Stuart Scott981d8582015-04-21 14:09:50 -070048import android.os.UserManager;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070049import android.os.WorkSource;
Derek Tan97ebb422014-09-05 16:55:38 -070050import android.preference.PreferenceManager;
Ihab Awadf2177b72013-11-25 13:33:23 -080051import android.provider.Settings;
Meng Wang1a7c35a2016-05-05 20:56:15 -070052import android.service.carrier.CarrierIdentifier;
Santos Cordon7a1885b2015-02-03 11:15:19 -080053import android.telecom.PhoneAccount;
Nancy Chen31f9ba12016-01-06 11:42:12 -080054import android.telecom.PhoneAccountHandle;
Andrew Lee9431b832015-03-09 18:46:45 -070055import android.telecom.TelecomManager;
Junda Liu12f7d802015-05-01 12:06:44 -070056import android.telephony.CarrierConfigManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070057import android.telephony.CellInfo;
Nathan Haroldf180aac2018-06-01 18:43:55 -070058import android.telephony.CellInfoGsm;
59import android.telephony.CellInfoWcdma;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070060import android.telephony.ClientRequestStats;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -070061import android.telephony.IccOpenLogicalChannelResponse;
Hall Liu1aa510f2017-11-22 17:40:08 -080062import android.telephony.LocationAccessPolicy;
Ta-wei Yen87c49842016-05-13 21:19:52 -070063import android.telephony.ModemActivityInfo;
Jake Hambye994d462014-02-03 13:10:13 -080064import android.telephony.NeighboringCellInfo;
yinxu504e1392017-04-12 16:03:22 -070065import android.telephony.NetworkScanRequest;
Wink Saville5d475dd2014-10-17 15:00:58 -070066import android.telephony.RadioAccessFamily;
Tyler Gunn65d45c22017-06-05 11:22:26 -070067import android.telephony.Rlog;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070068import android.telephony.ServiceState;
Nathan Harold46b42aa2017-03-10 19:38:22 -080069import android.telephony.SignalStrength;
Jack Yu84291ec2017-05-26 16:07:50 -070070import android.telephony.SmsManager;
Wink Saville0f3b5fc2014-11-11 08:40:49 -080071import android.telephony.SubscriptionInfo;
Jeff Sharkey85190e62014-12-05 09:40:12 -080072import android.telephony.SubscriptionManager;
Sanket Padawe99ef1e32016-05-18 16:12:33 -070073import android.telephony.TelephonyHistogram;
Ta-wei Yenb6929602016-05-24 15:48:27 -070074import android.telephony.TelephonyManager;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +000075import android.telephony.UiccSlotInfo;
Tyler Gunn65d45c22017-06-05 11:22:26 -070076import android.telephony.UssdResponse;
Ta-wei Yenb6929602016-05-24 15:48:27 -070077import android.telephony.VisualVoicemailSmsFilterSettings;
Brad Ebinger22bc3e42018-01-16 09:39:35 -080078import android.telephony.ims.aidl.IImsConfig;
79import android.telephony.ims.aidl.IImsMmTelFeature;
80import android.telephony.ims.aidl.IImsRcsFeature;
81import android.telephony.ims.aidl.IImsRegistration;
Brad Ebinger1f2b5082018-02-08 16:11:32 -080082import android.telephony.ims.stub.ImsRegistrationImplBase;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070083import android.text.TextUtils;
Jeff Sharkey85190e62014-12-05 09:40:12 -080084import android.util.ArraySet;
Tyler Gunn67073572018-02-14 14:19:42 -080085import android.util.EventLog;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070086import android.util.Log;
Jake Hambye994d462014-02-03 13:10:13 -080087import android.util.Pair;
Jeff Sharkey85190e62014-12-05 09:40:12 -080088import android.util.Slog;
Ta-wei Yen30a69c82016-12-27 14:52:32 -080089
Andrew Lee312e8172014-10-23 17:01:36 -070090import com.android.ims.ImsManager;
Brad Ebinger34bef922017-11-09 10:27:08 -080091import com.android.ims.internal.IImsServiceFeatureCallback;
Shishir Agrawal566b7612013-10-28 14:41:00 -070092import com.android.internal.telephony.CallManager;
Tyler Gunn52dcf772017-04-26 11:30:31 -070093import com.android.internal.telephony.CallStateException;
pkanwar79ec0542017-07-31 14:10:01 -070094import com.android.internal.telephony.CarrierInfoManager;
Shishir Agrawal302c8692015-06-19 13:49:39 -070095import com.android.internal.telephony.CellNetworkScanResult;
Shishir Agrawal566b7612013-10-28 14:41:00 -070096import com.android.internal.telephony.CommandException;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070097import com.android.internal.telephony.DefaultPhoneNotifier;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070098import com.android.internal.telephony.ITelephony;
Jake Hambye994d462014-02-03 13:10:13 -080099import com.android.internal.telephony.IccCard;
Jack Yu5f7092c2018-04-13 14:05:37 -0700100import com.android.internal.telephony.LocaleTracker;
Narayan Kamath1c496c22015-04-16 14:40:19 +0100101import com.android.internal.telephony.MccTable;
yinxub1bed742017-04-17 11:45:04 -0700102import com.android.internal.telephony.NetworkScanRequestTracker;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700103import com.android.internal.telephony.OperatorInfo;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700104import com.android.internal.telephony.Phone;
Malcolm Chen2c63d402018-08-14 16:00:53 -0700105import com.android.internal.telephony.PhoneConfigurationManager;
Nathan Harolda667c152016-12-14 11:27:20 -0800106import com.android.internal.telephony.PhoneConstantConversions;
Ta-wei Yen87c49842016-05-13 21:19:52 -0700107import com.android.internal.telephony.PhoneConstants;
Wink Saville36469e72014-06-11 15:17:00 -0700108import com.android.internal.telephony.PhoneFactory;
Wink Saville5d475dd2014-10-17 15:00:58 -0700109import com.android.internal.telephony.ProxyController;
Sanket Padawe99ef1e32016-05-18 16:12:33 -0700110import com.android.internal.telephony.RIL;
Svet Ganovb320e182015-04-16 12:30:10 -0700111import com.android.internal.telephony.RILConstants;
Jack Yu5f7092c2018-04-13 14:05:37 -0700112import com.android.internal.telephony.ServiceStateTracker;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800113import com.android.internal.telephony.SubscriptionController;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800114import com.android.internal.telephony.TelephonyPermissions;
Derek Tan740e1672017-06-27 14:56:27 -0700115import com.android.internal.telephony.euicc.EuiccConnector;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700116import com.android.internal.telephony.uicc.IccIoResult;
117import com.android.internal.telephony.uicc.IccUtils;
Nathan Haroldb3014052017-01-25 15:57:32 -0800118import com.android.internal.telephony.uicc.SIMRecords;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700119import com.android.internal.telephony.uicc.UiccCard;
Nathan Haroldb3014052017-01-25 15:57:32 -0800120import com.android.internal.telephony.uicc.UiccCardApplication;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700121import com.android.internal.telephony.uicc.UiccController;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800122import com.android.internal.telephony.uicc.UiccProfile;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000123import com.android.internal.telephony.uicc.UiccSlot;
fionaxu7ed723d2017-05-30 18:58:54 -0700124import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
Jake Hambye994d462014-02-03 13:10:13 -0800125import com.android.internal.util.HexDump;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700126import com.android.phone.vvm.PhoneAccountHandleConverter;
Ta-wei Yen527a9c02017-01-06 15:29:25 -0800127import com.android.phone.vvm.RemoteVvmTaskManager;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700128import com.android.phone.vvm.VisualVoicemailSettingsUtil;
Ta-wei Yenc8905312017-03-28 11:14:45 -0700129import com.android.phone.vvm.VisualVoicemailSmsFilterConfig;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800130
Ta-wei Yenc236d6b2016-06-21 13:33:12 -0700131import java.io.FileDescriptor;
132import java.io.PrintWriter;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800133import java.nio.charset.StandardCharsets;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700134import java.util.ArrayList;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800135import java.util.Arrays;
Jake Hambye994d462014-02-03 13:10:13 -0800136import java.util.List;
Narayan Kamath1c496c22015-04-16 14:40:19 +0100137import java.util.Locale;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800138import java.util.Map;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700139
140/**
141 * Implementation of the ITelephony interface.
142 */
Santos Cordon117fee72014-05-16 17:56:12 -0700143public class PhoneInterfaceManager extends ITelephony.Stub {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700144 private static final String LOG_TAG = "PhoneInterfaceManager";
145 private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
146 private static final boolean DBG_LOC = false;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800147 private static final boolean DBG_MERGE = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700148
149 // Message codes used with mMainThreadHandler
150 private static final int CMD_HANDLE_PIN_MMI = 1;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700151 private static final int CMD_ANSWER_RINGING_CALL = 4;
152 private static final int CMD_END_CALL = 5; // not used yet
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700153 private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7;
154 private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700155 private static final int CMD_OPEN_CHANNEL = 9;
156 private static final int EVENT_OPEN_CHANNEL_DONE = 10;
157 private static final int CMD_CLOSE_CHANNEL = 11;
158 private static final int EVENT_CLOSE_CHANNEL_DONE = 12;
Jake Hambye994d462014-02-03 13:10:13 -0800159 private static final int CMD_NV_READ_ITEM = 13;
160 private static final int EVENT_NV_READ_ITEM_DONE = 14;
161 private static final int CMD_NV_WRITE_ITEM = 15;
162 private static final int EVENT_NV_WRITE_ITEM_DONE = 16;
163 private static final int CMD_NV_WRITE_CDMA_PRL = 17;
164 private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18;
165 private static final int CMD_NV_RESET_CONFIG = 19;
166 private static final int EVENT_NV_RESET_CONFIG_DONE = 20;
Jake Hamby7c27be32014-03-03 13:25:59 -0800167 private static final int CMD_GET_PREFERRED_NETWORK_TYPE = 21;
168 private static final int EVENT_GET_PREFERRED_NETWORK_TYPE_DONE = 22;
169 private static final int CMD_SET_PREFERRED_NETWORK_TYPE = 23;
170 private static final int EVENT_SET_PREFERRED_NETWORK_TYPE_DONE = 24;
Sailesh Nepal35b59452014-03-06 09:26:56 -0800171 private static final int CMD_SEND_ENVELOPE = 25;
172 private static final int EVENT_SEND_ENVELOPE_DONE = 26;
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000173 private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27;
174 private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28;
Derek Tan6b088ee2014-09-05 14:15:18 -0700175 private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29;
176 private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30;
177 private static final int CMD_EXCHANGE_SIM_IO = 31;
178 private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800179 private static final int CMD_SET_VOICEMAIL_NUMBER = 33;
180 private static final int EVENT_SET_VOICEMAIL_NUMBER_DONE = 34;
Stuart Scott54788802015-03-30 13:18:01 -0700181 private static final int CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC = 35;
182 private static final int EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE = 36;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700183 private static final int CMD_GET_MODEM_ACTIVITY_INFO = 37;
184 private static final int EVENT_GET_MODEM_ACTIVITY_INFO_DONE = 38;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700185 private static final int CMD_PERFORM_NETWORK_SCAN = 39;
186 private static final int EVENT_PERFORM_NETWORK_SCAN_DONE = 40;
187 private static final int CMD_SET_NETWORK_SELECTION_MODE_MANUAL = 41;
188 private static final int EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE = 42;
Meng Wang1a7c35a2016-05-05 20:56:15 -0700189 private static final int CMD_SET_ALLOWED_CARRIERS = 43;
190 private static final int EVENT_SET_ALLOWED_CARRIERS_DONE = 44;
191 private static final int CMD_GET_ALLOWED_CARRIERS = 45;
192 private static final int EVENT_GET_ALLOWED_CARRIERS_DONE = 46;
pkanwar32d516d2016-10-14 19:37:38 -0700193 private static final int CMD_HANDLE_USSD_REQUEST = 47;
Nathan Haroldb3014052017-01-25 15:57:32 -0800194 private static final int CMD_GET_FORBIDDEN_PLMNS = 48;
195 private static final int EVENT_GET_FORBIDDEN_PLMNS_DONE = 49;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000196 private static final int CMD_SWITCH_SLOTS = 50;
197 private static final int EVENT_SWITCH_SLOTS_DONE = 51;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700198
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -0800199 // Parameters of select command.
200 private static final int SELECT_COMMAND = 0xA4;
201 private static final int SELECT_P1 = 0x04;
202 private static final int SELECT_P2 = 0;
203 private static final int SELECT_P3 = 0x10;
204
Pengquan Meng85728fb2018-03-12 16:31:21 -0700205 private static final String DEFAULT_NETWORK_MODE_PROPERTY_NAME = "ro.telephony.default_network";
206 private static final String DEFAULT_DATA_ROAMING_PROPERTY_NAME = "ro.com.android.dataroaming";
207 private static final String DEFAULT_MOBILE_DATA_PROPERTY_NAME = "ro.com.android.mobiledata";
208
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700209 /** The singleton instance. */
210 private static PhoneInterfaceManager sInstance;
211
Wink Saville3ab207e2014-11-20 13:07:20 -0800212 private PhoneGlobals mApp;
213 private Phone mPhone;
214 private CallManager mCM;
Stuart Scott981d8582015-04-21 14:09:50 -0700215 private UserManager mUserManager;
Wink Saville3ab207e2014-11-20 13:07:20 -0800216 private AppOpsManager mAppOps;
217 private MainThreadHandler mMainThreadHandler;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800218 private SubscriptionController mSubscriptionController;
Wink Saville3ab207e2014-11-20 13:07:20 -0800219 private SharedPreferences mTelephonySharedPreferences;
Malcolm Chen2c63d402018-08-14 16:00:53 -0700220 private PhoneConfigurationManager mPhoneConfigurationManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700221
Derek Tan97ebb422014-09-05 16:55:38 -0700222 private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
223 private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
Jeff Sharkey85190e62014-12-05 09:40:12 -0800224 private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
Derek Tan89e89d42014-07-08 17:00:10 -0700225
Derek Tan740e1672017-06-27 14:56:27 -0700226 // The AID of ISD-R.
227 private static final String ISDR_AID = "A0000005591010FFFFFFFF8900000100";
228
yinxub1bed742017-04-17 11:45:04 -0700229 private NetworkScanRequestTracker mNetworkScanRequestTracker;
230
David Kelly5e06a7f2018-03-12 14:10:59 +0000231 private static final int TYPE_ALLOCATION_CODE_LENGTH = 8;
232 private static final int MANUFACTURER_CODE_LENGTH = 8;
233
Derek Tan89e89d42014-07-08 17:00:10 -0700234 /**
Shishir Agrawal566b7612013-10-28 14:41:00 -0700235 * A request object to use for transmitting data to an ICC.
236 */
237 private static final class IccAPDUArgument {
238 public int channel, cla, command, p1, p2, p3;
239 public String data;
240
241 public IccAPDUArgument(int channel, int cla, int command,
242 int p1, int p2, int p3, String data) {
243 this.channel = channel;
244 this.cla = cla;
245 this.command = command;
246 this.p1 = p1;
247 this.p2 = p2;
248 this.p3 = p3;
249 this.data = data;
250 }
251 }
252
253 /**
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700254 * A request object to use for transmitting data to an ICC.
255 */
256 private static final class ManualNetworkSelectionArgument {
257 public OperatorInfo operatorInfo;
258 public boolean persistSelection;
259
260 public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) {
261 this.operatorInfo = operatorInfo;
262 this.persistSelection = persistSelection;
263 }
264 }
265
266 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700267 * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
268 * request after sending. The main thread will notify the request when it is complete.
269 */
270 private static final class MainThreadRequest {
271 /** The argument to use for the request */
272 public Object argument;
273 /** The result of the request that is run on the main thread */
274 public Object result;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800275 // The subscriber id that this request applies to. Defaults to
276 // SubscriptionManager.INVALID_SUBSCRIPTION_ID
277 public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700278
vagdeviaf9a5b92018-08-15 16:01:53 -0700279 public WorkSource workSource;
280
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700281 public MainThreadRequest(Object argument) {
282 this.argument = argument;
283 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800284
vagdeviaf9a5b92018-08-15 16:01:53 -0700285 MainThreadRequest(Object argument, Integer subId, WorkSource workSource) {
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800286 this.argument = argument;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800287 if (subId != null) {
288 this.subId = subId;
289 }
vagdeviaf9a5b92018-08-15 16:01:53 -0700290 this.workSource = workSource;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800291 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700292 }
293
Sailesh Nepalcc0375f2013-11-13 09:15:18 -0800294 private static final class IncomingThirdPartyCallArgs {
295 public final ComponentName component;
296 public final String callId;
297 public final String callerDisplayName;
298
299 public IncomingThirdPartyCallArgs(ComponentName component, String callId,
300 String callerDisplayName) {
301 this.component = component;
302 this.callId = callId;
303 this.callerDisplayName = callerDisplayName;
304 }
305 }
306
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700307 /**
308 * A handler that processes messages on the main thread in the phone process. Since many
309 * of the Phone calls are not thread safe this is needed to shuttle the requests from the
310 * inbound binder threads to the main thread in the phone process. The Binder thread
311 * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
312 * on, which will be notified when the operation completes and will contain the result of the
313 * request.
314 *
315 * <p>If a MainThreadRequest object is provided in the msg.obj field,
316 * note that request.result must be set to something non-null for the calling thread to
317 * unblock.
318 */
319 private final class MainThreadHandler extends Handler {
320 @Override
321 public void handleMessage(Message msg) {
322 MainThreadRequest request;
323 Message onCompleted;
324 AsyncResult ar;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800325 UiccCard uiccCard;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700326 IccAPDUArgument iccArgument;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700327
328 switch (msg.what) {
pkanwar32d516d2016-10-14 19:37:38 -0700329 case CMD_HANDLE_USSD_REQUEST: {
330 request = (MainThreadRequest) msg.obj;
331 final Phone phone = getPhoneFromRequest(request);
332 Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
333 String ussdRequest = ussdObject.first;
334 ResultReceiver wrappedCallback = ussdObject.second;
Tyler Gunn65d45c22017-06-05 11:22:26 -0700335
336 if (!isUssdApiAllowed(request.subId)) {
337 // Carrier does not support use of this API, return failure.
338 Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
339 UssdResponse response = new UssdResponse(ussdRequest, null);
340 Bundle returnData = new Bundle();
341 returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
342 wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
343
344 request.result = true;
345 synchronized (request) {
346 request.notifyAll();
347 }
348 return;
349 }
350
Tyler Gunn52dcf772017-04-26 11:30:31 -0700351 try {
352 request.result = phone != null ?
353 phone.handleUssdRequest(ussdRequest, wrappedCallback)
354 : false;
355 } catch (CallStateException cse) {
356 request.result = false;
357 }
pkanwar32d516d2016-10-14 19:37:38 -0700358 // Wake up the requesting thread
359 synchronized (request) {
360 request.notifyAll();
361 }
362 break;
363 }
364
Yorke Lee716f67e2015-06-17 15:39:16 -0700365 case CMD_HANDLE_PIN_MMI: {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700366 request = (MainThreadRequest) msg.obj;
Yorke Lee716f67e2015-06-17 15:39:16 -0700367 final Phone phone = getPhoneFromRequest(request);
368 request.result = phone != null ?
369 getPhoneFromRequest(request).handlePinMmi((String) request.argument)
370 : false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700371 // Wake up the requesting thread
372 synchronized (request) {
373 request.notifyAll();
374 }
375 break;
Yorke Lee716f67e2015-06-17 15:39:16 -0700376 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700377
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700378 case CMD_ANSWER_RINGING_CALL:
Wink Saville08874612014-08-31 19:19:58 -0700379 request = (MainThreadRequest) msg.obj;
Stuart Scott584921c2015-01-15 17:10:34 -0800380 int answer_subId = request.subId;
Wink Saville08874612014-08-31 19:19:58 -0700381 answerRingingCallInternal(answer_subId);
Mengjun Lengb3369682017-10-19 18:39:20 +0800382 request.result = ""; // dummy result for notifying the waiting thread
383 // Wake up the requesting thread
384 synchronized (request) {
385 request.notifyAll();
386 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700387 break;
388
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700389 case CMD_END_CALL:
390 request = (MainThreadRequest) msg.obj;
Stuart Scott584921c2015-01-15 17:10:34 -0800391 int end_subId = request.subId;
Wink Saville08874612014-08-31 19:19:58 -0700392 final boolean hungUp;
Anthony Leeae4e36d2015-05-21 07:17:46 -0700393 Phone phone = getPhone(end_subId);
394 if (phone == null) {
395 if (DBG) log("CMD_END_CALL: no phone for id: " + end_subId);
396 break;
397 }
398 int phoneType = phone.getPhoneType();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700399 if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
400 // CDMA: If the user presses the Power button we treat it as
401 // ending the complete call session
Wink Saville08874612014-08-31 19:19:58 -0700402 hungUp = PhoneUtils.hangupRingingAndActive(getPhone(end_subId));
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700403 } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
404 // GSM: End the call as per the Phone state
405 hungUp = PhoneUtils.hangup(mCM);
406 } else {
407 throw new IllegalStateException("Unexpected phone type: " + phoneType);
408 }
409 if (DBG) log("CMD_END_CALL: " + (hungUp ? "hung up!" : "no call to hang up"));
410 request.result = hungUp;
411 // Wake up the requesting thread
412 synchronized (request) {
413 request.notifyAll();
414 }
415 break;
416
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700417 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700418 request = (MainThreadRequest) msg.obj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700419 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800420 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700421 if (uiccCard == null) {
422 loge("iccTransmitApduLogicalChannel: No UICC");
423 request.result = new IccIoResult(0x6F, 0, (byte[])null);
424 synchronized (request) {
425 request.notifyAll();
426 }
427 } else {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700428 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
429 request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700430 uiccCard.iccTransmitApduLogicalChannel(
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700431 iccArgument.channel, iccArgument.cla, iccArgument.command,
432 iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data,
Shishir Agrawal566b7612013-10-28 14:41:00 -0700433 onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700434 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700435 break;
436
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700437 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700438 ar = (AsyncResult) msg.obj;
439 request = (MainThreadRequest) ar.userObj;
440 if (ar.exception == null && ar.result != null) {
441 request.result = ar.result;
442 } else {
443 request.result = new IccIoResult(0x6F, 0, (byte[])null);
444 if (ar.result == null) {
445 loge("iccTransmitApduLogicalChannel: Empty response");
Jake Hambye994d462014-02-03 13:10:13 -0800446 } else if (ar.exception instanceof CommandException) {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700447 loge("iccTransmitApduLogicalChannel: CommandException: " +
Jake Hambye994d462014-02-03 13:10:13 -0800448 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700449 } else {
450 loge("iccTransmitApduLogicalChannel: Unknown exception");
451 }
452 }
453 synchronized (request) {
454 request.notifyAll();
455 }
456 break;
457
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700458 case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
459 request = (MainThreadRequest) msg.obj;
460 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800461 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700462 if (uiccCard == null) {
463 loge("iccTransmitApduBasicChannel: No UICC");
464 request.result = new IccIoResult(0x6F, 0, (byte[])null);
465 synchronized (request) {
466 request.notifyAll();
467 }
468 } else {
469 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
470 request);
471 uiccCard.iccTransmitApduBasicChannel(
472 iccArgument.cla, iccArgument.command, iccArgument.p1, iccArgument.p2,
473 iccArgument.p3, iccArgument.data, onCompleted);
474 }
475 break;
476
477 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
478 ar = (AsyncResult) msg.obj;
479 request = (MainThreadRequest) ar.userObj;
480 if (ar.exception == null && ar.result != null) {
481 request.result = ar.result;
482 } else {
483 request.result = new IccIoResult(0x6F, 0, (byte[])null);
484 if (ar.result == null) {
485 loge("iccTransmitApduBasicChannel: Empty response");
486 } else if (ar.exception instanceof CommandException) {
487 loge("iccTransmitApduBasicChannel: CommandException: " +
488 ar.exception);
489 } else {
490 loge("iccTransmitApduBasicChannel: Unknown exception");
491 }
492 }
493 synchronized (request) {
494 request.notifyAll();
495 }
496 break;
497
498 case CMD_EXCHANGE_SIM_IO:
499 request = (MainThreadRequest) msg.obj;
500 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800501 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700502 if (uiccCard == null) {
503 loge("iccExchangeSimIO: No UICC");
504 request.result = new IccIoResult(0x6F, 0, (byte[])null);
505 synchronized (request) {
506 request.notifyAll();
507 }
508 } else {
509 onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
510 request);
511 uiccCard.iccExchangeSimIO(iccArgument.cla, /* fileID */
512 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3,
513 iccArgument.data, onCompleted);
514 }
515 break;
516
517 case EVENT_EXCHANGE_SIM_IO_DONE:
518 ar = (AsyncResult) msg.obj;
519 request = (MainThreadRequest) ar.userObj;
520 if (ar.exception == null && ar.result != null) {
521 request.result = ar.result;
522 } else {
523 request.result = new IccIoResult(0x6f, 0, (byte[])null);
524 }
525 synchronized (request) {
526 request.notifyAll();
527 }
528 break;
529
Derek Tan4d5e5c12014-02-04 11:54:58 -0800530 case CMD_SEND_ENVELOPE:
531 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800532 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700533 if (uiccCard == null) {
534 loge("sendEnvelopeWithStatus: No UICC");
535 request.result = new IccIoResult(0x6F, 0, (byte[])null);
536 synchronized (request) {
537 request.notifyAll();
538 }
539 } else {
540 onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
541 uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted);
542 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800543 break;
544
545 case EVENT_SEND_ENVELOPE_DONE:
546 ar = (AsyncResult) msg.obj;
547 request = (MainThreadRequest) ar.userObj;
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700548 if (ar.exception == null && ar.result != null) {
549 request.result = ar.result;
Derek Tan4d5e5c12014-02-04 11:54:58 -0800550 } else {
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700551 request.result = new IccIoResult(0x6F, 0, (byte[])null);
552 if (ar.result == null) {
553 loge("sendEnvelopeWithStatus: Empty response");
554 } else if (ar.exception instanceof CommandException) {
555 loge("sendEnvelopeWithStatus: CommandException: " +
556 ar.exception);
557 } else {
558 loge("sendEnvelopeWithStatus: exception:" + ar.exception);
559 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800560 }
561 synchronized (request) {
562 request.notifyAll();
563 }
564 break;
565
Shishir Agrawal566b7612013-10-28 14:41:00 -0700566 case CMD_OPEN_CHANNEL:
567 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800568 uiccCard = getUiccCardFromRequest(request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800569 Pair<String, Integer> openChannelArgs = (Pair<String, Integer>) request.argument;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700570 if (uiccCard == null) {
571 loge("iccOpenLogicalChannel: No UICC");
Shishir Agrawalfc0492a2016-02-17 11:15:33 -0800572 request.result = new IccOpenLogicalChannelResponse(-1,
573 IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700574 synchronized (request) {
575 request.notifyAll();
576 }
577 } else {
578 onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800579 uiccCard.iccOpenLogicalChannel(openChannelArgs.first,
580 openChannelArgs.second, onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700581 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700582 break;
583
584 case EVENT_OPEN_CHANNEL_DONE:
585 ar = (AsyncResult) msg.obj;
586 request = (MainThreadRequest) ar.userObj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700587 IccOpenLogicalChannelResponse openChannelResp;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700588 if (ar.exception == null && ar.result != null) {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700589 int[] result = (int[]) ar.result;
590 int channelId = result[0];
591 byte[] selectResponse = null;
592 if (result.length > 1) {
593 selectResponse = new byte[result.length - 1];
594 for (int i = 1; i < result.length; ++i) {
595 selectResponse[i - 1] = (byte) result[i];
596 }
597 }
598 openChannelResp = new IccOpenLogicalChannelResponse(channelId,
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700599 IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700600 } else {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700601 if (ar.result == null) {
602 loge("iccOpenLogicalChannel: Empty response");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700603 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700604 if (ar.exception != null) {
605 loge("iccOpenLogicalChannel: Exception: " + ar.exception);
606 }
607
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700608 int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR;
Junda Liua754ba12015-05-20 01:17:52 -0700609 if (ar.exception instanceof CommandException) {
610 CommandException.Error error =
611 ((CommandException) (ar.exception)).getCommandError();
612 if (error == CommandException.Error.MISSING_RESOURCE) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700613 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE;
Junda Liua754ba12015-05-20 01:17:52 -0700614 } else if (error == CommandException.Error.NO_SUCH_ELEMENT) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700615 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700616 }
617 }
618 openChannelResp = new IccOpenLogicalChannelResponse(
619 IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700620 }
Shishir Agrawal82c8a462014-07-31 18:13:17 -0700621 request.result = openChannelResp;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700622 synchronized (request) {
623 request.notifyAll();
624 }
625 break;
626
627 case CMD_CLOSE_CHANNEL:
628 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800629 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700630 if (uiccCard == null) {
631 loge("iccCloseLogicalChannel: No UICC");
Yoshiaki Naka2e29d822016-09-02 19:27:39 +0900632 request.result = false;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700633 synchronized (request) {
634 request.notifyAll();
635 }
636 } else {
637 onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
638 uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
639 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700640 break;
641
642 case EVENT_CLOSE_CHANNEL_DONE:
Jake Hambye994d462014-02-03 13:10:13 -0800643 handleNullReturnEvent(msg, "iccCloseLogicalChannel");
644 break;
645
646 case CMD_NV_READ_ITEM:
647 request = (MainThreadRequest) msg.obj;
648 onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
vagdeviaf9a5b92018-08-15 16:01:53 -0700649 mPhone.nvReadItem((Integer) request.argument, onCompleted, request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800650 break;
651
652 case EVENT_NV_READ_ITEM_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700653 ar = (AsyncResult) msg.obj;
654 request = (MainThreadRequest) ar.userObj;
Jake Hambye994d462014-02-03 13:10:13 -0800655 if (ar.exception == null && ar.result != null) {
656 request.result = ar.result; // String
Shishir Agrawal566b7612013-10-28 14:41:00 -0700657 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800658 request.result = "";
659 if (ar.result == null) {
660 loge("nvReadItem: Empty response");
661 } else if (ar.exception instanceof CommandException) {
662 loge("nvReadItem: CommandException: " +
663 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700664 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800665 loge("nvReadItem: Unknown exception");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700666 }
667 }
668 synchronized (request) {
669 request.notifyAll();
670 }
671 break;
672
Jake Hambye994d462014-02-03 13:10:13 -0800673 case CMD_NV_WRITE_ITEM:
674 request = (MainThreadRequest) msg.obj;
675 onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
676 Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
vagdeviaf9a5b92018-08-15 16:01:53 -0700677 mPhone.nvWriteItem(idValue.first, idValue.second, onCompleted,
678 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800679 break;
680
681 case EVENT_NV_WRITE_ITEM_DONE:
682 handleNullReturnEvent(msg, "nvWriteItem");
683 break;
684
685 case CMD_NV_WRITE_CDMA_PRL:
686 request = (MainThreadRequest) msg.obj;
687 onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
688 mPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
689 break;
690
691 case EVENT_NV_WRITE_CDMA_PRL_DONE:
692 handleNullReturnEvent(msg, "nvWriteCdmaPrl");
693 break;
694
695 case CMD_NV_RESET_CONFIG:
696 request = (MainThreadRequest) msg.obj;
697 onCompleted = obtainMessage(EVENT_NV_RESET_CONFIG_DONE, request);
698 mPhone.nvResetConfig((Integer) request.argument, onCompleted);
699 break;
700
701 case EVENT_NV_RESET_CONFIG_DONE:
702 handleNullReturnEvent(msg, "nvResetConfig");
703 break;
704
Jake Hamby7c27be32014-03-03 13:25:59 -0800705 case CMD_GET_PREFERRED_NETWORK_TYPE:
706 request = (MainThreadRequest) msg.obj;
707 onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request);
Stuart Scott54788802015-03-30 13:18:01 -0700708 getPhoneFromRequest(request).getPreferredNetworkType(onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800709 break;
710
711 case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE:
712 ar = (AsyncResult) msg.obj;
713 request = (MainThreadRequest) ar.userObj;
714 if (ar.exception == null && ar.result != null) {
715 request.result = ar.result; // Integer
716 } else {
Sanket Padawecfc2d352016-01-05 19:52:14 -0800717 request.result = null;
Jake Hamby7c27be32014-03-03 13:25:59 -0800718 if (ar.result == null) {
719 loge("getPreferredNetworkType: Empty response");
720 } else if (ar.exception instanceof CommandException) {
721 loge("getPreferredNetworkType: CommandException: " +
722 ar.exception);
723 } else {
724 loge("getPreferredNetworkType: Unknown exception");
725 }
726 }
727 synchronized (request) {
728 request.notifyAll();
729 }
730 break;
731
732 case CMD_SET_PREFERRED_NETWORK_TYPE:
733 request = (MainThreadRequest) msg.obj;
734 onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request);
735 int networkType = (Integer) request.argument;
Stuart Scott54788802015-03-30 13:18:01 -0700736 getPhoneFromRequest(request).setPreferredNetworkType(networkType, onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800737 break;
738
739 case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE:
740 handleNullReturnEvent(msg, "setPreferredNetworkType");
741 break;
742
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000743 case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
744 request = (MainThreadRequest)msg.obj;
745 onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
vagdeviaf9a5b92018-08-15 16:01:53 -0700746 mPhone.invokeOemRilRequestRaw((byte[]) request.argument, onCompleted);
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000747 break;
748
749 case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
750 ar = (AsyncResult)msg.obj;
751 request = (MainThreadRequest)ar.userObj;
752 request.result = ar;
753 synchronized (request) {
754 request.notifyAll();
755 }
756 break;
757
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800758 case CMD_SET_VOICEMAIL_NUMBER:
759 request = (MainThreadRequest) msg.obj;
760 onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
761 Pair<String, String> tagNum = (Pair<String, String>) request.argument;
Stuart Scott584921c2015-01-15 17:10:34 -0800762 getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
763 onCompleted);
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800764 break;
765
766 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
767 handleNullReturnEvent(msg, "setVoicemailNumber");
768 break;
769
Stuart Scott54788802015-03-30 13:18:01 -0700770 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC:
771 request = (MainThreadRequest) msg.obj;
772 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE,
773 request);
774 getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted);
775 break;
776
777 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE:
778 handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic");
779 break;
780
Shishir Agrawal302c8692015-06-19 13:49:39 -0700781 case CMD_PERFORM_NETWORK_SCAN:
782 request = (MainThreadRequest) msg.obj;
783 onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request);
784 getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
785 break;
786
787 case EVENT_PERFORM_NETWORK_SCAN_DONE:
788 ar = (AsyncResult) msg.obj;
789 request = (MainThreadRequest) ar.userObj;
790 CellNetworkScanResult cellScanResult;
791 if (ar.exception == null && ar.result != null) {
792 cellScanResult = new CellNetworkScanResult(
793 CellNetworkScanResult.STATUS_SUCCESS,
794 (List<OperatorInfo>) ar.result);
795 } else {
796 if (ar.result == null) {
797 loge("getCellNetworkScanResults: Empty response");
798 }
799 if (ar.exception != null) {
800 loge("getCellNetworkScanResults: Exception: " + ar.exception);
801 }
802 int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR;
803 if (ar.exception instanceof CommandException) {
804 CommandException.Error error =
805 ((CommandException) (ar.exception)).getCommandError();
806 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
807 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE;
808 } else if (error == CommandException.Error.GENERIC_FAILURE) {
809 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE;
810 }
811 }
812 cellScanResult = new CellNetworkScanResult(errorCode, null);
813 }
814 request.result = cellScanResult;
815 synchronized (request) {
816 request.notifyAll();
817 }
818 break;
819
820 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
821 request = (MainThreadRequest) msg.obj;
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700822 ManualNetworkSelectionArgument selArg =
823 (ManualNetworkSelectionArgument) request.argument;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700824 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE,
825 request);
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700826 getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo,
827 selArg.persistSelection, onCompleted);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700828 break;
829
830 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
831 handleNullReturnEvent(msg, "setNetworkSelectionModeManual");
832 break;
833
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700834 case CMD_GET_MODEM_ACTIVITY_INFO:
835 request = (MainThreadRequest) msg.obj;
836 onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
vagdeviaf9a5b92018-08-15 16:01:53 -0700837 mPhone.getModemActivityInfo(onCompleted, request.workSource);
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700838 break;
839
840 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE:
841 ar = (AsyncResult) msg.obj;
842 request = (MainThreadRequest) ar.userObj;
843 if (ar.exception == null && ar.result != null) {
844 request.result = ar.result;
845 } else {
846 if (ar.result == null) {
847 loge("queryModemActivityInfo: Empty response");
848 } else if (ar.exception instanceof CommandException) {
849 loge("queryModemActivityInfo: CommandException: " +
850 ar.exception);
851 } else {
852 loge("queryModemActivityInfo: Unknown exception");
853 }
854 }
Amit Mahajand4766222016-01-28 15:28:28 -0800855 // Result cannot be null. Return ModemActivityInfo with all fields set to 0.
856 if (request.result == null) {
857 request.result = new ModemActivityInfo(0, 0, 0, null, 0, 0);
858 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700859 synchronized (request) {
860 request.notifyAll();
861 }
862 break;
863
Meng Wang1a7c35a2016-05-05 20:56:15 -0700864 case CMD_SET_ALLOWED_CARRIERS:
865 request = (MainThreadRequest) msg.obj;
866 onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
867 mPhone.setAllowedCarriers(
868 (List<CarrierIdentifier>) request.argument,
vagdeviaf9a5b92018-08-15 16:01:53 -0700869 onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700870 break;
871
872 case EVENT_SET_ALLOWED_CARRIERS_DONE:
873 ar = (AsyncResult) msg.obj;
874 request = (MainThreadRequest) ar.userObj;
875 if (ar.exception == null && ar.result != null) {
876 request.result = ar.result;
877 } else {
878 if (ar.result == null) {
879 loge("setAllowedCarriers: Empty response");
880 } else if (ar.exception instanceof CommandException) {
881 loge("setAllowedCarriers: CommandException: " +
882 ar.exception);
883 } else {
884 loge("setAllowedCarriers: Unknown exception");
885 }
886 }
887 // Result cannot be null. Return -1 on error.
888 if (request.result == null) {
889 request.result = new int[]{-1};
890 }
891 synchronized (request) {
892 request.notifyAll();
893 }
894 break;
895
896 case CMD_GET_ALLOWED_CARRIERS:
897 request = (MainThreadRequest) msg.obj;
898 onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
vagdeviaf9a5b92018-08-15 16:01:53 -0700899 mPhone.getAllowedCarriers(onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700900 break;
901
902 case EVENT_GET_ALLOWED_CARRIERS_DONE:
903 ar = (AsyncResult) msg.obj;
904 request = (MainThreadRequest) ar.userObj;
905 if (ar.exception == null && ar.result != null) {
906 request.result = ar.result;
907 } else {
908 if (ar.result == null) {
909 loge("getAllowedCarriers: Empty response");
910 } else if (ar.exception instanceof CommandException) {
911 loge("getAllowedCarriers: CommandException: " +
912 ar.exception);
913 } else {
914 loge("getAllowedCarriers: Unknown exception");
915 }
916 }
917 // Result cannot be null. Return empty list of CarrierIdentifier.
918 if (request.result == null) {
919 request.result = new ArrayList<CarrierIdentifier>(0);
920 }
921 synchronized (request) {
922 request.notifyAll();
923 }
924 break;
925
Nathan Haroldb3014052017-01-25 15:57:32 -0800926 case EVENT_GET_FORBIDDEN_PLMNS_DONE:
927 ar = (AsyncResult) msg.obj;
928 request = (MainThreadRequest) ar.userObj;
929 if (ar.exception == null && ar.result != null) {
930 request.result = ar.result;
931 } else {
932 request.result = new IllegalArgumentException(
933 "Failed to retrieve Forbidden Plmns");
934 if (ar.result == null) {
935 loge("getForbiddenPlmns: Empty response");
936 } else {
937 loge("getForbiddenPlmns: Unknown exception");
938 }
939 }
940 synchronized (request) {
941 request.notifyAll();
942 }
943 break;
944
945 case CMD_GET_FORBIDDEN_PLMNS:
946 request = (MainThreadRequest) msg.obj;
947 uiccCard = getUiccCardFromRequest(request);
948 if (uiccCard == null) {
949 loge("getForbiddenPlmns() UiccCard is null");
950 request.result = new IllegalArgumentException(
951 "getForbiddenPlmns() UiccCard is null");
952 synchronized (request) {
953 request.notifyAll();
954 }
955 break;
956 }
957 Integer appType = (Integer) request.argument;
958 UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType);
959 if (uiccApp == null) {
960 loge("getForbiddenPlmns() no app with specified type -- "
961 + appType);
962 request.result = new IllegalArgumentException("Failed to get UICC App");
963 synchronized (request) {
964 request.notifyAll();
965 }
966 break;
967 } else {
968 if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
969 + " specified type -- " + appType);
970 }
971 onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
972 ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
973 onCompleted);
974 break;
975
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000976 case CMD_SWITCH_SLOTS:
977 request = (MainThreadRequest) msg.obj;
978 int[] physicalSlots = (int[]) request.argument;
979 onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
980 UiccController.getInstance().switchSlots(physicalSlots, onCompleted);
981 break;
982
983 case EVENT_SWITCH_SLOTS_DONE:
984 ar = (AsyncResult) msg.obj;
985 request = (MainThreadRequest) ar.userObj;
986 request.result = (ar.exception == null);
987 synchronized (request) {
988 request.notifyAll();
989 }
990 break;
991
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700992 default:
993 Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
994 break;
995 }
996 }
Jake Hambye994d462014-02-03 13:10:13 -0800997
998 private void handleNullReturnEvent(Message msg, String command) {
999 AsyncResult ar = (AsyncResult) msg.obj;
1000 MainThreadRequest request = (MainThreadRequest) ar.userObj;
1001 if (ar.exception == null) {
1002 request.result = true;
1003 } else {
1004 request.result = false;
1005 if (ar.exception instanceof CommandException) {
1006 loge(command + ": CommandException: " + ar.exception);
1007 } else {
1008 loge(command + ": Unknown exception");
1009 }
1010 }
1011 synchronized (request) {
1012 request.notifyAll();
1013 }
1014 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001015 }
1016
1017 /**
1018 * Posts the specified command to be executed on the main thread,
1019 * waits for the request to complete, and returns the result.
1020 * @see #sendRequestAsync
1021 */
1022 private Object sendRequest(int command, Object argument) {
vagdeviaf9a5b92018-08-15 16:01:53 -07001023 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, null);
1024 }
1025
1026 /**
1027 * Posts the specified command to be executed on the main thread,
1028 * waits for the request to complete, and returns the result.
1029 * @see #sendRequestAsync
1030 */
1031 private Object sendRequest(int command, Object argument, WorkSource workSource) {
1032 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
1033 workSource);
Wink Saville36469e72014-06-11 15:17:00 -07001034 }
1035
1036 /**
1037 * Posts the specified command to be executed on the main thread,
1038 * waits for the request to complete, and returns the result.
1039 * @see #sendRequestAsync
1040 */
Shishir Agrawal76d5da92014-11-09 16:17:25 -08001041 private Object sendRequest(int command, Object argument, Integer subId) {
vagdeviaf9a5b92018-08-15 16:01:53 -07001042 return sendRequest(command, argument, subId, null);
1043 }
1044
1045 /**
1046 * Posts the specified command to be executed on the main thread,
1047 * waits for the request to complete, and returns the result.
1048 * @see #sendRequestAsync
1049 */
1050 private Object sendRequest(int command, Object argument, Integer subId, WorkSource workSource) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001051 if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
1052 throw new RuntimeException("This method will deadlock if called from the main thread.");
1053 }
1054
vagdeviaf9a5b92018-08-15 16:01:53 -07001055 MainThreadRequest request = new MainThreadRequest(argument, subId, workSource);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001056 Message msg = mMainThreadHandler.obtainMessage(command, request);
1057 msg.sendToTarget();
1058
1059 // Wait for the request to complete
1060 synchronized (request) {
1061 while (request.result == null) {
1062 try {
1063 request.wait();
1064 } catch (InterruptedException e) {
1065 // Do nothing, go back and wait until the request is complete
1066 }
1067 }
1068 }
1069 return request.result;
1070 }
1071
1072 /**
1073 * Asynchronous ("fire and forget") version of sendRequest():
1074 * Posts the specified command to be executed on the main thread, and
1075 * returns immediately.
1076 * @see #sendRequest
1077 */
1078 private void sendRequestAsync(int command) {
1079 mMainThreadHandler.sendEmptyMessage(command);
1080 }
1081
1082 /**
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001083 * Same as {@link #sendRequestAsync(int)} except it takes an argument.
1084 * @see {@link #sendRequest(int,Object)}
1085 */
1086 private void sendRequestAsync(int command, Object argument) {
1087 MainThreadRequest request = new MainThreadRequest(argument);
1088 Message msg = mMainThreadHandler.obtainMessage(command, request);
1089 msg.sendToTarget();
1090 }
1091
1092 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001093 * Initialize the singleton PhoneInterfaceManager instance.
1094 * This is only done once, at startup, from PhoneApp.onCreate().
1095 */
Sailesh Nepal194161e2014-07-03 08:57:44 -07001096 /* package */ static PhoneInterfaceManager init(PhoneGlobals app, Phone phone) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001097 synchronized (PhoneInterfaceManager.class) {
1098 if (sInstance == null) {
Sailesh Nepal194161e2014-07-03 08:57:44 -07001099 sInstance = new PhoneInterfaceManager(app, phone);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001100 } else {
1101 Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
1102 }
1103 return sInstance;
1104 }
1105 }
1106
1107 /** Private constructor; @see init() */
Sailesh Nepal194161e2014-07-03 08:57:44 -07001108 private PhoneInterfaceManager(PhoneGlobals app, Phone phone) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001109 mApp = app;
1110 mPhone = phone;
1111 mCM = PhoneGlobals.getInstance().mCM;
Stuart Scott981d8582015-04-21 14:09:50 -07001112 mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001113 mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
1114 mMainThreadHandler = new MainThreadHandler();
Andrew Leedf14ead2014-10-17 14:22:52 -07001115 mTelephonySharedPreferences =
Derek Tan97ebb422014-09-05 16:55:38 -07001116 PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
Wink Savilleac1bdfd2014-11-20 23:04:44 -08001117 mSubscriptionController = SubscriptionController.getInstance();
yinxub1bed742017-04-17 11:45:04 -07001118 mNetworkScanRequestTracker = new NetworkScanRequestTracker();
Malcolm Chen2c63d402018-08-14 16:00:53 -07001119 mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
Wink Saville3ab207e2014-11-20 13:07:20 -08001120
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001121 publish();
1122 }
1123
1124 private void publish() {
1125 if (DBG) log("publish: " + this);
1126
1127 ServiceManager.addService("phone", this);
1128 }
1129
Stuart Scott584921c2015-01-15 17:10:34 -08001130 private Phone getPhoneFromRequest(MainThreadRequest request) {
Sanket Padawe56e75a32016-02-08 12:18:19 -08001131 return (request.subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
1132 ? mPhone : getPhone(request.subId);
Stuart Scott584921c2015-01-15 17:10:34 -08001133 }
1134
Shishir Agrawalc04d9752016-02-19 10:41:00 -08001135 private UiccCard getUiccCardFromRequest(MainThreadRequest request) {
1136 Phone phone = getPhoneFromRequest(request);
1137 return phone == null ? null :
1138 UiccController.getInstance().getUiccCard(phone.getPhoneId());
1139 }
1140
Wink Saville36469e72014-06-11 15:17:00 -07001141 // returns phone associated with the subId.
Wink Savilleb564aae2014-10-23 10:18:09 -07001142 private Phone getPhone(int subId) {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08001143 return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId));
Wink Saville36469e72014-06-11 15:17:00 -07001144 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001145 //
1146 // Implementation of the ITelephony interface.
1147 //
1148
1149 public void dial(String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001150 dialForSubscriber(getPreferredVoiceSubscription(), number);
Wink Saville36469e72014-06-11 15:17:00 -07001151 }
1152
Wink Savilleb564aae2014-10-23 10:18:09 -07001153 public void dialForSubscriber(int subId, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001154 if (DBG) log("dial: " + number);
1155 // No permission check needed here: This is just a wrapper around the
1156 // ACTION_DIAL intent, which is available to any app since it puts up
1157 // the UI before it does anything.
1158
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001159 final long identity = Binder.clearCallingIdentity();
1160 try {
1161 String url = createTelUrl(number);
1162 if (url == null) {
1163 return;
1164 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001165
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001166 // PENDING: should we just silently fail if phone is offhook or ringing?
1167 PhoneConstants.State state = mCM.getState(subId);
1168 if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
1169 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
1170 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1171 mApp.startActivity(intent);
1172 }
1173 } finally {
1174 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001175 }
1176 }
1177
1178 public void call(String callingPackage, String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001179 callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number);
Wink Saville36469e72014-06-11 15:17:00 -07001180 }
1181
Wink Savilleb564aae2014-10-23 10:18:09 -07001182 public void callForSubscriber(int subId, String callingPackage, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001183 if (DBG) log("call: " + number);
1184
1185 // This is just a wrapper around the ACTION_CALL intent, but we still
1186 // need to do a permission check since we're calling startActivity()
1187 // from the context of the phone app.
1188 enforceCallPermission();
1189
1190 if (mAppOps.noteOp(AppOpsManager.OP_CALL_PHONE, Binder.getCallingUid(), callingPackage)
1191 != AppOpsManager.MODE_ALLOWED) {
1192 return;
1193 }
1194
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001195 final long identity = Binder.clearCallingIdentity();
1196 try {
1197 String url = createTelUrl(number);
1198 if (url == null) {
1199 return;
1200 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001201
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001202 boolean isValid = false;
1203 final List<SubscriptionInfo> slist = getActiveSubscriptionInfoListPrivileged();
1204 if (slist != null) {
1205 for (SubscriptionInfo subInfoRecord : slist) {
1206 if (subInfoRecord.getSubscriptionId() == subId) {
1207 isValid = true;
1208 break;
1209 }
Wink Saville3ab207e2014-11-20 13:07:20 -08001210 }
Wink Saville08874612014-08-31 19:19:58 -07001211 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001212 if (!isValid) {
1213 return;
1214 }
Wink Saville08874612014-08-31 19:19:58 -07001215
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001216 Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
1217 intent.putExtra(SUBSCRIPTION_KEY, subId);
1218 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1219 mApp.startActivity(intent);
1220 } finally {
1221 Binder.restoreCallingIdentity(identity);
1222 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001223 }
1224
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001225 /**
1226 * End a call based on call state
1227 * @return true is a call was ended
1228 */
1229 public boolean endCall() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001230 return endCallForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001231 }
1232
1233 /**
1234 * End a call based on the call state of the subId
1235 * @return true is a call was ended
1236 */
Wink Savilleb564aae2014-10-23 10:18:09 -07001237 public boolean endCallForSubscriber(int subId) {
Tyler Gunn67073572018-02-14 14:19:42 -08001238 if (mApp.checkCallingOrSelfPermission(permission.MODIFY_PHONE_STATE)
1239 != PackageManager.PERMISSION_GRANTED) {
1240 Log.i(LOG_TAG, "endCall: called without modify phone state.");
1241 EventLog.writeEvent(0x534e4554, "67862398", -1, "");
1242 throw new SecurityException("MODIFY_PHONE_STATE permission required.");
1243 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001244
1245 final long identity = Binder.clearCallingIdentity();
1246 try {
1247 return (Boolean) sendRequest(CMD_END_CALL, null, new Integer(subId));
1248 } finally {
1249 Binder.restoreCallingIdentity(identity);
1250 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001251 }
1252
1253 public void answerRingingCall() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001254 answerRingingCallForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001255 }
1256
Wink Savilleb564aae2014-10-23 10:18:09 -07001257 public void answerRingingCallForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001258 if (DBG) log("answerRingingCall...");
1259 // TODO: there should eventually be a separate "ANSWER_PHONE" permission,
1260 // but that can probably wait till the big TelephonyManager API overhaul.
1261 // For now, protect this call with the MODIFY_PHONE_STATE permission.
1262 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001263
1264 final long identity = Binder.clearCallingIdentity();
1265 try {
1266 sendRequest(CMD_ANSWER_RINGING_CALL, null, new Integer(subId));
1267 } finally {
1268 Binder.restoreCallingIdentity(identity);
1269 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001270 }
1271
1272 /**
1273 * Make the actual telephony calls to implement answerRingingCall().
1274 * This should only be called from the main thread of the Phone app.
1275 * @see #answerRingingCall
1276 *
1277 * TODO: it would be nice to return true if we answered the call, or
1278 * false if there wasn't actually a ringing incoming call, or some
1279 * other error occurred. (In other words, pass back the return value
1280 * from PhoneUtils.answerCall() or PhoneUtils.answerAndEndActive().)
1281 * But that would require calling this method via sendRequest() rather
1282 * than sendRequestAsync(), and right now we don't actually *need* that
1283 * return value, so let's just return void for now.
1284 */
Wink Savilleb564aae2014-10-23 10:18:09 -07001285 private void answerRingingCallInternal(int subId) {
Wink Saville08874612014-08-31 19:19:58 -07001286 final boolean hasRingingCall = !getPhone(subId).getRingingCall().isIdle();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001287 if (hasRingingCall) {
Wink Saville08874612014-08-31 19:19:58 -07001288 final boolean hasActiveCall = !getPhone(subId).getForegroundCall().isIdle();
1289 final boolean hasHoldingCall = !getPhone(subId).getBackgroundCall().isIdle();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001290 if (hasActiveCall && hasHoldingCall) {
1291 // Both lines are in use!
1292 // TODO: provide a flag to let the caller specify what
1293 // policy to use if both lines are in use. (The current
1294 // behavior is hardwired to "answer incoming, end ongoing",
1295 // which is how the CALL button is specced to behave.)
1296 PhoneUtils.answerAndEndActive(mCM, mCM.getFirstActiveRingingCall());
1297 return;
1298 } else {
1299 // answerCall() will automatically hold the current active
1300 // call, if there is one.
1301 PhoneUtils.answerCall(mCM.getFirstActiveRingingCall());
1302 return;
1303 }
1304 } else {
1305 // No call was ringing.
1306 return;
1307 }
1308 }
1309
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001310 /**
Santos Cordon5422a8d2014-09-12 04:20:56 -07001311 * This method is no longer used and can be removed once TelephonyManager stops referring to it.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001312 */
Santos Cordon5422a8d2014-09-12 04:20:56 -07001313 public void silenceRinger() {
1314 Log.e(LOG_TAG, "silenseRinger not supported");
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001315 }
1316
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001317 @Override
1318 public boolean isOffhook(String callingPackage) {
1319 return isOffhookForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07001320 }
1321
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001322 @Override
1323 public boolean isOffhookForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08001324 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08001325 mApp, subId, callingPackage, "isOffhookForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001326 return false;
1327 }
1328
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001329 final long identity = Binder.clearCallingIdentity();
1330 try {
1331 final Phone phone = getPhone(subId);
1332 if (phone != null) {
1333 return (phone.getState() == PhoneConstants.State.OFFHOOK);
1334 } else {
1335 return false;
1336 }
1337 } finally {
1338 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001339 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001340 }
1341
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001342 @Override
1343 public boolean isRinging(String callingPackage) {
1344 return (isRingingForSubscriber(getDefaultSubscription(), callingPackage));
Wink Saville36469e72014-06-11 15:17:00 -07001345 }
1346
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001347 @Override
1348 public boolean isRingingForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08001349 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08001350 mApp, subId, callingPackage, "isRingingForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001351 return false;
1352 }
1353
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001354 final long identity = Binder.clearCallingIdentity();
1355 try {
1356 final Phone phone = getPhone(subId);
1357 if (phone != null) {
1358 return (phone.getState() == PhoneConstants.State.RINGING);
1359 } else {
1360 return false;
1361 }
1362 } finally {
1363 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001364 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001365 }
1366
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001367 @Override
1368 public boolean isIdle(String callingPackage) {
1369 return isIdleForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07001370 }
1371
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001372 @Override
1373 public boolean isIdleForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08001374 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08001375 mApp, subId, callingPackage, "isIdleForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001376 return false;
1377 }
1378
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001379 final long identity = Binder.clearCallingIdentity();
1380 try {
1381 final Phone phone = getPhone(subId);
1382 if (phone != null) {
1383 return (phone.getState() == PhoneConstants.State.IDLE);
1384 } else {
1385 return false;
1386 }
1387 } finally {
1388 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001389 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001390 }
1391
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001392 public boolean supplyPin(String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001393 return supplyPinForSubscriber(getDefaultSubscription(), pin);
Wink Saville36469e72014-06-11 15:17:00 -07001394 }
1395
Wink Savilleb564aae2014-10-23 10:18:09 -07001396 public boolean supplyPinForSubscriber(int subId, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001397 int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07001398 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1399 }
1400
1401 public boolean supplyPuk(String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001402 return supplyPukForSubscriber(getDefaultSubscription(), puk, pin);
Wink Saville36469e72014-06-11 15:17:00 -07001403 }
1404
Wink Savilleb564aae2014-10-23 10:18:09 -07001405 public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001406 int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07001407 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1408 }
1409
1410 /** {@hide} */
1411 public int[] supplyPinReportResult(String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001412 return supplyPinReportResultForSubscriber(getDefaultSubscription(), pin);
Wink Saville36469e72014-06-11 15:17:00 -07001413 }
1414
Wink Savilleb564aae2014-10-23 10:18:09 -07001415 public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001416 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001417
1418 final long identity = Binder.clearCallingIdentity();
1419 try {
1420 final UnlockSim checkSimPin = new UnlockSim(getPhone(subId).getIccCard());
1421 checkSimPin.start();
1422 return checkSimPin.unlockSim(null, pin);
1423 } finally {
1424 Binder.restoreCallingIdentity(identity);
1425 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001426 }
1427
Wink Saville9de0f752013-10-22 19:04:03 -07001428 /** {@hide} */
1429 public int[] supplyPukReportResult(String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001430 return supplyPukReportResultForSubscriber(getDefaultSubscription(), puk, pin);
Wink Saville36469e72014-06-11 15:17:00 -07001431 }
1432
Wink Savilleb564aae2014-10-23 10:18:09 -07001433 public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001434 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001435
1436 final long identity = Binder.clearCallingIdentity();
1437 try {
1438 final UnlockSim checkSimPuk = new UnlockSim(getPhone(subId).getIccCard());
1439 checkSimPuk.start();
1440 return checkSimPuk.unlockSim(puk, pin);
1441 } finally {
1442 Binder.restoreCallingIdentity(identity);
1443 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001444 }
1445
1446 /**
Wink Saville9de0f752013-10-22 19:04:03 -07001447 * Helper thread to turn async call to SimCard#supplyPin into
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001448 * a synchronous one.
1449 */
1450 private static class UnlockSim extends Thread {
1451
1452 private final IccCard mSimCard;
1453
1454 private boolean mDone = false;
Wink Saville9de0f752013-10-22 19:04:03 -07001455 private int mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1456 private int mRetryCount = -1;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001457
1458 // For replies from SimCard interface
1459 private Handler mHandler;
1460
1461 // For async handler to identify request type
1462 private static final int SUPPLY_PIN_COMPLETE = 100;
1463
1464 public UnlockSim(IccCard simCard) {
1465 mSimCard = simCard;
1466 }
1467
1468 @Override
1469 public void run() {
1470 Looper.prepare();
1471 synchronized (UnlockSim.this) {
1472 mHandler = new Handler() {
1473 @Override
1474 public void handleMessage(Message msg) {
1475 AsyncResult ar = (AsyncResult) msg.obj;
1476 switch (msg.what) {
1477 case SUPPLY_PIN_COMPLETE:
1478 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
1479 synchronized (UnlockSim.this) {
Wink Saville9de0f752013-10-22 19:04:03 -07001480 mRetryCount = msg.arg1;
1481 if (ar.exception != null) {
1482 if (ar.exception instanceof CommandException &&
1483 ((CommandException)(ar.exception)).getCommandError()
1484 == CommandException.Error.PASSWORD_INCORRECT) {
1485 mResult = PhoneConstants.PIN_PASSWORD_INCORRECT;
1486 } else {
1487 mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1488 }
1489 } else {
1490 mResult = PhoneConstants.PIN_RESULT_SUCCESS;
1491 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001492 mDone = true;
1493 UnlockSim.this.notifyAll();
1494 }
1495 break;
1496 }
1497 }
1498 };
1499 UnlockSim.this.notifyAll();
1500 }
1501 Looper.loop();
1502 }
1503
1504 /*
1505 * Use PIN or PUK to unlock SIM card
1506 *
1507 * If PUK is null, unlock SIM card with PIN
1508 *
1509 * If PUK is not null, unlock SIM card with PUK and set PIN code
1510 */
Wink Saville9de0f752013-10-22 19:04:03 -07001511 synchronized int[] unlockSim(String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001512
1513 while (mHandler == null) {
1514 try {
1515 wait();
1516 } catch (InterruptedException e) {
1517 Thread.currentThread().interrupt();
1518 }
1519 }
1520 Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
1521
1522 if (puk == null) {
1523 mSimCard.supplyPin(pin, callback);
1524 } else {
1525 mSimCard.supplyPuk(puk, pin, callback);
1526 }
1527
1528 while (!mDone) {
1529 try {
1530 Log.d(LOG_TAG, "wait for done");
1531 wait();
1532 } catch (InterruptedException e) {
1533 // Restore the interrupted status
1534 Thread.currentThread().interrupt();
1535 }
1536 }
1537 Log.d(LOG_TAG, "done");
Wink Saville9de0f752013-10-22 19:04:03 -07001538 int[] resultArray = new int[2];
1539 resultArray[0] = mResult;
1540 resultArray[1] = mRetryCount;
1541 return resultArray;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001542 }
1543 }
1544
1545 public void updateServiceLocation() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001546 updateServiceLocationForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001547
1548 }
1549
Wink Savilleb564aae2014-10-23 10:18:09 -07001550 public void updateServiceLocationForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001551 // No permission check needed here: this call is harmless, and it's
1552 // needed for the ServiceState.requestStateUpdate() call (which is
1553 // already intentionally exposed to 3rd parties.)
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001554 final long identity = Binder.clearCallingIdentity();
1555 try {
1556 final Phone phone = getPhone(subId);
1557 if (phone != null) {
1558 phone.updateServiceLocation();
1559 }
1560 } finally {
1561 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001562 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001563 }
1564
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001565 @Override
1566 public boolean isRadioOn(String callingPackage) {
1567 return isRadioOnForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07001568 }
1569
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001570 @Override
1571 public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08001572 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08001573 mApp, subId, callingPackage, "isRadioOnForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001574 return false;
1575 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001576
1577 final long identity = Binder.clearCallingIdentity();
1578 try {
1579 return isRadioOnForSubscriber(subId);
1580 } finally {
1581 Binder.restoreCallingIdentity(identity);
1582 }
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001583 }
1584
1585 private boolean isRadioOnForSubscriber(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001586 final long identity = Binder.clearCallingIdentity();
1587 try {
1588 final Phone phone = getPhone(subId);
1589 if (phone != null) {
1590 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
1591 } else {
1592 return false;
1593 }
1594 } finally {
1595 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001596 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001597 }
1598
1599 public void toggleRadioOnOff() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001600 toggleRadioOnOffForSubscriber(getDefaultSubscription());
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001601 }
Wink Saville36469e72014-06-11 15:17:00 -07001602
Wink Savilleb564aae2014-10-23 10:18:09 -07001603 public void toggleRadioOnOffForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001604 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001605
1606 final long identity = Binder.clearCallingIdentity();
1607 try {
1608 final Phone phone = getPhone(subId);
1609 if (phone != null) {
1610 phone.setRadioPower(!isRadioOnForSubscriber(subId));
1611 }
1612 } finally {
1613 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001614 }
Wink Saville36469e72014-06-11 15:17:00 -07001615 }
1616
1617 public boolean setRadio(boolean turnOn) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001618 return setRadioForSubscriber(getDefaultSubscription(), turnOn);
Wink Saville36469e72014-06-11 15:17:00 -07001619 }
1620
Wink Savilleb564aae2014-10-23 10:18:09 -07001621 public boolean setRadioForSubscriber(int subId, boolean turnOn) {
Wink Saville36469e72014-06-11 15:17:00 -07001622 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001623
1624 final long identity = Binder.clearCallingIdentity();
1625 try {
1626 final Phone phone = getPhone(subId);
1627 if (phone == null) {
1628 return false;
1629 }
1630 if ((phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF) != turnOn) {
1631 toggleRadioOnOffForSubscriber(subId);
1632 }
1633 return true;
1634 } finally {
1635 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001636 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001637 }
Wink Saville36469e72014-06-11 15:17:00 -07001638
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001639 public boolean needMobileRadioShutdown() {
1640 /*
1641 * If any of the Radios are available, it will need to be
1642 * shutdown. So return true if any Radio is available.
1643 */
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001644 final long identity = Binder.clearCallingIdentity();
1645 try {
1646 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1647 Phone phone = PhoneFactory.getPhone(i);
1648 if (phone != null && phone.isRadioAvailable()) return true;
1649 }
1650 logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown.");
1651 return false;
1652 } finally {
1653 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001654 }
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001655 }
1656
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001657 @Override
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001658 public void shutdownMobileRadios() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001659 enforceModifyPermission();
1660
1661 final long identity = Binder.clearCallingIdentity();
1662 try {
1663 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1664 logv("Shutting down Phone " + i);
1665 shutdownRadioUsingPhoneId(i);
1666 }
1667 } finally {
1668 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001669 }
1670 }
1671
1672 private void shutdownRadioUsingPhoneId(int phoneId) {
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001673 Phone phone = PhoneFactory.getPhone(phoneId);
1674 if (phone != null && phone.isRadioAvailable()) {
1675 phone.shutdownRadio();
1676 }
1677 }
1678
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001679 public boolean setRadioPower(boolean turnOn) {
Jack Yub4e16162017-05-15 12:48:40 -07001680 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001681
1682 final long identity = Binder.clearCallingIdentity();
1683 try {
1684 final Phone defaultPhone = PhoneFactory.getDefaultPhone();
1685 if (defaultPhone != null) {
1686 defaultPhone.setRadioPower(turnOn);
1687 return true;
1688 } else {
1689 loge("There's no default phone.");
1690 return false;
1691 }
1692 } finally {
1693 Binder.restoreCallingIdentity(identity);
Wei Liu9ae2a062016-08-08 11:09:34 -07001694 }
Wink Saville36469e72014-06-11 15:17:00 -07001695 }
1696
Wink Savilleb564aae2014-10-23 10:18:09 -07001697 public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001698 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001699
1700 final long identity = Binder.clearCallingIdentity();
1701 try {
1702 final Phone phone = getPhone(subId);
1703 if (phone != null) {
1704 phone.setRadioPower(turnOn);
1705 return true;
1706 } else {
1707 return false;
1708 }
1709 } finally {
1710 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001711 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001712 }
1713
Wink Saville36469e72014-06-11 15:17:00 -07001714 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07001715 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001716 public boolean enableDataConnectivity() {
1717 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001718
1719 final long identity = Binder.clearCallingIdentity();
1720 try {
1721 int subId = mSubscriptionController.getDefaultDataSubId();
1722 final Phone phone = getPhone(subId);
1723 if (phone != null) {
1724 phone.setUserDataEnabled(true);
1725 return true;
1726 } else {
1727 return false;
1728 }
1729 } finally {
1730 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001731 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001732 }
1733
Wink Saville36469e72014-06-11 15:17:00 -07001734 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07001735 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001736 public boolean disableDataConnectivity() {
1737 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001738
1739 final long identity = Binder.clearCallingIdentity();
1740 try {
1741 int subId = mSubscriptionController.getDefaultDataSubId();
1742 final Phone phone = getPhone(subId);
1743 if (phone != null) {
1744 phone.setUserDataEnabled(false);
1745 return true;
1746 } else {
1747 return false;
1748 }
1749 } finally {
1750 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001751 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001752 }
1753
Sanket Padawe356d7632015-06-22 14:03:32 -07001754 @Override
Jack Yuacf8a132017-05-01 17:00:48 -07001755 public boolean isDataConnectivityPossible(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001756 final long identity = Binder.clearCallingIdentity();
1757 try {
1758 final Phone phone = getPhone(subId);
1759 if (phone != null) {
1760 return phone.isDataAllowed();
1761 } else {
1762 return false;
1763 }
1764 } finally {
1765 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001766 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001767 }
1768
1769 public boolean handlePinMmi(String dialString) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001770 return handlePinMmiForSubscriber(getDefaultSubscription(), dialString);
Wink Saville36469e72014-06-11 15:17:00 -07001771 }
1772
pkanwarae03a6b2016-11-06 20:37:09 -08001773 public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001774 enforceCallPermission();
1775
1776 final long identity = Binder.clearCallingIdentity();
1777 try {
1778 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1779 return;
1780 }
1781 Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback);
1782 sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId);
1783 } finally {
1784 Binder.restoreCallingIdentity(identity);
1785 }
pkanwar32d516d2016-10-14 19:37:38 -07001786 };
1787
Wink Savilleb564aae2014-10-23 10:18:09 -07001788 public boolean handlePinMmiForSubscriber(int subId, String dialString) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001789 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001790
1791 final long identity = Binder.clearCallingIdentity();
1792 try {
1793 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1794 return false;
1795 }
1796 return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
1797 } finally {
1798 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001799 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001800 }
1801
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001802 public int getCallState() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07001803 return getCallStateForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001804 }
1805
Sanket Padawe13bac7b2017-03-20 15:04:47 -07001806 public int getCallStateForSlot(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001807 final long identity = Binder.clearCallingIdentity();
1808 try {
1809 Phone phone = PhoneFactory.getPhone(slotIndex);
1810 return phone == null ? TelephonyManager.CALL_STATE_IDLE :
1811 PhoneConstantConversions.convertCallState(phone.getState());
1812 } finally {
1813 Binder.restoreCallingIdentity(identity);
1814 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001815 }
1816
Sanket Padawe356d7632015-06-22 14:03:32 -07001817 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001818 public int getDataState() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001819 final long identity = Binder.clearCallingIdentity();
1820 try {
1821 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1822 if (phone != null) {
1823 return PhoneConstantConversions.convertDataState(phone.getDataConnectionState());
1824 } else {
1825 return PhoneConstantConversions.convertDataState(
1826 PhoneConstants.DataState.DISCONNECTED);
1827 }
1828 } finally {
1829 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001830 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001831 }
1832
Sanket Padawe356d7632015-06-22 14:03:32 -07001833 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001834 public int getDataActivity() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001835 final long identity = Binder.clearCallingIdentity();
1836 try {
1837 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1838 if (phone != null) {
1839 return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState());
1840 } else {
1841 return TelephonyManager.DATA_ACTIVITY_NONE;
1842 }
1843 } finally {
1844 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001845 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001846 }
1847
1848 @Override
Svetoslav64fad262015-04-14 14:35:21 -07001849 public Bundle getCellLocation(String callingPackage) {
Hall Liu1aa510f2017-11-22 17:40:08 -08001850 mPhone.getContext().getSystemService(AppOpsManager.class)
1851 .checkPackage(Binder.getCallingUid(), callingPackage);
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001852 if (!LocationAccessPolicy.canAccessCellLocation(mPhone.getContext(),
Svet Ganov4af66282018-03-07 19:57:05 -08001853 callingPackage, Binder.getCallingUid(), Binder.getCallingPid(), true)) {
Svetoslav64fad262015-04-14 14:35:21 -07001854 return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001855 }
1856
Narayan Kamathf04b5a12018-01-09 11:47:15 +00001857 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001858 final long identity = Binder.clearCallingIdentity();
1859 try {
1860 if (DBG_LOC) log("getCellLocation: is active user");
1861 Bundle data = new Bundle();
1862 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1863 if (phone == null) {
1864 return null;
1865 }
1866
1867 phone.getCellLocation(workSource).fillInNotifierBundle(data);
1868 return data;
1869 } finally {
1870 Binder.restoreCallingIdentity(identity);
1871 }
Svetoslav64fad262015-04-14 14:35:21 -07001872 }
1873
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001874 @Override
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001875 public String getNetworkCountryIsoForPhone(int phoneId) {
1876 // Reporting the correct network country is ambiguous when IWLAN could conflict with
1877 // registered cell info, so return a NULL country instead.
1878 final long identity = Binder.clearCallingIdentity();
1879 try {
Malcolm Chen3732c2b2018-07-18 20:15:24 -07001880 if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
1881 // Get default phone in this case.
1882 phoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
1883 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001884 final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
Jack Yu5f7092c2018-04-13 14:05:37 -07001885 // Todo: fix this when we can get the actual cellular network info when the device
1886 // is on IWLAN.
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001887 if (TelephonyManager.NETWORK_TYPE_IWLAN
1888 == getVoiceNetworkTypeForSubscriber(subId, mApp.getPackageName())) {
1889 return "";
1890 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001891 Phone phone = PhoneFactory.getPhone(phoneId);
1892 if (phone != null) {
1893 ServiceStateTracker sst = phone.getServiceStateTracker();
1894 if (sst != null) {
1895 LocaleTracker lt = sst.getLocaleTracker();
1896 if (lt != null) {
1897 return lt.getCurrentCountry();
1898 }
1899 }
1900 }
1901 return "";
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001902 } finally {
1903 Binder.restoreCallingIdentity(identity);
1904 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001905 }
1906
1907 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001908 public void enableLocationUpdates() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001909 enableLocationUpdatesForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001910 }
1911
Sanket Padawe356d7632015-06-22 14:03:32 -07001912 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07001913 public void enableLocationUpdatesForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001914 mApp.enforceCallingOrSelfPermission(
1915 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001916
1917 final long identity = Binder.clearCallingIdentity();
1918 try {
1919 final Phone phone = getPhone(subId);
1920 if (phone != null) {
1921 phone.enableLocationUpdates();
1922 }
1923 } finally {
1924 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001925 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001926 }
1927
1928 @Override
1929 public void disableLocationUpdates() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001930 disableLocationUpdatesForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001931 }
1932
Sanket Padawe356d7632015-06-22 14:03:32 -07001933 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07001934 public void disableLocationUpdatesForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001935 mApp.enforceCallingOrSelfPermission(
1936 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001937
1938 final long identity = Binder.clearCallingIdentity();
1939 try {
1940 final Phone phone = getPhone(subId);
1941 if (phone != null) {
1942 phone.disableLocationUpdates();
1943 }
1944 } finally {
1945 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001946 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001947 }
1948
1949 @Override
1950 @SuppressWarnings("unchecked")
Nathan Haroldb4d55612018-07-20 13:13:08 -07001951 public List<NeighboringCellInfo>
1952 getNeighboringCellInfo(String callingPackage, int targetSdk) {
Nathan Harold54a07f92018-08-09 16:20:42 -07001953 if (targetSdk > android.os.Build.VERSION_CODES.P) return null;
Nathan Haroldb4d55612018-07-20 13:13:08 -07001954
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001955 if (mAppOps.noteOp(AppOpsManager.OP_NEIGHBORING_CELLS, Binder.getCallingUid(),
1956 callingPackage) != AppOpsManager.MODE_ALLOWED) {
1957 return null;
1958 }
Svetoslav64fad262015-04-14 14:35:21 -07001959
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001960 if (DBG_LOC) log("getNeighboringCellInfo: is active user");
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001961
Nathan Haroldf180aac2018-06-01 18:43:55 -07001962 List<CellInfo> info = getAllCellInfo(callingPackage);
1963 if (info == null) return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001964
Nathan Haroldf180aac2018-06-01 18:43:55 -07001965 List<NeighboringCellInfo> neighbors = new ArrayList<NeighboringCellInfo>();
1966 for (CellInfo ci : info) {
1967 if (ci instanceof CellInfoGsm) {
1968 neighbors.add(new NeighboringCellInfo((CellInfoGsm) ci));
1969 } else if (ci instanceof CellInfoWcdma) {
1970 neighbors.add(new NeighboringCellInfo((CellInfoWcdma) ci));
1971 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001972 }
Nathan Haroldf180aac2018-06-01 18:43:55 -07001973 return (neighbors.size()) > 0 ? neighbors : null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001974 }
1975
1976
1977 @Override
Svetoslav64fad262015-04-14 14:35:21 -07001978 public List<CellInfo> getAllCellInfo(String callingPackage) {
Hall Liu1aa510f2017-11-22 17:40:08 -08001979 mPhone.getContext().getSystemService(AppOpsManager.class)
1980 .checkPackage(Binder.getCallingUid(), callingPackage);
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001981 if (!LocationAccessPolicy.canAccessCellLocation(mPhone.getContext(),
Svet Ganov4af66282018-03-07 19:57:05 -08001982 callingPackage, Binder.getCallingUid(), Binder.getCallingPid(), true)) {
Svetoslav64fad262015-04-14 14:35:21 -07001983 return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001984 }
1985
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001986 if (DBG_LOC) log("getAllCellInfo: is active user");
Narayan Kamathf04b5a12018-01-09 11:47:15 +00001987 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08001988 final long identity = Binder.clearCallingIdentity();
1989 try {
1990 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
1991 for (Phone phone : PhoneFactory.getPhones()) {
1992 final List<CellInfo> info = phone.getAllCellInfo(workSource);
1993 if (info != null) cellInfos.addAll(info);
1994 }
1995 return cellInfos;
1996 } finally {
1997 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001998 }
1999 }
2000
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07002001 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002002 public void setCellInfoListRate(int rateInMillis) {
Jack Yua8d8cb82017-01-16 10:15:34 -08002003 enforceModifyPermission();
Narayan Kamathf04b5a12018-01-09 11:47:15 +00002004 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002005
2006 final long identity = Binder.clearCallingIdentity();
2007 try {
2008 mPhone.setCellInfoListRate(rateInMillis, workSource);
2009 } finally {
2010 Binder.restoreCallingIdentity(identity);
2011 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002012 }
2013
Shishir Agrawala9f32182016-04-12 12:00:16 -07002014 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002015 public String getImeiForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002016 Phone phone = PhoneFactory.getPhone(slotIndex);
2017 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002018 return null;
2019 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002020 int subId = phone.getSubId();
2021 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2022 mApp, subId, callingPackage, "getImeiForSlot")) {
2023 return null;
2024 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002025
2026 final long identity = Binder.clearCallingIdentity();
2027 try {
2028 return phone.getImei();
2029 } finally {
2030 Binder.restoreCallingIdentity(identity);
2031 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002032 }
2033
2034 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002035 public String getTypeAllocationCodeForSlot(int slotIndex) {
2036 Phone phone = PhoneFactory.getPhone(slotIndex);
2037 String tac = null;
2038 if (phone != null) {
2039 String imei = phone.getImei();
2040 tac = imei == null ? null : imei.substring(0, TYPE_ALLOCATION_CODE_LENGTH);
2041 }
2042 return tac;
2043 }
2044
2045 @Override
Jack Yu2af8d712017-03-15 17:14:14 -07002046 public String getMeidForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002047 Phone phone = PhoneFactory.getPhone(slotIndex);
2048 if (phone == null) {
Jack Yu2af8d712017-03-15 17:14:14 -07002049 return null;
2050 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002051 int subId = phone.getSubId();
2052 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2053 mApp, subId, callingPackage, "getMeidForSlot")) {
2054 return null;
2055 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002056
2057 final long identity = Binder.clearCallingIdentity();
2058 try {
2059 return phone.getMeid();
2060 } finally {
2061 Binder.restoreCallingIdentity(identity);
2062 }
Jack Yu2af8d712017-03-15 17:14:14 -07002063 }
2064
2065 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002066 public String getManufacturerCodeForSlot(int slotIndex) {
2067 Phone phone = PhoneFactory.getPhone(slotIndex);
2068 String manufacturerCode = null;
2069 if (phone != null) {
2070 String meid = phone.getMeid();
2071 manufacturerCode = meid == null ? null : meid.substring(0, MANUFACTURER_CODE_LENGTH);
2072 }
2073 return manufacturerCode;
2074 }
2075
2076 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002077 public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002078 Phone phone = PhoneFactory.getPhone(slotIndex);
2079 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002080 return null;
2081 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002082 int subId = phone.getSubId();
2083 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2084 mApp, subId, callingPackage, "getDeviceSoftwareVersionForSlot")) {
2085 return null;
2086 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002087
2088 final long identity = Binder.clearCallingIdentity();
2089 try {
2090 return phone.getDeviceSvn();
2091 } finally {
2092 Binder.restoreCallingIdentity(identity);
2093 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002094 }
2095
fionaxu43304da2017-11-27 22:51:16 -08002096 @Override
2097 public int getSubscriptionCarrierId(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002098 final long identity = Binder.clearCallingIdentity();
2099 try {
2100 final Phone phone = getPhone(subId);
2101 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getCarrierId();
2102 } finally {
2103 Binder.restoreCallingIdentity(identity);
2104 }
fionaxu43304da2017-11-27 22:51:16 -08002105 }
2106
2107 @Override
2108 public String getSubscriptionCarrierName(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002109 final long identity = Binder.clearCallingIdentity();
2110 try {
2111 final Phone phone = getPhone(subId);
2112 return phone == null ? null : phone.getCarrierName();
2113 } finally {
2114 Binder.restoreCallingIdentity(identity);
2115 }
fionaxu43304da2017-11-27 22:51:16 -08002116 }
2117
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002118 //
2119 // Internal helper methods.
2120 //
2121
Sanket Padaweee13a9b2016-03-08 17:30:28 -08002122 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002123 * Make sure the caller has the MODIFY_PHONE_STATE permission.
2124 *
2125 * @throws SecurityException if the caller does not have the required permission
2126 */
2127 private void enforceModifyPermission() {
2128 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
2129 }
2130
2131 /**
2132 * Make sure the caller has the CALL_PHONE permission.
2133 *
2134 * @throws SecurityException if the caller does not have the required permission
2135 */
2136 private void enforceCallPermission() {
2137 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
2138 }
2139
Stuart Scott8eef64f2015-04-08 15:13:54 -07002140 private void enforceConnectivityInternalPermission() {
2141 mApp.enforceCallingOrSelfPermission(
2142 android.Manifest.permission.CONNECTIVITY_INTERNAL,
2143 "ConnectivityService");
2144 }
2145
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002146 private String createTelUrl(String number) {
2147 if (TextUtils.isEmpty(number)) {
2148 return null;
2149 }
2150
Jake Hambye994d462014-02-03 13:10:13 -08002151 return "tel:" + number;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002152 }
2153
Ihab Awadf9e92732013-12-05 18:02:52 -08002154 private static void log(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002155 Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg);
2156 }
2157
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002158 private static void logv(String msg) {
2159 Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg);
2160 }
2161
Ihab Awadf9e92732013-12-05 18:02:52 -08002162 private static void loge(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002163 Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg);
2164 }
2165
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002166 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002167 public int getActivePhoneType() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07002168 return getActivePhoneTypeForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002169 }
2170
Sanket Padawe356d7632015-06-22 14:03:32 -07002171 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002172 public int getActivePhoneTypeForSlot(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002173 final long identity = Binder.clearCallingIdentity();
2174 try {
2175 final Phone phone = PhoneFactory.getPhone(slotIndex);
2176 if (phone == null) {
2177 return PhoneConstants.PHONE_TYPE_NONE;
2178 } else {
2179 return phone.getPhoneType();
2180 }
2181 } finally {
2182 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002183 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002184 }
2185
2186 /**
2187 * Returns the CDMA ERI icon index to display
2188 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002189 @Override
2190 public int getCdmaEriIconIndex(String callingPackage) {
2191 return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002192 }
2193
Sanket Padawe356d7632015-06-22 14:03:32 -07002194 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002195 public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002196 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002197 mApp, subId, callingPackage, "getCdmaEriIconIndexForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002198 return -1;
2199 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002200
2201 final long identity = Binder.clearCallingIdentity();
2202 try {
2203 final Phone phone = getPhone(subId);
2204 if (phone != null) {
2205 return phone.getCdmaEriIconIndex();
2206 } else {
2207 return -1;
2208 }
2209 } finally {
2210 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002211 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002212 }
2213
2214 /**
2215 * Returns the CDMA ERI icon mode,
2216 * 0 - ON
2217 * 1 - FLASHING
2218 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002219 @Override
2220 public int getCdmaEriIconMode(String callingPackage) {
2221 return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002222 }
2223
Sanket Padawe356d7632015-06-22 14:03:32 -07002224 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002225 public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002226 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002227 mApp, subId, callingPackage, "getCdmaEriIconModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002228 return -1;
2229 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002230
2231 final long identity = Binder.clearCallingIdentity();
2232 try {
2233 final Phone phone = getPhone(subId);
2234 if (phone != null) {
2235 return phone.getCdmaEriIconMode();
2236 } else {
2237 return -1;
2238 }
2239 } finally {
2240 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002241 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002242 }
2243
2244 /**
2245 * Returns the CDMA ERI text,
2246 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002247 @Override
2248 public String getCdmaEriText(String callingPackage) {
2249 return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002250 }
2251
Sanket Padawe356d7632015-06-22 14:03:32 -07002252 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002253 public String getCdmaEriTextForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002254 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002255 mApp, subId, callingPackage, "getCdmaEriIconTextForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002256 return null;
2257 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002258
2259 final long identity = Binder.clearCallingIdentity();
2260 try {
2261 final Phone phone = getPhone(subId);
2262 if (phone != null) {
2263 return phone.getCdmaEriText();
2264 } else {
2265 return null;
2266 }
2267 } finally {
2268 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002269 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002270 }
2271
2272 /**
Junda Liuca05d5d2014-08-14 22:36:34 -07002273 * Returns the CDMA MDN.
2274 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002275 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002276 public String getCdmaMdn(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002277 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2278 mApp, subId, "getCdmaMdn");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002279
2280 final long identity = Binder.clearCallingIdentity();
2281 try {
2282 final Phone phone = getPhone(subId);
2283 if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA && phone != null) {
2284 return phone.getLine1Number();
2285 } else {
2286 return null;
2287 }
2288 } finally {
2289 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07002290 }
2291 }
2292
2293 /**
2294 * Returns the CDMA MIN.
2295 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002296 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002297 public String getCdmaMin(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002298 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2299 mApp, subId, "getCdmaMin");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002300
2301 final long identity = Binder.clearCallingIdentity();
2302 try {
2303 final Phone phone = getPhone(subId);
2304 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
2305 return phone.getCdmaMin();
2306 } else {
2307 return null;
2308 }
2309 } finally {
2310 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07002311 }
2312 }
2313
2314 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002315 * Returns true if CDMA provisioning needs to run.
2316 */
2317 public boolean needsOtaServiceProvisioning() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002318 final long identity = Binder.clearCallingIdentity();
2319 try {
2320 return mPhone.needsOtaServiceProvisioning();
2321 } finally {
2322 Binder.restoreCallingIdentity(identity);
2323 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002324 }
2325
2326 /**
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002327 * Sets the voice mail number of a given subId.
2328 */
2329 @Override
2330 public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002331 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setVoiceMailNumber");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002332
2333 final long identity = Binder.clearCallingIdentity();
2334 try {
2335 Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
2336 new Pair<String, String>(alphaTag, number), new Integer(subId));
2337 return success;
2338 } finally {
2339 Binder.restoreCallingIdentity(identity);
2340 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002341 }
2342
Ta-wei Yen87c49842016-05-13 21:19:52 -07002343 @Override
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002344 public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
2345 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2346 String systemDialer = TelecomManager.from(mPhone.getContext()).getSystemDialerPackage();
2347 if (!TextUtils.equals(callingPackage, systemDialer)) {
2348 throw new SecurityException("caller must be system dialer");
2349 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002350
2351 final long identity = Binder.clearCallingIdentity();
2352 try {
2353 PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
2354 if (phoneAccountHandle == null) {
2355 return null;
2356 }
2357 return VisualVoicemailSettingsUtil.dump(mPhone.getContext(), phoneAccountHandle);
2358 } finally {
2359 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002360 }
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002361 }
2362
2363 @Override
Ta-wei Yen409ac562017-03-06 16:00:44 -08002364 public String getVisualVoicemailPackageName(String callingPackage, int subId) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08002365 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jeff Davidson7e17e312018-02-13 18:17:36 -08002366 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002367 mApp, subId, callingPackage, "getVisualVoicemailPackageName")) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08002368 return null;
2369 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002370
Jeff Davidsona8e4e242018-03-15 17:16:18 -07002371 final long identity = Binder.clearCallingIdentity();
2372 try {
2373 return RemoteVvmTaskManager
2374 .getRemotePackage(mPhone.getContext(), subId).getPackageName();
2375 } finally {
2376 Binder.restoreCallingIdentity(identity);
2377 }
Ta-wei Yendca928f2017-01-10 16:17:08 -08002378 }
2379
2380 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002381 public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
2382 VisualVoicemailSmsFilterSettings settings) {
2383 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002384
2385 final long identity = Binder.clearCallingIdentity();
2386 try {
2387 VisualVoicemailSmsFilterConfig.enableVisualVoicemailSmsFilter(
2388 mPhone.getContext(), callingPackage, subId, settings);
2389 } finally {
2390 Binder.restoreCallingIdentity(identity);
2391 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002392 }
2393
2394 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002395 public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
2396 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002397
2398 final long identity = Binder.clearCallingIdentity();
2399 try {
2400 VisualVoicemailSmsFilterConfig.disableVisualVoicemailSmsFilter(
2401 mPhone.getContext(), callingPackage, subId);
2402 } finally {
2403 Binder.restoreCallingIdentity(identity);
2404 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002405 }
2406
2407 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002408 public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
2409 String callingPackage, int subId) {
2410 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002411
2412 final long identity = Binder.clearCallingIdentity();
2413 try {
2414 return VisualVoicemailSmsFilterConfig.getVisualVoicemailSmsFilterSettings(
2415 mPhone.getContext(), callingPackage, subId);
2416 } finally {
2417 Binder.restoreCallingIdentity(identity);
2418 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002419 }
2420
2421 @Override
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002422 public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
Ta-wei Yenb6929602016-05-24 15:48:27 -07002423 enforceReadPrivilegedPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002424
2425 final long identity = Binder.clearCallingIdentity();
2426 try {
2427 return VisualVoicemailSmsFilterConfig.getActiveVisualVoicemailSmsFilterSettings(
2428 mPhone.getContext(), subId);
2429 } finally {
2430 Binder.restoreCallingIdentity(identity);
2431 }
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002432 }
2433
2434 @Override
2435 public void sendVisualVoicemailSmsForSubscriber(String callingPackage, int subId,
2436 String number, int port, String text, PendingIntent sentIntent) {
2437 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Ta-wei Yen527a9c02017-01-06 15:29:25 -08002438 enforceVisualVoicemailPackage(callingPackage, subId);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002439 enforceSendSmsPermission();
2440 // Make the calls as the phone process.
2441 final long identity = Binder.clearCallingIdentity();
2442 try {
2443 SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(subId);
2444 if (port == 0) {
2445 smsManager.sendTextMessageWithSelfPermissions(number, null, text,
2446 sentIntent, null, false);
2447 } else {
2448 byte[] data = text.getBytes(StandardCharsets.UTF_8);
2449 smsManager.sendDataMessageWithSelfPermissions(number, null,
2450 (short) port, data, sentIntent, null);
2451 }
2452 } finally {
2453 Binder.restoreCallingIdentity(identity);
2454 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002455 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002456 /**
fionaxu0152e512016-11-14 13:36:14 -08002457 * Sets the voice activation state of a given subId.
2458 */
2459 @Override
2460 public void setVoiceActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002461 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2462 mApp, subId, "setVoiceActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002463
2464 final long identity = Binder.clearCallingIdentity();
2465 try {
2466 final Phone phone = getPhone(subId);
2467 if (phone != null) {
2468 phone.setVoiceActivationState(activationState);
2469 } else {
2470 loge("setVoiceActivationState fails with invalid subId: " + subId);
2471 }
2472 } finally {
2473 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002474 }
2475 }
2476
2477 /**
2478 * Sets the data activation state of a given subId.
2479 */
2480 @Override
2481 public void setDataActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002482 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2483 mApp, subId, "setDataActivationState");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002484
2485 final long identity = Binder.clearCallingIdentity();
2486 try {
2487 final Phone phone = getPhone(subId);
2488 if (phone != null) {
2489 phone.setDataActivationState(activationState);
2490 } else {
2491 loge("setVoiceActivationState fails with invalid subId: " + subId);
2492 }
2493 } finally {
2494 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002495 }
2496 }
2497
2498 /**
2499 * Returns the voice activation state of a given subId.
2500 */
2501 @Override
2502 public int getVoiceActivationState(int subId, String callingPackage) {
goneil799f6e92017-12-13 12:57:23 -08002503 enforceReadPrivilegedPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002504
fionaxu0152e512016-11-14 13:36:14 -08002505 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002506 final long identity = Binder.clearCallingIdentity();
2507 try {
2508 if (phone != null) {
2509 return phone.getVoiceActivationState();
2510 } else {
2511 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2512 }
2513 } finally {
2514 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002515 }
2516 }
2517
2518 /**
2519 * Returns the data activation state of a given subId.
2520 */
2521 @Override
2522 public int getDataActivationState(int subId, String callingPackage) {
goneil799f6e92017-12-13 12:57:23 -08002523 enforceReadPrivilegedPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002524
fionaxu0152e512016-11-14 13:36:14 -08002525 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002526 final long identity = Binder.clearCallingIdentity();
2527 try {
2528 if (phone != null) {
2529 return phone.getDataActivationState();
2530 } else {
2531 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2532 }
2533 } finally {
2534 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002535 }
2536 }
2537
2538 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002539 * Returns the unread count of voicemails
2540 */
2541 public int getVoiceMessageCount() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002542 return getVoiceMessageCountForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002543 }
2544
2545 /**
2546 * Returns the unread count of voicemails for a subId
2547 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002548 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002549 public int getVoiceMessageCountForSubscriber( int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002550 final long identity = Binder.clearCallingIdentity();
2551 try {
2552 final Phone phone = getPhone(subId);
2553 if (phone != null) {
2554 return phone.getVoiceMessageCount();
2555 } else {
2556 return 0;
2557 }
2558 } finally {
2559 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002560 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002561 }
2562
2563 /**
pkanwar8a4dcfb2017-01-19 13:43:16 -08002564 * returns true, if the device is in a state where both voice and data
2565 * are supported simultaneously. This can change based on location or network condition.
2566 */
2567 @Override
2568 public boolean isConcurrentVoiceAndDataAllowed(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002569 final long identity = Binder.clearCallingIdentity();
2570 try {
2571 final Phone phone = getPhone(subId);
2572 return (phone == null ? false : phone.isConcurrentVoiceAndDataAllowed());
2573 } finally {
2574 Binder.restoreCallingIdentity(identity);
2575 }
pkanwar8a4dcfb2017-01-19 13:43:16 -08002576 }
2577
2578 /**
fionaxu235cc5e2017-03-06 22:25:57 -08002579 * Send the dialer code if called from the current default dialer or the caller has
2580 * carrier privilege.
2581 * @param inputCode The dialer code to send
2582 */
2583 @Override
2584 public void sendDialerSpecialCode(String callingPackage, String inputCode) {
2585 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2586 String defaultDialer = TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage();
2587 if (!TextUtils.equals(callingPackage, defaultDialer)) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002588 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
2589 getDefaultSubscription(), "sendDialerSpecialCode");
fionaxu235cc5e2017-03-06 22:25:57 -08002590 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002591
2592 final long identity = Binder.clearCallingIdentity();
2593 try {
2594 mPhone.sendDialerSpecialCode(inputCode);
2595 } finally {
2596 Binder.restoreCallingIdentity(identity);
2597 }
fionaxu235cc5e2017-03-06 22:25:57 -08002598 }
2599
2600 /**
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002601 * Returns the data network type.
2602 * Legacy call, permission-free.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002603 *
2604 * @Deprecated to be removed Q3 2013 use {@link #getDataNetworkType}.
2605 */
2606 @Override
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002607 public int getNetworkType() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002608 final long identity = Binder.clearCallingIdentity();
2609 try {
2610 final Phone phone = getPhone(getDefaultSubscription());
2611 if (phone != null) {
2612 return phone.getServiceState().getDataNetworkType();
2613 } else {
2614 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2615 }
2616 } finally {
2617 Binder.restoreCallingIdentity(identity);
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002618 }
Wink Saville36469e72014-06-11 15:17:00 -07002619 }
2620
2621 /**
2622 * Returns the network type for a subId
2623 */
2624 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002625 public int getNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002626 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002627 mApp, subId, callingPackage, "getNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002628 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2629 }
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002630
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002631 final long identity = Binder.clearCallingIdentity();
2632 try {
2633 final Phone phone = getPhone(subId);
2634 if (phone != null) {
2635 return phone.getServiceState().getDataNetworkType();
2636 } else {
2637 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2638 }
2639 } finally {
2640 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002641 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002642 }
2643
2644 /**
2645 * Returns the data network type
2646 */
2647 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002648 public int getDataNetworkType(String callingPackage) {
2649 return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002650 }
2651
2652 /**
2653 * Returns the data network type for a subId
2654 */
2655 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002656 public int getDataNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002657 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002658 mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002659 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2660 }
2661
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002662 final long identity = Binder.clearCallingIdentity();
2663 try {
2664 final Phone phone = getPhone(subId);
2665 if (phone != null) {
2666 return phone.getServiceState().getDataNetworkType();
2667 } else {
2668 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2669 }
2670 } finally {
2671 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002672 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002673 }
2674
2675 /**
Wink Saville36469e72014-06-11 15:17:00 -07002676 * Returns the Voice network type for a subId
2677 */
2678 @Override
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002679 public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002680 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002681 mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002682 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2683 }
2684
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002685 final long identity = Binder.clearCallingIdentity();
2686 try {
2687 final Phone phone = getPhone(subId);
2688 if (phone != null) {
2689 return phone.getServiceState().getVoiceNetworkType();
2690 } else {
2691 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2692 }
2693 } finally {
2694 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002695 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002696 }
2697
2698 /**
2699 * @return true if a ICC card is present
2700 */
2701 public boolean hasIccCard() {
Wink Saville36469e72014-06-11 15:17:00 -07002702 // FIXME Make changes to pass defaultSimId of type int
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002703 return hasIccCardUsingSlotIndex(mSubscriptionController.getSlotIndex(
2704 getDefaultSubscription()));
Wink Saville36469e72014-06-11 15:17:00 -07002705 }
2706
2707 /**
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002708 * @return true if a ICC card is present for a slotIndex
Wink Saville36469e72014-06-11 15:17:00 -07002709 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002710 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002711 public boolean hasIccCardUsingSlotIndex(int slotIndex) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002712 final long identity = Binder.clearCallingIdentity();
2713 try {
2714 final Phone phone = PhoneFactory.getPhone(slotIndex);
2715 if (phone != null) {
2716 return phone.getIccCard().hasIccCard();
2717 } else {
2718 return false;
2719 }
2720 } finally {
2721 Binder.restoreCallingIdentity(identity);
Amit Mahajana6fc2a82015-01-06 11:53:51 -08002722 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002723 }
2724
2725 /**
2726 * Return if the current radio is LTE on CDMA. This
2727 * is a tri-state return value as for a period of time
2728 * the mode may be unknown.
2729 *
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002730 * @param callingPackage the name of the package making the call.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002731 * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
Jake Hambye994d462014-02-03 13:10:13 -08002732 * or {@link Phone#LTE_ON_CDMA_TRUE}
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002733 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002734 @Override
2735 public int getLteOnCdmaMode(String callingPackage) {
2736 return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002737 }
2738
Sanket Padawe356d7632015-06-22 14:03:32 -07002739 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002740 public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002741 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002742 mApp, subId, callingPackage, "getLteOnCdmaModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002743 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
2744 }
2745
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002746 final long identity = Binder.clearCallingIdentity();
2747 try {
2748 final Phone phone = getPhone(subId);
2749 if (phone == null) {
2750 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
2751 } else {
2752 return phone.getLteOnCdmaMode();
2753 }
2754 } finally {
2755 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002756 }
Wink Saville36469e72014-06-11 15:17:00 -07002757 }
2758
2759 public void setPhone(Phone phone) {
2760 mPhone = phone;
2761 }
2762
2763 /**
2764 * {@hide}
2765 * Returns Default subId, 0 in the case of single standby.
2766 */
Wink Savilleb564aae2014-10-23 10:18:09 -07002767 private int getDefaultSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08002768 return mSubscriptionController.getDefaultSubId();
Wink Saville36469e72014-06-11 15:17:00 -07002769 }
2770
Shishir Agrawala9f32182016-04-12 12:00:16 -07002771 private int getSlotForDefaultSubscription() {
2772 return mSubscriptionController.getPhoneId(getDefaultSubscription());
2773 }
2774
Wink Savilleb564aae2014-10-23 10:18:09 -07002775 private int getPreferredVoiceSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08002776 return mSubscriptionController.getDefaultVoiceSubId();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002777 }
Ihab Awadf2177b72013-11-25 13:33:23 -08002778
2779 /**
2780 * @see android.telephony.TelephonyManager.WifiCallingChoices
2781 */
2782 public int getWhenToMakeWifiCalls() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002783 final long identity = Binder.clearCallingIdentity();
2784 try {
2785 return Settings.System.getInt(mPhone.getContext().getContentResolver(),
2786 Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
2787 getWhenToMakeWifiCallsDefaultPreference());
2788 } finally {
2789 Binder.restoreCallingIdentity(identity);
2790 }
Ihab Awadf2177b72013-11-25 13:33:23 -08002791 }
2792
2793 /**
2794 * @see android.telephony.TelephonyManager.WifiCallingChoices
2795 */
2796 public void setWhenToMakeWifiCalls(int preference) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002797 final long identity = Binder.clearCallingIdentity();
2798 try {
2799 if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference);
2800 Settings.System.putInt(mPhone.getContext().getContentResolver(),
2801 Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference);
2802 } finally {
2803 Binder.restoreCallingIdentity(identity);
2804 }
Ihab Awadf9e92732013-12-05 18:02:52 -08002805 }
2806
Sailesh Nepald1e68152013-12-12 19:08:02 -08002807 private static int getWhenToMakeWifiCallsDefaultPreference() {
Santos Cordonda120f42014-08-06 04:44:34 -07002808 // TODO: Use a build property to choose this value.
Evan Charlton9829e882013-12-19 15:30:38 -08002809 return TelephonyManager.WifiCallingChoices.ALWAYS_USE;
Ihab Awadf2177b72013-11-25 13:33:23 -08002810 }
Shishir Agrawal69f68122013-12-16 17:25:49 -08002811
Shishir Agrawal566b7612013-10-28 14:41:00 -07002812 @Override
Derek Tan740e1672017-06-27 14:56:27 -07002813 public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
2814 int subId, String callingPackage, String aid, int p2) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002815 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2816 mApp, subId, "iccOpenLogicalChannel");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002817 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Shishir Agrawal566b7612013-10-28 14:41:00 -07002818
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002819 final long identity = Binder.clearCallingIdentity();
2820 try {
2821 if (TextUtils.equals(ISDR_AID, aid)) {
2822 // Only allows LPA to open logical channel to ISD-R.
2823 ComponentInfo bestComponent =
2824 EuiccConnector.findBestComponent(mPhone.getContext().getPackageManager());
2825 if (bestComponent == null
2826 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
2827 loge("The calling package is not allowed to access ISD-R.");
2828 throw new SecurityException(
2829 "The calling package is not allowed to access ISD-R.");
2830 }
Derek Tan740e1672017-06-27 14:56:27 -07002831 }
Derek Tan740e1672017-06-27 14:56:27 -07002832
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002833 if (DBG) {
2834 log("iccOpenLogicalChannel: subId=" + subId + " aid=" + aid + " p2=" + p2);
2835 }
2836 IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse) sendRequest(
2837 CMD_OPEN_CHANNEL, new Pair<String, Integer>(aid, p2), subId);
2838 if (DBG) log("iccOpenLogicalChannel: " + response);
2839 return response;
2840 } finally {
2841 Binder.restoreCallingIdentity(identity);
2842 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07002843 }
2844
2845 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08002846 public boolean iccCloseLogicalChannel(int subId, int channel) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002847 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2848 mApp, subId, "iccCloseLogicalChannel");
Shishir Agrawal566b7612013-10-28 14:41:00 -07002849
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002850 final long identity = Binder.clearCallingIdentity();
2851 try {
2852 if (DBG) log("iccCloseLogicalChannel: subId=" + subId + " chnl=" + channel);
2853 if (channel < 0) {
2854 return false;
2855 }
2856 Boolean success = (Boolean) sendRequest(CMD_CLOSE_CHANNEL, channel, subId);
2857 if (DBG) log("iccCloseLogicalChannel: " + success);
2858 return success;
2859 } finally {
2860 Binder.restoreCallingIdentity(identity);
Shishir Agrawal566b7612013-10-28 14:41:00 -07002861 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07002862 }
2863
2864 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08002865 public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
Shishir Agrawal566b7612013-10-28 14:41:00 -07002866 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002867 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2868 mApp, subId, "iccTransmitApduLogicalChannel");
Shishir Agrawal566b7612013-10-28 14:41:00 -07002869
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002870 final long identity = Binder.clearCallingIdentity();
2871 try {
2872 if (DBG) {
2873 log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel
2874 + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
2875 + p3 + " data=" + data);
2876 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07002877
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002878 if (channel < 0) {
2879 return "";
2880 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07002881
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002882 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL,
2883 new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), subId);
2884 if (DBG) log("iccTransmitApduLogicalChannel: " + response);
Shishir Agrawal566b7612013-10-28 14:41:00 -07002885
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002886 // Append the returned status code to the end of the response payload.
2887 String s = Integer.toHexString(
2888 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
2889 if (response.payload != null) {
2890 s = IccUtils.bytesToHexString(response.payload) + s;
2891 }
2892 return s;
2893 } finally {
2894 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07002895 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07002896 }
Jake Hambye994d462014-02-03 13:10:13 -08002897
Evan Charltonc66da362014-05-16 14:06:40 -07002898 @Override
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08002899 public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
2900 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002901 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2902 mApp, subId, "iccTransmitApduBasicChannel");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002903 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002904
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002905 final long identity = Binder.clearCallingIdentity();
2906 try {
2907 if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
2908 && TextUtils.equals(ISDR_AID, data)) {
2909 // Only allows LPA to select ISD-R.
2910 ComponentInfo bestComponent =
2911 EuiccConnector.findBestComponent(mPhone.getContext().getPackageManager());
2912 if (bestComponent == null
2913 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
2914 loge("The calling package is not allowed to select ISD-R.");
2915 throw new SecurityException(
2916 "The calling package is not allowed to select ISD-R.");
2917 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08002918 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08002919
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002920 if (DBG) {
2921 log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd="
2922 + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
2923 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002924
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002925 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL,
2926 new IccAPDUArgument(0, cla, command, p1, p2, p3, data), subId);
2927 if (DBG) log("iccTransmitApduBasicChannel: " + response);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002928
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002929 // Append the returned status code to the end of the response payload.
2930 String s = Integer.toHexString(
2931 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
2932 if (response.payload != null) {
2933 s = IccUtils.bytesToHexString(response.payload) + s;
2934 }
2935 return s;
2936 } finally {
2937 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07002938 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002939 }
2940
2941 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08002942 public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002943 String filePath) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002944 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2945 mApp, subId, "iccExchangeSimIO");
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002946
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002947 final long identity = Binder.clearCallingIdentity();
2948 try {
2949 if (DBG) {
2950 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " "
2951 + p1 + " " + p2 + " " + p3 + ":" + filePath);
2952 }
2953
2954 IccIoResult response =
2955 (IccIoResult) sendRequest(CMD_EXCHANGE_SIM_IO,
2956 new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath),
2957 subId);
2958
2959 if (DBG) {
2960 log("Exchange SIM_IO [R]" + response);
2961 }
2962
2963 byte[] result = null;
2964 int length = 2;
2965 if (response.payload != null) {
2966 length = 2 + response.payload.length;
2967 result = new byte[length];
2968 System.arraycopy(response.payload, 0, result, 0, response.payload.length);
2969 } else {
2970 result = new byte[length];
2971 }
2972
2973 result[length - 1] = (byte) response.sw2;
2974 result[length - 2] = (byte) response.sw1;
2975 return result;
2976 } finally {
2977 Binder.restoreCallingIdentity(identity);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002978 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002979 }
2980
Nathan Haroldb3014052017-01-25 15:57:32 -08002981 /**
2982 * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
2983 * on a particular subscription
2984 */
sqianb6e41952018-03-12 14:54:01 -07002985 public String[] getForbiddenPlmns(int subId, int appType, String callingPackage) {
2986 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2987 mApp, subId, callingPackage, "getForbiddenPlmns")) {
2988 return null;
2989 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08002990
2991 final long identity = Binder.clearCallingIdentity();
2992 try {
2993 if (appType != TelephonyManager.APPTYPE_USIM
2994 && appType != TelephonyManager.APPTYPE_SIM) {
2995 loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
2996 return null;
2997 }
2998 Object response = sendRequest(
2999 CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
3000 if (response instanceof String[]) {
3001 return (String[]) response;
3002 }
3003 // Response is an Exception of some kind,
3004 // which is signalled to the user as a NULL retval
Nathan Haroldb3014052017-01-25 15:57:32 -08003005 return null;
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003006 } finally {
3007 Binder.restoreCallingIdentity(identity);
Nathan Haroldb3014052017-01-25 15:57:32 -08003008 }
Nathan Haroldb3014052017-01-25 15:57:32 -08003009 }
3010
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003011 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003012 public String sendEnvelopeWithStatus(int subId, String content) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003013 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3014 mApp, subId, "sendEnvelopeWithStatus");
Evan Charltonc66da362014-05-16 14:06:40 -07003015
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003016 final long identity = Binder.clearCallingIdentity();
3017 try {
3018 IccIoResult response = (IccIoResult) sendRequest(CMD_SEND_ENVELOPE, content, subId);
3019 if (response.payload == null) {
3020 return "";
3021 }
Evan Charltonc66da362014-05-16 14:06:40 -07003022
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003023 // Append the returned status code to the end of the response payload.
3024 String s = Integer.toHexString(
3025 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
3026 s = IccUtils.bytesToHexString(response.payload) + s;
3027 return s;
3028 } finally {
3029 Binder.restoreCallingIdentity(identity);
3030 }
Evan Charltonc66da362014-05-16 14:06:40 -07003031 }
3032
Jake Hambye994d462014-02-03 13:10:13 -08003033 /**
3034 * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
3035 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
3036 *
3037 * @param itemID the ID of the item to read
3038 * @return the NV item as a String, or null on error.
3039 */
3040 @Override
3041 public String nvReadItem(int itemID) {
vagdeviaf9a5b92018-08-15 16:01:53 -07003042 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08003043 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3044 mApp, getDefaultSubscription(), "nvReadItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003045
3046 final long identity = Binder.clearCallingIdentity();
3047 try {
3048 if (DBG) log("nvReadItem: item " + itemID);
vagdeviaf9a5b92018-08-15 16:01:53 -07003049 String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003050 if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
3051 return value;
3052 } finally {
3053 Binder.restoreCallingIdentity(identity);
3054 }
Jake Hambye994d462014-02-03 13:10:13 -08003055 }
3056
3057 /**
3058 * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
3059 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
3060 *
3061 * @param itemID the ID of the item to read
3062 * @param itemValue the value to write, as a String
3063 * @return true on success; false on any failure
3064 */
3065 @Override
3066 public boolean nvWriteItem(int itemID, String itemValue) {
vagdeviaf9a5b92018-08-15 16:01:53 -07003067 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08003068 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3069 mApp, getDefaultSubscription(), "nvWriteItem");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003070
3071 final long identity = Binder.clearCallingIdentity();
3072 try {
3073 if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
3074 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
vagdeviaf9a5b92018-08-15 16:01:53 -07003075 new Pair<Integer, String>(itemID, itemValue), workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003076 if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
3077 return success;
3078 } finally {
3079 Binder.restoreCallingIdentity(identity);
3080 }
Jake Hambye994d462014-02-03 13:10:13 -08003081 }
3082
3083 /**
3084 * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
3085 * Used for device configuration by some CDMA operators.
3086 *
3087 * @param preferredRoamingList byte array containing the new PRL
3088 * @return true on success; false on any failure
3089 */
3090 @Override
3091 public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003092 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3093 mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003094
3095 final long identity = Binder.clearCallingIdentity();
3096 try {
3097 if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
3098 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
3099 if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
3100 return success;
3101 } finally {
3102 Binder.restoreCallingIdentity(identity);
3103 }
Jake Hambye994d462014-02-03 13:10:13 -08003104 }
3105
3106 /**
3107 * Perform the specified type of NV config reset.
3108 * Used for device configuration by some CDMA operators.
3109 *
3110 * @param resetType the type of reset to perform (1 == factory reset; 2 == NV-only reset)
3111 * @return true on success; false on any failure
3112 */
3113 @Override
3114 public boolean nvResetConfig(int resetType) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003115 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3116 mApp, getDefaultSubscription(), "nvResetConfig");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003117
3118 final long identity = Binder.clearCallingIdentity();
3119 try {
3120 if (DBG) log("nvResetConfig: type " + resetType);
3121 Boolean success = (Boolean) sendRequest(CMD_NV_RESET_CONFIG, resetType);
3122 if (DBG) log("nvResetConfig: type " + resetType + ' ' + (success ? "ok" : "fail"));
3123 return success;
3124 } finally {
3125 Binder.restoreCallingIdentity(identity);
3126 }
Jake Hambye994d462014-02-03 13:10:13 -08003127 }
Jake Hamby7c27be32014-03-03 13:25:59 -08003128
Svet Ganovb320e182015-04-16 12:30:10 -07003129 public String[] getPcscfAddress(String apnType, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003130 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003131 mApp, mPhone.getSubId(), callingPackage, "getPcscfAddress")) {
Svet Ganovb320e182015-04-16 12:30:10 -07003132 return new String[0];
3133 }
3134
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003135 final long identity = Binder.clearCallingIdentity();
3136 try {
3137 return mPhone.getPcscfAddress(apnType);
3138 } finally {
3139 Binder.restoreCallingIdentity(identity);
3140 }
Wink Saville36469e72014-06-11 15:17:00 -07003141 }
3142
Brad Ebinger51f743a2017-01-23 13:50:20 -08003143 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003144 * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
3145 * status updates, if not already enabled.
Brad Ebinger51f743a2017-01-23 13:50:20 -08003146 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003147 public void enableIms(int slotId) {
Brad Ebinger51f743a2017-01-23 13:50:20 -08003148 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003149
3150 final long identity = Binder.clearCallingIdentity();
3151 try {
3152 PhoneFactory.getImsResolver().enableIms(slotId);
3153 } finally {
3154 Binder.restoreCallingIdentity(identity);
3155 }
Brad Ebinger34bef922017-11-09 10:27:08 -08003156 }
3157
3158 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003159 * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
3160 * status updates to disabled.
Brad Ebinger34bef922017-11-09 10:27:08 -08003161 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003162 public void disableIms(int slotId) {
3163 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003164
3165 final long identity = Binder.clearCallingIdentity();
3166 try {
3167 PhoneFactory.getImsResolver().disableIms(slotId);
3168 } finally {
3169 Binder.restoreCallingIdentity(identity);
3170 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003171 }
3172
3173 /**
3174 * Returns the {@link IImsMmTelFeature} that corresponds to the given slot Id for the MMTel
3175 * feature or {@link null} if the service is not available. If the feature is available, the
3176 * {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates.
3177 */
3178 public IImsMmTelFeature getMmTelFeatureAndListen(int slotId,
Brad Ebinger34bef922017-11-09 10:27:08 -08003179 IImsServiceFeatureCallback callback) {
3180 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003181
3182 final long identity = Binder.clearCallingIdentity();
3183 try {
3184 return PhoneFactory.getImsResolver().getMmTelFeatureAndListen(slotId, callback);
3185 } finally {
3186 Binder.restoreCallingIdentity(identity);
3187 }
Brad Ebinger34bef922017-11-09 10:27:08 -08003188 }
3189
3190 /**
3191 * Returns the {@link IImsRcsFeature} that corresponds to the given slot Id for the RCS
3192 * feature during emergency calling or {@link null} if the service is not available. If the
3193 * feature is available, the {@link IImsServiceFeatureCallback} callback is registered as a
3194 * listener for feature updates.
3195 */
3196 public IImsRcsFeature getRcsFeatureAndListen(int slotId, IImsServiceFeatureCallback callback) {
3197 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003198
3199 final long identity = Binder.clearCallingIdentity();
3200 try {
3201 return PhoneFactory.getImsResolver().getRcsFeatureAndListen(slotId, callback);
3202 } finally {
3203 Binder.restoreCallingIdentity(identity);
3204 }
Brad Ebinger51f743a2017-01-23 13:50:20 -08003205 }
3206
Brad Ebinger5f64b052017-12-14 14:26:15 -08003207 /**
3208 * Returns the {@link IImsRegistration} structure associated with the slotId and feature
3209 * specified.
3210 */
3211 public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
3212 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003213
3214 final long identity = Binder.clearCallingIdentity();
3215 try {
3216 return PhoneFactory.getImsResolver().getImsRegistration(slotId, feature);
3217 } finally {
3218 Binder.restoreCallingIdentity(identity);
3219 }
Brad Ebinger5f64b052017-12-14 14:26:15 -08003220 }
3221
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003222 /**
3223 * Returns the {@link IImsConfig} structure associated with the slotId and feature
3224 * specified.
3225 */
3226 public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
3227 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003228
3229 final long identity = Binder.clearCallingIdentity();
3230 try {
3231 return PhoneFactory.getImsResolver().getImsConfig(slotId, feature);
3232 } finally {
3233 Binder.restoreCallingIdentity(identity);
3234 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003235 }
3236
Brad Ebinger884c07b2018-02-15 16:17:40 -08003237 /**
Brad Ebingerdac2f002018-04-03 15:17:52 -07003238 * Sets the ImsService Package Name that Telephony will bind to.
3239 *
3240 * @param slotId the slot ID that the ImsService should bind for.
3241 * @param isCarrierImsService true if the ImsService is the carrier override, false if the
3242 * ImsService is the device default ImsService.
3243 * @param packageName The package name of the application that contains the ImsService to bind
3244 * to.
3245 * @return true if setting the ImsService to bind to succeeded, false if it did not.
3246 * @hide
3247 */
3248 public boolean setImsService(int slotId, boolean isCarrierImsService, String packageName) {
Brad Ebingerde696de2018-04-06 09:56:40 -07003249 int[] subIds = SubscriptionManager.getSubId(slotId);
3250 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
3251 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
3252 "setImsService");
3253
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003254 final long identity = Binder.clearCallingIdentity();
3255 try {
3256 return PhoneFactory.getImsResolver().overrideImsServiceConfiguration(slotId,
3257 isCarrierImsService, packageName);
3258 } finally {
3259 Binder.restoreCallingIdentity(identity);
3260 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07003261 }
3262
3263 /**
3264 * Return the ImsService configuration.
3265 *
3266 * @param slotId The slot that the ImsService is associated with.
3267 * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
3268 * the device default.
3269 * @return the package name of the ImsService configuration.
3270 */
3271 public String getImsService(int slotId, boolean isCarrierImsService) {
Brad Ebingerde696de2018-04-06 09:56:40 -07003272 int[] subIds = SubscriptionManager.getSubId(slotId);
3273 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
3274 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
3275 "getImsService");
3276
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003277 final long identity = Binder.clearCallingIdentity();
3278 try {
3279 return PhoneFactory.getImsResolver().getImsServiceConfiguration(slotId,
3280 isCarrierImsService);
3281 } finally {
3282 Binder.restoreCallingIdentity(identity);
3283 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07003284 }
3285
Wink Saville36469e72014-06-11 15:17:00 -07003286 public void setImsRegistrationState(boolean registered) {
3287 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003288
3289 final long identity = Binder.clearCallingIdentity();
3290 try {
3291 mPhone.setImsRegistrationState(registered);
3292 } finally {
3293 Binder.restoreCallingIdentity(identity);
3294 }
Wink Saville36469e72014-06-11 15:17:00 -07003295 }
3296
3297 /**
Stuart Scott54788802015-03-30 13:18:01 -07003298 * Set the network selection mode to automatic.
3299 *
3300 */
3301 @Override
3302 public void setNetworkSelectionModeAutomatic(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003303 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3304 mApp, subId, "setNetworkSelectionModeAutomatic");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003305
3306 final long identity = Binder.clearCallingIdentity();
3307 try {
3308 if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
3309 sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId);
3310 } finally {
3311 Binder.restoreCallingIdentity(identity);
3312 }
Stuart Scott54788802015-03-30 13:18:01 -07003313 }
3314
3315 /**
Shishir Agrawal302c8692015-06-19 13:49:39 -07003316 * Set the network selection mode to manual with the selected carrier.
3317 */
3318 @Override
yinxu6e5abd72017-12-01 11:35:19 -08003319 public boolean setNetworkSelectionModeManual(int subId, String operatorNumeric,
Shishir Agrawal77ba3172015-09-10 14:50:19 -07003320 boolean persistSelection) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003321 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3322 mApp, subId, "setNetworkSelectionModeManual");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003323
3324 final long identity = Binder.clearCallingIdentity();
3325 try {
3326 OperatorInfo operator = new OperatorInfo(
yinxu6e5abd72017-12-01 11:35:19 -08003327 /* operatorAlphaLong */ "",
3328 /* operatorAlphaShort */ "",
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003329 operatorNumeric);
3330 if (DBG) log("setNetworkSelectionModeManual: subId:" + subId + " operator:" + operator);
3331 ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operator,
3332 persistSelection);
3333 return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
3334 } finally {
3335 Binder.restoreCallingIdentity(identity);
3336 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07003337 }
3338
3339 /**
3340 * Scans for available networks.
3341 */
3342 @Override
3343 public CellNetworkScanResult getCellNetworkScanResults(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003344 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3345 mApp, subId, "getCellNetworkScanResults");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003346
3347 final long identity = Binder.clearCallingIdentity();
3348 try {
3349 if (DBG) log("getCellNetworkScanResults: subId " + subId);
3350 CellNetworkScanResult result = (CellNetworkScanResult) sendRequest(
3351 CMD_PERFORM_NETWORK_SCAN, null, subId);
3352 return result;
3353 } finally {
3354 Binder.restoreCallingIdentity(identity);
3355 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07003356 }
3357
3358 /**
yinxub1bed742017-04-17 11:45:04 -07003359 * Starts a new network scan and returns the id of this scan.
yinxu504e1392017-04-12 16:03:22 -07003360 *
yinxub1bed742017-04-17 11:45:04 -07003361 * @param subId id of the subscription
3362 * @param request contains the radio access networks with bands/channels to scan
3363 * @param messenger callback messenger for scan results or errors
3364 * @param binder for the purpose of auto clean when the user thread crashes
yinxu504e1392017-04-12 16:03:22 -07003365 * @return the id of the requested scan which can be used to stop the scan.
3366 */
3367 @Override
3368 public int requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger,
3369 IBinder binder) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003370 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3371 mApp, subId, "requestNetworkScan");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003372
3373 final long identity = Binder.clearCallingIdentity();
3374 try {
3375 return mNetworkScanRequestTracker.startNetworkScan(
3376 request, messenger, binder, getPhone(subId));
3377 } finally {
3378 Binder.restoreCallingIdentity(identity);
3379 }
yinxu504e1392017-04-12 16:03:22 -07003380 }
3381
3382 /**
3383 * Stops an existing network scan with the given scanId.
yinxub1bed742017-04-17 11:45:04 -07003384 *
3385 * @param subId id of the subscription
3386 * @param scanId id of the scan that needs to be stopped
yinxu504e1392017-04-12 16:03:22 -07003387 */
3388 @Override
3389 public void stopNetworkScan(int subId, int scanId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003390 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3391 mApp, subId, "stopNetworkScan");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003392
3393 final long identity = Binder.clearCallingIdentity();
3394 try {
3395 mNetworkScanRequestTracker.stopNetworkScan(scanId);
3396 } finally {
3397 Binder.restoreCallingIdentity(identity);
3398 }
yinxu504e1392017-04-12 16:03:22 -07003399 }
3400
3401 /**
Junda Liu84d15a22014-07-02 11:21:04 -07003402 * Get the calculated preferred network type.
3403 * Used for debugging incorrect network type.
3404 *
3405 * @return the preferred network type, defined in RILConstants.java.
3406 */
3407 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07003408 public int getCalculatedPreferredNetworkType(String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003409 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003410 mApp, mPhone.getSubId(), callingPackage, "getCalculatedPreferredNetworkType")) {
Svet Ganovb320e182015-04-16 12:30:10 -07003411 return RILConstants.PREFERRED_NETWORK_MODE;
3412 }
3413
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003414 final long identity = Binder.clearCallingIdentity();
3415 try {
3416 // FIXME: need to get SubId from somewhere.
3417 return PhoneFactory.calculatePreferredNetworkType(mPhone.getContext(), 0);
3418 } finally {
3419 Binder.restoreCallingIdentity(identity);
3420 }
Junda Liu84d15a22014-07-02 11:21:04 -07003421 }
3422
3423 /**
Jake Hamby7c27be32014-03-03 13:25:59 -08003424 * Get the preferred network type.
3425 * Used for device configuration by some CDMA operators.
3426 *
3427 * @return the preferred network type, defined in RILConstants.java.
3428 */
3429 @Override
Stuart Scott54788802015-03-30 13:18:01 -07003430 public int getPreferredNetworkType(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003431 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3432 mApp, subId, "getPreferredNetworkType");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003433
3434 final long identity = Binder.clearCallingIdentity();
3435 try {
3436 if (DBG) log("getPreferredNetworkType");
3437 int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null, subId);
3438 int networkType = (result != null ? result[0] : -1);
3439 if (DBG) log("getPreferredNetworkType: " + networkType);
3440 return networkType;
3441 } finally {
3442 Binder.restoreCallingIdentity(identity);
3443 }
Jake Hamby7c27be32014-03-03 13:25:59 -08003444 }
3445
3446 /**
3447 * Set the preferred network type.
3448 * Used for device configuration by some CDMA operators.
3449 *
3450 * @param networkType the preferred network type, defined in RILConstants.java.
3451 * @return true on success; false on any failure.
3452 */
3453 @Override
Stuart Scott54788802015-03-30 13:18:01 -07003454 public boolean setPreferredNetworkType(int subId, int networkType) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003455 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3456 mApp, subId, "setPreferredNetworkType");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003457
3458 final long identity = Binder.clearCallingIdentity();
3459 try {
3460 if (DBG) log("setPreferredNetworkType: subId " + subId + " type " + networkType);
3461 Boolean success = (Boolean) sendRequest(
3462 CMD_SET_PREFERRED_NETWORK_TYPE, networkType, subId);
3463 if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail"));
3464 if (success) {
3465 Settings.Global.putInt(mPhone.getContext().getContentResolver(),
3466 Settings.Global.PREFERRED_NETWORK_MODE + subId, networkType);
3467 }
3468 return success;
3469 } finally {
3470 Binder.restoreCallingIdentity(identity);
Junda Liu80bc0d12014-07-14 16:36:44 -07003471 }
Jake Hamby7c27be32014-03-03 13:25:59 -08003472 }
Robert Greenwalted86e582014-05-21 20:03:20 -07003473
3474 /**
Junda Liu475951f2014-11-07 16:45:03 -08003475 * Check TETHER_DUN_REQUIRED and TETHER_DUN_APN settings, net.tethering.noprovisioning
3476 * SystemProperty, and config_tether_apndata to decide whether DUN APN is required for
3477 * tethering.
3478 *
3479 * @return 0: Not required. 1: required. 2: Not set.
3480 * @hide
3481 */
3482 @Override
3483 public int getTetherApnRequired() {
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003484 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003485
3486 final long identity = Binder.clearCallingIdentity();
3487 try {
3488 int dunRequired = Settings.Global.getInt(mPhone.getContext().getContentResolver(),
3489 Settings.Global.TETHER_DUN_REQUIRED, 2);
3490 // If not set, check net.tethering.noprovisioning, TETHER_DUN_APN setting and
3491 // config_tether_apndata.
3492 if (dunRequired == 2 && mPhone.hasMatchedTetherApnSetting()) {
3493 dunRequired = 1;
3494 }
3495 return dunRequired;
3496 } finally {
3497 Binder.restoreCallingIdentity(identity);
Junda Liu475951f2014-11-07 16:45:03 -08003498 }
Junda Liu475951f2014-11-07 16:45:03 -08003499 }
3500
3501 /**
Robert Greenwalted86e582014-05-21 20:03:20 -07003502 * Set mobile data enabled
3503 * Used by the user through settings etc to turn on/off mobile data
3504 *
3505 * @param enable {@code true} turn turn data on, else {@code false}
3506 */
3507 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08003508 public void setUserDataEnabled(int subId, boolean enable) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003509 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3510 mApp, subId, "setUserDataEnabled");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003511
3512 final long identity = Binder.clearCallingIdentity();
3513 try {
3514 int phoneId = mSubscriptionController.getPhoneId(subId);
3515 if (DBG) log("setUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
3516 Phone phone = PhoneFactory.getPhone(phoneId);
3517 if (phone != null) {
3518 if (DBG) log("setUserDataEnabled: subId=" + subId + " enable=" + enable);
3519 phone.setUserDataEnabled(enable);
3520 } else {
3521 loge("setUserDataEnabled: no phone for subId=" + subId);
3522 }
3523 } finally {
3524 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08003525 }
Robert Greenwalted86e582014-05-21 20:03:20 -07003526 }
3527
3528 /**
Malcolm Chen964682d2017-11-28 16:20:07 -08003529 * Get the user enabled state of Mobile Data.
3530 *
3531 * TODO: remove and use isUserDataEnabled.
3532 * This can't be removed now because some vendor codes
3533 * calls through ITelephony directly while they should
3534 * use TelephonyManager.
3535 *
3536 * @return true on enabled
3537 */
3538 @Override
3539 public boolean getDataEnabled(int subId) {
3540 return isUserDataEnabled(subId);
3541 }
3542
3543 /**
3544 * Get whether mobile data is enabled per user setting.
3545 *
3546 * There are other factors deciding whether mobile data is actually enabled, but they are
3547 * not considered here. See {@link #isDataEnabled(int)} for more details.
Robert Greenwalt646120a2014-05-23 11:54:03 -07003548 *
Jeff Davidsona1920712016-11-18 17:05:56 -08003549 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
Robert Greenwalted86e582014-05-21 20:03:20 -07003550 *
3551 * @return {@code true} if data is enabled else {@code false}
3552 */
3553 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08003554 public boolean isUserDataEnabled(int subId) {
Robert Greenwalt646120a2014-05-23 11:54:03 -07003555 try {
3556 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
3557 null);
3558 } catch (Exception e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003559 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3560 mApp, subId, "isUserDataEnabled");
Robert Greenwalt646120a2014-05-23 11:54:03 -07003561 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003562
3563 final long identity = Binder.clearCallingIdentity();
3564 try {
3565 int phoneId = mSubscriptionController.getPhoneId(subId);
3566 if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
3567 Phone phone = PhoneFactory.getPhone(phoneId);
3568 if (phone != null) {
3569 boolean retVal = phone.isUserDataEnabled();
3570 if (DBG) log("isUserDataEnabled: subId=" + subId + " retVal=" + retVal);
3571 return retVal;
3572 } else {
3573 if (DBG) loge("isUserDataEnabled: no phone subId=" + subId + " retVal=false");
3574 return false;
3575 }
3576 } finally {
3577 Binder.restoreCallingIdentity(identity);
Malcolm Chen964682d2017-11-28 16:20:07 -08003578 }
3579 }
3580
3581 /**
3582 * Get whether mobile data is enabled.
3583 *
3584 * Comparable to {@link #isUserDataEnabled(int)}, this considers all factors deciding
3585 * whether mobile data is actually enabled.
3586 *
3587 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
3588 *
3589 * @return {@code true} if data is enabled else {@code false}
3590 */
3591 @Override
3592 public boolean isDataEnabled(int subId) {
3593 try {
3594 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
3595 null);
3596 } catch (Exception e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003597 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3598 mApp, subId, "isDataEnabled");
Malcolm Chen964682d2017-11-28 16:20:07 -08003599 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003600
3601 final long identity = Binder.clearCallingIdentity();
3602 try {
3603 int phoneId = mSubscriptionController.getPhoneId(subId);
3604 if (DBG) log("isDataEnabled: subId=" + subId + " phoneId=" + phoneId);
3605 Phone phone = PhoneFactory.getPhone(phoneId);
3606 if (phone != null) {
3607 boolean retVal = phone.isDataEnabled();
3608 if (DBG) log("isDataEnabled: subId=" + subId + " retVal=" + retVal);
3609 return retVal;
3610 } else {
3611 if (DBG) loge("isDataEnabled: no phone subId=" + subId + " retVal=false");
3612 return false;
3613 }
3614 } finally {
3615 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08003616 }
Robert Greenwalted86e582014-05-21 20:03:20 -07003617 }
Shishir Agrawal60f9c952014-06-23 12:00:43 -07003618
3619 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003620 public int getCarrierPrivilegeStatus(int subId) {
3621 final Phone phone = getPhone(subId);
3622 if (phone == null) {
3623 loge("getCarrierPrivilegeStatus: Invalid subId");
3624 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
3625 }
3626 UiccCard card = UiccController.getInstance().getUiccCard(phone.getPhoneId());
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07003627 if (card == null) {
Shishir Agrawal5e5becd2014-11-18 11:38:23 -08003628 loge("getCarrierPrivilegeStatus: No UICC");
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07003629 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3630 }
3631 return card.getCarrierPrivilegeStatusForCurrentTransaction(
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003632 phone.getContext().getPackageManager());
Shishir Agrawal60f9c952014-06-23 12:00:43 -07003633 }
Junda Liu29340342014-07-10 15:23:27 -07003634
3635 @Override
Jeff Davidson7e17e312018-02-13 18:17:36 -08003636 public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
3637 final Phone phone = getPhone(subId);
3638 if (phone == null) {
3639 loge("getCarrierPrivilegeStatus: Invalid subId");
3640 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
3641 }
3642 UiccProfile profile =
3643 UiccController.getInstance().getUiccProfileForPhone(phone.getPhoneId());
3644 if (profile == null) {
3645 loge("getCarrierPrivilegeStatus: No UICC");
3646 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3647 }
3648 return profile.getCarrierPrivilegeStatusForUid(phone.getContext().getPackageManager(), uid);
3649 }
3650
3651 @Override
Zach Johnson50ecba32015-05-19 00:24:21 -07003652 public int checkCarrierPrivilegesForPackage(String pkgName) {
Junda Liu317d70b2016-03-08 09:33:53 -08003653 if (TextUtils.isEmpty(pkgName))
3654 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Shishir Agrawal21409252015-01-15 23:33:50 -08003655 UiccCard card = UiccController.getInstance().getUiccCard(mPhone.getPhoneId());
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07003656 if (card == null) {
3657 loge("checkCarrierPrivilegesForPackage: No UICC");
3658 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3659 }
Zach Johnson50ecba32015-05-19 00:24:21 -07003660 return card.getCarrierPrivilegeStatus(mPhone.getContext().getPackageManager(), pkgName);
3661 }
3662
3663 @Override
3664 public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
Junda Liu317d70b2016-03-08 09:33:53 -08003665 if (TextUtils.isEmpty(pkgName))
3666 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Zach Johnson50ecba32015-05-19 00:24:21 -07003667 int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3668 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
3669 UiccCard card = UiccController.getInstance().getUiccCard(i);
3670 if (card == null) {
Jonathan Basseri7d320df2015-06-16 12:17:08 -07003671 // No UICC in that slot.
Zach Johnson50ecba32015-05-19 00:24:21 -07003672 continue;
3673 }
3674
3675 result = card.getCarrierPrivilegeStatus(
3676 mPhone.getContext().getPackageManager(), pkgName);
3677 if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
3678 break;
3679 }
3680 }
3681
3682 return result;
Junda Liu29340342014-07-10 15:23:27 -07003683 }
Derek Tan89e89d42014-07-08 17:00:10 -07003684
3685 @Override
Junda Liue64de782015-04-16 17:19:16 -07003686 public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
3687 if (!SubscriptionManager.isValidPhoneId(phoneId)) {
3688 loge("phoneId " + phoneId + " is not valid.");
3689 return null;
3690 }
3691 UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07003692 if (card == null) {
Diego Pontorieroaf74c862014-08-28 11:51:16 -07003693 loge("getCarrierPackageNamesForIntent: No UICC");
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07003694 return null ;
3695 }
Diego Pontorieroaf74c862014-08-28 11:51:16 -07003696 return card.getCarrierPackageNamesForIntent(
Svetoslav483aff72015-04-21 14:16:07 -07003697 mPhone.getContext().getPackageManager(), intent);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07003698 }
3699
Amith Yamasani6e118872016-02-19 12:53:51 -08003700 @Override
3701 public List<String> getPackagesWithCarrierPrivileges() {
3702 PackageManager pm = mPhone.getContext().getPackageManager();
3703 List<String> privilegedPackages = new ArrayList<>();
3704 List<PackageInfo> packages = null;
3705 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
3706 UiccCard card = UiccController.getInstance().getUiccCard(i);
3707 if (card == null) {
3708 // No UICC in that slot.
3709 continue;
3710 }
3711 if (card.hasCarrierPrivilegeRules()) {
3712 if (packages == null) {
3713 // Only check packages in user 0 for now
3714 packages = pm.getInstalledPackagesAsUser(
3715 PackageManager.MATCH_DISABLED_COMPONENTS
3716 | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
3717 | PackageManager.GET_SIGNATURES, UserHandle.USER_SYSTEM);
3718 }
3719 for (int p = packages.size() - 1; p >= 0; p--) {
3720 PackageInfo pkgInfo = packages.get(p);
3721 if (pkgInfo != null && pkgInfo.packageName != null
3722 && card.getCarrierPrivilegeStatus(pkgInfo)
3723 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
3724 privilegedPackages.add(pkgInfo.packageName);
3725 }
3726 }
3727 }
3728 }
3729 return privilegedPackages;
3730 }
3731
Wink Savilleb564aae2014-10-23 10:18:09 -07003732 private String getIccId(int subId) {
Sanket Padawe356d7632015-06-22 14:03:32 -07003733 final Phone phone = getPhone(subId);
3734 UiccCard card = phone == null ? null : phone.getUiccCard();
Derek Tan97ebb422014-09-05 16:55:38 -07003735 if (card == null) {
3736 loge("getIccId: No UICC");
3737 return null;
3738 }
3739 String iccId = card.getIccId();
3740 if (TextUtils.isEmpty(iccId)) {
3741 loge("getIccId: ICC ID is null or empty.");
3742 return null;
3743 }
3744 return iccId;
3745 }
3746
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07003747 @Override
Jeff Sharkey85190e62014-12-05 09:40:12 -08003748 public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
3749 String number) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003750 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
3751 subId, "setLine1NumberForDisplayForSubscriber");
Derek Tan97ebb422014-09-05 16:55:38 -07003752
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003753 final long identity = Binder.clearCallingIdentity();
3754 try {
3755 final String iccId = getIccId(subId);
3756 final Phone phone = getPhone(subId);
3757 if (phone == null) {
3758 return false;
3759 }
3760 final String subscriberId = phone.getSubscriberId();
3761
3762 if (DBG_MERGE) {
3763 Slog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId="
3764 + subscriberId + " to " + number);
3765 }
3766
3767 if (TextUtils.isEmpty(iccId)) {
3768 return false;
3769 }
3770
3771 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
3772
3773 final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
3774 if (alphaTag == null) {
3775 editor.remove(alphaTagPrefKey);
3776 } else {
3777 editor.putString(alphaTagPrefKey, alphaTag);
3778 }
3779
3780 // Record both the line number and IMSI for this ICCID, since we need to
3781 // track all merged IMSIs based on line number
3782 final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
3783 final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
3784 if (number == null) {
3785 editor.remove(numberPrefKey);
3786 editor.remove(subscriberPrefKey);
3787 } else {
3788 editor.putString(numberPrefKey, number);
3789 editor.putString(subscriberPrefKey, subscriberId);
3790 }
3791
3792 editor.commit();
3793 return true;
3794 } finally {
3795 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003796 }
Derek Tan7226c842014-07-02 17:42:23 -07003797 }
3798
3799 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07003800 public String getLine1NumberForDisplay(int subId, String callingPackage) {
Makoto Onukifee69342015-06-29 14:44:50 -07003801 // This is open to apps with WRITE_SMS.
Jeff Davidson7e17e312018-02-13 18:17:36 -08003802 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
Jeff Davidson913390f2018-02-23 17:11:49 -08003803 mApp, subId, callingPackage, "getLine1NumberForDisplay")) {
Amit Mahajan9cf11512015-11-09 11:40:48 -08003804 if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
Svet Ganovb320e182015-04-16 12:30:10 -07003805 return null;
3806 }
Derek Tan97ebb422014-09-05 16:55:38 -07003807
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003808 final long identity = Binder.clearCallingIdentity();
3809 try {
3810 String iccId = getIccId(subId);
3811 if (iccId != null) {
3812 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
3813 if (DBG_MERGE) {
3814 log("getLine1NumberForDisplay returning "
3815 + mTelephonySharedPreferences.getString(numberPrefKey, null));
3816 }
3817 return mTelephonySharedPreferences.getString(numberPrefKey, null);
Amit Mahajan9cf11512015-11-09 11:40:48 -08003818 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003819 if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null");
3820 return null;
3821 } finally {
3822 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07003823 }
Derek Tan7226c842014-07-02 17:42:23 -07003824 }
3825
3826 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07003827 public String getLine1AlphaTagForDisplay(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003828 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003829 mApp, subId, callingPackage, "getLine1AlphaTagForDisplay")) {
Svet Ganovb320e182015-04-16 12:30:10 -07003830 return null;
3831 }
Derek Tan97ebb422014-09-05 16:55:38 -07003832
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003833 final long identity = Binder.clearCallingIdentity();
3834 try {
3835 String iccId = getIccId(subId);
3836 if (iccId != null) {
3837 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
3838 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null);
3839 }
3840 return null;
3841 } finally {
3842 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07003843 }
Derek Tan7226c842014-07-02 17:42:23 -07003844 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07003845
3846 @Override
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07003847 public String[] getMergedSubscriberIds(String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08003848 // This API isn't public, so no need to provide a valid subscription ID - we're not worried
3849 // about carrier-privileged callers not having access.
Jeff Davidson7e17e312018-02-13 18:17:36 -08003850 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003851 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
3852 "getMergedSubscriberIds")) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07003853 return null;
3854 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08003855
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07003856 final long identity = Binder.clearCallingIdentity();
3857 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003858 final Context context = mPhone.getContext();
3859 final TelephonyManager tele = TelephonyManager.from(context);
3860 final SubscriptionManager sub = SubscriptionManager.from(context);
3861
3862 // Figure out what subscribers are currently active
3863 final ArraySet<String> activeSubscriberIds = new ArraySet<>();
3864 // Clear calling identity, when calling TelephonyManager, because callerUid must be
3865 // the process, where TelephonyManager was instantiated.
3866 // Otherwise AppOps check will fail.
3867
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07003868 final int[] subIds = sub.getActiveSubscriptionIdList();
3869 for (int subId : subIds) {
3870 activeSubscriberIds.add(tele.getSubscriberId(subId));
3871 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003872
3873 // First pass, find a number override for an active subscriber
3874 String mergeNumber = null;
3875 final Map<String, ?> prefs = mTelephonySharedPreferences.getAll();
3876 for (String key : prefs.keySet()) {
3877 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) {
3878 final String subscriberId = (String) prefs.get(key);
3879 if (activeSubscriberIds.contains(subscriberId)) {
3880 final String iccId = key.substring(
3881 PREF_CARRIERS_SUBSCRIBER_PREFIX.length());
3882 final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
3883 mergeNumber = (String) prefs.get(numberKey);
3884 if (DBG_MERGE) {
3885 Slog.d(LOG_TAG, "Found line number " + mergeNumber
3886 + " for active subscriber " + subscriberId);
3887 }
3888 if (!TextUtils.isEmpty(mergeNumber)) {
3889 break;
3890 }
3891 }
3892 }
3893 }
3894
3895 // Shortcut when no active merged subscribers
3896 if (TextUtils.isEmpty(mergeNumber)) {
3897 return null;
3898 }
3899
3900 // Second pass, find all subscribers under that line override
3901 final ArraySet<String> result = new ArraySet<>();
3902 for (String key : prefs.keySet()) {
3903 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) {
3904 final String number = (String) prefs.get(key);
3905 if (mergeNumber.equals(number)) {
3906 final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length());
3907 final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
3908 final String subscriberId = (String) prefs.get(subscriberKey);
3909 if (!TextUtils.isEmpty(subscriberId)) {
3910 result.add(subscriberId);
3911 }
3912 }
3913 }
3914 }
3915
3916 final String[] resultArray = result.toArray(new String[result.size()]);
3917 Arrays.sort(resultArray);
3918 if (DBG_MERGE) {
3919 Slog.d(LOG_TAG,
3920 "Found subscribers " + Arrays.toString(resultArray) + " after merge");
3921 }
3922 return resultArray;
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07003923 } finally {
3924 Binder.restoreCallingIdentity(identity);
Jeff Sharkey85190e62014-12-05 09:40:12 -08003925 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08003926 }
3927
3928 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003929 public boolean setOperatorBrandOverride(int subId, String brand) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003930 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
3931 subId, "setOperatorBrandOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003932
3933 final long identity = Binder.clearCallingIdentity();
3934 try {
3935 final Phone phone = getPhone(subId);
3936 return phone == null ? false : phone.setOperatorBrandOverride(brand);
3937 } finally {
3938 Binder.restoreCallingIdentity(identity);
3939 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07003940 }
Steven Liu4bf01bc2014-07-17 11:05:29 -05003941
3942 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003943 public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
Shishir Agrawal621a47c2014-12-01 10:25:09 -08003944 List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
3945 List<String> cdmaNonRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003946 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setRoamingOverride");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08003947
3948 final long identity = Binder.clearCallingIdentity();
3949 try {
3950 final Phone phone = getPhone(subId);
3951 if (phone == null) {
3952 return false;
3953 }
3954 return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList,
3955 cdmaNonRoamingList);
3956 } finally {
3957 Binder.restoreCallingIdentity(identity);
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003958 }
Shishir Agrawal621a47c2014-12-01 10:25:09 -08003959 }
3960
3961 @Override
Shuo Qian850e4d6a2018-04-25 21:02:08 +00003962 @Deprecated
3963 public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
3964 enforceModifyPermission();
3965
3966 int returnValue = 0;
3967 try {
vagdeviaf9a5b92018-08-15 16:01:53 -07003968 AsyncResult result = (AsyncResult) sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
Shuo Qian850e4d6a2018-04-25 21:02:08 +00003969 if(result.exception == null) {
3970 if (result.result != null) {
3971 byte[] responseData = (byte[])(result.result);
3972 if(responseData.length > oemResp.length) {
3973 Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +
3974 responseData.length + "bytes. Buffer Size is " +
3975 oemResp.length + "bytes.");
3976 }
3977 System.arraycopy(responseData, 0, oemResp, 0, responseData.length);
3978 returnValue = responseData.length;
3979 }
3980 } else {
3981 CommandException ex = (CommandException) result.exception;
3982 returnValue = ex.getCommandError().ordinal();
3983 if(returnValue > 0) returnValue *= -1;
3984 }
3985 } catch (RuntimeException e) {
3986 Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");
3987 returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());
3988 if(returnValue > 0) returnValue *= -1;
3989 }
3990
3991 return returnValue;
3992 }
3993
3994 @Override
Wink Saville5d475dd2014-10-17 15:00:58 -07003995 public void setRadioCapability(RadioAccessFamily[] rafs) {
3996 try {
3997 ProxyController.getInstance().setRadioCapability(rafs);
3998 } catch (RuntimeException e) {
3999 Log.w(LOG_TAG, "setRadioCapability: Runtime Exception");
4000 }
4001 }
4002
4003 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004004 public int getRadioAccessFamily(int phoneId, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08004005 Phone phone = PhoneFactory.getPhone(phoneId);
4006 if (phone == null) {
4007 return RadioAccessFamily.RAF_UNKNOWN;
4008 }
4009 int subId = phone.getSubId();
Jeff Davidson7e17e312018-02-13 18:17:36 -08004010 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08004011 mApp, subId, callingPackage, "getRadioAccessFamily")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004012 return RadioAccessFamily.RAF_UNKNOWN;
4013 }
4014
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004015 final long identity = Binder.clearCallingIdentity();
4016 try {
4017 return ProxyController.getInstance().getRadioAccessFamily(phoneId);
4018 } finally {
4019 Binder.restoreCallingIdentity(identity);
4020 }
Wink Saville5d475dd2014-10-17 15:00:58 -07004021 }
Andrew Leedf14ead2014-10-17 14:22:52 -07004022
4023 @Override
4024 public void enableVideoCalling(boolean enable) {
4025 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004026
4027 final long identity = Binder.clearCallingIdentity();
4028 try {
4029 ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId()).setVtSetting(enable);
4030 } finally {
4031 Binder.restoreCallingIdentity(identity);
4032 }
Andrew Leedf14ead2014-10-17 14:22:52 -07004033 }
4034
4035 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004036 public boolean isVideoCallingEnabled(String callingPackage) {
Amit Mahajan578e53d2018-03-20 16:18:38 +00004037 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4038 mApp, mPhone.getSubId(), callingPackage, "isVideoCallingEnabled")) {
4039 return false;
4040 }
Svet Ganovb320e182015-04-16 12:30:10 -07004041
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004042 final long identity = Binder.clearCallingIdentity();
4043 try {
4044 // Check the user preference and the system-level IMS setting. Even if the user has
4045 // enabled video calling, if IMS is disabled we aren't able to support video calling.
4046 // In the long run, we may instead need to check if there exists a connection service
4047 // which can support video calling.
4048 ImsManager imsManager =
4049 ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId());
4050 return imsManager.isVtEnabledByPlatform()
4051 && imsManager.isEnhanced4gLteModeSettingEnabledByUser()
4052 && imsManager.isVtEnabledByUser();
4053 } finally {
4054 Binder.restoreCallingIdentity(identity);
4055 }
Andrew Leedf14ead2014-10-17 14:22:52 -07004056 }
Libin.Tang@motorola.comafe82642014-12-18 13:27:53 -06004057
Andrew Leea1239f22015-03-02 17:44:07 -08004058 @Override
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004059 public boolean canChangeDtmfToneLength(int subId, String callingPackage) {
4060 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4061 mApp, subId, callingPackage, "isVideoCallingEnabled")) {
4062 return false;
4063 }
4064
4065 final long identity = Binder.clearCallingIdentity();
4066 try {
4067 CarrierConfigManager configManager =
4068 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
4069 return configManager.getConfigForSubId(mPhone.getSubId())
4070 .getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL);
4071 } finally {
4072 Binder.restoreCallingIdentity(identity);
4073 }
Andrew Leea1239f22015-03-02 17:44:07 -08004074 }
4075
4076 @Override
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004077 public boolean isWorldPhone(int subId, String callingPackage) {
4078 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4079 mApp, subId, callingPackage, "isVideoCallingEnabled")) {
4080 return false;
4081 }
4082
4083 final long identity = Binder.clearCallingIdentity();
4084 try {
4085 CarrierConfigManager configManager =
4086 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
4087 return configManager.getConfigForSubId(mPhone.getSubId())
4088 .getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL);
4089 } finally {
4090 Binder.restoreCallingIdentity(identity);
4091 }
Andrew Leea1239f22015-03-02 17:44:07 -08004092 }
4093
Andrew Lee9431b832015-03-09 18:46:45 -07004094 @Override
4095 public boolean isTtyModeSupported() {
4096 TelecomManager telecomManager = TelecomManager.from(mPhone.getContext());
Wooki Wu1f82f7a2016-02-15 15:59:58 +08004097 return telecomManager.isTtySupported();
Andrew Lee9431b832015-03-09 18:46:45 -07004098 }
4099
4100 @Override
4101 public boolean isHearingAidCompatibilitySupported() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004102 final long identity = Binder.clearCallingIdentity();
4103 try {
4104 return mPhone.getContext().getResources().getBoolean(R.bool.hac_enabled);
4105 } finally {
4106 Binder.restoreCallingIdentity(identity);
4107 }
Andrew Lee9431b832015-03-09 18:46:45 -07004108 }
4109
Hall Liu98187582018-01-22 19:15:32 -08004110 public boolean isRttSupported() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004111 final long identity = Binder.clearCallingIdentity();
4112 try {
4113 boolean isCarrierSupported = mApp.getCarrierConfigForSubId(
4114 mPhone.getSubId()).getBoolean(
4115 CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
4116 boolean isDeviceSupported =
4117 mPhone.getContext().getResources().getBoolean(R.bool.config_support_rtt);
4118 return isCarrierSupported && isDeviceSupported;
4119 } finally {
4120 Binder.restoreCallingIdentity(identity);
4121 }
Hall Liu98187582018-01-22 19:15:32 -08004122 }
4123
Hall Liu3ad5f012018-04-06 16:23:39 -07004124 public boolean isRttEnabled() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004125 final long identity = Binder.clearCallingIdentity();
4126 try {
4127 return isRttSupported() && Settings.Secure.getInt(
4128 mPhone.getContext().getContentResolver(),
4129 Settings.Secure.RTT_CALLING_MODE, 0) != 0;
4130 } finally {
4131 Binder.restoreCallingIdentity(identity);
4132 }
Hall Liu3ad5f012018-04-06 16:23:39 -07004133 }
4134
Sanket Padawe7310cc72015-01-14 09:53:20 -08004135 /**
4136 * Returns the unique device ID of phone, for example, the IMEI for
4137 * GSM and the MEID for CDMA phones. Return null if device ID is not available.
4138 *
4139 * <p>Requires Permission:
4140 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
4141 */
4142 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004143 public String getDeviceId(String callingPackage) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08004144 final Phone phone = PhoneFactory.getPhone(0);
Jeff Davidson913390f2018-02-23 17:11:49 -08004145 if (phone == null) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08004146 return null;
4147 }
Jeff Davidson913390f2018-02-23 17:11:49 -08004148 int subId = phone.getSubId();
4149 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4150 mApp, subId, callingPackage, "getDeviceId")) {
4151 return null;
4152 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004153
4154 final long identity = Binder.clearCallingIdentity();
4155 try {
4156 return phone.getDeviceId();
4157 } finally {
4158 Binder.restoreCallingIdentity(identity);
4159 }
Sanket Padawe7310cc72015-01-14 09:53:20 -08004160 }
4161
Ping Sunc67b7c22016-03-02 19:16:45 +08004162 /**
4163 * {@hide}
4164 * Returns the IMS Registration Status on a particular subid
4165 *
4166 * @param subId
4167 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004168 public boolean isImsRegistered(int subId) {
Ping Sunc67b7c22016-03-02 19:16:45 +08004169 Phone phone = getPhone(subId);
4170 if (phone != null) {
4171 return phone.isImsRegistered();
4172 } else {
4173 return false;
4174 }
4175 }
4176
Santos Cordon7a1885b2015-02-03 11:15:19 -08004177 @Override
4178 public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004179 final long identity = Binder.clearCallingIdentity();
4180 try {
4181 return PhoneUtils.getSubIdForPhoneAccount(phoneAccount);
4182 } finally {
4183 Binder.restoreCallingIdentity(identity);
4184 }
Santos Cordon7a1885b2015-02-03 11:15:19 -08004185 }
Nathan Harolddcfc7932015-03-18 10:01:20 -07004186
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004187 /**
4188 * @return the VoWiFi calling availability.
Nathan Haroldc55097a2015-03-11 18:14:50 -07004189 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004190 public boolean isWifiCallingAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004191 final long identity = Binder.clearCallingIdentity();
4192 try {
4193 Phone phone = getPhone(subId);
4194 if (phone != null) {
4195 return phone.isWifiCallingEnabled();
4196 } else {
4197 return false;
4198 }
4199 } finally {
4200 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004201 }
Nathan Haroldc55097a2015-03-11 18:14:50 -07004202 }
4203
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004204 /**
4205 * @return the VoLTE availability.
Nathan Haroldc55097a2015-03-11 18:14:50 -07004206 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004207 public boolean isVolteAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004208 final long identity = Binder.clearCallingIdentity();
4209 try {
4210 Phone phone = getPhone(subId);
4211 if (phone != null) {
4212 return phone.isVolteEnabled();
4213 } else {
4214 return false;
4215 }
4216 } finally {
4217 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004218 }
Nathan Haroldc55097a2015-03-11 18:14:50 -07004219 }
Svet Ganovb320e182015-04-16 12:30:10 -07004220
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004221 /**
4222 * @return the VT calling availability.
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07004223 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004224 public boolean isVideoTelephonyAvailable(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004225 final long identity = Binder.clearCallingIdentity();
4226 try {
4227 Phone phone = getPhone(subId);
4228 if (phone != null) {
4229 return phone.isVideoEnabled();
4230 } else {
4231 return false;
4232 }
4233 } finally {
4234 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004235 }
4236 }
4237
4238 /**
4239 * @return the IMS registration technology for the MMTEL feature. Valid return values are
4240 * defined in {@link ImsRegistrationImplBase}.
4241 */
4242 public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004243 final long identity = Binder.clearCallingIdentity();
4244 try {
4245 Phone phone = getPhone(subId);
4246 if (phone != null) {
4247 return phone.getImsRegistrationTech();
4248 } else {
4249 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
4250 }
4251 } finally {
4252 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004253 }
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07004254 }
4255
Stuart Scott8eef64f2015-04-08 15:13:54 -07004256 @Override
4257 public void factoryReset(int subId) {
4258 enforceConnectivityInternalPermission();
Stuart Scott981d8582015-04-21 14:09:50 -07004259 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
4260 return;
4261 }
4262
Svet Ganovcc087f82015-05-12 20:35:54 -07004263 final long identity = Binder.clearCallingIdentity();
4264 try {
Stuart Scott981d8582015-04-21 14:09:50 -07004265 if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
4266 UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
Pengquan Meng85728fb2018-03-12 16:31:21 -07004267 setUserDataEnabled(subId, getDefaultDataEnabled());
Svet Ganovcc087f82015-05-12 20:35:54 -07004268 setNetworkSelectionModeAutomatic(subId);
Pengquan Meng85728fb2018-03-12 16:31:21 -07004269 setPreferredNetworkType(subId, getDefaultNetworkType(subId));
4270 mPhone.setDataRoamingEnabled(getDefaultDataRoamingEnabled(subId));
pkanwar79ec0542017-07-31 14:10:01 -07004271 CarrierInfoManager.deleteAllCarrierKeysForImsiEncryption(mPhone.getContext());
Svet Ganovcc087f82015-05-12 20:35:54 -07004272 }
4273 } finally {
4274 Binder.restoreCallingIdentity(identity);
Stuart Scott8eef64f2015-04-08 15:13:54 -07004275 }
4276 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004277
4278 @Override
4279 public String getLocaleFromDefaultSim() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004280 final long identity = Binder.clearCallingIdentity();
4281 try {
4282 // We query all subscriptions instead of just the active ones, because
4283 // this might be called early on in the provisioning flow when the
4284 // subscriptions potentially aren't active yet.
4285 final List<SubscriptionInfo> slist = getAllSubscriptionInfoList();
4286 if (slist == null || slist.isEmpty()) {
Narayan Kamath1c496c22015-04-16 14:40:19 +01004287 return null;
4288 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004289
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004290 // This function may be called very early, say, from the setup wizard, at
4291 // which point we won't have a default subscription set. If that's the case
4292 // we just choose the first, which will be valid in "most cases".
4293 final int defaultSubId = getDefaultSubscription();
4294 SubscriptionInfo info = null;
4295 if (defaultSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
4296 info = slist.get(0);
4297 } else {
4298 for (SubscriptionInfo item : slist) {
4299 if (item.getSubscriptionId() == defaultSubId) {
4300 info = item;
4301 break;
4302 }
4303 }
4304
4305 if (info == null) {
4306 return null;
Tony Hill183b2de2015-06-24 14:53:58 +01004307 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004308 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004309
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004310 // Try and fetch the locale from the carrier properties or from the SIM language
4311 // preferences (EF-PL and EF-LI)...
4312 final int mcc = info.getMcc();
4313 final Phone defaultPhone = getPhone(info.getSubscriptionId());
4314 String simLanguage = null;
4315 if (defaultPhone != null) {
4316 final Locale localeFromDefaultSim = defaultPhone.getLocaleFromSimAndCarrierPrefs();
4317 if (localeFromDefaultSim != null) {
4318 if (!localeFromDefaultSim.getCountry().isEmpty()) {
4319 if (DBG) log("Using locale from default SIM:" + localeFromDefaultSim);
4320 return localeFromDefaultSim.toLanguageTag();
4321 } else {
4322 simLanguage = localeFromDefaultSim.getLanguage();
4323 }
4324 }
4325 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004326
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004327 // The SIM language preferences only store a language (e.g. fr = French), not an
4328 // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
4329 // the SIM and carrier preferences does not include a country we add the country
4330 // determined from the SIM MCC to provide an exact locale.
4331 final Locale mccLocale = MccTable.getLocaleFromMcc(mPhone.getContext(), mcc,
4332 simLanguage);
4333 if (mccLocale != null) {
4334 if (DBG) log("No locale from default SIM, using mcc locale:" + mccLocale);
4335 return mccLocale.toLanguageTag();
4336 }
4337
4338 if (DBG) log("No locale found - returning null");
4339 return null;
4340 } finally {
4341 Binder.restoreCallingIdentity(identity);
4342 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004343 }
4344
4345 private List<SubscriptionInfo> getAllSubscriptionInfoList() {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004346 return mSubscriptionController.getAllSubInfoList(
4347 mPhone.getContext().getOpPackageName());
Narayan Kamath1c496c22015-04-16 14:40:19 +01004348 }
4349
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004350 /**
4351 * NOTE: this method assumes permission checks are done and caller identity has been cleared.
4352 */
4353 private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
4354 return mSubscriptionController.getActiveSubscriptionInfoList(
4355 mPhone.getContext().getOpPackageName());
Narayan Kamath1c496c22015-04-16 14:40:19 +01004356 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004357
Chenjie Yu1ba97252018-01-11 18:16:20 -08004358 private final ModemActivityInfo mLastModemActivityInfo =
4359 new ModemActivityInfo(0, 0, 0, new int[0], 0, 0);
4360
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004361 /**
Adam Lesinski903a54c2016-04-11 14:49:52 -07004362 * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
4363 * representing the state of the modem.
4364 *
Chenjie Yu1ba97252018-01-11 18:16:20 -08004365 * NOTE: The underlying implementation clears the modem state, so there should only ever be one
4366 * caller to it. Everyone should call this class to get cumulative data.
Adam Lesinski903a54c2016-04-11 14:49:52 -07004367 * @hide
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004368 */
4369 @Override
Adam Lesinski903a54c2016-04-11 14:49:52 -07004370 public void requestModemActivityInfo(ResultReceiver result) {
4371 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07004372 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004373
4374 final long identity = Binder.clearCallingIdentity();
4375 try {
4376 ModemActivityInfo ret = null;
4377 synchronized (mLastModemActivityInfo) {
4378 ModemActivityInfo info = (ModemActivityInfo) sendRequest(
4379 CMD_GET_MODEM_ACTIVITY_INFO,
vagdeviaf9a5b92018-08-15 16:01:53 -07004380 null, workSource);
Siddharth Rayb8114062018-06-17 15:02:38 -07004381 if (isModemActivityInfoValid(info)) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004382 int[] mergedTxTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
4383 for (int i = 0; i < mergedTxTimeMs.length; i++) {
4384 mergedTxTimeMs[i] =
4385 info.getTxTimeMillis()[i]
4386 + mLastModemActivityInfo.getTxTimeMillis()[i];
4387 }
4388 mLastModemActivityInfo.setTimestamp(info.getTimestamp());
4389 mLastModemActivityInfo.setSleepTimeMillis(
4390 info.getSleepTimeMillis()
4391 + mLastModemActivityInfo.getSleepTimeMillis());
4392 mLastModemActivityInfo.setIdleTimeMillis(
4393 info.getIdleTimeMillis() + mLastModemActivityInfo.getIdleTimeMillis());
4394 mLastModemActivityInfo.setTxTimeMillis(mergedTxTimeMs);
4395 mLastModemActivityInfo.setRxTimeMillis(
4396 info.getRxTimeMillis() + mLastModemActivityInfo.getRxTimeMillis());
4397 mLastModemActivityInfo.setEnergyUsed(
4398 info.getEnergyUsed() + mLastModemActivityInfo.getEnergyUsed());
Chenjie Yu1ba97252018-01-11 18:16:20 -08004399 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004400 ret = new ModemActivityInfo(mLastModemActivityInfo.getTimestamp(),
4401 mLastModemActivityInfo.getSleepTimeMillis(),
4402 mLastModemActivityInfo.getIdleTimeMillis(),
4403 mLastModemActivityInfo.getTxTimeMillis(),
4404 mLastModemActivityInfo.getRxTimeMillis(),
4405 mLastModemActivityInfo.getEnergyUsed());
Chenjie Yu1ba97252018-01-11 18:16:20 -08004406 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004407 Bundle bundle = new Bundle();
4408 bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, ret);
4409 result.send(0, bundle);
4410 } finally {
4411 Binder.restoreCallingIdentity(identity);
Chenjie Yu1ba97252018-01-11 18:16:20 -08004412 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004413 }
Jack Yu85bd38a2015-11-09 11:34:32 -08004414
Siddharth Rayb8114062018-06-17 15:02:38 -07004415 // Checks that ModemActivityInfo is valid. Sleep time, Idle time, Rx time and Tx time should be
4416 // less than total activity duration.
4417 private boolean isModemActivityInfoValid(ModemActivityInfo info) {
4418 if (info == null) {
4419 return false;
4420 }
4421 int activityDurationMs =
4422 (int) (info.getTimestamp() - mLastModemActivityInfo.getTimestamp());
4423 int totalTxTimeMs = 0;
4424 for (int i = 0; i < info.getTxTimeMillis().length; i++) {
4425 totalTxTimeMs += info.getTxTimeMillis()[i];
4426 }
4427 return (info.isValid()
4428 && (info.getSleepTimeMillis() <= activityDurationMs)
4429 && (info.getIdleTimeMillis() <= activityDurationMs)
4430 && (info.getRxTimeMillis() <= activityDurationMs)
4431 && (totalTxTimeMs <= activityDurationMs));
4432 }
4433
Jack Yu85bd38a2015-11-09 11:34:32 -08004434 /**
4435 * {@hide}
4436 * Returns the service state information on specified subscription.
4437 */
4438 @Override
4439 public ServiceState getServiceStateForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004440 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08004441 mApp, subId, callingPackage, "getServiceStateForSubscriber")) {
Jack Yu85bd38a2015-11-09 11:34:32 -08004442 return null;
4443 }
4444
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004445 final long identity = Binder.clearCallingIdentity();
4446 try {
4447 final Phone phone = getPhone(subId);
4448 if (phone == null) {
4449 return null;
4450 }
Jack Yu85bd38a2015-11-09 11:34:32 -08004451
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004452 return phone.getServiceState();
4453 } finally {
4454 Binder.restoreCallingIdentity(identity);
4455 }
Jack Yu85bd38a2015-11-09 11:34:32 -08004456 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004457
4458 /**
4459 * Returns the URI for the per-account voicemail ringtone set in Phone settings.
4460 *
4461 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
4462 * voicemail ringtone.
4463 * @return The URI for the ringtone to play when receiving a voicemail from a specific
4464 * PhoneAccount.
4465 */
4466 @Override
4467 public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004468 final long identity = Binder.clearCallingIdentity();
4469 try {
4470 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
4471 if (phone == null) {
4472 phone = mPhone;
4473 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004474
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004475 return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext());
4476 } finally {
4477 Binder.restoreCallingIdentity(identity);
4478 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004479 }
4480
4481 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004482 * Sets the per-account voicemail ringtone.
4483 *
4484 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
4485 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
4486 *
4487 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
4488 * voicemail ringtone.
4489 * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
4490 * PhoneAccount.
4491 */
4492 @Override
4493 public void setVoicemailRingtoneUri(String callingPackage,
4494 PhoneAccountHandle phoneAccountHandle, Uri uri) {
4495 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4496 if (!TextUtils.equals(callingPackage,
4497 TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004498 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4499 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
4500 "setVoicemailRingtoneUri");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004501 }
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004502
4503 final long identity = Binder.clearCallingIdentity();
4504 try {
4505 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
4506 if (phone == null) {
4507 phone = mPhone;
4508 }
4509 VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri);
4510 } finally {
4511 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004512 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004513 }
4514
4515 /**
Nancy Chen31f9ba12016-01-06 11:42:12 -08004516 * Returns whether vibration is set for voicemail notification in Phone settings.
4517 *
4518 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
4519 * voicemail vibration setting.
4520 * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
4521 */
4522 @Override
4523 public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004524 final long identity = Binder.clearCallingIdentity();
4525 try {
4526 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
4527 if (phone == null) {
4528 phone = mPhone;
4529 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004530
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004531 return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext());
4532 } finally {
4533 Binder.restoreCallingIdentity(identity);
4534 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004535 }
4536
Youhan Wange64578a2016-05-02 15:32:42 -07004537 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004538 * Sets the per-account voicemail vibration.
4539 *
4540 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
4541 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
4542 *
4543 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
4544 * voicemail vibration setting.
4545 * @param enabled Whether to enable or disable vibration for voicemail notifications from a
4546 * specific PhoneAccount.
4547 */
4548 @Override
4549 public void setVoicemailVibrationEnabled(String callingPackage,
4550 PhoneAccountHandle phoneAccountHandle, boolean enabled) {
4551 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4552 if (!TextUtils.equals(callingPackage,
4553 TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004554 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4555 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
4556 "setVoicemailVibrationEnabled");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004557 }
4558
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004559 final long identity = Binder.clearCallingIdentity();
4560 try {
4561 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
4562 if (phone == null) {
4563 phone = mPhone;
4564 }
4565 VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled);
4566 } finally {
4567 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004568 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004569 }
4570
4571 /**
Youhan Wange64578a2016-05-02 15:32:42 -07004572 * Make sure either called from same process as self (phone) or IPC caller has read privilege.
4573 *
4574 * @throws SecurityException if the caller does not have the required permission
4575 */
4576 private void enforceReadPrivilegedPermission() {
4577 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
4578 null);
4579 }
4580
4581 /**
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004582 * Make sure either called from same process as self (phone) or IPC caller has send SMS
4583 * permission.
4584 *
4585 * @throws SecurityException if the caller does not have the required permission
4586 */
4587 private void enforceSendSmsPermission() {
4588 mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null);
4589 }
4590
4591 /**
Ta-wei Yen527a9c02017-01-06 15:29:25 -08004592 * Make sure called from the package in charge of visual voicemail.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004593 *
Ta-wei Yen527a9c02017-01-06 15:29:25 -08004594 * @throws SecurityException if the caller is not the visual voicemail package.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004595 */
Ta-wei Yen527a9c02017-01-06 15:29:25 -08004596 private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004597 final long identity = Binder.clearCallingIdentity();
4598 try {
4599 ComponentName componentName =
4600 RemoteVvmTaskManager.getRemotePackage(mPhone.getContext(), subId);
4601 if (componentName == null) {
4602 throw new SecurityException(
4603 "Caller not current active visual voicemail package[null]");
4604 }
4605 String vvmPackage = componentName.getPackageName();
4606 if (!callingPackage.equals(vvmPackage)) {
4607 throw new SecurityException("Caller not current active visual voicemail package["
4608 + vvmPackage + "]");
4609 }
4610 } finally {
4611 Binder.restoreCallingIdentity(identity);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004612 }
4613 }
4614
4615 /**
Youhan Wange64578a2016-05-02 15:32:42 -07004616 * Return the application ID for the app type.
4617 *
4618 * @param subId the subscription ID that this request applies to.
4619 * @param appType the uicc app type.
4620 * @return Application ID for specificied app type, or null if no uicc.
4621 */
4622 @Override
4623 public String getAidForAppType(int subId, int appType) {
4624 enforceReadPrivilegedPermission();
4625 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004626
4627 final long identity = Binder.clearCallingIdentity();
Youhan Wange64578a2016-05-02 15:32:42 -07004628 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004629 if (phone == null) {
4630 return null;
4631 }
4632 String aid = null;
4633 try {
4634 aid = UiccController.getInstance().getUiccCard(phone.getPhoneId())
4635 .getApplicationByType(appType).getAid();
4636 } catch (Exception e) {
4637 Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e);
4638 }
4639 return aid;
4640 } finally {
4641 Binder.restoreCallingIdentity(identity);
Youhan Wange64578a2016-05-02 15:32:42 -07004642 }
Youhan Wange64578a2016-05-02 15:32:42 -07004643 }
4644
Youhan Wang4001d252016-05-11 10:29:41 -07004645 /**
4646 * Return the Electronic Serial Number.
4647 *
4648 * @param subId the subscription ID that this request applies to.
4649 * @return ESN or null if error.
4650 */
4651 @Override
4652 public String getEsn(int subId) {
4653 enforceReadPrivilegedPermission();
4654 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004655
4656 final long identity = Binder.clearCallingIdentity();
Youhan Wang4001d252016-05-11 10:29:41 -07004657 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004658 if (phone == null) {
4659 return null;
4660 }
4661 String esn = null;
4662 try {
4663 esn = phone.getEsn();
4664 } catch (Exception e) {
4665 Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e);
4666 }
4667 return esn;
4668 } finally {
4669 Binder.restoreCallingIdentity(identity);
Youhan Wang4001d252016-05-11 10:29:41 -07004670 }
Youhan Wang4001d252016-05-11 10:29:41 -07004671 }
4672
Sanket Padawe99ef1e32016-05-18 16:12:33 -07004673 /**
Youhan Wang66ad5d72016-07-18 17:56:58 -07004674 * Return the Preferred Roaming List Version.
4675 *
4676 * @param subId the subscription ID that this request applies to.
4677 * @return PRLVersion or null if error.
4678 */
4679 @Override
4680 public String getCdmaPrlVersion(int subId) {
4681 enforceReadPrivilegedPermission();
4682 Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004683
4684 final long identity = Binder.clearCallingIdentity();
Youhan Wang66ad5d72016-07-18 17:56:58 -07004685 try {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004686 if (phone == null) {
4687 return null;
4688 }
4689 String cdmaPrlVersion = null;
4690 try {
4691 cdmaPrlVersion = phone.getCdmaPrlVersion();
4692 } catch (Exception e) {
4693 Log.e(LOG_TAG, "Not getting PRLVersion", e);
4694 }
4695 return cdmaPrlVersion;
4696 } finally {
4697 Binder.restoreCallingIdentity(identity);
Youhan Wang66ad5d72016-07-18 17:56:58 -07004698 }
Youhan Wang66ad5d72016-07-18 17:56:58 -07004699 }
4700
4701 /**
Sanket Padawe99ef1e32016-05-18 16:12:33 -07004702 * Get snapshot of Telephony histograms
4703 * @return List of Telephony histograms
4704 * @hide
4705 */
4706 @Override
4707 public List<TelephonyHistogram> getTelephonyHistograms() {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004708 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4709 mApp, getDefaultSubscription(), "getTelephonyHistograms");
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004710
4711 final long identity = Binder.clearCallingIdentity();
4712 try {
4713 return RIL.getTelephonyRILTimingHistograms();
4714 } finally {
4715 Binder.restoreCallingIdentity(identity);
4716 }
Sanket Padawe99ef1e32016-05-18 16:12:33 -07004717 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07004718
4719 /**
4720 * {@hide}
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004721 * Set the allowed carrier list for slotIndex
Meng Wang1a7c35a2016-05-05 20:56:15 -07004722 * Require system privileges. In the future we may add this to carrier APIs.
4723 *
4724 * @return The number of carriers set successfully, should match length of carriers
4725 */
4726 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004727 public int setAllowedCarriers(int slotIndex, List<CarrierIdentifier> carriers) {
Meng Wang1a7c35a2016-05-05 20:56:15 -07004728 enforceModifyPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07004729 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004730
Meng Wang9b7c4e92017-02-17 11:41:27 -08004731 if (carriers == null) {
4732 throw new NullPointerException("carriers cannot be null");
4733 }
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004734
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004735 final long identity = Binder.clearCallingIdentity();
4736 try {
4737 int subId = SubscriptionManager.getSubId(slotIndex)[0];
vagdeviaf9a5b92018-08-15 16:01:53 -07004738 int[] retVal = (int[]) sendRequest(CMD_SET_ALLOWED_CARRIERS, carriers, subId,
4739 workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004740 return retVal[0];
4741 } finally {
4742 Binder.restoreCallingIdentity(identity);
4743 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07004744 }
4745
4746 /**
4747 * {@hide}
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004748 * Get the allowed carrier list for slotIndex.
Meng Wang1a7c35a2016-05-05 20:56:15 -07004749 * Require system privileges. In the future we may add this to carrier APIs.
4750 *
4751 * @return List of {@link android.service.telephony.CarrierIdentifier}; empty list
4752 * means all carriers are allowed.
4753 */
4754 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004755 public List<CarrierIdentifier> getAllowedCarriers(int slotIndex) {
Meng Wang1a7c35a2016-05-05 20:56:15 -07004756 enforceReadPrivilegedPermission();
vagdeviaf9a5b92018-08-15 16:01:53 -07004757 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004758
4759 final long identity = Binder.clearCallingIdentity();
4760 try {
4761 int subId = SubscriptionManager.getSubId(slotIndex)[0];
vagdeviaf9a5b92018-08-15 16:01:53 -07004762 return (List<CarrierIdentifier>) sendRequest(CMD_GET_ALLOWED_CARRIERS, null, subId,
4763 workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004764 } finally {
4765 Binder.restoreCallingIdentity(identity);
4766 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07004767 }
4768
fionaxu59545b42016-05-25 15:53:37 -07004769 /**
4770 * Action set from carrier signalling broadcast receivers to enable/disable metered apns
4771 * @param subId the subscription ID that this action applies to.
4772 * @param enabled control enable or disable metered apns.
4773 * {@hide}
4774 */
4775 @Override
4776 public void carrierActionSetMeteredApnsEnabled(int subId, boolean enabled) {
4777 enforceModifyPermission();
4778 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004779
4780 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07004781 if (phone == null) {
4782 loge("carrierAction: SetMeteredApnsEnabled fails with invalid subId: " + subId);
4783 return;
4784 }
4785 try {
4786 phone.carrierActionSetMeteredApnsEnabled(enabled);
4787 } catch (Exception e) {
4788 Log.e(LOG_TAG, "carrierAction: SetMeteredApnsEnabled fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004789 } finally {
4790 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07004791 }
4792 }
4793
4794 /**
4795 * Action set from carrier signalling broadcast receivers to enable/disable radio
4796 * @param subId the subscription ID that this action applies to.
4797 * @param enabled control enable or disable radio.
4798 * {@hide}
4799 */
4800 @Override
4801 public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
4802 enforceModifyPermission();
4803 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004804
4805 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07004806 if (phone == null) {
4807 loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
4808 return;
4809 }
4810 try {
4811 phone.carrierActionSetRadioEnabled(enabled);
4812 } catch (Exception e) {
4813 Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004814 } finally {
4815 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07004816 }
4817 }
4818
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07004819 /**
fionaxu8da9cb12017-05-23 15:02:46 -07004820 * Action set from carrier signalling broadcast receivers to start/stop reporting the default
4821 * network status based on which carrier apps could apply actions accordingly,
4822 * enable/disable default url handler for example.
4823 *
4824 * @param subId the subscription ID that this action applies to.
4825 * @param report control start/stop reporting the default network status.
4826 * {@hide}
4827 */
4828 @Override
4829 public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
4830 enforceModifyPermission();
4831 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004832
4833 final long identity = Binder.clearCallingIdentity();
fionaxu8da9cb12017-05-23 15:02:46 -07004834 if (phone == null) {
4835 loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId);
4836 return;
4837 }
4838 try {
4839 phone.carrierActionReportDefaultNetworkStatus(report);
4840 } catch (Exception e) {
4841 Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004842 } finally {
4843 Binder.restoreCallingIdentity(identity);
fionaxu8da9cb12017-05-23 15:02:46 -07004844 }
4845 }
4846
4847 /**
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07004848 * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a
4849 * bug report is being generated.
4850 */
4851 @Override
Ta-wei Yen99282e02016-06-21 18:19:35 -07004852 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
dcashman22b950d2016-06-27 11:39:02 -07004853 if (mPhone.getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
4854 != PackageManager.PERMISSION_GRANTED) {
4855 writer.println("Permission Denial: can't dump Phone from pid="
4856 + Binder.getCallingPid()
4857 + ", uid=" + Binder.getCallingUid()
4858 + "without permission "
4859 + android.Manifest.permission.DUMP);
4860 return;
4861 }
Ta-wei Yen99282e02016-06-21 18:19:35 -07004862 DumpsysHandler.dump(mPhone.getContext(), fd, writer, args);
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07004863 }
Jack Yueb89b242016-06-22 13:27:47 -07004864
Brad Ebingerdac2f002018-04-03 15:17:52 -07004865 @Override
4866 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
4867 String[] args, ShellCallback callback, ResultReceiver resultReceiver)
4868 throws RemoteException {
4869 (new TelephonyShellCommand(this)).exec(this, in, out, err, args, callback, resultReceiver);
4870 }
4871
Jack Yueb89b242016-06-22 13:27:47 -07004872 /**
Jack Yu84291ec2017-05-26 16:07:50 -07004873 * Get aggregated video call data usage since boot.
4874 *
4875 * @param perUidStats True if requesting data usage per uid, otherwise overall usage.
4876 * @return Snapshot of video call data usage
Jack Yueb89b242016-06-22 13:27:47 -07004877 * {@hide}
4878 */
4879 @Override
Jack Yu84291ec2017-05-26 16:07:50 -07004880 public NetworkStats getVtDataUsage(int subId, boolean perUidStats) {
Jack Yueb89b242016-06-22 13:27:47 -07004881 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_NETWORK_USAGE_HISTORY,
4882 null);
4883
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004884 final long identity = Binder.clearCallingIdentity();
4885 try {
4886 // NetworkStatsService keeps tracking the active network interface and identity. It
4887 // records the delta with the corresponding network identity.
4888 // We just return the total video call data usage snapshot since boot.
4889 Phone phone = getPhone(subId);
4890 if (phone != null) {
4891 return phone.getVtDataUsage(perUidStats);
4892 }
4893 return null;
4894 } finally {
4895 Binder.restoreCallingIdentity(identity);
Jack Yueb89b242016-06-22 13:27:47 -07004896 }
Jack Yueb89b242016-06-22 13:27:47 -07004897 }
Jack Yu75ab2952016-07-08 14:29:33 -07004898
4899 /**
4900 * Policy control of data connection. Usually used when data limit is passed.
4901 * @param enabled True if enabling the data, otherwise disabling.
4902 * @param subId Subscription index
4903 * {@hide}
4904 */
4905 @Override
4906 public void setPolicyDataEnabled(boolean enabled, int subId) {
4907 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004908
4909 final long identity = Binder.clearCallingIdentity();
4910 try {
4911 Phone phone = getPhone(subId);
4912 if (phone != null) {
4913 phone.setPolicyDataEnabled(enabled);
4914 }
4915 } finally {
4916 Binder.restoreCallingIdentity(identity);
Jack Yu75ab2952016-07-08 14:29:33 -07004917 }
4918 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004919
4920 /**
4921 * Get Client request stats
4922 * @return List of Client Request Stats
4923 * @hide
4924 */
4925 @Override
4926 public List<ClientRequestStats> getClientRequestStats(String callingPackage, int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004927 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08004928 mApp, subId, callingPackage, "getClientRequestStats")) {
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004929 return null;
4930 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004931 Phone phone = getPhone(subId);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004932
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004933 final long identity = Binder.clearCallingIdentity();
4934 try {
4935 if (phone != null) {
4936 return phone.getClientRequestStats();
4937 }
4938
4939 return null;
4940 } finally {
4941 Binder.restoreCallingIdentity(identity);
4942 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004943 }
4944
Narayan Kamathf04b5a12018-01-09 11:47:15 +00004945 private WorkSource getWorkSource(int uid) {
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004946 String packageName = mPhone.getContext().getPackageManager().getNameForUid(uid);
Narayan Kamathf04b5a12018-01-09 11:47:15 +00004947 return new WorkSource(uid, packageName);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004948 }
Jack Yueb4124c2017-02-16 15:32:43 -08004949
4950 /**
Grace Chen70990072017-03-24 17:21:30 -07004951 * Set SIM card power state.
Jack Yueb4124c2017-02-16 15:32:43 -08004952 *
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004953 * @param slotIndex SIM slot id.
Grace Chen70990072017-03-24 17:21:30 -07004954 * @param state State of SIM (power down, power up, pass through)
4955 * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
4956 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
4957 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
Jack Yueb4124c2017-02-16 15:32:43 -08004958 *
4959 **/
4960 @Override
Grace Chen70990072017-03-24 17:21:30 -07004961 public void setSimPowerStateForSlot(int slotIndex, int state) {
Jack Yueb4124c2017-02-16 15:32:43 -08004962 enforceModifyPermission();
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004963 Phone phone = PhoneFactory.getPhone(slotIndex);
4964
vagdeviaf9a5b92018-08-15 16:01:53 -07004965 WorkSource workSource = getWorkSource(Binder.getCallingUid());
4966
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004967 final long identity = Binder.clearCallingIdentity();
4968 try {
4969 if (phone != null) {
vagdeviaf9a5b92018-08-15 16:01:53 -07004970 phone.setSimPowerState(state, workSource);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08004971 }
4972 } finally {
4973 Binder.restoreCallingIdentity(identity);
Jack Yueb4124c2017-02-16 15:32:43 -08004974 }
4975 }
Shuo Qiandd210312017-04-12 22:11:33 +00004976
Tyler Gunn65d45c22017-06-05 11:22:26 -07004977 private boolean isUssdApiAllowed(int subId) {
4978 CarrierConfigManager configManager =
4979 (CarrierConfigManager) mPhone.getContext().getSystemService(
4980 Context.CARRIER_CONFIG_SERVICE);
4981 if (configManager == null) {
4982 return false;
4983 }
4984 PersistableBundle pb = configManager.getConfigForSubId(subId);
4985 if (pb == null) {
4986 return false;
4987 }
4988 return pb.getBoolean(
4989 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL);
4990 }
4991
Shuo Qiandd210312017-04-12 22:11:33 +00004992 /**
4993 * Check if phone is in emergency callback mode
4994 * @return true if phone is in emergency callback mode
4995 * @param subId sub id
4996 */
goneil9c5f4872017-12-05 14:07:56 -08004997 @Override
Shuo Qiandd210312017-04-12 22:11:33 +00004998 public boolean getEmergencyCallbackMode(int subId) {
goneil9c5f4872017-12-05 14:07:56 -08004999 enforceReadPrivilegedPermission();
Shuo Qiandd210312017-04-12 22:11:33 +00005000 final Phone phone = getPhone(subId);
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005001
5002 final long identity = Binder.clearCallingIdentity();
5003 try {
5004 if (phone != null) {
5005 return phone.isInEcm();
5006 } else {
5007 return false;
5008 }
5009 } finally {
5010 Binder.restoreCallingIdentity(identity);
Shuo Qiandd210312017-04-12 22:11:33 +00005011 }
5012 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08005013
5014 /**
5015 * Get the current signal strength information for the given subscription.
5016 * Because this information is not updated when the device is in a low power state
5017 * it should not be relied-upon to be current.
5018 * @param subId Subscription index
5019 * @return the most recent cached signal strength info from the modem
5020 */
5021 @Override
5022 public SignalStrength getSignalStrength(int subId) {
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005023 final long identity = Binder.clearCallingIdentity();
5024 try {
5025 Phone p = getPhone(subId);
5026 if (p == null) {
5027 return null;
5028 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08005029
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005030 return p.getSignalStrength();
5031 } finally {
5032 Binder.restoreCallingIdentity(identity);
5033 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08005034 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005035
5036 @Override
5037 public UiccSlotInfo[] getUiccSlotsInfo() {
5038 enforceReadPrivilegedPermission();
5039
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005040 final long identity = Binder.clearCallingIdentity();
5041 try {
5042 UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
5043 if (slots == null) {
5044 Rlog.i(LOG_TAG, "slots is null.");
5045 return null;
5046 }
5047
5048 UiccSlotInfo[] infos = new UiccSlotInfo[slots.length];
5049 for (int i = 0; i < slots.length; i++) {
5050 UiccSlot slot = slots[i];
5051 if (slot == null) {
5052 continue;
5053 }
5054
5055 String cardId;
5056 UiccCard card = slot.getUiccCard();
5057 if (card != null) {
5058 cardId = card.getCardId();
5059 } else {
5060 cardId = slot.getIccId();
5061 }
5062
5063 int cardState = 0;
5064 switch (slot.getCardState()) {
5065 case CARDSTATE_ABSENT:
5066 cardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
5067 break;
5068 case CARDSTATE_PRESENT:
5069 cardState = UiccSlotInfo.CARD_STATE_INFO_PRESENT;
5070 break;
5071 case CARDSTATE_ERROR:
5072 cardState = UiccSlotInfo.CARD_STATE_INFO_ERROR;
5073 break;
5074 case CARDSTATE_RESTRICTED:
5075 cardState = UiccSlotInfo.CARD_STATE_INFO_RESTRICTED;
5076 break;
5077 default:
5078 break;
5079
5080 }
5081
5082 infos[i] = new UiccSlotInfo(
5083 slot.isActive(),
5084 slot.isEuicc(),
5085 cardId,
5086 cardState,
5087 slot.getPhoneId(),
5088 slot.isExtendedApduSupported());
5089 }
5090 return infos;
5091 } finally {
5092 Binder.restoreCallingIdentity(identity);
Holly Jiuyu Sun1d957c52018-04-04 13:52:42 -07005093 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005094 }
5095
5096 @Override
5097 public boolean switchSlots(int[] physicalSlots) {
5098 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005099
5100 final long identity = Binder.clearCallingIdentity();
5101 try {
5102 return (Boolean) sendRequest(CMD_SWITCH_SLOTS, physicalSlots);
5103 } finally {
5104 Binder.restoreCallingIdentity(identity);
5105 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005106 }
Jack Yu4c988042018-02-27 15:30:01 -08005107
5108 @Override
5109 public void setRadioIndicationUpdateMode(int subId, int filters, int mode) {
5110 enforceModifyPermission();
5111 final Phone phone = getPhone(subId);
5112 if (phone == null) {
5113 loge("setRadioIndicationUpdateMode fails with invalid subId: " + subId);
5114 return;
5115 }
5116
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005117 final long identity = Binder.clearCallingIdentity();
5118 try {
5119 phone.setRadioIndicationUpdateMode(filters, mode);
5120 } finally {
5121 Binder.restoreCallingIdentity(identity);
5122 }
Jack Yu4c988042018-02-27 15:30:01 -08005123 }
Pengquan Meng85728fb2018-03-12 16:31:21 -07005124
5125 /**
goneil47ffb6e2018-04-06 15:40:58 -07005126 * A test API to reload the UICC profile.
5127 *
5128 * <p>Requires that the calling app has permission
5129 * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
5130 * @hide
5131 */
5132 @Override
5133 public void refreshUiccProfile(int subId) {
5134 enforceModifyPermission();
5135
5136 final long identity = Binder.clearCallingIdentity();
5137 try {
5138 Phone phone = getPhone(subId);
5139 if (phone == null) {
5140 return;
5141 }
5142 UiccCard uiccCard = phone.getUiccCard();
5143 if (uiccCard == null) {
5144 return;
5145 }
5146 UiccProfile uiccProfile = uiccCard.getUiccProfile();
5147 if (uiccProfile == null) {
5148 return;
5149 }
5150 uiccProfile.refresh();
5151 } finally {
5152 Binder.restoreCallingIdentity(identity);
5153 }
5154 }
5155
5156 /**
Pengquan Meng85728fb2018-03-12 16:31:21 -07005157 * Returns false if the mobile data is disabled by default, otherwise return true.
5158 */
5159 private boolean getDefaultDataEnabled() {
5160 return "true".equalsIgnoreCase(
5161 SystemProperties.get(DEFAULT_MOBILE_DATA_PROPERTY_NAME, "true"));
5162 }
5163
5164 /**
5165 * Returns true if the data roaming is enabled by default, i.e the system property
5166 * of {@link #DEFAULT_DATA_ROAMING_PROPERTY_NAME} is true or the config of
5167 * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} is true.
5168 */
5169 private boolean getDefaultDataRoamingEnabled(int subId) {
5170 final CarrierConfigManager configMgr = (CarrierConfigManager)
5171 mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
5172 boolean isDataRoamingEnabled = "true".equalsIgnoreCase(
5173 SystemProperties.get(DEFAULT_DATA_ROAMING_PROPERTY_NAME, "false"));
5174 isDataRoamingEnabled |= configMgr.getConfigForSubId(subId).getBoolean(
5175 CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
5176 return isDataRoamingEnabled;
5177 }
5178
5179 /**
5180 * Returns the default network type for the given {@code subId}, if the default network type is
5181 * not set, return {@link Phone#PREFERRED_NT_MODE}.
5182 */
5183 private int getDefaultNetworkType(int subId) {
5184 return Integer.parseInt(
5185 TelephonyManager.getTelephonyProperty(
5186 mSubscriptionController.getPhoneId(subId),
5187 DEFAULT_NETWORK_MODE_PROPERTY_NAME,
5188 String.valueOf(Phone.PREFERRED_NT_MODE)));
5189 }
fionaxua13278b2018-03-21 00:08:13 -07005190
5191 @Override
5192 public void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String
5193 gid1, String gid2, String plmn, String spn) {
5194 enforceModifyPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005195
5196 final long identity = Binder.clearCallingIdentity();
5197 try {
5198 final Phone phone = getPhone(subId);
5199 if (phone == null) {
5200 loge("setCarrierTestOverride fails with invalid subId: " + subId);
5201 return;
5202 }
5203 phone.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, plmn, spn);
5204 } finally {
5205 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07005206 }
fionaxua13278b2018-03-21 00:08:13 -07005207 }
5208
5209 @Override
5210 public int getCarrierIdListVersion(int subId) {
5211 enforceReadPrivilegedPermission();
Malcolm Chenaa4a8532018-02-28 15:00:40 -08005212
5213 final long identity = Binder.clearCallingIdentity();
5214 try {
5215 final Phone phone = getPhone(subId);
5216 if (phone == null) {
5217 loge("getCarrierIdListVersion fails with invalid subId: " + subId);
5218 return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
5219 }
5220 return phone.getCarrierIdListVersion();
5221 } finally {
5222 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07005223 }
fionaxua13278b2018-03-21 00:08:13 -07005224 }
Malcolm Chen2c63d402018-08-14 16:00:53 -07005225
5226 @Override
5227 public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage) {
5228 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5229 mApp, subId, callingPackage, "getNumberOfModemsWithSimultaneousDataConnections")) {
5230 return -1;
5231 }
5232
5233 final long identity = Binder.clearCallingIdentity();
5234 try {
5235 return mPhoneConfigurationManager.getNumberOfModemsWithSimultaneousDataConnections();
5236 } finally {
5237 Binder.restoreCallingIdentity(identity);
5238 }
5239 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005240}