blob: 145c21f9d1afbc02340e501c72364aad728dd4ce [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 Chenf144d942018-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 Chenf144d942018-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
279 public MainThreadRequest(Object argument) {
280 this.argument = argument;
281 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800282
283 public MainThreadRequest(Object argument, Integer subId) {
284 this.argument = argument;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800285 if (subId != null) {
286 this.subId = subId;
287 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800288 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700289 }
290
Sailesh Nepalcc0375f2013-11-13 09:15:18 -0800291 private static final class IncomingThirdPartyCallArgs {
292 public final ComponentName component;
293 public final String callId;
294 public final String callerDisplayName;
295
296 public IncomingThirdPartyCallArgs(ComponentName component, String callId,
297 String callerDisplayName) {
298 this.component = component;
299 this.callId = callId;
300 this.callerDisplayName = callerDisplayName;
301 }
302 }
303
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700304 /**
305 * A handler that processes messages on the main thread in the phone process. Since many
306 * of the Phone calls are not thread safe this is needed to shuttle the requests from the
307 * inbound binder threads to the main thread in the phone process. The Binder thread
308 * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
309 * on, which will be notified when the operation completes and will contain the result of the
310 * request.
311 *
312 * <p>If a MainThreadRequest object is provided in the msg.obj field,
313 * note that request.result must be set to something non-null for the calling thread to
314 * unblock.
315 */
316 private final class MainThreadHandler extends Handler {
317 @Override
318 public void handleMessage(Message msg) {
319 MainThreadRequest request;
320 Message onCompleted;
321 AsyncResult ar;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800322 UiccCard uiccCard;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700323 IccAPDUArgument iccArgument;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700324
325 switch (msg.what) {
pkanwar32d516d2016-10-14 19:37:38 -0700326 case CMD_HANDLE_USSD_REQUEST: {
327 request = (MainThreadRequest) msg.obj;
328 final Phone phone = getPhoneFromRequest(request);
329 Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
330 String ussdRequest = ussdObject.first;
331 ResultReceiver wrappedCallback = ussdObject.second;
Tyler Gunn65d45c22017-06-05 11:22:26 -0700332
333 if (!isUssdApiAllowed(request.subId)) {
334 // Carrier does not support use of this API, return failure.
335 Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
336 UssdResponse response = new UssdResponse(ussdRequest, null);
337 Bundle returnData = new Bundle();
338 returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
339 wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
340
341 request.result = true;
342 synchronized (request) {
343 request.notifyAll();
344 }
345 return;
346 }
347
Tyler Gunn52dcf772017-04-26 11:30:31 -0700348 try {
349 request.result = phone != null ?
350 phone.handleUssdRequest(ussdRequest, wrappedCallback)
351 : false;
352 } catch (CallStateException cse) {
353 request.result = false;
354 }
pkanwar32d516d2016-10-14 19:37:38 -0700355 // Wake up the requesting thread
356 synchronized (request) {
357 request.notifyAll();
358 }
359 break;
360 }
361
Yorke Lee716f67e2015-06-17 15:39:16 -0700362 case CMD_HANDLE_PIN_MMI: {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700363 request = (MainThreadRequest) msg.obj;
Yorke Lee716f67e2015-06-17 15:39:16 -0700364 final Phone phone = getPhoneFromRequest(request);
365 request.result = phone != null ?
366 getPhoneFromRequest(request).handlePinMmi((String) request.argument)
367 : false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700368 // Wake up the requesting thread
369 synchronized (request) {
370 request.notifyAll();
371 }
372 break;
Yorke Lee716f67e2015-06-17 15:39:16 -0700373 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700374
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700375 case CMD_ANSWER_RINGING_CALL:
Wink Saville08874612014-08-31 19:19:58 -0700376 request = (MainThreadRequest) msg.obj;
Stuart Scott584921c2015-01-15 17:10:34 -0800377 int answer_subId = request.subId;
Wink Saville08874612014-08-31 19:19:58 -0700378 answerRingingCallInternal(answer_subId);
Mengjun Lengb3369682017-10-19 18:39:20 +0800379 request.result = ""; // dummy result for notifying the waiting thread
380 // Wake up the requesting thread
381 synchronized (request) {
382 request.notifyAll();
383 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700384 break;
385
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700386 case CMD_END_CALL:
387 request = (MainThreadRequest) msg.obj;
Stuart Scott584921c2015-01-15 17:10:34 -0800388 int end_subId = request.subId;
Wink Saville08874612014-08-31 19:19:58 -0700389 final boolean hungUp;
Anthony Leeae4e36d2015-05-21 07:17:46 -0700390 Phone phone = getPhone(end_subId);
391 if (phone == null) {
392 if (DBG) log("CMD_END_CALL: no phone for id: " + end_subId);
393 break;
394 }
395 int phoneType = phone.getPhoneType();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700396 if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
397 // CDMA: If the user presses the Power button we treat it as
398 // ending the complete call session
Wink Saville08874612014-08-31 19:19:58 -0700399 hungUp = PhoneUtils.hangupRingingAndActive(getPhone(end_subId));
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700400 } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
401 // GSM: End the call as per the Phone state
402 hungUp = PhoneUtils.hangup(mCM);
403 } else {
404 throw new IllegalStateException("Unexpected phone type: " + phoneType);
405 }
406 if (DBG) log("CMD_END_CALL: " + (hungUp ? "hung up!" : "no call to hang up"));
407 request.result = hungUp;
408 // Wake up the requesting thread
409 synchronized (request) {
410 request.notifyAll();
411 }
412 break;
413
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700414 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700415 request = (MainThreadRequest) msg.obj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700416 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800417 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700418 if (uiccCard == null) {
419 loge("iccTransmitApduLogicalChannel: No UICC");
420 request.result = new IccIoResult(0x6F, 0, (byte[])null);
421 synchronized (request) {
422 request.notifyAll();
423 }
424 } else {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700425 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
426 request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700427 uiccCard.iccTransmitApduLogicalChannel(
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700428 iccArgument.channel, iccArgument.cla, iccArgument.command,
429 iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data,
Shishir Agrawal566b7612013-10-28 14:41:00 -0700430 onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700431 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700432 break;
433
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700434 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700435 ar = (AsyncResult) msg.obj;
436 request = (MainThreadRequest) ar.userObj;
437 if (ar.exception == null && ar.result != null) {
438 request.result = ar.result;
439 } else {
440 request.result = new IccIoResult(0x6F, 0, (byte[])null);
441 if (ar.result == null) {
442 loge("iccTransmitApduLogicalChannel: Empty response");
Jake Hambye994d462014-02-03 13:10:13 -0800443 } else if (ar.exception instanceof CommandException) {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700444 loge("iccTransmitApduLogicalChannel: CommandException: " +
Jake Hambye994d462014-02-03 13:10:13 -0800445 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700446 } else {
447 loge("iccTransmitApduLogicalChannel: Unknown exception");
448 }
449 }
450 synchronized (request) {
451 request.notifyAll();
452 }
453 break;
454
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700455 case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
456 request = (MainThreadRequest) msg.obj;
457 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800458 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700459 if (uiccCard == null) {
460 loge("iccTransmitApduBasicChannel: No UICC");
461 request.result = new IccIoResult(0x6F, 0, (byte[])null);
462 synchronized (request) {
463 request.notifyAll();
464 }
465 } else {
466 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
467 request);
468 uiccCard.iccTransmitApduBasicChannel(
469 iccArgument.cla, iccArgument.command, iccArgument.p1, iccArgument.p2,
470 iccArgument.p3, iccArgument.data, onCompleted);
471 }
472 break;
473
474 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
475 ar = (AsyncResult) msg.obj;
476 request = (MainThreadRequest) ar.userObj;
477 if (ar.exception == null && ar.result != null) {
478 request.result = ar.result;
479 } else {
480 request.result = new IccIoResult(0x6F, 0, (byte[])null);
481 if (ar.result == null) {
482 loge("iccTransmitApduBasicChannel: Empty response");
483 } else if (ar.exception instanceof CommandException) {
484 loge("iccTransmitApduBasicChannel: CommandException: " +
485 ar.exception);
486 } else {
487 loge("iccTransmitApduBasicChannel: Unknown exception");
488 }
489 }
490 synchronized (request) {
491 request.notifyAll();
492 }
493 break;
494
495 case CMD_EXCHANGE_SIM_IO:
496 request = (MainThreadRequest) msg.obj;
497 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800498 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700499 if (uiccCard == null) {
500 loge("iccExchangeSimIO: No UICC");
501 request.result = new IccIoResult(0x6F, 0, (byte[])null);
502 synchronized (request) {
503 request.notifyAll();
504 }
505 } else {
506 onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
507 request);
508 uiccCard.iccExchangeSimIO(iccArgument.cla, /* fileID */
509 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3,
510 iccArgument.data, onCompleted);
511 }
512 break;
513
514 case EVENT_EXCHANGE_SIM_IO_DONE:
515 ar = (AsyncResult) msg.obj;
516 request = (MainThreadRequest) ar.userObj;
517 if (ar.exception == null && ar.result != null) {
518 request.result = ar.result;
519 } else {
520 request.result = new IccIoResult(0x6f, 0, (byte[])null);
521 }
522 synchronized (request) {
523 request.notifyAll();
524 }
525 break;
526
Derek Tan4d5e5c12014-02-04 11:54:58 -0800527 case CMD_SEND_ENVELOPE:
528 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800529 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700530 if (uiccCard == null) {
531 loge("sendEnvelopeWithStatus: No UICC");
532 request.result = new IccIoResult(0x6F, 0, (byte[])null);
533 synchronized (request) {
534 request.notifyAll();
535 }
536 } else {
537 onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
538 uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted);
539 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800540 break;
541
542 case EVENT_SEND_ENVELOPE_DONE:
543 ar = (AsyncResult) msg.obj;
544 request = (MainThreadRequest) ar.userObj;
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700545 if (ar.exception == null && ar.result != null) {
546 request.result = ar.result;
Derek Tan4d5e5c12014-02-04 11:54:58 -0800547 } else {
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700548 request.result = new IccIoResult(0x6F, 0, (byte[])null);
549 if (ar.result == null) {
550 loge("sendEnvelopeWithStatus: Empty response");
551 } else if (ar.exception instanceof CommandException) {
552 loge("sendEnvelopeWithStatus: CommandException: " +
553 ar.exception);
554 } else {
555 loge("sendEnvelopeWithStatus: exception:" + ar.exception);
556 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800557 }
558 synchronized (request) {
559 request.notifyAll();
560 }
561 break;
562
Shishir Agrawal566b7612013-10-28 14:41:00 -0700563 case CMD_OPEN_CHANNEL:
564 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800565 uiccCard = getUiccCardFromRequest(request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800566 Pair<String, Integer> openChannelArgs = (Pair<String, Integer>) request.argument;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700567 if (uiccCard == null) {
568 loge("iccOpenLogicalChannel: No UICC");
Shishir Agrawalfc0492a2016-02-17 11:15:33 -0800569 request.result = new IccOpenLogicalChannelResponse(-1,
570 IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700571 synchronized (request) {
572 request.notifyAll();
573 }
574 } else {
575 onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800576 uiccCard.iccOpenLogicalChannel(openChannelArgs.first,
577 openChannelArgs.second, onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700578 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700579 break;
580
581 case EVENT_OPEN_CHANNEL_DONE:
582 ar = (AsyncResult) msg.obj;
583 request = (MainThreadRequest) ar.userObj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700584 IccOpenLogicalChannelResponse openChannelResp;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700585 if (ar.exception == null && ar.result != null) {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700586 int[] result = (int[]) ar.result;
587 int channelId = result[0];
588 byte[] selectResponse = null;
589 if (result.length > 1) {
590 selectResponse = new byte[result.length - 1];
591 for (int i = 1; i < result.length; ++i) {
592 selectResponse[i - 1] = (byte) result[i];
593 }
594 }
595 openChannelResp = new IccOpenLogicalChannelResponse(channelId,
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700596 IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700597 } else {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700598 if (ar.result == null) {
599 loge("iccOpenLogicalChannel: Empty response");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700600 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700601 if (ar.exception != null) {
602 loge("iccOpenLogicalChannel: Exception: " + ar.exception);
603 }
604
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700605 int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR;
Junda Liua754ba12015-05-20 01:17:52 -0700606 if (ar.exception instanceof CommandException) {
607 CommandException.Error error =
608 ((CommandException) (ar.exception)).getCommandError();
609 if (error == CommandException.Error.MISSING_RESOURCE) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700610 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE;
Junda Liua754ba12015-05-20 01:17:52 -0700611 } else if (error == CommandException.Error.NO_SUCH_ELEMENT) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700612 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700613 }
614 }
615 openChannelResp = new IccOpenLogicalChannelResponse(
616 IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700617 }
Shishir Agrawal82c8a462014-07-31 18:13:17 -0700618 request.result = openChannelResp;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700619 synchronized (request) {
620 request.notifyAll();
621 }
622 break;
623
624 case CMD_CLOSE_CHANNEL:
625 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800626 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700627 if (uiccCard == null) {
628 loge("iccCloseLogicalChannel: No UICC");
Yoshiaki Naka2e29d822016-09-02 19:27:39 +0900629 request.result = false;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700630 synchronized (request) {
631 request.notifyAll();
632 }
633 } else {
634 onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
635 uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
636 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700637 break;
638
639 case EVENT_CLOSE_CHANNEL_DONE:
Jake Hambye994d462014-02-03 13:10:13 -0800640 handleNullReturnEvent(msg, "iccCloseLogicalChannel");
641 break;
642
643 case CMD_NV_READ_ITEM:
644 request = (MainThreadRequest) msg.obj;
645 onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
646 mPhone.nvReadItem((Integer) request.argument, onCompleted);
647 break;
648
649 case EVENT_NV_READ_ITEM_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700650 ar = (AsyncResult) msg.obj;
651 request = (MainThreadRequest) ar.userObj;
Jake Hambye994d462014-02-03 13:10:13 -0800652 if (ar.exception == null && ar.result != null) {
653 request.result = ar.result; // String
Shishir Agrawal566b7612013-10-28 14:41:00 -0700654 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800655 request.result = "";
656 if (ar.result == null) {
657 loge("nvReadItem: Empty response");
658 } else if (ar.exception instanceof CommandException) {
659 loge("nvReadItem: CommandException: " +
660 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700661 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800662 loge("nvReadItem: Unknown exception");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700663 }
664 }
665 synchronized (request) {
666 request.notifyAll();
667 }
668 break;
669
Jake Hambye994d462014-02-03 13:10:13 -0800670 case CMD_NV_WRITE_ITEM:
671 request = (MainThreadRequest) msg.obj;
672 onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
673 Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
674 mPhone.nvWriteItem(idValue.first, idValue.second, onCompleted);
675 break;
676
677 case EVENT_NV_WRITE_ITEM_DONE:
678 handleNullReturnEvent(msg, "nvWriteItem");
679 break;
680
681 case CMD_NV_WRITE_CDMA_PRL:
682 request = (MainThreadRequest) msg.obj;
683 onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
684 mPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
685 break;
686
687 case EVENT_NV_WRITE_CDMA_PRL_DONE:
688 handleNullReturnEvent(msg, "nvWriteCdmaPrl");
689 break;
690
691 case CMD_NV_RESET_CONFIG:
692 request = (MainThreadRequest) msg.obj;
693 onCompleted = obtainMessage(EVENT_NV_RESET_CONFIG_DONE, request);
694 mPhone.nvResetConfig((Integer) request.argument, onCompleted);
695 break;
696
697 case EVENT_NV_RESET_CONFIG_DONE:
698 handleNullReturnEvent(msg, "nvResetConfig");
699 break;
700
Jake Hamby7c27be32014-03-03 13:25:59 -0800701 case CMD_GET_PREFERRED_NETWORK_TYPE:
702 request = (MainThreadRequest) msg.obj;
703 onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request);
Stuart Scott54788802015-03-30 13:18:01 -0700704 getPhoneFromRequest(request).getPreferredNetworkType(onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800705 break;
706
707 case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE:
708 ar = (AsyncResult) msg.obj;
709 request = (MainThreadRequest) ar.userObj;
710 if (ar.exception == null && ar.result != null) {
711 request.result = ar.result; // Integer
712 } else {
Sanket Padawecfc2d352016-01-05 19:52:14 -0800713 request.result = null;
Jake Hamby7c27be32014-03-03 13:25:59 -0800714 if (ar.result == null) {
715 loge("getPreferredNetworkType: Empty response");
716 } else if (ar.exception instanceof CommandException) {
717 loge("getPreferredNetworkType: CommandException: " +
718 ar.exception);
719 } else {
720 loge("getPreferredNetworkType: Unknown exception");
721 }
722 }
723 synchronized (request) {
724 request.notifyAll();
725 }
726 break;
727
728 case CMD_SET_PREFERRED_NETWORK_TYPE:
729 request = (MainThreadRequest) msg.obj;
730 onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request);
731 int networkType = (Integer) request.argument;
Stuart Scott54788802015-03-30 13:18:01 -0700732 getPhoneFromRequest(request).setPreferredNetworkType(networkType, onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800733 break;
734
735 case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE:
736 handleNullReturnEvent(msg, "setPreferredNetworkType");
737 break;
738
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000739 case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
740 request = (MainThreadRequest)msg.obj;
741 onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
742 mPhone.invokeOemRilRequestRaw((byte[])request.argument, onCompleted);
743 break;
744
745 case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
746 ar = (AsyncResult)msg.obj;
747 request = (MainThreadRequest)ar.userObj;
748 request.result = ar;
749 synchronized (request) {
750 request.notifyAll();
751 }
752 break;
753
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800754 case CMD_SET_VOICEMAIL_NUMBER:
755 request = (MainThreadRequest) msg.obj;
756 onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
757 Pair<String, String> tagNum = (Pair<String, String>) request.argument;
Stuart Scott584921c2015-01-15 17:10:34 -0800758 getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
759 onCompleted);
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800760 break;
761
762 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
763 handleNullReturnEvent(msg, "setVoicemailNumber");
764 break;
765
Stuart Scott54788802015-03-30 13:18:01 -0700766 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC:
767 request = (MainThreadRequest) msg.obj;
768 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE,
769 request);
770 getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted);
771 break;
772
773 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE:
774 handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic");
775 break;
776
Shishir Agrawal302c8692015-06-19 13:49:39 -0700777 case CMD_PERFORM_NETWORK_SCAN:
778 request = (MainThreadRequest) msg.obj;
779 onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request);
780 getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
781 break;
782
783 case EVENT_PERFORM_NETWORK_SCAN_DONE:
784 ar = (AsyncResult) msg.obj;
785 request = (MainThreadRequest) ar.userObj;
786 CellNetworkScanResult cellScanResult;
787 if (ar.exception == null && ar.result != null) {
788 cellScanResult = new CellNetworkScanResult(
789 CellNetworkScanResult.STATUS_SUCCESS,
790 (List<OperatorInfo>) ar.result);
791 } else {
792 if (ar.result == null) {
793 loge("getCellNetworkScanResults: Empty response");
794 }
795 if (ar.exception != null) {
796 loge("getCellNetworkScanResults: Exception: " + ar.exception);
797 }
798 int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR;
799 if (ar.exception instanceof CommandException) {
800 CommandException.Error error =
801 ((CommandException) (ar.exception)).getCommandError();
802 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
803 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE;
804 } else if (error == CommandException.Error.GENERIC_FAILURE) {
805 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE;
806 }
807 }
808 cellScanResult = new CellNetworkScanResult(errorCode, null);
809 }
810 request.result = cellScanResult;
811 synchronized (request) {
812 request.notifyAll();
813 }
814 break;
815
816 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
817 request = (MainThreadRequest) msg.obj;
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700818 ManualNetworkSelectionArgument selArg =
819 (ManualNetworkSelectionArgument) request.argument;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700820 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE,
821 request);
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700822 getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo,
823 selArg.persistSelection, onCompleted);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700824 break;
825
826 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
827 handleNullReturnEvent(msg, "setNetworkSelectionModeManual");
828 break;
829
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700830 case CMD_GET_MODEM_ACTIVITY_INFO:
831 request = (MainThreadRequest) msg.obj;
832 onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
Prerepa Viswanadham61a60ad2015-06-08 18:07:51 -0700833 mPhone.getModemActivityInfo(onCompleted);
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700834 break;
835
836 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE:
837 ar = (AsyncResult) msg.obj;
838 request = (MainThreadRequest) ar.userObj;
839 if (ar.exception == null && ar.result != null) {
840 request.result = ar.result;
841 } else {
842 if (ar.result == null) {
843 loge("queryModemActivityInfo: Empty response");
844 } else if (ar.exception instanceof CommandException) {
845 loge("queryModemActivityInfo: CommandException: " +
846 ar.exception);
847 } else {
848 loge("queryModemActivityInfo: Unknown exception");
849 }
850 }
Amit Mahajand4766222016-01-28 15:28:28 -0800851 // Result cannot be null. Return ModemActivityInfo with all fields set to 0.
852 if (request.result == null) {
853 request.result = new ModemActivityInfo(0, 0, 0, null, 0, 0);
854 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700855 synchronized (request) {
856 request.notifyAll();
857 }
858 break;
859
Meng Wang1a7c35a2016-05-05 20:56:15 -0700860 case CMD_SET_ALLOWED_CARRIERS:
861 request = (MainThreadRequest) msg.obj;
862 onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
863 mPhone.setAllowedCarriers(
864 (List<CarrierIdentifier>) request.argument,
865 onCompleted);
866 break;
867
868 case EVENT_SET_ALLOWED_CARRIERS_DONE:
869 ar = (AsyncResult) msg.obj;
870 request = (MainThreadRequest) ar.userObj;
871 if (ar.exception == null && ar.result != null) {
872 request.result = ar.result;
873 } else {
874 if (ar.result == null) {
875 loge("setAllowedCarriers: Empty response");
876 } else if (ar.exception instanceof CommandException) {
877 loge("setAllowedCarriers: CommandException: " +
878 ar.exception);
879 } else {
880 loge("setAllowedCarriers: Unknown exception");
881 }
882 }
883 // Result cannot be null. Return -1 on error.
884 if (request.result == null) {
885 request.result = new int[]{-1};
886 }
887 synchronized (request) {
888 request.notifyAll();
889 }
890 break;
891
892 case CMD_GET_ALLOWED_CARRIERS:
893 request = (MainThreadRequest) msg.obj;
894 onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
895 mPhone.getAllowedCarriers(onCompleted);
896 break;
897
898 case EVENT_GET_ALLOWED_CARRIERS_DONE:
899 ar = (AsyncResult) msg.obj;
900 request = (MainThreadRequest) ar.userObj;
901 if (ar.exception == null && ar.result != null) {
902 request.result = ar.result;
903 } else {
904 if (ar.result == null) {
905 loge("getAllowedCarriers: Empty response");
906 } else if (ar.exception instanceof CommandException) {
907 loge("getAllowedCarriers: CommandException: " +
908 ar.exception);
909 } else {
910 loge("getAllowedCarriers: Unknown exception");
911 }
912 }
913 // Result cannot be null. Return empty list of CarrierIdentifier.
914 if (request.result == null) {
915 request.result = new ArrayList<CarrierIdentifier>(0);
916 }
917 synchronized (request) {
918 request.notifyAll();
919 }
920 break;
921
Nathan Haroldb3014052017-01-25 15:57:32 -0800922 case EVENT_GET_FORBIDDEN_PLMNS_DONE:
923 ar = (AsyncResult) msg.obj;
924 request = (MainThreadRequest) ar.userObj;
925 if (ar.exception == null && ar.result != null) {
926 request.result = ar.result;
927 } else {
928 request.result = new IllegalArgumentException(
929 "Failed to retrieve Forbidden Plmns");
930 if (ar.result == null) {
931 loge("getForbiddenPlmns: Empty response");
932 } else {
933 loge("getForbiddenPlmns: Unknown exception");
934 }
935 }
936 synchronized (request) {
937 request.notifyAll();
938 }
939 break;
940
941 case CMD_GET_FORBIDDEN_PLMNS:
942 request = (MainThreadRequest) msg.obj;
943 uiccCard = getUiccCardFromRequest(request);
944 if (uiccCard == null) {
945 loge("getForbiddenPlmns() UiccCard is null");
946 request.result = new IllegalArgumentException(
947 "getForbiddenPlmns() UiccCard is null");
948 synchronized (request) {
949 request.notifyAll();
950 }
951 break;
952 }
953 Integer appType = (Integer) request.argument;
954 UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType);
955 if (uiccApp == null) {
956 loge("getForbiddenPlmns() no app with specified type -- "
957 + appType);
958 request.result = new IllegalArgumentException("Failed to get UICC App");
959 synchronized (request) {
960 request.notifyAll();
961 }
962 break;
963 } else {
964 if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
965 + " specified type -- " + appType);
966 }
967 onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
968 ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
969 onCompleted);
970 break;
971
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000972 case CMD_SWITCH_SLOTS:
973 request = (MainThreadRequest) msg.obj;
974 int[] physicalSlots = (int[]) request.argument;
975 onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
976 UiccController.getInstance().switchSlots(physicalSlots, onCompleted);
977 break;
978
979 case EVENT_SWITCH_SLOTS_DONE:
980 ar = (AsyncResult) msg.obj;
981 request = (MainThreadRequest) ar.userObj;
982 request.result = (ar.exception == null);
983 synchronized (request) {
984 request.notifyAll();
985 }
986 break;
987
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700988 default:
989 Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
990 break;
991 }
992 }
Jake Hambye994d462014-02-03 13:10:13 -0800993
994 private void handleNullReturnEvent(Message msg, String command) {
995 AsyncResult ar = (AsyncResult) msg.obj;
996 MainThreadRequest request = (MainThreadRequest) ar.userObj;
997 if (ar.exception == null) {
998 request.result = true;
999 } else {
1000 request.result = false;
1001 if (ar.exception instanceof CommandException) {
1002 loge(command + ": CommandException: " + ar.exception);
1003 } else {
1004 loge(command + ": Unknown exception");
1005 }
1006 }
1007 synchronized (request) {
1008 request.notifyAll();
1009 }
1010 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001011 }
1012
1013 /**
1014 * Posts the specified command to be executed on the main thread,
1015 * waits for the request to complete, and returns the result.
1016 * @see #sendRequestAsync
1017 */
1018 private Object sendRequest(int command, Object argument) {
Sanket Padawe56e75a32016-02-08 12:18:19 -08001019 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Wink Saville36469e72014-06-11 15:17:00 -07001020 }
1021
1022 /**
1023 * Posts the specified command to be executed on the main thread,
1024 * waits for the request to complete, and returns the result.
1025 * @see #sendRequestAsync
1026 */
Shishir Agrawal76d5da92014-11-09 16:17:25 -08001027 private Object sendRequest(int command, Object argument, Integer subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001028 if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
1029 throw new RuntimeException("This method will deadlock if called from the main thread.");
1030 }
1031
Shishir Agrawal76d5da92014-11-09 16:17:25 -08001032 MainThreadRequest request = new MainThreadRequest(argument, subId);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001033 Message msg = mMainThreadHandler.obtainMessage(command, request);
1034 msg.sendToTarget();
1035
1036 // Wait for the request to complete
1037 synchronized (request) {
1038 while (request.result == null) {
1039 try {
1040 request.wait();
1041 } catch (InterruptedException e) {
1042 // Do nothing, go back and wait until the request is complete
1043 }
1044 }
1045 }
1046 return request.result;
1047 }
1048
1049 /**
1050 * Asynchronous ("fire and forget") version of sendRequest():
1051 * Posts the specified command to be executed on the main thread, and
1052 * returns immediately.
1053 * @see #sendRequest
1054 */
1055 private void sendRequestAsync(int command) {
1056 mMainThreadHandler.sendEmptyMessage(command);
1057 }
1058
1059 /**
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001060 * Same as {@link #sendRequestAsync(int)} except it takes an argument.
1061 * @see {@link #sendRequest(int,Object)}
1062 */
1063 private void sendRequestAsync(int command, Object argument) {
1064 MainThreadRequest request = new MainThreadRequest(argument);
1065 Message msg = mMainThreadHandler.obtainMessage(command, request);
1066 msg.sendToTarget();
1067 }
1068
1069 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001070 * Initialize the singleton PhoneInterfaceManager instance.
1071 * This is only done once, at startup, from PhoneApp.onCreate().
1072 */
Sailesh Nepal194161e2014-07-03 08:57:44 -07001073 /* package */ static PhoneInterfaceManager init(PhoneGlobals app, Phone phone) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001074 synchronized (PhoneInterfaceManager.class) {
1075 if (sInstance == null) {
Sailesh Nepal194161e2014-07-03 08:57:44 -07001076 sInstance = new PhoneInterfaceManager(app, phone);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001077 } else {
1078 Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
1079 }
1080 return sInstance;
1081 }
1082 }
1083
1084 /** Private constructor; @see init() */
Sailesh Nepal194161e2014-07-03 08:57:44 -07001085 private PhoneInterfaceManager(PhoneGlobals app, Phone phone) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001086 mApp = app;
1087 mPhone = phone;
1088 mCM = PhoneGlobals.getInstance().mCM;
Stuart Scott981d8582015-04-21 14:09:50 -07001089 mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001090 mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
1091 mMainThreadHandler = new MainThreadHandler();
Andrew Leedf14ead2014-10-17 14:22:52 -07001092 mTelephonySharedPreferences =
Derek Tan97ebb422014-09-05 16:55:38 -07001093 PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
Wink Savilleac1bdfd2014-11-20 23:04:44 -08001094 mSubscriptionController = SubscriptionController.getInstance();
yinxub1bed742017-04-17 11:45:04 -07001095 mNetworkScanRequestTracker = new NetworkScanRequestTracker();
Malcolm Chenf144d942018-08-14 16:00:53 -07001096 mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
Wink Saville3ab207e2014-11-20 13:07:20 -08001097
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001098 publish();
1099 }
1100
1101 private void publish() {
1102 if (DBG) log("publish: " + this);
1103
1104 ServiceManager.addService("phone", this);
1105 }
1106
Stuart Scott584921c2015-01-15 17:10:34 -08001107 private Phone getPhoneFromRequest(MainThreadRequest request) {
Sanket Padawe56e75a32016-02-08 12:18:19 -08001108 return (request.subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
1109 ? mPhone : getPhone(request.subId);
Stuart Scott584921c2015-01-15 17:10:34 -08001110 }
1111
Shishir Agrawalc04d9752016-02-19 10:41:00 -08001112 private UiccCard getUiccCardFromRequest(MainThreadRequest request) {
1113 Phone phone = getPhoneFromRequest(request);
1114 return phone == null ? null :
1115 UiccController.getInstance().getUiccCard(phone.getPhoneId());
1116 }
1117
Wink Saville36469e72014-06-11 15:17:00 -07001118 // returns phone associated with the subId.
Wink Savilleb564aae2014-10-23 10:18:09 -07001119 private Phone getPhone(int subId) {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08001120 return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId));
Wink Saville36469e72014-06-11 15:17:00 -07001121 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001122 //
1123 // Implementation of the ITelephony interface.
1124 //
1125
1126 public void dial(String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001127 dialForSubscriber(getPreferredVoiceSubscription(), number);
Wink Saville36469e72014-06-11 15:17:00 -07001128 }
1129
Wink Savilleb564aae2014-10-23 10:18:09 -07001130 public void dialForSubscriber(int subId, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001131 if (DBG) log("dial: " + number);
1132 // No permission check needed here: This is just a wrapper around the
1133 // ACTION_DIAL intent, which is available to any app since it puts up
1134 // the UI before it does anything.
1135
Malcolm Chenaabec062018-02-28 15:00:40 -08001136 final long identity = Binder.clearCallingIdentity();
1137 try {
1138 String url = createTelUrl(number);
1139 if (url == null) {
1140 return;
1141 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001142
Malcolm Chenaabec062018-02-28 15:00:40 -08001143 // PENDING: should we just silently fail if phone is offhook or ringing?
1144 PhoneConstants.State state = mCM.getState(subId);
1145 if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
1146 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
1147 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1148 mApp.startActivity(intent);
1149 }
1150 } finally {
1151 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001152 }
1153 }
1154
1155 public void call(String callingPackage, String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001156 callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number);
Wink Saville36469e72014-06-11 15:17:00 -07001157 }
1158
Wink Savilleb564aae2014-10-23 10:18:09 -07001159 public void callForSubscriber(int subId, String callingPackage, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001160 if (DBG) log("call: " + number);
1161
1162 // This is just a wrapper around the ACTION_CALL intent, but we still
1163 // need to do a permission check since we're calling startActivity()
1164 // from the context of the phone app.
1165 enforceCallPermission();
1166
1167 if (mAppOps.noteOp(AppOpsManager.OP_CALL_PHONE, Binder.getCallingUid(), callingPackage)
1168 != AppOpsManager.MODE_ALLOWED) {
1169 return;
1170 }
1171
Malcolm Chenaabec062018-02-28 15:00:40 -08001172 final long identity = Binder.clearCallingIdentity();
1173 try {
1174 String url = createTelUrl(number);
1175 if (url == null) {
1176 return;
1177 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001178
Malcolm Chenaabec062018-02-28 15:00:40 -08001179 boolean isValid = false;
1180 final List<SubscriptionInfo> slist = getActiveSubscriptionInfoListPrivileged();
1181 if (slist != null) {
1182 for (SubscriptionInfo subInfoRecord : slist) {
1183 if (subInfoRecord.getSubscriptionId() == subId) {
1184 isValid = true;
1185 break;
1186 }
Wink Saville3ab207e2014-11-20 13:07:20 -08001187 }
Wink Saville08874612014-08-31 19:19:58 -07001188 }
Malcolm Chenaabec062018-02-28 15:00:40 -08001189 if (!isValid) {
1190 return;
1191 }
Wink Saville08874612014-08-31 19:19:58 -07001192
Malcolm Chenaabec062018-02-28 15:00:40 -08001193 Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
1194 intent.putExtra(SUBSCRIPTION_KEY, subId);
1195 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1196 mApp.startActivity(intent);
1197 } finally {
1198 Binder.restoreCallingIdentity(identity);
1199 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001200 }
1201
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001202 /**
1203 * End a call based on call state
1204 * @return true is a call was ended
1205 */
1206 public boolean endCall() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001207 return endCallForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001208 }
1209
1210 /**
1211 * End a call based on the call state of the subId
1212 * @return true is a call was ended
1213 */
Wink Savilleb564aae2014-10-23 10:18:09 -07001214 public boolean endCallForSubscriber(int subId) {
Tyler Gunn67073572018-02-14 14:19:42 -08001215 if (mApp.checkCallingOrSelfPermission(permission.MODIFY_PHONE_STATE)
1216 != PackageManager.PERMISSION_GRANTED) {
1217 Log.i(LOG_TAG, "endCall: called without modify phone state.");
1218 EventLog.writeEvent(0x534e4554, "67862398", -1, "");
1219 throw new SecurityException("MODIFY_PHONE_STATE permission required.");
1220 }
Malcolm Chenaabec062018-02-28 15:00:40 -08001221 final long identity = Binder.clearCallingIdentity();
1222 try {
1223 return (Boolean) sendRequest(CMD_END_CALL, null, new Integer(subId));
1224 } finally {
1225 Binder.restoreCallingIdentity(identity);
1226 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001227 }
1228
1229 public void answerRingingCall() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001230 answerRingingCallForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001231 }
1232
Wink Savilleb564aae2014-10-23 10:18:09 -07001233 public void answerRingingCallForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001234 if (DBG) log("answerRingingCall...");
1235 // TODO: there should eventually be a separate "ANSWER_PHONE" permission,
1236 // but that can probably wait till the big TelephonyManager API overhaul.
1237 // For now, protect this call with the MODIFY_PHONE_STATE permission.
1238 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001239
1240 final long identity = Binder.clearCallingIdentity();
1241 try {
1242 sendRequest(CMD_ANSWER_RINGING_CALL, null, new Integer(subId));
1243 } finally {
1244 Binder.restoreCallingIdentity(identity);
1245 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001246 }
1247
1248 /**
1249 * Make the actual telephony calls to implement answerRingingCall().
1250 * This should only be called from the main thread of the Phone app.
1251 * @see #answerRingingCall
1252 *
1253 * TODO: it would be nice to return true if we answered the call, or
1254 * false if there wasn't actually a ringing incoming call, or some
1255 * other error occurred. (In other words, pass back the return value
1256 * from PhoneUtils.answerCall() or PhoneUtils.answerAndEndActive().)
1257 * But that would require calling this method via sendRequest() rather
1258 * than sendRequestAsync(), and right now we don't actually *need* that
1259 * return value, so let's just return void for now.
1260 */
Wink Savilleb564aae2014-10-23 10:18:09 -07001261 private void answerRingingCallInternal(int subId) {
Wink Saville08874612014-08-31 19:19:58 -07001262 final boolean hasRingingCall = !getPhone(subId).getRingingCall().isIdle();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001263 if (hasRingingCall) {
Wink Saville08874612014-08-31 19:19:58 -07001264 final boolean hasActiveCall = !getPhone(subId).getForegroundCall().isIdle();
1265 final boolean hasHoldingCall = !getPhone(subId).getBackgroundCall().isIdle();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001266 if (hasActiveCall && hasHoldingCall) {
1267 // Both lines are in use!
1268 // TODO: provide a flag to let the caller specify what
1269 // policy to use if both lines are in use. (The current
1270 // behavior is hardwired to "answer incoming, end ongoing",
1271 // which is how the CALL button is specced to behave.)
1272 PhoneUtils.answerAndEndActive(mCM, mCM.getFirstActiveRingingCall());
1273 return;
1274 } else {
1275 // answerCall() will automatically hold the current active
1276 // call, if there is one.
1277 PhoneUtils.answerCall(mCM.getFirstActiveRingingCall());
1278 return;
1279 }
1280 } else {
1281 // No call was ringing.
1282 return;
1283 }
1284 }
1285
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001286 /**
Santos Cordon5422a8d2014-09-12 04:20:56 -07001287 * This method is no longer used and can be removed once TelephonyManager stops referring to it.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001288 */
Santos Cordon5422a8d2014-09-12 04:20:56 -07001289 public void silenceRinger() {
1290 Log.e(LOG_TAG, "silenseRinger not supported");
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001291 }
1292
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001293 @Override
1294 public boolean isOffhook(String callingPackage) {
1295 return isOffhookForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07001296 }
1297
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001298 @Override
1299 public boolean isOffhookForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08001300 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08001301 mApp, subId, callingPackage, "isOffhookForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001302 return false;
1303 }
1304
Malcolm Chenaabec062018-02-28 15:00:40 -08001305 final long identity = Binder.clearCallingIdentity();
1306 try {
1307 final Phone phone = getPhone(subId);
1308 if (phone != null) {
1309 return (phone.getState() == PhoneConstants.State.OFFHOOK);
1310 } else {
1311 return false;
1312 }
1313 } finally {
1314 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001315 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001316 }
1317
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001318 @Override
1319 public boolean isRinging(String callingPackage) {
1320 return (isRingingForSubscriber(getDefaultSubscription(), callingPackage));
Wink Saville36469e72014-06-11 15:17:00 -07001321 }
1322
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001323 @Override
1324 public boolean isRingingForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08001325 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08001326 mApp, subId, callingPackage, "isRingingForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001327 return false;
1328 }
1329
Malcolm Chenaabec062018-02-28 15:00:40 -08001330 final long identity = Binder.clearCallingIdentity();
1331 try {
1332 final Phone phone = getPhone(subId);
1333 if (phone != null) {
1334 return (phone.getState() == PhoneConstants.State.RINGING);
1335 } else {
1336 return false;
1337 }
1338 } finally {
1339 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001340 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001341 }
1342
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001343 @Override
1344 public boolean isIdle(String callingPackage) {
1345 return isIdleForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07001346 }
1347
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001348 @Override
1349 public boolean isIdleForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08001350 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08001351 mApp, subId, callingPackage, "isIdleForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001352 return false;
1353 }
1354
Malcolm Chenaabec062018-02-28 15:00:40 -08001355 final long identity = Binder.clearCallingIdentity();
1356 try {
1357 final Phone phone = getPhone(subId);
1358 if (phone != null) {
1359 return (phone.getState() == PhoneConstants.State.IDLE);
1360 } else {
1361 return false;
1362 }
1363 } finally {
1364 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001365 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001366 }
1367
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001368 public boolean supplyPin(String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001369 return supplyPinForSubscriber(getDefaultSubscription(), pin);
Wink Saville36469e72014-06-11 15:17:00 -07001370 }
1371
Wink Savilleb564aae2014-10-23 10:18:09 -07001372 public boolean supplyPinForSubscriber(int subId, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001373 int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07001374 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1375 }
1376
1377 public boolean supplyPuk(String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001378 return supplyPukForSubscriber(getDefaultSubscription(), puk, pin);
Wink Saville36469e72014-06-11 15:17:00 -07001379 }
1380
Wink Savilleb564aae2014-10-23 10:18:09 -07001381 public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001382 int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07001383 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1384 }
1385
1386 /** {@hide} */
1387 public int[] supplyPinReportResult(String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001388 return supplyPinReportResultForSubscriber(getDefaultSubscription(), pin);
Wink Saville36469e72014-06-11 15:17:00 -07001389 }
1390
Wink Savilleb564aae2014-10-23 10:18:09 -07001391 public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001392 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001393
1394 final long identity = Binder.clearCallingIdentity();
1395 try {
1396 final UnlockSim checkSimPin = new UnlockSim(getPhone(subId).getIccCard());
1397 checkSimPin.start();
1398 return checkSimPin.unlockSim(null, pin);
1399 } finally {
1400 Binder.restoreCallingIdentity(identity);
1401 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001402 }
1403
Wink Saville9de0f752013-10-22 19:04:03 -07001404 /** {@hide} */
1405 public int[] supplyPukReportResult(String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001406 return supplyPukReportResultForSubscriber(getDefaultSubscription(), puk, pin);
Wink Saville36469e72014-06-11 15:17:00 -07001407 }
1408
Wink Savilleb564aae2014-10-23 10:18:09 -07001409 public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001410 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001411
1412 final long identity = Binder.clearCallingIdentity();
1413 try {
1414 final UnlockSim checkSimPuk = new UnlockSim(getPhone(subId).getIccCard());
1415 checkSimPuk.start();
1416 return checkSimPuk.unlockSim(puk, pin);
1417 } finally {
1418 Binder.restoreCallingIdentity(identity);
1419 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001420 }
1421
1422 /**
Wink Saville9de0f752013-10-22 19:04:03 -07001423 * Helper thread to turn async call to SimCard#supplyPin into
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001424 * a synchronous one.
1425 */
1426 private static class UnlockSim extends Thread {
1427
1428 private final IccCard mSimCard;
1429
1430 private boolean mDone = false;
Wink Saville9de0f752013-10-22 19:04:03 -07001431 private int mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1432 private int mRetryCount = -1;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001433
1434 // For replies from SimCard interface
1435 private Handler mHandler;
1436
1437 // For async handler to identify request type
1438 private static final int SUPPLY_PIN_COMPLETE = 100;
1439
1440 public UnlockSim(IccCard simCard) {
1441 mSimCard = simCard;
1442 }
1443
1444 @Override
1445 public void run() {
1446 Looper.prepare();
1447 synchronized (UnlockSim.this) {
1448 mHandler = new Handler() {
1449 @Override
1450 public void handleMessage(Message msg) {
1451 AsyncResult ar = (AsyncResult) msg.obj;
1452 switch (msg.what) {
1453 case SUPPLY_PIN_COMPLETE:
1454 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
1455 synchronized (UnlockSim.this) {
Wink Saville9de0f752013-10-22 19:04:03 -07001456 mRetryCount = msg.arg1;
1457 if (ar.exception != null) {
1458 if (ar.exception instanceof CommandException &&
1459 ((CommandException)(ar.exception)).getCommandError()
1460 == CommandException.Error.PASSWORD_INCORRECT) {
1461 mResult = PhoneConstants.PIN_PASSWORD_INCORRECT;
1462 } else {
1463 mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1464 }
1465 } else {
1466 mResult = PhoneConstants.PIN_RESULT_SUCCESS;
1467 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001468 mDone = true;
1469 UnlockSim.this.notifyAll();
1470 }
1471 break;
1472 }
1473 }
1474 };
1475 UnlockSim.this.notifyAll();
1476 }
1477 Looper.loop();
1478 }
1479
1480 /*
1481 * Use PIN or PUK to unlock SIM card
1482 *
1483 * If PUK is null, unlock SIM card with PIN
1484 *
1485 * If PUK is not null, unlock SIM card with PUK and set PIN code
1486 */
Wink Saville9de0f752013-10-22 19:04:03 -07001487 synchronized int[] unlockSim(String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001488
1489 while (mHandler == null) {
1490 try {
1491 wait();
1492 } catch (InterruptedException e) {
1493 Thread.currentThread().interrupt();
1494 }
1495 }
1496 Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
1497
1498 if (puk == null) {
1499 mSimCard.supplyPin(pin, callback);
1500 } else {
1501 mSimCard.supplyPuk(puk, pin, callback);
1502 }
1503
1504 while (!mDone) {
1505 try {
1506 Log.d(LOG_TAG, "wait for done");
1507 wait();
1508 } catch (InterruptedException e) {
1509 // Restore the interrupted status
1510 Thread.currentThread().interrupt();
1511 }
1512 }
1513 Log.d(LOG_TAG, "done");
Wink Saville9de0f752013-10-22 19:04:03 -07001514 int[] resultArray = new int[2];
1515 resultArray[0] = mResult;
1516 resultArray[1] = mRetryCount;
1517 return resultArray;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001518 }
1519 }
1520
1521 public void updateServiceLocation() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001522 updateServiceLocationForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001523
1524 }
1525
Wink Savilleb564aae2014-10-23 10:18:09 -07001526 public void updateServiceLocationForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001527 // No permission check needed here: this call is harmless, and it's
1528 // needed for the ServiceState.requestStateUpdate() call (which is
1529 // already intentionally exposed to 3rd parties.)
Malcolm Chenaabec062018-02-28 15:00:40 -08001530 final long identity = Binder.clearCallingIdentity();
1531 try {
1532 final Phone phone = getPhone(subId);
1533 if (phone != null) {
1534 phone.updateServiceLocation();
1535 }
1536 } finally {
1537 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001538 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001539 }
1540
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001541 @Override
1542 public boolean isRadioOn(String callingPackage) {
1543 return isRadioOnForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07001544 }
1545
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001546 @Override
1547 public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08001548 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08001549 mApp, subId, callingPackage, "isRadioOnForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001550 return false;
1551 }
Malcolm Chenaabec062018-02-28 15:00:40 -08001552
1553 final long identity = Binder.clearCallingIdentity();
1554 try {
1555 return isRadioOnForSubscriber(subId);
1556 } finally {
1557 Binder.restoreCallingIdentity(identity);
1558 }
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001559 }
1560
1561 private boolean isRadioOnForSubscriber(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08001562 final long identity = Binder.clearCallingIdentity();
1563 try {
1564 final Phone phone = getPhone(subId);
1565 if (phone != null) {
1566 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
1567 } else {
1568 return false;
1569 }
1570 } finally {
1571 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001572 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001573 }
1574
1575 public void toggleRadioOnOff() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001576 toggleRadioOnOffForSubscriber(getDefaultSubscription());
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001577 }
Wink Saville36469e72014-06-11 15:17:00 -07001578
Wink Savilleb564aae2014-10-23 10:18:09 -07001579 public void toggleRadioOnOffForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001580 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001581
1582 final long identity = Binder.clearCallingIdentity();
1583 try {
1584 final Phone phone = getPhone(subId);
1585 if (phone != null) {
1586 phone.setRadioPower(!isRadioOnForSubscriber(subId));
1587 }
1588 } finally {
1589 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001590 }
Wink Saville36469e72014-06-11 15:17:00 -07001591 }
1592
1593 public boolean setRadio(boolean turnOn) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001594 return setRadioForSubscriber(getDefaultSubscription(), turnOn);
Wink Saville36469e72014-06-11 15:17:00 -07001595 }
1596
Wink Savilleb564aae2014-10-23 10:18:09 -07001597 public boolean setRadioForSubscriber(int subId, boolean turnOn) {
Wink Saville36469e72014-06-11 15:17:00 -07001598 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001599
1600 final long identity = Binder.clearCallingIdentity();
1601 try {
1602 final Phone phone = getPhone(subId);
1603 if (phone == null) {
1604 return false;
1605 }
1606 if ((phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF) != turnOn) {
1607 toggleRadioOnOffForSubscriber(subId);
1608 }
1609 return true;
1610 } finally {
1611 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001612 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001613 }
Wink Saville36469e72014-06-11 15:17:00 -07001614
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001615 public boolean needMobileRadioShutdown() {
1616 /*
1617 * If any of the Radios are available, it will need to be
1618 * shutdown. So return true if any Radio is available.
1619 */
Malcolm Chenaabec062018-02-28 15:00:40 -08001620 final long identity = Binder.clearCallingIdentity();
1621 try {
1622 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1623 Phone phone = PhoneFactory.getPhone(i);
1624 if (phone != null && phone.isRadioAvailable()) return true;
1625 }
1626 logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown.");
1627 return false;
1628 } finally {
1629 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001630 }
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001631 }
1632
Malcolm Chenaabec062018-02-28 15:00:40 -08001633 @Override
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001634 public void shutdownMobileRadios() {
Malcolm Chenaabec062018-02-28 15:00:40 -08001635 enforceModifyPermission();
1636
1637 final long identity = Binder.clearCallingIdentity();
1638 try {
1639 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1640 logv("Shutting down Phone " + i);
1641 shutdownRadioUsingPhoneId(i);
1642 }
1643 } finally {
1644 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001645 }
1646 }
1647
1648 private void shutdownRadioUsingPhoneId(int phoneId) {
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001649 Phone phone = PhoneFactory.getPhone(phoneId);
1650 if (phone != null && phone.isRadioAvailable()) {
1651 phone.shutdownRadio();
1652 }
1653 }
1654
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001655 public boolean setRadioPower(boolean turnOn) {
Jack Yub4e16162017-05-15 12:48:40 -07001656 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001657
1658 final long identity = Binder.clearCallingIdentity();
1659 try {
1660 final Phone defaultPhone = PhoneFactory.getDefaultPhone();
1661 if (defaultPhone != null) {
1662 defaultPhone.setRadioPower(turnOn);
1663 return true;
1664 } else {
1665 loge("There's no default phone.");
1666 return false;
1667 }
1668 } finally {
1669 Binder.restoreCallingIdentity(identity);
Wei Liu9ae2a062016-08-08 11:09:34 -07001670 }
Wink Saville36469e72014-06-11 15:17:00 -07001671 }
1672
Wink Savilleb564aae2014-10-23 10:18:09 -07001673 public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001674 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001675
1676 final long identity = Binder.clearCallingIdentity();
1677 try {
1678 final Phone phone = getPhone(subId);
1679 if (phone != null) {
1680 phone.setRadioPower(turnOn);
1681 return true;
1682 } else {
1683 return false;
1684 }
1685 } finally {
1686 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001687 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001688 }
1689
Wink Saville36469e72014-06-11 15:17:00 -07001690 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07001691 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001692 public boolean enableDataConnectivity() {
1693 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001694
1695 final long identity = Binder.clearCallingIdentity();
1696 try {
1697 int subId = mSubscriptionController.getDefaultDataSubId();
1698 final Phone phone = getPhone(subId);
1699 if (phone != null) {
1700 phone.setUserDataEnabled(true);
1701 return true;
1702 } else {
1703 return false;
1704 }
1705 } finally {
1706 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001707 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001708 }
1709
Wink Saville36469e72014-06-11 15:17:00 -07001710 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07001711 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001712 public boolean disableDataConnectivity() {
1713 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001714
1715 final long identity = Binder.clearCallingIdentity();
1716 try {
1717 int subId = mSubscriptionController.getDefaultDataSubId();
1718 final Phone phone = getPhone(subId);
1719 if (phone != null) {
1720 phone.setUserDataEnabled(false);
1721 return true;
1722 } else {
1723 return false;
1724 }
1725 } finally {
1726 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001727 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001728 }
1729
Sanket Padawe356d7632015-06-22 14:03:32 -07001730 @Override
Jack Yuacf8a132017-05-01 17:00:48 -07001731 public boolean isDataConnectivityPossible(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08001732 final long identity = Binder.clearCallingIdentity();
1733 try {
1734 final Phone phone = getPhone(subId);
1735 if (phone != null) {
1736 return phone.isDataAllowed();
1737 } else {
1738 return false;
1739 }
1740 } finally {
1741 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001742 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001743 }
1744
1745 public boolean handlePinMmi(String dialString) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001746 return handlePinMmiForSubscriber(getDefaultSubscription(), dialString);
Wink Saville36469e72014-06-11 15:17:00 -07001747 }
1748
pkanwarae03a6b2016-11-06 20:37:09 -08001749 public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
Malcolm Chenaabec062018-02-28 15:00:40 -08001750 enforceCallPermission();
1751
1752 final long identity = Binder.clearCallingIdentity();
1753 try {
1754 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1755 return;
1756 }
1757 Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback);
1758 sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId);
1759 } finally {
1760 Binder.restoreCallingIdentity(identity);
1761 }
pkanwar32d516d2016-10-14 19:37:38 -07001762 };
1763
Wink Savilleb564aae2014-10-23 10:18:09 -07001764 public boolean handlePinMmiForSubscriber(int subId, String dialString) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001765 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001766
1767 final long identity = Binder.clearCallingIdentity();
1768 try {
1769 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1770 return false;
1771 }
1772 return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
1773 } finally {
1774 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001775 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001776 }
1777
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001778 public int getCallState() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07001779 return getCallStateForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001780 }
1781
Sanket Padawe13bac7b2017-03-20 15:04:47 -07001782 public int getCallStateForSlot(int slotIndex) {
Malcolm Chenaabec062018-02-28 15:00:40 -08001783 final long identity = Binder.clearCallingIdentity();
1784 try {
1785 Phone phone = PhoneFactory.getPhone(slotIndex);
1786 return phone == null ? TelephonyManager.CALL_STATE_IDLE :
1787 PhoneConstantConversions.convertCallState(phone.getState());
1788 } finally {
1789 Binder.restoreCallingIdentity(identity);
1790 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001791 }
1792
Sanket Padawe356d7632015-06-22 14:03:32 -07001793 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001794 public int getDataState() {
Malcolm Chenaabec062018-02-28 15:00:40 -08001795 final long identity = Binder.clearCallingIdentity();
1796 try {
1797 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1798 if (phone != null) {
1799 return PhoneConstantConversions.convertDataState(phone.getDataConnectionState());
1800 } else {
1801 return PhoneConstantConversions.convertDataState(
1802 PhoneConstants.DataState.DISCONNECTED);
1803 }
1804 } finally {
1805 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001806 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001807 }
1808
Sanket Padawe356d7632015-06-22 14:03:32 -07001809 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001810 public int getDataActivity() {
Malcolm Chenaabec062018-02-28 15:00:40 -08001811 final long identity = Binder.clearCallingIdentity();
1812 try {
1813 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1814 if (phone != null) {
1815 return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState());
1816 } else {
1817 return TelephonyManager.DATA_ACTIVITY_NONE;
1818 }
1819 } finally {
1820 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001821 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001822 }
1823
1824 @Override
Svetoslav64fad262015-04-14 14:35:21 -07001825 public Bundle getCellLocation(String callingPackage) {
Hall Liu1aa510f2017-11-22 17:40:08 -08001826 mPhone.getContext().getSystemService(AppOpsManager.class)
1827 .checkPackage(Binder.getCallingUid(), callingPackage);
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001828 if (!LocationAccessPolicy.canAccessCellLocation(mPhone.getContext(),
Svet Ganov4af66282018-03-07 19:57:05 -08001829 callingPackage, Binder.getCallingUid(), Binder.getCallingPid(), true)) {
Svetoslav64fad262015-04-14 14:35:21 -07001830 return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001831 }
1832
Narayan Kamathf04b5a12018-01-09 11:47:15 +00001833 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaabec062018-02-28 15:00:40 -08001834 final long identity = Binder.clearCallingIdentity();
1835 try {
1836 if (DBG_LOC) log("getCellLocation: is active user");
1837 Bundle data = new Bundle();
1838 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1839 if (phone == null) {
1840 return null;
1841 }
1842
1843 phone.getCellLocation(workSource).fillInNotifierBundle(data);
1844 return data;
1845 } finally {
1846 Binder.restoreCallingIdentity(identity);
1847 }
Svetoslav64fad262015-04-14 14:35:21 -07001848 }
1849
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001850 @Override
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001851 public String getNetworkCountryIsoForPhone(int phoneId) {
1852 // Reporting the correct network country is ambiguous when IWLAN could conflict with
1853 // registered cell info, so return a NULL country instead.
1854 final long identity = Binder.clearCallingIdentity();
1855 try {
1856 final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
Jack Yu5f7092c2018-04-13 14:05:37 -07001857 // Todo: fix this when we can get the actual cellular network info when the device
1858 // is on IWLAN.
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001859 if (TelephonyManager.NETWORK_TYPE_IWLAN
1860 == getVoiceNetworkTypeForSubscriber(subId, mApp.getPackageName())) {
1861 return "";
1862 }
Malcolm Chenaabec062018-02-28 15:00:40 -08001863 Phone phone = PhoneFactory.getPhone(phoneId);
1864 if (phone != null) {
1865 ServiceStateTracker sst = phone.getServiceStateTracker();
1866 if (sst != null) {
1867 LocaleTracker lt = sst.getLocaleTracker();
1868 if (lt != null) {
1869 return lt.getCurrentCountry();
1870 }
1871 }
1872 }
1873 return "";
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001874 } finally {
1875 Binder.restoreCallingIdentity(identity);
1876 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001877 }
1878
1879 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001880 public void enableLocationUpdates() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001881 enableLocationUpdatesForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001882 }
1883
Sanket Padawe356d7632015-06-22 14:03:32 -07001884 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07001885 public void enableLocationUpdatesForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001886 mApp.enforceCallingOrSelfPermission(
1887 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Malcolm Chenaabec062018-02-28 15:00:40 -08001888
1889 final long identity = Binder.clearCallingIdentity();
1890 try {
1891 final Phone phone = getPhone(subId);
1892 if (phone != null) {
1893 phone.enableLocationUpdates();
1894 }
1895 } finally {
1896 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001897 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001898 }
1899
1900 @Override
1901 public void disableLocationUpdates() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001902 disableLocationUpdatesForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001903 }
1904
Sanket Padawe356d7632015-06-22 14:03:32 -07001905 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07001906 public void disableLocationUpdatesForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001907 mApp.enforceCallingOrSelfPermission(
1908 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Malcolm Chenaabec062018-02-28 15:00:40 -08001909
1910 final long identity = Binder.clearCallingIdentity();
1911 try {
1912 final Phone phone = getPhone(subId);
1913 if (phone != null) {
1914 phone.disableLocationUpdates();
1915 }
1916 } finally {
1917 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001918 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001919 }
1920
1921 @Override
1922 @SuppressWarnings("unchecked")
Nathan Haroldb4d55612018-07-20 13:13:08 -07001923 public List<NeighboringCellInfo>
1924 getNeighboringCellInfo(String callingPackage, int targetSdk) {
Nathan Harolddbea45a2018-08-30 14:35:07 -07001925 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
1926 throw new SecurityException(
1927 "getNeighboringCellInfo() is unavailable to callers targeting Q+ SDK levels.");
1928 }
Nathan Haroldb4d55612018-07-20 13:13:08 -07001929
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001930 if (mAppOps.noteOp(AppOpsManager.OP_NEIGHBORING_CELLS, Binder.getCallingUid(),
1931 callingPackage) != AppOpsManager.MODE_ALLOWED) {
1932 return null;
1933 }
Svetoslav64fad262015-04-14 14:35:21 -07001934
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001935 if (DBG_LOC) log("getNeighboringCellInfo: is active user");
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001936
Nathan Haroldf180aac2018-06-01 18:43:55 -07001937 List<CellInfo> info = getAllCellInfo(callingPackage);
1938 if (info == null) return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001939
Nathan Haroldf180aac2018-06-01 18:43:55 -07001940 List<NeighboringCellInfo> neighbors = new ArrayList<NeighboringCellInfo>();
1941 for (CellInfo ci : info) {
1942 if (ci instanceof CellInfoGsm) {
1943 neighbors.add(new NeighboringCellInfo((CellInfoGsm) ci));
1944 } else if (ci instanceof CellInfoWcdma) {
1945 neighbors.add(new NeighboringCellInfo((CellInfoWcdma) ci));
1946 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001947 }
Nathan Haroldf180aac2018-06-01 18:43:55 -07001948 return (neighbors.size()) > 0 ? neighbors : null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001949 }
1950
1951
1952 @Override
Svetoslav64fad262015-04-14 14:35:21 -07001953 public List<CellInfo> getAllCellInfo(String callingPackage) {
Hall Liu1aa510f2017-11-22 17:40:08 -08001954 mPhone.getContext().getSystemService(AppOpsManager.class)
1955 .checkPackage(Binder.getCallingUid(), callingPackage);
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001956 if (!LocationAccessPolicy.canAccessCellLocation(mPhone.getContext(),
Svet Ganov4af66282018-03-07 19:57:05 -08001957 callingPackage, Binder.getCallingUid(), Binder.getCallingPid(), true)) {
Svetoslav64fad262015-04-14 14:35:21 -07001958 return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001959 }
1960
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001961 if (DBG_LOC) log("getAllCellInfo: is active user");
Narayan Kamathf04b5a12018-01-09 11:47:15 +00001962 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaabec062018-02-28 15:00:40 -08001963 final long identity = Binder.clearCallingIdentity();
1964 try {
1965 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
1966 for (Phone phone : PhoneFactory.getPhones()) {
1967 final List<CellInfo> info = phone.getAllCellInfo(workSource);
1968 if (info != null) cellInfos.addAll(info);
1969 }
1970 return cellInfos;
1971 } finally {
1972 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001973 }
1974 }
1975
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001976 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001977 public void setCellInfoListRate(int rateInMillis) {
Jack Yua8d8cb82017-01-16 10:15:34 -08001978 enforceModifyPermission();
Narayan Kamathf04b5a12018-01-09 11:47:15 +00001979 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaabec062018-02-28 15:00:40 -08001980
1981 final long identity = Binder.clearCallingIdentity();
1982 try {
1983 mPhone.setCellInfoListRate(rateInMillis, workSource);
1984 } finally {
1985 Binder.restoreCallingIdentity(identity);
1986 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001987 }
1988
Shishir Agrawala9f32182016-04-12 12:00:16 -07001989 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07001990 public String getImeiForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08001991 Phone phone = PhoneFactory.getPhone(slotIndex);
1992 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08001993 return null;
1994 }
Jeff Davidson913390f2018-02-23 17:11:49 -08001995 int subId = phone.getSubId();
1996 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
1997 mApp, subId, callingPackage, "getImeiForSlot")) {
1998 return null;
1999 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002000
2001 final long identity = Binder.clearCallingIdentity();
2002 try {
2003 return phone.getImei();
2004 } finally {
2005 Binder.restoreCallingIdentity(identity);
2006 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002007 }
2008
2009 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002010 public String getTypeAllocationCodeForSlot(int slotIndex) {
2011 Phone phone = PhoneFactory.getPhone(slotIndex);
2012 String tac = null;
2013 if (phone != null) {
2014 String imei = phone.getImei();
2015 tac = imei == null ? null : imei.substring(0, TYPE_ALLOCATION_CODE_LENGTH);
2016 }
2017 return tac;
2018 }
2019
2020 @Override
Jack Yu2af8d712017-03-15 17:14:14 -07002021 public String getMeidForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002022 Phone phone = PhoneFactory.getPhone(slotIndex);
2023 if (phone == null) {
Jack Yu2af8d712017-03-15 17:14:14 -07002024 return null;
2025 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002026 int subId = phone.getSubId();
2027 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2028 mApp, subId, callingPackage, "getMeidForSlot")) {
2029 return null;
2030 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002031
2032 final long identity = Binder.clearCallingIdentity();
2033 try {
2034 return phone.getMeid();
2035 } finally {
2036 Binder.restoreCallingIdentity(identity);
2037 }
Jack Yu2af8d712017-03-15 17:14:14 -07002038 }
2039
2040 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002041 public String getManufacturerCodeForSlot(int slotIndex) {
2042 Phone phone = PhoneFactory.getPhone(slotIndex);
2043 String manufacturerCode = null;
2044 if (phone != null) {
2045 String meid = phone.getMeid();
2046 manufacturerCode = meid == null ? null : meid.substring(0, MANUFACTURER_CODE_LENGTH);
2047 }
2048 return manufacturerCode;
2049 }
2050
2051 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002052 public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002053 Phone phone = PhoneFactory.getPhone(slotIndex);
2054 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002055 return null;
2056 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002057 int subId = phone.getSubId();
2058 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2059 mApp, subId, callingPackage, "getDeviceSoftwareVersionForSlot")) {
2060 return null;
2061 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002062
2063 final long identity = Binder.clearCallingIdentity();
2064 try {
2065 return phone.getDeviceSvn();
2066 } finally {
2067 Binder.restoreCallingIdentity(identity);
2068 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002069 }
2070
fionaxu43304da2017-11-27 22:51:16 -08002071 @Override
2072 public int getSubscriptionCarrierId(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08002073 final long identity = Binder.clearCallingIdentity();
2074 try {
2075 final Phone phone = getPhone(subId);
2076 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getCarrierId();
2077 } finally {
2078 Binder.restoreCallingIdentity(identity);
2079 }
fionaxu43304da2017-11-27 22:51:16 -08002080 }
2081
2082 @Override
2083 public String getSubscriptionCarrierName(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08002084 final long identity = Binder.clearCallingIdentity();
2085 try {
2086 final Phone phone = getPhone(subId);
2087 return phone == null ? null : phone.getCarrierName();
2088 } finally {
2089 Binder.restoreCallingIdentity(identity);
2090 }
fionaxu43304da2017-11-27 22:51:16 -08002091 }
2092
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002093 //
2094 // Internal helper methods.
2095 //
2096
Sanket Padaweee13a9b2016-03-08 17:30:28 -08002097 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002098 * Make sure the caller has the MODIFY_PHONE_STATE permission.
2099 *
2100 * @throws SecurityException if the caller does not have the required permission
2101 */
2102 private void enforceModifyPermission() {
2103 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
2104 }
2105
2106 /**
2107 * Make sure the caller has the CALL_PHONE permission.
2108 *
2109 * @throws SecurityException if the caller does not have the required permission
2110 */
2111 private void enforceCallPermission() {
2112 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
2113 }
2114
Stuart Scott8eef64f2015-04-08 15:13:54 -07002115 private void enforceConnectivityInternalPermission() {
2116 mApp.enforceCallingOrSelfPermission(
2117 android.Manifest.permission.CONNECTIVITY_INTERNAL,
2118 "ConnectivityService");
2119 }
2120
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002121 private String createTelUrl(String number) {
2122 if (TextUtils.isEmpty(number)) {
2123 return null;
2124 }
2125
Jake Hambye994d462014-02-03 13:10:13 -08002126 return "tel:" + number;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002127 }
2128
Ihab Awadf9e92732013-12-05 18:02:52 -08002129 private static void log(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002130 Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg);
2131 }
2132
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002133 private static void logv(String msg) {
2134 Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg);
2135 }
2136
Ihab Awadf9e92732013-12-05 18:02:52 -08002137 private static void loge(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002138 Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg);
2139 }
2140
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002141 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002142 public int getActivePhoneType() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07002143 return getActivePhoneTypeForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002144 }
2145
Sanket Padawe356d7632015-06-22 14:03:32 -07002146 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002147 public int getActivePhoneTypeForSlot(int slotIndex) {
Malcolm Chenaabec062018-02-28 15:00:40 -08002148 final long identity = Binder.clearCallingIdentity();
2149 try {
2150 final Phone phone = PhoneFactory.getPhone(slotIndex);
2151 if (phone == null) {
2152 return PhoneConstants.PHONE_TYPE_NONE;
2153 } else {
2154 return phone.getPhoneType();
2155 }
2156 } finally {
2157 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002158 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002159 }
2160
2161 /**
2162 * Returns the CDMA ERI icon index to display
2163 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002164 @Override
2165 public int getCdmaEriIconIndex(String callingPackage) {
2166 return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002167 }
2168
Sanket Padawe356d7632015-06-22 14:03:32 -07002169 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002170 public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002171 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002172 mApp, subId, callingPackage, "getCdmaEriIconIndexForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002173 return -1;
2174 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002175
2176 final long identity = Binder.clearCallingIdentity();
2177 try {
2178 final Phone phone = getPhone(subId);
2179 if (phone != null) {
2180 return phone.getCdmaEriIconIndex();
2181 } else {
2182 return -1;
2183 }
2184 } finally {
2185 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002186 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002187 }
2188
2189 /**
2190 * Returns the CDMA ERI icon mode,
2191 * 0 - ON
2192 * 1 - FLASHING
2193 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002194 @Override
2195 public int getCdmaEriIconMode(String callingPackage) {
2196 return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002197 }
2198
Sanket Padawe356d7632015-06-22 14:03:32 -07002199 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002200 public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002201 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002202 mApp, subId, callingPackage, "getCdmaEriIconModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002203 return -1;
2204 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002205
2206 final long identity = Binder.clearCallingIdentity();
2207 try {
2208 final Phone phone = getPhone(subId);
2209 if (phone != null) {
2210 return phone.getCdmaEriIconMode();
2211 } else {
2212 return -1;
2213 }
2214 } finally {
2215 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002216 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002217 }
2218
2219 /**
2220 * Returns the CDMA ERI text,
2221 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002222 @Override
2223 public String getCdmaEriText(String callingPackage) {
2224 return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002225 }
2226
Sanket Padawe356d7632015-06-22 14:03:32 -07002227 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002228 public String getCdmaEriTextForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002229 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002230 mApp, subId, callingPackage, "getCdmaEriIconTextForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002231 return null;
2232 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002233
2234 final long identity = Binder.clearCallingIdentity();
2235 try {
2236 final Phone phone = getPhone(subId);
2237 if (phone != null) {
2238 return phone.getCdmaEriText();
2239 } else {
2240 return null;
2241 }
2242 } finally {
2243 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002244 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002245 }
2246
2247 /**
Junda Liuca05d5d2014-08-14 22:36:34 -07002248 * Returns the CDMA MDN.
2249 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002250 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002251 public String getCdmaMdn(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002252 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2253 mApp, subId, "getCdmaMdn");
Malcolm Chenaabec062018-02-28 15:00:40 -08002254
2255 final long identity = Binder.clearCallingIdentity();
2256 try {
2257 final Phone phone = getPhone(subId);
2258 if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA && phone != null) {
2259 return phone.getLine1Number();
2260 } else {
2261 return null;
2262 }
2263 } finally {
2264 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07002265 }
2266 }
2267
2268 /**
2269 * Returns the CDMA MIN.
2270 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002271 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002272 public String getCdmaMin(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002273 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2274 mApp, subId, "getCdmaMin");
Malcolm Chenaabec062018-02-28 15:00:40 -08002275
2276 final long identity = Binder.clearCallingIdentity();
2277 try {
2278 final Phone phone = getPhone(subId);
2279 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
2280 return phone.getCdmaMin();
2281 } else {
2282 return null;
2283 }
2284 } finally {
2285 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07002286 }
2287 }
2288
2289 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002290 * Returns true if CDMA provisioning needs to run.
2291 */
2292 public boolean needsOtaServiceProvisioning() {
Malcolm Chenaabec062018-02-28 15:00:40 -08002293 final long identity = Binder.clearCallingIdentity();
2294 try {
2295 return mPhone.needsOtaServiceProvisioning();
2296 } finally {
2297 Binder.restoreCallingIdentity(identity);
2298 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002299 }
2300
2301 /**
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002302 * Sets the voice mail number of a given subId.
2303 */
2304 @Override
2305 public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002306 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setVoiceMailNumber");
Malcolm Chenaabec062018-02-28 15:00:40 -08002307
2308 final long identity = Binder.clearCallingIdentity();
2309 try {
2310 Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
2311 new Pair<String, String>(alphaTag, number), new Integer(subId));
2312 return success;
2313 } finally {
2314 Binder.restoreCallingIdentity(identity);
2315 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002316 }
2317
Ta-wei Yen87c49842016-05-13 21:19:52 -07002318 @Override
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002319 public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
2320 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2321 String systemDialer = TelecomManager.from(mPhone.getContext()).getSystemDialerPackage();
2322 if (!TextUtils.equals(callingPackage, systemDialer)) {
2323 throw new SecurityException("caller must be system dialer");
2324 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002325
2326 final long identity = Binder.clearCallingIdentity();
2327 try {
2328 PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
2329 if (phoneAccountHandle == null) {
2330 return null;
2331 }
2332 return VisualVoicemailSettingsUtil.dump(mPhone.getContext(), phoneAccountHandle);
2333 } finally {
2334 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002335 }
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002336 }
2337
2338 @Override
Ta-wei Yen409ac562017-03-06 16:00:44 -08002339 public String getVisualVoicemailPackageName(String callingPackage, int subId) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08002340 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jeff Davidson7e17e312018-02-13 18:17:36 -08002341 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002342 mApp, subId, callingPackage, "getVisualVoicemailPackageName")) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08002343 return null;
2344 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002345
Jeff Davidsona8e4e242018-03-15 17:16:18 -07002346 final long identity = Binder.clearCallingIdentity();
2347 try {
2348 return RemoteVvmTaskManager
2349 .getRemotePackage(mPhone.getContext(), subId).getPackageName();
2350 } finally {
2351 Binder.restoreCallingIdentity(identity);
2352 }
Ta-wei Yendca928f2017-01-10 16:17:08 -08002353 }
2354
2355 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002356 public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
2357 VisualVoicemailSmsFilterSettings settings) {
2358 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaabec062018-02-28 15:00:40 -08002359
2360 final long identity = Binder.clearCallingIdentity();
2361 try {
2362 VisualVoicemailSmsFilterConfig.enableVisualVoicemailSmsFilter(
2363 mPhone.getContext(), callingPackage, subId, settings);
2364 } finally {
2365 Binder.restoreCallingIdentity(identity);
2366 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002367 }
2368
2369 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002370 public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
2371 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaabec062018-02-28 15:00:40 -08002372
2373 final long identity = Binder.clearCallingIdentity();
2374 try {
2375 VisualVoicemailSmsFilterConfig.disableVisualVoicemailSmsFilter(
2376 mPhone.getContext(), callingPackage, subId);
2377 } finally {
2378 Binder.restoreCallingIdentity(identity);
2379 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002380 }
2381
2382 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002383 public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
2384 String callingPackage, int subId) {
2385 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaabec062018-02-28 15:00:40 -08002386
2387 final long identity = Binder.clearCallingIdentity();
2388 try {
2389 return VisualVoicemailSmsFilterConfig.getVisualVoicemailSmsFilterSettings(
2390 mPhone.getContext(), callingPackage, subId);
2391 } finally {
2392 Binder.restoreCallingIdentity(identity);
2393 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002394 }
2395
2396 @Override
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002397 public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
Ta-wei Yenb6929602016-05-24 15:48:27 -07002398 enforceReadPrivilegedPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08002399
2400 final long identity = Binder.clearCallingIdentity();
2401 try {
2402 return VisualVoicemailSmsFilterConfig.getActiveVisualVoicemailSmsFilterSettings(
2403 mPhone.getContext(), subId);
2404 } finally {
2405 Binder.restoreCallingIdentity(identity);
2406 }
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002407 }
2408
2409 @Override
2410 public void sendVisualVoicemailSmsForSubscriber(String callingPackage, int subId,
2411 String number, int port, String text, PendingIntent sentIntent) {
2412 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Ta-wei Yen527a9c02017-01-06 15:29:25 -08002413 enforceVisualVoicemailPackage(callingPackage, subId);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002414 enforceSendSmsPermission();
2415 // Make the calls as the phone process.
2416 final long identity = Binder.clearCallingIdentity();
2417 try {
2418 SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(subId);
2419 if (port == 0) {
2420 smsManager.sendTextMessageWithSelfPermissions(number, null, text,
2421 sentIntent, null, false);
2422 } else {
2423 byte[] data = text.getBytes(StandardCharsets.UTF_8);
2424 smsManager.sendDataMessageWithSelfPermissions(number, null,
2425 (short) port, data, sentIntent, null);
2426 }
2427 } finally {
2428 Binder.restoreCallingIdentity(identity);
2429 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002430 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002431 /**
fionaxu0152e512016-11-14 13:36:14 -08002432 * Sets the voice activation state of a given subId.
2433 */
2434 @Override
2435 public void setVoiceActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002436 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2437 mApp, subId, "setVoiceActivationState");
Malcolm Chenaabec062018-02-28 15:00:40 -08002438
2439 final long identity = Binder.clearCallingIdentity();
2440 try {
2441 final Phone phone = getPhone(subId);
2442 if (phone != null) {
2443 phone.setVoiceActivationState(activationState);
2444 } else {
2445 loge("setVoiceActivationState fails with invalid subId: " + subId);
2446 }
2447 } finally {
2448 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002449 }
2450 }
2451
2452 /**
2453 * Sets the data activation state of a given subId.
2454 */
2455 @Override
2456 public void setDataActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002457 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2458 mApp, subId, "setDataActivationState");
Malcolm Chenaabec062018-02-28 15:00:40 -08002459
2460 final long identity = Binder.clearCallingIdentity();
2461 try {
2462 final Phone phone = getPhone(subId);
2463 if (phone != null) {
2464 phone.setDataActivationState(activationState);
2465 } else {
2466 loge("setVoiceActivationState fails with invalid subId: " + subId);
2467 }
2468 } finally {
2469 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002470 }
2471 }
2472
2473 /**
2474 * Returns the voice activation state of a given subId.
2475 */
2476 @Override
2477 public int getVoiceActivationState(int subId, String callingPackage) {
goneil799f6e92017-12-13 12:57:23 -08002478 enforceReadPrivilegedPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08002479
fionaxu0152e512016-11-14 13:36:14 -08002480 final Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08002481 final long identity = Binder.clearCallingIdentity();
2482 try {
2483 if (phone != null) {
2484 return phone.getVoiceActivationState();
2485 } else {
2486 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2487 }
2488 } finally {
2489 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002490 }
2491 }
2492
2493 /**
2494 * Returns the data activation state of a given subId.
2495 */
2496 @Override
2497 public int getDataActivationState(int subId, String callingPackage) {
goneil799f6e92017-12-13 12:57:23 -08002498 enforceReadPrivilegedPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08002499
fionaxu0152e512016-11-14 13:36:14 -08002500 final Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08002501 final long identity = Binder.clearCallingIdentity();
2502 try {
2503 if (phone != null) {
2504 return phone.getDataActivationState();
2505 } else {
2506 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2507 }
2508 } finally {
2509 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002510 }
2511 }
2512
2513 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002514 * Returns the unread count of voicemails
2515 */
2516 public int getVoiceMessageCount() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002517 return getVoiceMessageCountForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002518 }
2519
2520 /**
2521 * Returns the unread count of voicemails for a subId
2522 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002523 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002524 public int getVoiceMessageCountForSubscriber( int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08002525 final long identity = Binder.clearCallingIdentity();
2526 try {
2527 final Phone phone = getPhone(subId);
2528 if (phone != null) {
2529 return phone.getVoiceMessageCount();
2530 } else {
2531 return 0;
2532 }
2533 } finally {
2534 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002535 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002536 }
2537
2538 /**
pkanwar8a4dcfb2017-01-19 13:43:16 -08002539 * returns true, if the device is in a state where both voice and data
2540 * are supported simultaneously. This can change based on location or network condition.
2541 */
2542 @Override
2543 public boolean isConcurrentVoiceAndDataAllowed(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08002544 final long identity = Binder.clearCallingIdentity();
2545 try {
2546 final Phone phone = getPhone(subId);
2547 return (phone == null ? false : phone.isConcurrentVoiceAndDataAllowed());
2548 } finally {
2549 Binder.restoreCallingIdentity(identity);
2550 }
pkanwar8a4dcfb2017-01-19 13:43:16 -08002551 }
2552
2553 /**
fionaxu235cc5e2017-03-06 22:25:57 -08002554 * Send the dialer code if called from the current default dialer or the caller has
2555 * carrier privilege.
2556 * @param inputCode The dialer code to send
2557 */
2558 @Override
2559 public void sendDialerSpecialCode(String callingPackage, String inputCode) {
2560 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2561 String defaultDialer = TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage();
2562 if (!TextUtils.equals(callingPackage, defaultDialer)) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002563 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
2564 getDefaultSubscription(), "sendDialerSpecialCode");
fionaxu235cc5e2017-03-06 22:25:57 -08002565 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002566
2567 final long identity = Binder.clearCallingIdentity();
2568 try {
2569 mPhone.sendDialerSpecialCode(inputCode);
2570 } finally {
2571 Binder.restoreCallingIdentity(identity);
2572 }
fionaxu235cc5e2017-03-06 22:25:57 -08002573 }
2574
2575 /**
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002576 * Returns the data network type.
2577 * Legacy call, permission-free.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002578 *
2579 * @Deprecated to be removed Q3 2013 use {@link #getDataNetworkType}.
2580 */
2581 @Override
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002582 public int getNetworkType() {
Malcolm Chenaabec062018-02-28 15:00:40 -08002583 final long identity = Binder.clearCallingIdentity();
2584 try {
2585 final Phone phone = getPhone(getDefaultSubscription());
2586 if (phone != null) {
2587 return phone.getServiceState().getDataNetworkType();
2588 } else {
2589 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2590 }
2591 } finally {
2592 Binder.restoreCallingIdentity(identity);
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002593 }
Wink Saville36469e72014-06-11 15:17:00 -07002594 }
2595
2596 /**
2597 * Returns the network type for a subId
2598 */
2599 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002600 public int getNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002601 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002602 mApp, subId, callingPackage, "getNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002603 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2604 }
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002605
Malcolm Chenaabec062018-02-28 15:00:40 -08002606 final long identity = Binder.clearCallingIdentity();
2607 try {
2608 final Phone phone = getPhone(subId);
2609 if (phone != null) {
2610 return phone.getServiceState().getDataNetworkType();
2611 } else {
2612 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2613 }
2614 } finally {
2615 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002616 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002617 }
2618
2619 /**
2620 * Returns the data network type
2621 */
2622 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002623 public int getDataNetworkType(String callingPackage) {
2624 return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002625 }
2626
2627 /**
2628 * Returns the data network type for a subId
2629 */
2630 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002631 public int getDataNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002632 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002633 mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002634 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2635 }
2636
Malcolm Chenaabec062018-02-28 15:00:40 -08002637 final long identity = Binder.clearCallingIdentity();
2638 try {
2639 final Phone phone = getPhone(subId);
2640 if (phone != null) {
2641 return phone.getServiceState().getDataNetworkType();
2642 } else {
2643 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2644 }
2645 } finally {
2646 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002647 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002648 }
2649
2650 /**
Wink Saville36469e72014-06-11 15:17:00 -07002651 * Returns the Voice network type for a subId
2652 */
2653 @Override
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002654 public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002655 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002656 mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002657 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2658 }
2659
Malcolm Chenaabec062018-02-28 15:00:40 -08002660 final long identity = Binder.clearCallingIdentity();
2661 try {
2662 final Phone phone = getPhone(subId);
2663 if (phone != null) {
2664 return phone.getServiceState().getVoiceNetworkType();
2665 } else {
2666 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2667 }
2668 } finally {
2669 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002670 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002671 }
2672
2673 /**
2674 * @return true if a ICC card is present
2675 */
2676 public boolean hasIccCard() {
Wink Saville36469e72014-06-11 15:17:00 -07002677 // FIXME Make changes to pass defaultSimId of type int
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002678 return hasIccCardUsingSlotIndex(mSubscriptionController.getSlotIndex(
2679 getDefaultSubscription()));
Wink Saville36469e72014-06-11 15:17:00 -07002680 }
2681
2682 /**
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002683 * @return true if a ICC card is present for a slotIndex
Wink Saville36469e72014-06-11 15:17:00 -07002684 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002685 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002686 public boolean hasIccCardUsingSlotIndex(int slotIndex) {
Malcolm Chenaabec062018-02-28 15:00:40 -08002687 final long identity = Binder.clearCallingIdentity();
2688 try {
2689 final Phone phone = PhoneFactory.getPhone(slotIndex);
2690 if (phone != null) {
2691 return phone.getIccCard().hasIccCard();
2692 } else {
2693 return false;
2694 }
2695 } finally {
2696 Binder.restoreCallingIdentity(identity);
Amit Mahajana6fc2a82015-01-06 11:53:51 -08002697 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002698 }
2699
2700 /**
2701 * Return if the current radio is LTE on CDMA. This
2702 * is a tri-state return value as for a period of time
2703 * the mode may be unknown.
2704 *
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002705 * @param callingPackage the name of the package making the call.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002706 * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
Jake Hambye994d462014-02-03 13:10:13 -08002707 * or {@link Phone#LTE_ON_CDMA_TRUE}
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002708 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002709 @Override
2710 public int getLteOnCdmaMode(String callingPackage) {
2711 return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002712 }
2713
Sanket Padawe356d7632015-06-22 14:03:32 -07002714 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002715 public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002716 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002717 mApp, subId, callingPackage, "getLteOnCdmaModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002718 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
2719 }
2720
Malcolm Chenaabec062018-02-28 15:00:40 -08002721 final long identity = Binder.clearCallingIdentity();
2722 try {
2723 final Phone phone = getPhone(subId);
2724 if (phone == null) {
2725 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
2726 } else {
2727 return phone.getLteOnCdmaMode();
2728 }
2729 } finally {
2730 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002731 }
Wink Saville36469e72014-06-11 15:17:00 -07002732 }
2733
2734 public void setPhone(Phone phone) {
2735 mPhone = phone;
2736 }
2737
2738 /**
2739 * {@hide}
2740 * Returns Default subId, 0 in the case of single standby.
2741 */
Wink Savilleb564aae2014-10-23 10:18:09 -07002742 private int getDefaultSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08002743 return mSubscriptionController.getDefaultSubId();
Wink Saville36469e72014-06-11 15:17:00 -07002744 }
2745
Shishir Agrawala9f32182016-04-12 12:00:16 -07002746 private int getSlotForDefaultSubscription() {
2747 return mSubscriptionController.getPhoneId(getDefaultSubscription());
2748 }
2749
Wink Savilleb564aae2014-10-23 10:18:09 -07002750 private int getPreferredVoiceSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08002751 return mSubscriptionController.getDefaultVoiceSubId();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002752 }
Ihab Awadf2177b72013-11-25 13:33:23 -08002753
2754 /**
2755 * @see android.telephony.TelephonyManager.WifiCallingChoices
2756 */
2757 public int getWhenToMakeWifiCalls() {
Malcolm Chenaabec062018-02-28 15:00:40 -08002758 final long identity = Binder.clearCallingIdentity();
2759 try {
2760 return Settings.System.getInt(mPhone.getContext().getContentResolver(),
2761 Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
2762 getWhenToMakeWifiCallsDefaultPreference());
2763 } finally {
2764 Binder.restoreCallingIdentity(identity);
2765 }
Ihab Awadf2177b72013-11-25 13:33:23 -08002766 }
2767
2768 /**
2769 * @see android.telephony.TelephonyManager.WifiCallingChoices
2770 */
2771 public void setWhenToMakeWifiCalls(int preference) {
Malcolm Chenaabec062018-02-28 15:00:40 -08002772 final long identity = Binder.clearCallingIdentity();
2773 try {
2774 if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference);
2775 Settings.System.putInt(mPhone.getContext().getContentResolver(),
2776 Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference);
2777 } finally {
2778 Binder.restoreCallingIdentity(identity);
2779 }
Ihab Awadf9e92732013-12-05 18:02:52 -08002780 }
2781
Sailesh Nepald1e68152013-12-12 19:08:02 -08002782 private static int getWhenToMakeWifiCallsDefaultPreference() {
Santos Cordonda120f42014-08-06 04:44:34 -07002783 // TODO: Use a build property to choose this value.
Evan Charlton9829e882013-12-19 15:30:38 -08002784 return TelephonyManager.WifiCallingChoices.ALWAYS_USE;
Ihab Awadf2177b72013-11-25 13:33:23 -08002785 }
Shishir Agrawal69f68122013-12-16 17:25:49 -08002786
Shishir Agrawal566b7612013-10-28 14:41:00 -07002787 @Override
Derek Tan740e1672017-06-27 14:56:27 -07002788 public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
2789 int subId, String callingPackage, String aid, int p2) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002790 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2791 mApp, subId, "iccOpenLogicalChannel");
Malcolm Chenaabec062018-02-28 15:00:40 -08002792 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Shishir Agrawal566b7612013-10-28 14:41:00 -07002793
Malcolm Chenaabec062018-02-28 15:00:40 -08002794 final long identity = Binder.clearCallingIdentity();
2795 try {
2796 if (TextUtils.equals(ISDR_AID, aid)) {
2797 // Only allows LPA to open logical channel to ISD-R.
2798 ComponentInfo bestComponent =
2799 EuiccConnector.findBestComponent(mPhone.getContext().getPackageManager());
2800 if (bestComponent == null
2801 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
2802 loge("The calling package is not allowed to access ISD-R.");
2803 throw new SecurityException(
2804 "The calling package is not allowed to access ISD-R.");
2805 }
Derek Tan740e1672017-06-27 14:56:27 -07002806 }
Derek Tan740e1672017-06-27 14:56:27 -07002807
Malcolm Chenaabec062018-02-28 15:00:40 -08002808 if (DBG) {
2809 log("iccOpenLogicalChannel: subId=" + subId + " aid=" + aid + " p2=" + p2);
2810 }
2811 IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse) sendRequest(
2812 CMD_OPEN_CHANNEL, new Pair<String, Integer>(aid, p2), subId);
2813 if (DBG) log("iccOpenLogicalChannel: " + response);
2814 return response;
2815 } finally {
2816 Binder.restoreCallingIdentity(identity);
2817 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07002818 }
2819
2820 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08002821 public boolean iccCloseLogicalChannel(int subId, int channel) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002822 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2823 mApp, subId, "iccCloseLogicalChannel");
Shishir Agrawal566b7612013-10-28 14:41:00 -07002824
Malcolm Chenaabec062018-02-28 15:00:40 -08002825 final long identity = Binder.clearCallingIdentity();
2826 try {
2827 if (DBG) log("iccCloseLogicalChannel: subId=" + subId + " chnl=" + channel);
2828 if (channel < 0) {
2829 return false;
2830 }
2831 Boolean success = (Boolean) sendRequest(CMD_CLOSE_CHANNEL, channel, subId);
2832 if (DBG) log("iccCloseLogicalChannel: " + success);
2833 return success;
2834 } finally {
2835 Binder.restoreCallingIdentity(identity);
Shishir Agrawal566b7612013-10-28 14:41:00 -07002836 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07002837 }
2838
2839 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08002840 public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
Shishir Agrawal566b7612013-10-28 14:41:00 -07002841 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002842 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2843 mApp, subId, "iccTransmitApduLogicalChannel");
Shishir Agrawal566b7612013-10-28 14:41:00 -07002844
Malcolm Chenaabec062018-02-28 15:00:40 -08002845 final long identity = Binder.clearCallingIdentity();
2846 try {
2847 if (DBG) {
2848 log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel
2849 + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
2850 + p3 + " data=" + data);
2851 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07002852
Malcolm Chenaabec062018-02-28 15:00:40 -08002853 if (channel < 0) {
2854 return "";
2855 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07002856
Malcolm Chenaabec062018-02-28 15:00:40 -08002857 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL,
2858 new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), subId);
2859 if (DBG) log("iccTransmitApduLogicalChannel: " + response);
Shishir Agrawal566b7612013-10-28 14:41:00 -07002860
Malcolm Chenaabec062018-02-28 15:00:40 -08002861 // Append the returned status code to the end of the response payload.
2862 String s = Integer.toHexString(
2863 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
2864 if (response.payload != null) {
2865 s = IccUtils.bytesToHexString(response.payload) + s;
2866 }
2867 return s;
2868 } finally {
2869 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07002870 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07002871 }
Jake Hambye994d462014-02-03 13:10:13 -08002872
Evan Charltonc66da362014-05-16 14:06:40 -07002873 @Override
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08002874 public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
2875 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002876 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2877 mApp, subId, "iccTransmitApduBasicChannel");
Malcolm Chenaabec062018-02-28 15:00:40 -08002878 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002879
Malcolm Chenaabec062018-02-28 15:00:40 -08002880 final long identity = Binder.clearCallingIdentity();
2881 try {
2882 if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
2883 && TextUtils.equals(ISDR_AID, data)) {
2884 // Only allows LPA to select ISD-R.
2885 ComponentInfo bestComponent =
2886 EuiccConnector.findBestComponent(mPhone.getContext().getPackageManager());
2887 if (bestComponent == null
2888 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
2889 loge("The calling package is not allowed to select ISD-R.");
2890 throw new SecurityException(
2891 "The calling package is not allowed to select ISD-R.");
2892 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08002893 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08002894
Malcolm Chenaabec062018-02-28 15:00:40 -08002895 if (DBG) {
2896 log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd="
2897 + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
2898 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002899
Malcolm Chenaabec062018-02-28 15:00:40 -08002900 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL,
2901 new IccAPDUArgument(0, cla, command, p1, p2, p3, data), subId);
2902 if (DBG) log("iccTransmitApduBasicChannel: " + response);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002903
Malcolm Chenaabec062018-02-28 15:00:40 -08002904 // Append the returned status code to the end of the response payload.
2905 String s = Integer.toHexString(
2906 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
2907 if (response.payload != null) {
2908 s = IccUtils.bytesToHexString(response.payload) + s;
2909 }
2910 return s;
2911 } finally {
2912 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07002913 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002914 }
2915
2916 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08002917 public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002918 String filePath) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002919 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2920 mApp, subId, "iccExchangeSimIO");
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002921
Malcolm Chenaabec062018-02-28 15:00:40 -08002922 final long identity = Binder.clearCallingIdentity();
2923 try {
2924 if (DBG) {
2925 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " "
2926 + p1 + " " + p2 + " " + p3 + ":" + filePath);
2927 }
2928
2929 IccIoResult response =
2930 (IccIoResult) sendRequest(CMD_EXCHANGE_SIM_IO,
2931 new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath),
2932 subId);
2933
2934 if (DBG) {
2935 log("Exchange SIM_IO [R]" + response);
2936 }
2937
2938 byte[] result = null;
2939 int length = 2;
2940 if (response.payload != null) {
2941 length = 2 + response.payload.length;
2942 result = new byte[length];
2943 System.arraycopy(response.payload, 0, result, 0, response.payload.length);
2944 } else {
2945 result = new byte[length];
2946 }
2947
2948 result[length - 1] = (byte) response.sw2;
2949 result[length - 2] = (byte) response.sw1;
2950 return result;
2951 } finally {
2952 Binder.restoreCallingIdentity(identity);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002953 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002954 }
2955
Nathan Haroldb3014052017-01-25 15:57:32 -08002956 /**
2957 * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
2958 * on a particular subscription
2959 */
sqianb6e41952018-03-12 14:54:01 -07002960 public String[] getForbiddenPlmns(int subId, int appType, String callingPackage) {
2961 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2962 mApp, subId, callingPackage, "getForbiddenPlmns")) {
2963 return null;
2964 }
Nathan Haroldb3014052017-01-25 15:57:32 -08002965 if (appType != TelephonyManager.APPTYPE_USIM && appType != TelephonyManager.APPTYPE_SIM) {
2966 loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
2967 return null;
2968 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002969
2970 final long identity = Binder.clearCallingIdentity();
2971 try {
2972 Object response = sendRequest(CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
2973 if (response instanceof String[]) {
2974 return (String[]) response;
2975 }
2976 // Response is an Exception of some kind,
2977 // which is signalled to the user as a NULL retval
2978 return null;
2979 } finally {
2980 Binder.restoreCallingIdentity(identity);
Nathan Haroldb3014052017-01-25 15:57:32 -08002981 }
Nathan Haroldb3014052017-01-25 15:57:32 -08002982 }
2983
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002984 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08002985 public String sendEnvelopeWithStatus(int subId, String content) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002986 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2987 mApp, subId, "sendEnvelopeWithStatus");
Evan Charltonc66da362014-05-16 14:06:40 -07002988
Malcolm Chenaabec062018-02-28 15:00:40 -08002989 final long identity = Binder.clearCallingIdentity();
2990 try {
2991 IccIoResult response = (IccIoResult) sendRequest(CMD_SEND_ENVELOPE, content, subId);
2992 if (response.payload == null) {
2993 return "";
2994 }
Evan Charltonc66da362014-05-16 14:06:40 -07002995
Malcolm Chenaabec062018-02-28 15:00:40 -08002996 // Append the returned status code to the end of the response payload.
2997 String s = Integer.toHexString(
2998 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
2999 s = IccUtils.bytesToHexString(response.payload) + s;
3000 return s;
3001 } finally {
3002 Binder.restoreCallingIdentity(identity);
3003 }
Evan Charltonc66da362014-05-16 14:06:40 -07003004 }
3005
Jake Hambye994d462014-02-03 13:10:13 -08003006 /**
3007 * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
3008 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
3009 *
3010 * @param itemID the ID of the item to read
3011 * @return the NV item as a String, or null on error.
3012 */
3013 @Override
3014 public String nvReadItem(int itemID) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003015 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3016 mApp, getDefaultSubscription(), "nvReadItem");
Malcolm Chenaabec062018-02-28 15:00:40 -08003017
3018 final long identity = Binder.clearCallingIdentity();
3019 try {
3020 if (DBG) log("nvReadItem: item " + itemID);
3021 String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID);
3022 if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
3023 return value;
3024 } finally {
3025 Binder.restoreCallingIdentity(identity);
3026 }
Jake Hambye994d462014-02-03 13:10:13 -08003027 }
3028
3029 /**
3030 * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
3031 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
3032 *
3033 * @param itemID the ID of the item to read
3034 * @param itemValue the value to write, as a String
3035 * @return true on success; false on any failure
3036 */
3037 @Override
3038 public boolean nvWriteItem(int itemID, String itemValue) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003039 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3040 mApp, getDefaultSubscription(), "nvWriteItem");
Malcolm Chenaabec062018-02-28 15:00:40 -08003041
3042 final long identity = Binder.clearCallingIdentity();
3043 try {
3044 if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
3045 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
3046 new Pair<Integer, String>(itemID, itemValue));
3047 if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
3048 return success;
3049 } finally {
3050 Binder.restoreCallingIdentity(identity);
3051 }
Jake Hambye994d462014-02-03 13:10:13 -08003052 }
3053
3054 /**
3055 * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
3056 * Used for device configuration by some CDMA operators.
3057 *
3058 * @param preferredRoamingList byte array containing the new PRL
3059 * @return true on success; false on any failure
3060 */
3061 @Override
3062 public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003063 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3064 mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
Malcolm Chenaabec062018-02-28 15:00:40 -08003065
3066 final long identity = Binder.clearCallingIdentity();
3067 try {
3068 if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
3069 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
3070 if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
3071 return success;
3072 } finally {
3073 Binder.restoreCallingIdentity(identity);
3074 }
Jake Hambye994d462014-02-03 13:10:13 -08003075 }
3076
3077 /**
3078 * Perform the specified type of NV config reset.
3079 * Used for device configuration by some CDMA operators.
3080 *
3081 * @param resetType the type of reset to perform (1 == factory reset; 2 == NV-only reset)
3082 * @return true on success; false on any failure
3083 */
3084 @Override
3085 public boolean nvResetConfig(int resetType) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003086 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3087 mApp, getDefaultSubscription(), "nvResetConfig");
Malcolm Chenaabec062018-02-28 15:00:40 -08003088
3089 final long identity = Binder.clearCallingIdentity();
3090 try {
3091 if (DBG) log("nvResetConfig: type " + resetType);
3092 Boolean success = (Boolean) sendRequest(CMD_NV_RESET_CONFIG, resetType);
3093 if (DBG) log("nvResetConfig: type " + resetType + ' ' + (success ? "ok" : "fail"));
3094 return success;
3095 } finally {
3096 Binder.restoreCallingIdentity(identity);
3097 }
Jake Hambye994d462014-02-03 13:10:13 -08003098 }
Jake Hamby7c27be32014-03-03 13:25:59 -08003099
Svet Ganovb320e182015-04-16 12:30:10 -07003100 public String[] getPcscfAddress(String apnType, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003101 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003102 mApp, mPhone.getSubId(), callingPackage, "getPcscfAddress")) {
Svet Ganovb320e182015-04-16 12:30:10 -07003103 return new String[0];
3104 }
3105
Malcolm Chenaabec062018-02-28 15:00:40 -08003106 final long identity = Binder.clearCallingIdentity();
3107 try {
3108 return mPhone.getPcscfAddress(apnType);
3109 } finally {
3110 Binder.restoreCallingIdentity(identity);
3111 }
Wink Saville36469e72014-06-11 15:17:00 -07003112 }
3113
Brad Ebinger51f743a2017-01-23 13:50:20 -08003114 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003115 * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
3116 * status updates, if not already enabled.
Brad Ebinger51f743a2017-01-23 13:50:20 -08003117 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003118 public void enableIms(int slotId) {
Brad Ebinger51f743a2017-01-23 13:50:20 -08003119 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003120
3121 final long identity = Binder.clearCallingIdentity();
3122 try {
3123 PhoneFactory.getImsResolver().enableIms(slotId);
3124 } finally {
3125 Binder.restoreCallingIdentity(identity);
3126 }
Brad Ebinger34bef922017-11-09 10:27:08 -08003127 }
3128
3129 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003130 * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
3131 * status updates to disabled.
Brad Ebinger34bef922017-11-09 10:27:08 -08003132 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003133 public void disableIms(int slotId) {
3134 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003135
3136 final long identity = Binder.clearCallingIdentity();
3137 try {
3138 PhoneFactory.getImsResolver().disableIms(slotId);
3139 } finally {
3140 Binder.restoreCallingIdentity(identity);
3141 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003142 }
3143
3144 /**
3145 * Returns the {@link IImsMmTelFeature} that corresponds to the given slot Id for the MMTel
3146 * feature or {@link null} if the service is not available. If the feature is available, the
3147 * {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates.
3148 */
3149 public IImsMmTelFeature getMmTelFeatureAndListen(int slotId,
Brad Ebinger34bef922017-11-09 10:27:08 -08003150 IImsServiceFeatureCallback callback) {
3151 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003152
3153 final long identity = Binder.clearCallingIdentity();
3154 try {
3155 return PhoneFactory.getImsResolver().getMmTelFeatureAndListen(slotId, callback);
3156 } finally {
3157 Binder.restoreCallingIdentity(identity);
3158 }
Brad Ebinger34bef922017-11-09 10:27:08 -08003159 }
3160
3161 /**
3162 * Returns the {@link IImsRcsFeature} that corresponds to the given slot Id for the RCS
3163 * feature during emergency calling or {@link null} if the service is not available. If the
3164 * feature is available, the {@link IImsServiceFeatureCallback} callback is registered as a
3165 * listener for feature updates.
3166 */
3167 public IImsRcsFeature getRcsFeatureAndListen(int slotId, IImsServiceFeatureCallback callback) {
3168 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003169
3170 final long identity = Binder.clearCallingIdentity();
3171 try {
3172 return PhoneFactory.getImsResolver().getRcsFeatureAndListen(slotId, callback);
3173 } finally {
3174 Binder.restoreCallingIdentity(identity);
3175 }
Brad Ebinger51f743a2017-01-23 13:50:20 -08003176 }
3177
Brad Ebinger5f64b052017-12-14 14:26:15 -08003178 /**
3179 * Returns the {@link IImsRegistration} structure associated with the slotId and feature
3180 * specified.
3181 */
3182 public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
3183 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003184
3185 final long identity = Binder.clearCallingIdentity();
3186 try {
3187 return PhoneFactory.getImsResolver().getImsRegistration(slotId, feature);
3188 } finally {
3189 Binder.restoreCallingIdentity(identity);
3190 }
Brad Ebinger5f64b052017-12-14 14:26:15 -08003191 }
3192
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003193 /**
3194 * Returns the {@link IImsConfig} structure associated with the slotId and feature
3195 * specified.
3196 */
3197 public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
3198 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003199
3200 final long identity = Binder.clearCallingIdentity();
3201 try {
3202 return PhoneFactory.getImsResolver().getImsConfig(slotId, feature);
3203 } finally {
3204 Binder.restoreCallingIdentity(identity);
3205 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003206 }
3207
Brad Ebinger884c07b2018-02-15 16:17:40 -08003208 /**
Brad Ebinger67801702018-03-02 13:43:36 -08003209 * @return true if the IMS resolver is busy resolving a binding and should not be considered
3210 * available, false if the IMS resolver is idle.
3211 */
3212 public boolean isResolvingImsBinding() {
3213 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003214
3215 final long identity = Binder.clearCallingIdentity();
3216 try {
3217 return PhoneFactory.getImsResolver().isResolvingBinding();
3218 } finally {
3219 Binder.restoreCallingIdentity(identity);
3220 }
Brad Ebinger67801702018-03-02 13:43:36 -08003221 }
3222
Brad Ebingerdac2f002018-04-03 15:17:52 -07003223 /**
3224 * Sets the ImsService Package Name that Telephony will bind to.
3225 *
3226 * @param slotId the slot ID that the ImsService should bind for.
3227 * @param isCarrierImsService true if the ImsService is the carrier override, false if the
3228 * ImsService is the device default ImsService.
3229 * @param packageName The package name of the application that contains the ImsService to bind
3230 * to.
3231 * @return true if setting the ImsService to bind to succeeded, false if it did not.
3232 * @hide
3233 */
3234 public boolean setImsService(int slotId, boolean isCarrierImsService, String packageName) {
Brad Ebingerde696de2018-04-06 09:56:40 -07003235 int[] subIds = SubscriptionManager.getSubId(slotId);
3236 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
3237 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
3238 "setImsService");
3239
Malcolm Chenaabec062018-02-28 15:00:40 -08003240 final long identity = Binder.clearCallingIdentity();
3241 try {
3242 return PhoneFactory.getImsResolver().overrideImsServiceConfiguration(slotId,
3243 isCarrierImsService, packageName);
3244 } finally {
3245 Binder.restoreCallingIdentity(identity);
3246 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07003247 }
3248
3249 /**
3250 * Return the ImsService configuration.
3251 *
3252 * @param slotId The slot that the ImsService is associated with.
3253 * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
3254 * the device default.
3255 * @return the package name of the ImsService configuration.
3256 */
3257 public String getImsService(int slotId, boolean isCarrierImsService) {
Brad Ebingerde696de2018-04-06 09:56:40 -07003258 int[] subIds = SubscriptionManager.getSubId(slotId);
3259 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
3260 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
3261 "getImsService");
3262
Malcolm Chenaabec062018-02-28 15:00:40 -08003263 final long identity = Binder.clearCallingIdentity();
3264 try {
3265 return PhoneFactory.getImsResolver().getImsServiceConfiguration(slotId,
3266 isCarrierImsService);
3267 } finally {
3268 Binder.restoreCallingIdentity(identity);
3269 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07003270 }
3271
Wink Saville36469e72014-06-11 15:17:00 -07003272 public void setImsRegistrationState(boolean registered) {
3273 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003274
3275 final long identity = Binder.clearCallingIdentity();
3276 try {
3277 mPhone.setImsRegistrationState(registered);
3278 } finally {
3279 Binder.restoreCallingIdentity(identity);
3280 }
Wink Saville36469e72014-06-11 15:17:00 -07003281 }
3282
3283 /**
Stuart Scott54788802015-03-30 13:18:01 -07003284 * Set the network selection mode to automatic.
3285 *
3286 */
3287 @Override
3288 public void setNetworkSelectionModeAutomatic(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003289 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3290 mApp, subId, "setNetworkSelectionModeAutomatic");
Malcolm Chenaabec062018-02-28 15:00:40 -08003291
3292 final long identity = Binder.clearCallingIdentity();
3293 try {
3294 if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
3295 sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId);
3296 } finally {
3297 Binder.restoreCallingIdentity(identity);
3298 }
Stuart Scott54788802015-03-30 13:18:01 -07003299 }
3300
3301 /**
Shishir Agrawal302c8692015-06-19 13:49:39 -07003302 * Set the network selection mode to manual with the selected carrier.
3303 */
3304 @Override
yinxu6e5abd72017-12-01 11:35:19 -08003305 public boolean setNetworkSelectionModeManual(int subId, String operatorNumeric,
Shishir Agrawal77ba3172015-09-10 14:50:19 -07003306 boolean persistSelection) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003307 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3308 mApp, subId, "setNetworkSelectionModeManual");
Malcolm Chenaabec062018-02-28 15:00:40 -08003309
3310 final long identity = Binder.clearCallingIdentity();
3311 try {
3312 OperatorInfo operator = new OperatorInfo(
yinxu6e5abd72017-12-01 11:35:19 -08003313 /* operatorAlphaLong */ "",
3314 /* operatorAlphaShort */ "",
Malcolm Chenaabec062018-02-28 15:00:40 -08003315 operatorNumeric);
3316 if (DBG) log("setNetworkSelectionModeManual: subId:" + subId + " operator:" + operator);
3317 ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operator,
3318 persistSelection);
3319 return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
3320 } finally {
3321 Binder.restoreCallingIdentity(identity);
3322 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07003323 }
3324
3325 /**
3326 * Scans for available networks.
3327 */
3328 @Override
3329 public CellNetworkScanResult getCellNetworkScanResults(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003330 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3331 mApp, subId, "getCellNetworkScanResults");
Malcolm Chenaabec062018-02-28 15:00:40 -08003332
3333 final long identity = Binder.clearCallingIdentity();
3334 try {
3335 if (DBG) log("getCellNetworkScanResults: subId " + subId);
3336 CellNetworkScanResult result = (CellNetworkScanResult) sendRequest(
3337 CMD_PERFORM_NETWORK_SCAN, null, subId);
3338 return result;
3339 } finally {
3340 Binder.restoreCallingIdentity(identity);
3341 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07003342 }
3343
3344 /**
yinxub1bed742017-04-17 11:45:04 -07003345 * Starts a new network scan and returns the id of this scan.
yinxu504e1392017-04-12 16:03:22 -07003346 *
yinxub1bed742017-04-17 11:45:04 -07003347 * @param subId id of the subscription
3348 * @param request contains the radio access networks with bands/channels to scan
3349 * @param messenger callback messenger for scan results or errors
3350 * @param binder for the purpose of auto clean when the user thread crashes
yinxu504e1392017-04-12 16:03:22 -07003351 * @return the id of the requested scan which can be used to stop the scan.
3352 */
3353 @Override
3354 public int requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger,
3355 IBinder binder) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003356 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3357 mApp, subId, "requestNetworkScan");
Malcolm Chenaabec062018-02-28 15:00:40 -08003358
3359 final long identity = Binder.clearCallingIdentity();
3360 try {
3361 return mNetworkScanRequestTracker.startNetworkScan(
3362 request, messenger, binder, getPhone(subId));
3363 } finally {
3364 Binder.restoreCallingIdentity(identity);
3365 }
yinxu504e1392017-04-12 16:03:22 -07003366 }
3367
3368 /**
3369 * Stops an existing network scan with the given scanId.
yinxub1bed742017-04-17 11:45:04 -07003370 *
3371 * @param subId id of the subscription
3372 * @param scanId id of the scan that needs to be stopped
yinxu504e1392017-04-12 16:03:22 -07003373 */
3374 @Override
3375 public void stopNetworkScan(int subId, int scanId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003376 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3377 mApp, subId, "stopNetworkScan");
Malcolm Chenaabec062018-02-28 15:00:40 -08003378
3379 final long identity = Binder.clearCallingIdentity();
3380 try {
3381 mNetworkScanRequestTracker.stopNetworkScan(scanId);
3382 } finally {
3383 Binder.restoreCallingIdentity(identity);
3384 }
yinxu504e1392017-04-12 16:03:22 -07003385 }
3386
3387 /**
Junda Liu84d15a22014-07-02 11:21:04 -07003388 * Get the calculated preferred network type.
3389 * Used for debugging incorrect network type.
3390 *
3391 * @return the preferred network type, defined in RILConstants.java.
3392 */
3393 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07003394 public int getCalculatedPreferredNetworkType(String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003395 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003396 mApp, mPhone.getSubId(), callingPackage, "getCalculatedPreferredNetworkType")) {
Svet Ganovb320e182015-04-16 12:30:10 -07003397 return RILConstants.PREFERRED_NETWORK_MODE;
3398 }
3399
Malcolm Chenaabec062018-02-28 15:00:40 -08003400 final long identity = Binder.clearCallingIdentity();
3401 try {
3402 // FIXME: need to get SubId from somewhere.
3403 return PhoneFactory.calculatePreferredNetworkType(mPhone.getContext(), 0);
3404 } finally {
3405 Binder.restoreCallingIdentity(identity);
3406 }
Junda Liu84d15a22014-07-02 11:21:04 -07003407 }
3408
3409 /**
Jake Hamby7c27be32014-03-03 13:25:59 -08003410 * Get the preferred network type.
3411 * Used for device configuration by some CDMA operators.
3412 *
3413 * @return the preferred network type, defined in RILConstants.java.
3414 */
3415 @Override
Stuart Scott54788802015-03-30 13:18:01 -07003416 public int getPreferredNetworkType(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003417 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3418 mApp, subId, "getPreferredNetworkType");
Malcolm Chenaabec062018-02-28 15:00:40 -08003419
3420 final long identity = Binder.clearCallingIdentity();
3421 try {
3422 if (DBG) log("getPreferredNetworkType");
3423 int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null, subId);
3424 int networkType = (result != null ? result[0] : -1);
3425 if (DBG) log("getPreferredNetworkType: " + networkType);
3426 return networkType;
3427 } finally {
3428 Binder.restoreCallingIdentity(identity);
3429 }
Jake Hamby7c27be32014-03-03 13:25:59 -08003430 }
3431
3432 /**
3433 * Set the preferred network type.
3434 * Used for device configuration by some CDMA operators.
3435 *
3436 * @param networkType the preferred network type, defined in RILConstants.java.
3437 * @return true on success; false on any failure.
3438 */
3439 @Override
Stuart Scott54788802015-03-30 13:18:01 -07003440 public boolean setPreferredNetworkType(int subId, int networkType) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003441 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3442 mApp, subId, "setPreferredNetworkType");
Malcolm Chenaabec062018-02-28 15:00:40 -08003443
3444 final long identity = Binder.clearCallingIdentity();
3445 try {
3446 if (DBG) log("setPreferredNetworkType: subId " + subId + " type " + networkType);
3447 Boolean success = (Boolean) sendRequest(
3448 CMD_SET_PREFERRED_NETWORK_TYPE, networkType, subId);
3449 if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail"));
3450 if (success) {
3451 Settings.Global.putInt(mPhone.getContext().getContentResolver(),
3452 Settings.Global.PREFERRED_NETWORK_MODE + subId, networkType);
3453 }
3454 return success;
3455 } finally {
3456 Binder.restoreCallingIdentity(identity);
Junda Liu80bc0d12014-07-14 16:36:44 -07003457 }
Jake Hamby7c27be32014-03-03 13:25:59 -08003458 }
Robert Greenwalted86e582014-05-21 20:03:20 -07003459
3460 /**
Junda Liu475951f2014-11-07 16:45:03 -08003461 * Check TETHER_DUN_REQUIRED and TETHER_DUN_APN settings, net.tethering.noprovisioning
3462 * SystemProperty, and config_tether_apndata to decide whether DUN APN is required for
3463 * tethering.
3464 *
3465 * @return 0: Not required. 1: required. 2: Not set.
3466 * @hide
3467 */
3468 @Override
3469 public int getTetherApnRequired() {
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003470 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003471
3472 final long identity = Binder.clearCallingIdentity();
3473 try {
3474 int dunRequired = Settings.Global.getInt(mPhone.getContext().getContentResolver(),
3475 Settings.Global.TETHER_DUN_REQUIRED, 2);
3476 // If not set, check net.tethering.noprovisioning, TETHER_DUN_APN setting and
3477 // config_tether_apndata.
3478 if (dunRequired == 2 && mPhone.hasMatchedTetherApnSetting()) {
3479 dunRequired = 1;
3480 }
3481 return dunRequired;
3482 } finally {
3483 Binder.restoreCallingIdentity(identity);
Junda Liu475951f2014-11-07 16:45:03 -08003484 }
Junda Liu475951f2014-11-07 16:45:03 -08003485 }
3486
3487 /**
Robert Greenwalted86e582014-05-21 20:03:20 -07003488 * Set mobile data enabled
3489 * Used by the user through settings etc to turn on/off mobile data
3490 *
3491 * @param enable {@code true} turn turn data on, else {@code false}
3492 */
3493 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08003494 public void setUserDataEnabled(int subId, boolean enable) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003495 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3496 mApp, subId, "setUserDataEnabled");
Malcolm Chenaabec062018-02-28 15:00:40 -08003497
3498 final long identity = Binder.clearCallingIdentity();
3499 try {
3500 int phoneId = mSubscriptionController.getPhoneId(subId);
3501 if (DBG) log("setUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
3502 Phone phone = PhoneFactory.getPhone(phoneId);
3503 if (phone != null) {
3504 if (DBG) log("setUserDataEnabled: subId=" + subId + " enable=" + enable);
3505 phone.setUserDataEnabled(enable);
3506 } else {
3507 loge("setUserDataEnabled: no phone for subId=" + subId);
3508 }
3509 } finally {
3510 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08003511 }
Robert Greenwalted86e582014-05-21 20:03:20 -07003512 }
3513
3514 /**
Malcolm Chen964682d2017-11-28 16:20:07 -08003515 * Get the user enabled state of Mobile Data.
3516 *
3517 * TODO: remove and use isUserDataEnabled.
3518 * This can't be removed now because some vendor codes
3519 * calls through ITelephony directly while they should
3520 * use TelephonyManager.
3521 *
3522 * @return true on enabled
3523 */
3524 @Override
3525 public boolean getDataEnabled(int subId) {
3526 return isUserDataEnabled(subId);
3527 }
3528
3529 /**
3530 * Get whether mobile data is enabled per user setting.
3531 *
3532 * There are other factors deciding whether mobile data is actually enabled, but they are
3533 * not considered here. See {@link #isDataEnabled(int)} for more details.
Robert Greenwalt646120a2014-05-23 11:54:03 -07003534 *
Jeff Davidsona1920712016-11-18 17:05:56 -08003535 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
Robert Greenwalted86e582014-05-21 20:03:20 -07003536 *
3537 * @return {@code true} if data is enabled else {@code false}
3538 */
3539 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08003540 public boolean isUserDataEnabled(int subId) {
Robert Greenwalt646120a2014-05-23 11:54:03 -07003541 try {
3542 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
3543 null);
3544 } catch (Exception e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003545 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3546 mApp, subId, "isUserDataEnabled");
Robert Greenwalt646120a2014-05-23 11:54:03 -07003547 }
Malcolm Chenaabec062018-02-28 15:00:40 -08003548
3549 final long identity = Binder.clearCallingIdentity();
3550 try {
3551 int phoneId = mSubscriptionController.getPhoneId(subId);
3552 if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
3553 Phone phone = PhoneFactory.getPhone(phoneId);
3554 if (phone != null) {
3555 boolean retVal = phone.isUserDataEnabled();
3556 if (DBG) log("isUserDataEnabled: subId=" + subId + " retVal=" + retVal);
3557 return retVal;
3558 } else {
3559 if (DBG) loge("isUserDataEnabled: no phone subId=" + subId + " retVal=false");
3560 return false;
3561 }
3562 } finally {
3563 Binder.restoreCallingIdentity(identity);
Malcolm Chen964682d2017-11-28 16:20:07 -08003564 }
3565 }
3566
3567 /**
3568 * Get whether mobile data is enabled.
3569 *
3570 * Comparable to {@link #isUserDataEnabled(int)}, this considers all factors deciding
3571 * whether mobile data is actually enabled.
3572 *
3573 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
3574 *
3575 * @return {@code true} if data is enabled else {@code false}
3576 */
3577 @Override
3578 public boolean isDataEnabled(int subId) {
3579 try {
3580 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
3581 null);
3582 } catch (Exception e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003583 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3584 mApp, subId, "isDataEnabled");
Malcolm Chen964682d2017-11-28 16:20:07 -08003585 }
Malcolm Chenaabec062018-02-28 15:00:40 -08003586
3587 final long identity = Binder.clearCallingIdentity();
3588 try {
3589 int phoneId = mSubscriptionController.getPhoneId(subId);
3590 if (DBG) log("isDataEnabled: subId=" + subId + " phoneId=" + phoneId);
3591 Phone phone = PhoneFactory.getPhone(phoneId);
3592 if (phone != null) {
3593 boolean retVal = phone.isDataEnabled();
3594 if (DBG) log("isDataEnabled: subId=" + subId + " retVal=" + retVal);
3595 return retVal;
3596 } else {
3597 if (DBG) loge("isDataEnabled: no phone subId=" + subId + " retVal=false");
3598 return false;
3599 }
3600 } finally {
3601 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08003602 }
Robert Greenwalted86e582014-05-21 20:03:20 -07003603 }
Shishir Agrawal60f9c952014-06-23 12:00:43 -07003604
3605 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003606 public int getCarrierPrivilegeStatus(int subId) {
3607 final Phone phone = getPhone(subId);
3608 if (phone == null) {
3609 loge("getCarrierPrivilegeStatus: Invalid subId");
3610 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
3611 }
3612 UiccCard card = UiccController.getInstance().getUiccCard(phone.getPhoneId());
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07003613 if (card == null) {
Shishir Agrawal5e5becd2014-11-18 11:38:23 -08003614 loge("getCarrierPrivilegeStatus: No UICC");
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07003615 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3616 }
3617 return card.getCarrierPrivilegeStatusForCurrentTransaction(
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003618 phone.getContext().getPackageManager());
Shishir Agrawal60f9c952014-06-23 12:00:43 -07003619 }
Junda Liu29340342014-07-10 15:23:27 -07003620
3621 @Override
Jeff Davidson7e17e312018-02-13 18:17:36 -08003622 public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
3623 final Phone phone = getPhone(subId);
3624 if (phone == null) {
3625 loge("getCarrierPrivilegeStatus: Invalid subId");
3626 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
3627 }
3628 UiccProfile profile =
3629 UiccController.getInstance().getUiccProfileForPhone(phone.getPhoneId());
3630 if (profile == null) {
3631 loge("getCarrierPrivilegeStatus: No UICC");
3632 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3633 }
3634 return profile.getCarrierPrivilegeStatusForUid(phone.getContext().getPackageManager(), uid);
3635 }
3636
3637 @Override
Zach Johnson50ecba32015-05-19 00:24:21 -07003638 public int checkCarrierPrivilegesForPackage(String pkgName) {
Junda Liu317d70b2016-03-08 09:33:53 -08003639 if (TextUtils.isEmpty(pkgName))
3640 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Shishir Agrawal21409252015-01-15 23:33:50 -08003641 UiccCard card = UiccController.getInstance().getUiccCard(mPhone.getPhoneId());
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07003642 if (card == null) {
3643 loge("checkCarrierPrivilegesForPackage: No UICC");
3644 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3645 }
Zach Johnson50ecba32015-05-19 00:24:21 -07003646 return card.getCarrierPrivilegeStatus(mPhone.getContext().getPackageManager(), pkgName);
3647 }
3648
3649 @Override
3650 public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
Junda Liu317d70b2016-03-08 09:33:53 -08003651 if (TextUtils.isEmpty(pkgName))
3652 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Zach Johnson50ecba32015-05-19 00:24:21 -07003653 int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3654 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
3655 UiccCard card = UiccController.getInstance().getUiccCard(i);
3656 if (card == null) {
Jonathan Basseri7d320df2015-06-16 12:17:08 -07003657 // No UICC in that slot.
Zach Johnson50ecba32015-05-19 00:24:21 -07003658 continue;
3659 }
3660
3661 result = card.getCarrierPrivilegeStatus(
3662 mPhone.getContext().getPackageManager(), pkgName);
3663 if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
3664 break;
3665 }
3666 }
3667
3668 return result;
Junda Liu29340342014-07-10 15:23:27 -07003669 }
Derek Tan89e89d42014-07-08 17:00:10 -07003670
3671 @Override
Junda Liue64de782015-04-16 17:19:16 -07003672 public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
3673 if (!SubscriptionManager.isValidPhoneId(phoneId)) {
3674 loge("phoneId " + phoneId + " is not valid.");
3675 return null;
3676 }
3677 UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07003678 if (card == null) {
Diego Pontorieroaf74c862014-08-28 11:51:16 -07003679 loge("getCarrierPackageNamesForIntent: No UICC");
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07003680 return null ;
3681 }
Diego Pontorieroaf74c862014-08-28 11:51:16 -07003682 return card.getCarrierPackageNamesForIntent(
Svetoslav483aff72015-04-21 14:16:07 -07003683 mPhone.getContext().getPackageManager(), intent);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07003684 }
3685
Amith Yamasani6e118872016-02-19 12:53:51 -08003686 @Override
3687 public List<String> getPackagesWithCarrierPrivileges() {
3688 PackageManager pm = mPhone.getContext().getPackageManager();
3689 List<String> privilegedPackages = new ArrayList<>();
3690 List<PackageInfo> packages = null;
3691 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
3692 UiccCard card = UiccController.getInstance().getUiccCard(i);
3693 if (card == null) {
3694 // No UICC in that slot.
3695 continue;
3696 }
3697 if (card.hasCarrierPrivilegeRules()) {
3698 if (packages == null) {
3699 // Only check packages in user 0 for now
3700 packages = pm.getInstalledPackagesAsUser(
3701 PackageManager.MATCH_DISABLED_COMPONENTS
3702 | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
3703 | PackageManager.GET_SIGNATURES, UserHandle.USER_SYSTEM);
3704 }
3705 for (int p = packages.size() - 1; p >= 0; p--) {
3706 PackageInfo pkgInfo = packages.get(p);
3707 if (pkgInfo != null && pkgInfo.packageName != null
3708 && card.getCarrierPrivilegeStatus(pkgInfo)
3709 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
3710 privilegedPackages.add(pkgInfo.packageName);
3711 }
3712 }
3713 }
3714 }
3715 return privilegedPackages;
3716 }
3717
Wink Savilleb564aae2014-10-23 10:18:09 -07003718 private String getIccId(int subId) {
Sanket Padawe356d7632015-06-22 14:03:32 -07003719 final Phone phone = getPhone(subId);
3720 UiccCard card = phone == null ? null : phone.getUiccCard();
Derek Tan97ebb422014-09-05 16:55:38 -07003721 if (card == null) {
3722 loge("getIccId: No UICC");
3723 return null;
3724 }
3725 String iccId = card.getIccId();
3726 if (TextUtils.isEmpty(iccId)) {
3727 loge("getIccId: ICC ID is null or empty.");
3728 return null;
3729 }
3730 return iccId;
3731 }
3732
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07003733 @Override
Jeff Sharkey85190e62014-12-05 09:40:12 -08003734 public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
3735 String number) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003736 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
3737 subId, "setLine1NumberForDisplayForSubscriber");
Derek Tan97ebb422014-09-05 16:55:38 -07003738
Malcolm Chenaabec062018-02-28 15:00:40 -08003739 final long identity = Binder.clearCallingIdentity();
3740 try {
3741 final String iccId = getIccId(subId);
3742 final Phone phone = getPhone(subId);
3743 if (phone == null) {
3744 return false;
3745 }
3746 final String subscriberId = phone.getSubscriberId();
3747
3748 if (DBG_MERGE) {
3749 Slog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId="
3750 + subscriberId + " to " + number);
3751 }
3752
3753 if (TextUtils.isEmpty(iccId)) {
3754 return false;
3755 }
3756
3757 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
3758
3759 final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
3760 if (alphaTag == null) {
3761 editor.remove(alphaTagPrefKey);
3762 } else {
3763 editor.putString(alphaTagPrefKey, alphaTag);
3764 }
3765
3766 // Record both the line number and IMSI for this ICCID, since we need to
3767 // track all merged IMSIs based on line number
3768 final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
3769 final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
3770 if (number == null) {
3771 editor.remove(numberPrefKey);
3772 editor.remove(subscriberPrefKey);
3773 } else {
3774 editor.putString(numberPrefKey, number);
3775 editor.putString(subscriberPrefKey, subscriberId);
3776 }
3777
3778 editor.commit();
3779 return true;
3780 } finally {
3781 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003782 }
Derek Tan7226c842014-07-02 17:42:23 -07003783 }
3784
3785 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07003786 public String getLine1NumberForDisplay(int subId, String callingPackage) {
Makoto Onukifee69342015-06-29 14:44:50 -07003787 // This is open to apps with WRITE_SMS.
Jeff Davidson7e17e312018-02-13 18:17:36 -08003788 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
Jeff Davidson913390f2018-02-23 17:11:49 -08003789 mApp, subId, callingPackage, "getLine1NumberForDisplay")) {
Amit Mahajan9cf11512015-11-09 11:40:48 -08003790 if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
Svet Ganovb320e182015-04-16 12:30:10 -07003791 return null;
3792 }
Derek Tan97ebb422014-09-05 16:55:38 -07003793
Malcolm Chenaabec062018-02-28 15:00:40 -08003794 final long identity = Binder.clearCallingIdentity();
3795 try {
3796 String iccId = getIccId(subId);
3797 if (iccId != null) {
3798 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
3799 if (DBG_MERGE) {
3800 log("getLine1NumberForDisplay returning "
3801 + mTelephonySharedPreferences.getString(numberPrefKey, null));
3802 }
3803 return mTelephonySharedPreferences.getString(numberPrefKey, null);
Amit Mahajan9cf11512015-11-09 11:40:48 -08003804 }
Malcolm Chenaabec062018-02-28 15:00:40 -08003805 if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null");
3806 return null;
3807 } finally {
3808 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07003809 }
Derek Tan7226c842014-07-02 17:42:23 -07003810 }
3811
3812 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07003813 public String getLine1AlphaTagForDisplay(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003814 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003815 mApp, subId, callingPackage, "getLine1AlphaTagForDisplay")) {
Svet Ganovb320e182015-04-16 12:30:10 -07003816 return null;
3817 }
Derek Tan97ebb422014-09-05 16:55:38 -07003818
Malcolm Chenaabec062018-02-28 15:00:40 -08003819 final long identity = Binder.clearCallingIdentity();
3820 try {
3821 String iccId = getIccId(subId);
3822 if (iccId != null) {
3823 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
3824 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null);
3825 }
3826 return null;
3827 } finally {
3828 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07003829 }
Derek Tan7226c842014-07-02 17:42:23 -07003830 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07003831
3832 @Override
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07003833 public String[] getMergedSubscriberIds(String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08003834 // This API isn't public, so no need to provide a valid subscription ID - we're not worried
3835 // about carrier-privileged callers not having access.
Jeff Davidson7e17e312018-02-13 18:17:36 -08003836 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003837 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
3838 "getMergedSubscriberIds")) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07003839 return null;
3840 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08003841
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07003842 final long identity = Binder.clearCallingIdentity();
3843 try {
Malcolm Chenaabec062018-02-28 15:00:40 -08003844 final Context context = mPhone.getContext();
3845 final TelephonyManager tele = TelephonyManager.from(context);
3846 final SubscriptionManager sub = SubscriptionManager.from(context);
3847
3848 // Figure out what subscribers are currently active
3849 final ArraySet<String> activeSubscriberIds = new ArraySet<>();
3850 // Clear calling identity, when calling TelephonyManager, because callerUid must be
3851 // the process, where TelephonyManager was instantiated.
3852 // Otherwise AppOps check will fail.
3853
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07003854 final int[] subIds = sub.getActiveSubscriptionIdList();
3855 for (int subId : subIds) {
3856 activeSubscriberIds.add(tele.getSubscriberId(subId));
3857 }
Malcolm Chenaabec062018-02-28 15:00:40 -08003858
3859 // First pass, find a number override for an active subscriber
3860 String mergeNumber = null;
3861 final Map<String, ?> prefs = mTelephonySharedPreferences.getAll();
3862 for (String key : prefs.keySet()) {
3863 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) {
3864 final String subscriberId = (String) prefs.get(key);
3865 if (activeSubscriberIds.contains(subscriberId)) {
3866 final String iccId = key.substring(
3867 PREF_CARRIERS_SUBSCRIBER_PREFIX.length());
3868 final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
3869 mergeNumber = (String) prefs.get(numberKey);
3870 if (DBG_MERGE) {
3871 Slog.d(LOG_TAG, "Found line number " + mergeNumber
3872 + " for active subscriber " + subscriberId);
3873 }
3874 if (!TextUtils.isEmpty(mergeNumber)) {
3875 break;
3876 }
3877 }
3878 }
3879 }
3880
3881 // Shortcut when no active merged subscribers
3882 if (TextUtils.isEmpty(mergeNumber)) {
3883 return null;
3884 }
3885
3886 // Second pass, find all subscribers under that line override
3887 final ArraySet<String> result = new ArraySet<>();
3888 for (String key : prefs.keySet()) {
3889 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) {
3890 final String number = (String) prefs.get(key);
3891 if (mergeNumber.equals(number)) {
3892 final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length());
3893 final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
3894 final String subscriberId = (String) prefs.get(subscriberKey);
3895 if (!TextUtils.isEmpty(subscriberId)) {
3896 result.add(subscriberId);
3897 }
3898 }
3899 }
3900 }
3901
3902 final String[] resultArray = result.toArray(new String[result.size()]);
3903 Arrays.sort(resultArray);
3904 if (DBG_MERGE) {
3905 Slog.d(LOG_TAG,
3906 "Found subscribers " + Arrays.toString(resultArray) + " after merge");
3907 }
3908 return resultArray;
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07003909 } finally {
3910 Binder.restoreCallingIdentity(identity);
Jeff Sharkey85190e62014-12-05 09:40:12 -08003911 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08003912 }
3913
3914 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003915 public boolean setOperatorBrandOverride(int subId, String brand) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003916 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
3917 subId, "setOperatorBrandOverride");
Malcolm Chenaabec062018-02-28 15:00:40 -08003918
3919 final long identity = Binder.clearCallingIdentity();
3920 try {
3921 final Phone phone = getPhone(subId);
3922 return phone == null ? false : phone.setOperatorBrandOverride(brand);
3923 } finally {
3924 Binder.restoreCallingIdentity(identity);
3925 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07003926 }
Steven Liu4bf01bc2014-07-17 11:05:29 -05003927
3928 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003929 public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
Shishir Agrawal621a47c2014-12-01 10:25:09 -08003930 List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
3931 List<String> cdmaNonRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003932 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setRoamingOverride");
Malcolm Chenaabec062018-02-28 15:00:40 -08003933
3934 final long identity = Binder.clearCallingIdentity();
3935 try {
3936 final Phone phone = getPhone(subId);
3937 if (phone == null) {
3938 return false;
3939 }
3940 return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList,
3941 cdmaNonRoamingList);
3942 } finally {
3943 Binder.restoreCallingIdentity(identity);
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003944 }
Shishir Agrawal621a47c2014-12-01 10:25:09 -08003945 }
3946
3947 @Override
Shuo Qian850e4d6a2018-04-25 21:02:08 +00003948 @Deprecated
3949 public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
3950 enforceModifyPermission();
3951
3952 int returnValue = 0;
3953 try {
3954 AsyncResult result = (AsyncResult)sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
3955 if(result.exception == null) {
3956 if (result.result != null) {
3957 byte[] responseData = (byte[])(result.result);
3958 if(responseData.length > oemResp.length) {
3959 Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +
3960 responseData.length + "bytes. Buffer Size is " +
3961 oemResp.length + "bytes.");
3962 }
3963 System.arraycopy(responseData, 0, oemResp, 0, responseData.length);
3964 returnValue = responseData.length;
3965 }
3966 } else {
3967 CommandException ex = (CommandException) result.exception;
3968 returnValue = ex.getCommandError().ordinal();
3969 if(returnValue > 0) returnValue *= -1;
3970 }
3971 } catch (RuntimeException e) {
3972 Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");
3973 returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());
3974 if(returnValue > 0) returnValue *= -1;
3975 }
3976
3977 return returnValue;
3978 }
3979
3980 @Override
Wink Saville5d475dd2014-10-17 15:00:58 -07003981 public void setRadioCapability(RadioAccessFamily[] rafs) {
3982 try {
3983 ProxyController.getInstance().setRadioCapability(rafs);
3984 } catch (RuntimeException e) {
3985 Log.w(LOG_TAG, "setRadioCapability: Runtime Exception");
3986 }
3987 }
3988
3989 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003990 public int getRadioAccessFamily(int phoneId, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08003991 Phone phone = PhoneFactory.getPhone(phoneId);
3992 if (phone == null) {
3993 return RadioAccessFamily.RAF_UNKNOWN;
3994 }
3995 int subId = phone.getSubId();
Jeff Davidson7e17e312018-02-13 18:17:36 -08003996 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003997 mApp, subId, callingPackage, "getRadioAccessFamily")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07003998 return RadioAccessFamily.RAF_UNKNOWN;
3999 }
4000
Malcolm Chenaabec062018-02-28 15:00:40 -08004001 final long identity = Binder.clearCallingIdentity();
4002 try {
4003 return ProxyController.getInstance().getRadioAccessFamily(phoneId);
4004 } finally {
4005 Binder.restoreCallingIdentity(identity);
4006 }
Wink Saville5d475dd2014-10-17 15:00:58 -07004007 }
Andrew Leedf14ead2014-10-17 14:22:52 -07004008
4009 @Override
4010 public void enableVideoCalling(boolean enable) {
4011 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08004012
4013 final long identity = Binder.clearCallingIdentity();
4014 try {
4015 ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId()).setVtSetting(enable);
4016 } finally {
4017 Binder.restoreCallingIdentity(identity);
4018 }
Andrew Leedf14ead2014-10-17 14:22:52 -07004019 }
4020
4021 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004022 public boolean isVideoCallingEnabled(String callingPackage) {
Amit Mahajan578e53d2018-03-20 16:18:38 +00004023 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4024 mApp, mPhone.getSubId(), callingPackage, "isVideoCallingEnabled")) {
4025 return false;
4026 }
Svet Ganovb320e182015-04-16 12:30:10 -07004027
Malcolm Chenaabec062018-02-28 15:00:40 -08004028 final long identity = Binder.clearCallingIdentity();
4029 try {
4030 // Check the user preference and the system-level IMS setting. Even if the user has
4031 // enabled video calling, if IMS is disabled we aren't able to support video calling.
4032 // In the long run, we may instead need to check if there exists a connection service
4033 // which can support video calling.
4034 ImsManager imsManager =
4035 ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId());
4036 return imsManager.isVtEnabledByPlatform()
4037 && imsManager.isEnhanced4gLteModeSettingEnabledByUser()
4038 && imsManager.isVtEnabledByUser();
4039 } finally {
4040 Binder.restoreCallingIdentity(identity);
4041 }
Andrew Leedf14ead2014-10-17 14:22:52 -07004042 }
Libin.Tang@motorola.comafe82642014-12-18 13:27:53 -06004043
Andrew Leea1239f22015-03-02 17:44:07 -08004044 @Override
Malcolm Chenaabec062018-02-28 15:00:40 -08004045 public boolean canChangeDtmfToneLength(int subId, String callingPackage) {
4046 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4047 mApp, subId, callingPackage, "isVideoCallingEnabled")) {
4048 return false;
4049 }
4050
4051 final long identity = Binder.clearCallingIdentity();
4052 try {
4053 CarrierConfigManager configManager =
4054 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
4055 return configManager.getConfigForSubId(mPhone.getSubId())
4056 .getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL);
4057 } finally {
4058 Binder.restoreCallingIdentity(identity);
4059 }
Andrew Leea1239f22015-03-02 17:44:07 -08004060 }
4061
4062 @Override
Malcolm Chenaabec062018-02-28 15:00:40 -08004063 public boolean isWorldPhone(int subId, String callingPackage) {
4064 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4065 mApp, subId, callingPackage, "isVideoCallingEnabled")) {
4066 return false;
4067 }
4068
4069 final long identity = Binder.clearCallingIdentity();
4070 try {
4071 CarrierConfigManager configManager =
4072 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
4073 return configManager.getConfigForSubId(mPhone.getSubId())
4074 .getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL);
4075 } finally {
4076 Binder.restoreCallingIdentity(identity);
4077 }
Andrew Leea1239f22015-03-02 17:44:07 -08004078 }
4079
Andrew Lee9431b832015-03-09 18:46:45 -07004080 @Override
4081 public boolean isTtyModeSupported() {
4082 TelecomManager telecomManager = TelecomManager.from(mPhone.getContext());
Wooki Wu1f82f7a2016-02-15 15:59:58 +08004083 return telecomManager.isTtySupported();
Andrew Lee9431b832015-03-09 18:46:45 -07004084 }
4085
4086 @Override
4087 public boolean isHearingAidCompatibilitySupported() {
Malcolm Chenaabec062018-02-28 15:00:40 -08004088 final long identity = Binder.clearCallingIdentity();
4089 try {
4090 return mPhone.getContext().getResources().getBoolean(R.bool.hac_enabled);
4091 } finally {
4092 Binder.restoreCallingIdentity(identity);
4093 }
Andrew Lee9431b832015-03-09 18:46:45 -07004094 }
4095
Hall Liu98187582018-01-22 19:15:32 -08004096 public boolean isRttSupported() {
Malcolm Chenaabec062018-02-28 15:00:40 -08004097 final long identity = Binder.clearCallingIdentity();
4098 try {
4099 boolean isCarrierSupported = mApp.getCarrierConfigForSubId(
4100 mPhone.getSubId()).getBoolean(
4101 CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
4102 boolean isDeviceSupported =
4103 mPhone.getContext().getResources().getBoolean(R.bool.config_support_rtt);
4104 return isCarrierSupported && isDeviceSupported;
4105 } finally {
4106 Binder.restoreCallingIdentity(identity);
4107 }
Hall Liu98187582018-01-22 19:15:32 -08004108 }
4109
Hall Liu3ad5f012018-04-06 16:23:39 -07004110 public boolean isRttEnabled() {
Malcolm Chenaabec062018-02-28 15:00:40 -08004111 final long identity = Binder.clearCallingIdentity();
4112 try {
4113 return isRttSupported() && Settings.Secure.getInt(
4114 mPhone.getContext().getContentResolver(),
4115 Settings.Secure.RTT_CALLING_MODE, 0) != 0;
4116 } finally {
4117 Binder.restoreCallingIdentity(identity);
4118 }
Hall Liu3ad5f012018-04-06 16:23:39 -07004119 }
4120
Sanket Padawe7310cc72015-01-14 09:53:20 -08004121 /**
4122 * Returns the unique device ID of phone, for example, the IMEI for
4123 * GSM and the MEID for CDMA phones. Return null if device ID is not available.
4124 *
4125 * <p>Requires Permission:
4126 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
4127 */
4128 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004129 public String getDeviceId(String callingPackage) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08004130 final Phone phone = PhoneFactory.getPhone(0);
Jeff Davidson913390f2018-02-23 17:11:49 -08004131 if (phone == null) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08004132 return null;
4133 }
Jeff Davidson913390f2018-02-23 17:11:49 -08004134 int subId = phone.getSubId();
4135 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4136 mApp, subId, callingPackage, "getDeviceId")) {
4137 return null;
4138 }
Malcolm Chenaabec062018-02-28 15:00:40 -08004139
4140 final long identity = Binder.clearCallingIdentity();
4141 try {
4142 return phone.getDeviceId();
4143 } finally {
4144 Binder.restoreCallingIdentity(identity);
4145 }
Sanket Padawe7310cc72015-01-14 09:53:20 -08004146 }
4147
Ping Sunc67b7c22016-03-02 19:16:45 +08004148 /**
4149 * {@hide}
4150 * Returns the IMS Registration Status on a particular subid
4151 *
4152 * @param subId
4153 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004154 public boolean isImsRegistered(int subId) {
Ping Sunc67b7c22016-03-02 19:16:45 +08004155 Phone phone = getPhone(subId);
4156 if (phone != null) {
4157 return phone.isImsRegistered();
4158 } else {
4159 return false;
4160 }
4161 }
4162
Santos Cordon7a1885b2015-02-03 11:15:19 -08004163 @Override
4164 public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004165 final long identity = Binder.clearCallingIdentity();
4166 try {
4167 return PhoneUtils.getSubIdForPhoneAccount(phoneAccount);
4168 } finally {
4169 Binder.restoreCallingIdentity(identity);
4170 }
Santos Cordon7a1885b2015-02-03 11:15:19 -08004171 }
Nathan Harolddcfc7932015-03-18 10:01:20 -07004172
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004173 /**
4174 * @return the VoWiFi calling availability.
Nathan Haroldc55097a2015-03-11 18:14:50 -07004175 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004176 public boolean isWifiCallingAvailable(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004177 final long identity = Binder.clearCallingIdentity();
4178 try {
4179 Phone phone = getPhone(subId);
4180 if (phone != null) {
4181 return phone.isWifiCallingEnabled();
4182 } else {
4183 return false;
4184 }
4185 } finally {
4186 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004187 }
Nathan Haroldc55097a2015-03-11 18:14:50 -07004188 }
4189
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004190 /**
4191 * @return the VoLTE availability.
Nathan Haroldc55097a2015-03-11 18:14:50 -07004192 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004193 public boolean isVolteAvailable(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004194 final long identity = Binder.clearCallingIdentity();
4195 try {
4196 Phone phone = getPhone(subId);
4197 if (phone != null) {
4198 return phone.isVolteEnabled();
4199 } else {
4200 return false;
4201 }
4202 } finally {
4203 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004204 }
Nathan Haroldc55097a2015-03-11 18:14:50 -07004205 }
Svet Ganovb320e182015-04-16 12:30:10 -07004206
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004207 /**
4208 * @return the VT calling availability.
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07004209 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004210 public boolean isVideoTelephonyAvailable(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004211 final long identity = Binder.clearCallingIdentity();
4212 try {
4213 Phone phone = getPhone(subId);
4214 if (phone != null) {
4215 return phone.isVideoEnabled();
4216 } else {
4217 return false;
4218 }
4219 } finally {
4220 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004221 }
4222 }
4223
4224 /**
4225 * @return the IMS registration technology for the MMTEL feature. Valid return values are
4226 * defined in {@link ImsRegistrationImplBase}.
4227 */
4228 public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004229 final long identity = Binder.clearCallingIdentity();
4230 try {
4231 Phone phone = getPhone(subId);
4232 if (phone != null) {
4233 return phone.getImsRegistrationTech();
4234 } else {
4235 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
4236 }
4237 } finally {
4238 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004239 }
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07004240 }
4241
Stuart Scott8eef64f2015-04-08 15:13:54 -07004242 @Override
4243 public void factoryReset(int subId) {
4244 enforceConnectivityInternalPermission();
Stuart Scott981d8582015-04-21 14:09:50 -07004245 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
4246 return;
4247 }
4248
Svet Ganovcc087f82015-05-12 20:35:54 -07004249 final long identity = Binder.clearCallingIdentity();
4250 try {
Stuart Scott981d8582015-04-21 14:09:50 -07004251 if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
4252 UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
Pengquan Meng85728fb2018-03-12 16:31:21 -07004253 setUserDataEnabled(subId, getDefaultDataEnabled());
Svet Ganovcc087f82015-05-12 20:35:54 -07004254 setNetworkSelectionModeAutomatic(subId);
Pengquan Meng85728fb2018-03-12 16:31:21 -07004255 setPreferredNetworkType(subId, getDefaultNetworkType(subId));
4256 mPhone.setDataRoamingEnabled(getDefaultDataRoamingEnabled(subId));
pkanwar79ec0542017-07-31 14:10:01 -07004257 CarrierInfoManager.deleteAllCarrierKeysForImsiEncryption(mPhone.getContext());
Svet Ganovcc087f82015-05-12 20:35:54 -07004258 }
4259 } finally {
4260 Binder.restoreCallingIdentity(identity);
Stuart Scott8eef64f2015-04-08 15:13:54 -07004261 }
4262 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004263
4264 @Override
4265 public String getLocaleFromDefaultSim() {
Malcolm Chenaabec062018-02-28 15:00:40 -08004266 final long identity = Binder.clearCallingIdentity();
4267 try {
4268 // We query all subscriptions instead of just the active ones, because
4269 // this might be called early on in the provisioning flow when the
4270 // subscriptions potentially aren't active yet.
4271 final List<SubscriptionInfo> slist = getAllSubscriptionInfoList();
4272 if (slist == null || slist.isEmpty()) {
Narayan Kamath1c496c22015-04-16 14:40:19 +01004273 return null;
4274 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004275
Malcolm Chenaabec062018-02-28 15:00:40 -08004276 // This function may be called very early, say, from the setup wizard, at
4277 // which point we won't have a default subscription set. If that's the case
4278 // we just choose the first, which will be valid in "most cases".
4279 final int defaultSubId = getDefaultSubscription();
4280 SubscriptionInfo info = null;
4281 if (defaultSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
4282 info = slist.get(0);
4283 } else {
4284 for (SubscriptionInfo item : slist) {
4285 if (item.getSubscriptionId() == defaultSubId) {
4286 info = item;
4287 break;
4288 }
4289 }
4290
4291 if (info == null) {
4292 return null;
Tony Hill183b2de2015-06-24 14:53:58 +01004293 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004294 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004295
Malcolm Chenaabec062018-02-28 15:00:40 -08004296 // Try and fetch the locale from the carrier properties or from the SIM language
4297 // preferences (EF-PL and EF-LI)...
4298 final int mcc = info.getMcc();
4299 final Phone defaultPhone = getPhone(info.getSubscriptionId());
4300 String simLanguage = null;
4301 if (defaultPhone != null) {
4302 final Locale localeFromDefaultSim = defaultPhone.getLocaleFromSimAndCarrierPrefs();
4303 if (localeFromDefaultSim != null) {
4304 if (!localeFromDefaultSim.getCountry().isEmpty()) {
4305 if (DBG) log("Using locale from default SIM:" + localeFromDefaultSim);
4306 return localeFromDefaultSim.toLanguageTag();
4307 } else {
4308 simLanguage = localeFromDefaultSim.getLanguage();
4309 }
4310 }
4311 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004312
Malcolm Chenaabec062018-02-28 15:00:40 -08004313 // The SIM language preferences only store a language (e.g. fr = French), not an
4314 // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
4315 // the SIM and carrier preferences does not include a country we add the country
4316 // determined from the SIM MCC to provide an exact locale.
4317 final Locale mccLocale = MccTable.getLocaleFromMcc(mPhone.getContext(), mcc,
4318 simLanguage);
4319 if (mccLocale != null) {
4320 if (DBG) log("No locale from default SIM, using mcc locale:" + mccLocale);
4321 return mccLocale.toLanguageTag();
4322 }
4323
4324 if (DBG) log("No locale found - returning null");
4325 return null;
4326 } finally {
4327 Binder.restoreCallingIdentity(identity);
4328 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004329 }
4330
4331 private List<SubscriptionInfo> getAllSubscriptionInfoList() {
Malcolm Chenaabec062018-02-28 15:00:40 -08004332 return mSubscriptionController.getAllSubInfoList(
4333 mPhone.getContext().getOpPackageName());
Narayan Kamath1c496c22015-04-16 14:40:19 +01004334 }
4335
Malcolm Chenaabec062018-02-28 15:00:40 -08004336 /**
4337 * NOTE: this method assumes permission checks are done and caller identity has been cleared.
4338 */
4339 private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
4340 return mSubscriptionController.getActiveSubscriptionInfoList(
4341 mPhone.getContext().getOpPackageName());
Narayan Kamath1c496c22015-04-16 14:40:19 +01004342 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004343
Chenjie Yu1ba97252018-01-11 18:16:20 -08004344 private final ModemActivityInfo mLastModemActivityInfo =
4345 new ModemActivityInfo(0, 0, 0, new int[0], 0, 0);
4346
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004347 /**
Adam Lesinski903a54c2016-04-11 14:49:52 -07004348 * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
4349 * representing the state of the modem.
4350 *
Chenjie Yu1ba97252018-01-11 18:16:20 -08004351 * NOTE: The underlying implementation clears the modem state, so there should only ever be one
4352 * caller to it. Everyone should call this class to get cumulative data.
Adam Lesinski903a54c2016-04-11 14:49:52 -07004353 * @hide
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004354 */
4355 @Override
Adam Lesinski903a54c2016-04-11 14:49:52 -07004356 public void requestModemActivityInfo(ResultReceiver result) {
4357 enforceModifyPermission();
Chenjie Yu1ba97252018-01-11 18:16:20 -08004358 ModemActivityInfo ret = null;
Adam Lesinski903a54c2016-04-11 14:49:52 -07004359
Malcolm Chenaabec062018-02-28 15:00:40 -08004360 final long identity = Binder.clearCallingIdentity();
4361 try {
Malcolm Chen1cc36b62018-07-30 14:42:47 -07004362 synchronized (mLastModemActivityInfo) {
4363 ModemActivityInfo info = (ModemActivityInfo) sendRequest(CMD_GET_MODEM_ACTIVITY_INFO,
4364 null);
4365 if (info != null) {
4366 int[] mergedTxTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
4367 for (int i = 0; i < mergedTxTimeMs.length; i++) {
4368 mergedTxTimeMs[i] =
4369 info.getTxTimeMillis()[i] + mLastModemActivityInfo.getTxTimeMillis()[i];
4370 }
4371 mLastModemActivityInfo.setTimestamp(info.getTimestamp());
4372 mLastModemActivityInfo.setSleepTimeMillis(
4373 info.getSleepTimeMillis() + mLastModemActivityInfo.getSleepTimeMillis());
4374 mLastModemActivityInfo.setIdleTimeMillis(
4375 info.getIdleTimeMillis() + mLastModemActivityInfo.getIdleTimeMillis());
4376 mLastModemActivityInfo.setTxTimeMillis(mergedTxTimeMs);
4377 mLastModemActivityInfo.setRxTimeMillis(
4378 info.getRxTimeMillis() + mLastModemActivityInfo.getRxTimeMillis());
4379 mLastModemActivityInfo.setEnergyUsed(
4380 info.getEnergyUsed() + mLastModemActivityInfo.getEnergyUsed());
Chenjie Yu1ba97252018-01-11 18:16:20 -08004381 }
Malcolm Chen1cc36b62018-07-30 14:42:47 -07004382 ret = new ModemActivityInfo(mLastModemActivityInfo.getTimestamp(),
4383 mLastModemActivityInfo.getSleepTimeMillis(),
4384 mLastModemActivityInfo.getIdleTimeMillis(),
4385 mLastModemActivityInfo.getTxTimeMillis(),
4386 mLastModemActivityInfo.getRxTimeMillis(),
4387 mLastModemActivityInfo.getEnergyUsed());
Chenjie Yu1ba97252018-01-11 18:16:20 -08004388 }
Malcolm Chenaabec062018-02-28 15:00:40 -08004389 Bundle bundle = new Bundle();
Malcolm Chen1cc36b62018-07-30 14:42:47 -07004390 bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, ret);
Malcolm Chenaabec062018-02-28 15:00:40 -08004391 result.send(0, bundle);
4392 } finally {
4393 Binder.restoreCallingIdentity(identity);
Chenjie Yu1ba97252018-01-11 18:16:20 -08004394 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004395 }
Jack Yu85bd38a2015-11-09 11:34:32 -08004396
4397 /**
4398 * {@hide}
4399 * Returns the service state information on specified subscription.
4400 */
4401 @Override
4402 public ServiceState getServiceStateForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004403 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08004404 mApp, subId, callingPackage, "getServiceStateForSubscriber")) {
Jack Yu85bd38a2015-11-09 11:34:32 -08004405 return null;
4406 }
4407
Malcolm Chenaabec062018-02-28 15:00:40 -08004408 final long identity = Binder.clearCallingIdentity();
4409 try {
4410 final Phone phone = getPhone(subId);
4411 if (phone == null) {
4412 return null;
4413 }
Jack Yu85bd38a2015-11-09 11:34:32 -08004414
Malcolm Chenaabec062018-02-28 15:00:40 -08004415 return phone.getServiceState();
4416 } finally {
4417 Binder.restoreCallingIdentity(identity);
4418 }
Jack Yu85bd38a2015-11-09 11:34:32 -08004419 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004420
4421 /**
4422 * Returns the URI for the per-account voicemail ringtone set in Phone settings.
4423 *
4424 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
4425 * voicemail ringtone.
4426 * @return The URI for the ringtone to play when receiving a voicemail from a specific
4427 * PhoneAccount.
4428 */
4429 @Override
4430 public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004431 final long identity = Binder.clearCallingIdentity();
4432 try {
4433 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
4434 if (phone == null) {
4435 phone = mPhone;
4436 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004437
Malcolm Chenaabec062018-02-28 15:00:40 -08004438 return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext());
4439 } finally {
4440 Binder.restoreCallingIdentity(identity);
4441 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004442 }
4443
4444 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004445 * Sets the per-account voicemail ringtone.
4446 *
4447 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
4448 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
4449 *
4450 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
4451 * voicemail ringtone.
4452 * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
4453 * PhoneAccount.
4454 */
4455 @Override
4456 public void setVoicemailRingtoneUri(String callingPackage,
4457 PhoneAccountHandle phoneAccountHandle, Uri uri) {
4458 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4459 if (!TextUtils.equals(callingPackage,
4460 TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004461 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4462 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
4463 "setVoicemailRingtoneUri");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004464 }
Malcolm Chenaabec062018-02-28 15:00:40 -08004465
4466 final long identity = Binder.clearCallingIdentity();
4467 try {
4468 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
4469 if (phone == null) {
4470 phone = mPhone;
4471 }
4472 VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri);
4473 } finally {
4474 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004475 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004476 }
4477
4478 /**
Nancy Chen31f9ba12016-01-06 11:42:12 -08004479 * Returns whether vibration is set for voicemail notification in Phone settings.
4480 *
4481 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
4482 * voicemail vibration setting.
4483 * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
4484 */
4485 @Override
4486 public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004487 final long identity = Binder.clearCallingIdentity();
4488 try {
4489 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
4490 if (phone == null) {
4491 phone = mPhone;
4492 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004493
Malcolm Chenaabec062018-02-28 15:00:40 -08004494 return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext());
4495 } finally {
4496 Binder.restoreCallingIdentity(identity);
4497 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004498 }
4499
Youhan Wange64578a2016-05-02 15:32:42 -07004500 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004501 * Sets the per-account voicemail vibration.
4502 *
4503 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
4504 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
4505 *
4506 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
4507 * voicemail vibration setting.
4508 * @param enabled Whether to enable or disable vibration for voicemail notifications from a
4509 * specific PhoneAccount.
4510 */
4511 @Override
4512 public void setVoicemailVibrationEnabled(String callingPackage,
4513 PhoneAccountHandle phoneAccountHandle, boolean enabled) {
4514 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4515 if (!TextUtils.equals(callingPackage,
4516 TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004517 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4518 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
4519 "setVoicemailVibrationEnabled");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004520 }
4521
Malcolm Chenaabec062018-02-28 15:00:40 -08004522 final long identity = Binder.clearCallingIdentity();
4523 try {
4524 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
4525 if (phone == null) {
4526 phone = mPhone;
4527 }
4528 VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled);
4529 } finally {
4530 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004531 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004532 }
4533
4534 /**
Youhan Wange64578a2016-05-02 15:32:42 -07004535 * Make sure either called from same process as self (phone) or IPC caller has read privilege.
4536 *
4537 * @throws SecurityException if the caller does not have the required permission
4538 */
4539 private void enforceReadPrivilegedPermission() {
4540 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
4541 null);
4542 }
4543
4544 /**
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004545 * Make sure either called from same process as self (phone) or IPC caller has send SMS
4546 * permission.
4547 *
4548 * @throws SecurityException if the caller does not have the required permission
4549 */
4550 private void enforceSendSmsPermission() {
4551 mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null);
4552 }
4553
4554 /**
Ta-wei Yen527a9c02017-01-06 15:29:25 -08004555 * Make sure called from the package in charge of visual voicemail.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004556 *
Ta-wei Yen527a9c02017-01-06 15:29:25 -08004557 * @throws SecurityException if the caller is not the visual voicemail package.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004558 */
Ta-wei Yen527a9c02017-01-06 15:29:25 -08004559 private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004560 final long identity = Binder.clearCallingIdentity();
4561 try {
4562 ComponentName componentName =
4563 RemoteVvmTaskManager.getRemotePackage(mPhone.getContext(), subId);
4564 if (componentName == null) {
4565 throw new SecurityException(
4566 "Caller not current active visual voicemail package[null]");
4567 }
4568 String vvmPackage = componentName.getPackageName();
4569 if (!callingPackage.equals(vvmPackage)) {
4570 throw new SecurityException("Caller not current active visual voicemail package["
4571 + vvmPackage + "]");
4572 }
4573 } finally {
4574 Binder.restoreCallingIdentity(identity);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004575 }
4576 }
4577
4578 /**
Youhan Wange64578a2016-05-02 15:32:42 -07004579 * Return the application ID for the app type.
4580 *
4581 * @param subId the subscription ID that this request applies to.
4582 * @param appType the uicc app type.
4583 * @return Application ID for specificied app type, or null if no uicc.
4584 */
4585 @Override
4586 public String getAidForAppType(int subId, int appType) {
4587 enforceReadPrivilegedPermission();
4588 Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08004589
4590 final long identity = Binder.clearCallingIdentity();
Youhan Wange64578a2016-05-02 15:32:42 -07004591 try {
Malcolm Chenaabec062018-02-28 15:00:40 -08004592 if (phone == null) {
4593 return null;
4594 }
4595 String aid = null;
4596 try {
4597 aid = UiccController.getInstance().getUiccCard(phone.getPhoneId())
4598 .getApplicationByType(appType).getAid();
4599 } catch (Exception e) {
4600 Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e);
4601 }
4602 return aid;
4603 } finally {
4604 Binder.restoreCallingIdentity(identity);
Youhan Wange64578a2016-05-02 15:32:42 -07004605 }
Youhan Wange64578a2016-05-02 15:32:42 -07004606 }
4607
Youhan Wang4001d252016-05-11 10:29:41 -07004608 /**
4609 * Return the Electronic Serial Number.
4610 *
4611 * @param subId the subscription ID that this request applies to.
4612 * @return ESN or null if error.
4613 */
4614 @Override
4615 public String getEsn(int subId) {
4616 enforceReadPrivilegedPermission();
4617 Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08004618
4619 final long identity = Binder.clearCallingIdentity();
Youhan Wang4001d252016-05-11 10:29:41 -07004620 try {
Malcolm Chenaabec062018-02-28 15:00:40 -08004621 if (phone == null) {
4622 return null;
4623 }
4624 String esn = null;
4625 try {
4626 esn = phone.getEsn();
4627 } catch (Exception e) {
4628 Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e);
4629 }
4630 return esn;
4631 } finally {
4632 Binder.restoreCallingIdentity(identity);
Youhan Wang4001d252016-05-11 10:29:41 -07004633 }
Youhan Wang4001d252016-05-11 10:29:41 -07004634 }
4635
Sanket Padawe99ef1e32016-05-18 16:12:33 -07004636 /**
Youhan Wang66ad5d72016-07-18 17:56:58 -07004637 * Return the Preferred Roaming List Version.
4638 *
4639 * @param subId the subscription ID that this request applies to.
4640 * @return PRLVersion or null if error.
4641 */
4642 @Override
4643 public String getCdmaPrlVersion(int subId) {
4644 enforceReadPrivilegedPermission();
4645 Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08004646
4647 final long identity = Binder.clearCallingIdentity();
Youhan Wang66ad5d72016-07-18 17:56:58 -07004648 try {
Malcolm Chenaabec062018-02-28 15:00:40 -08004649 if (phone == null) {
4650 return null;
4651 }
4652 String cdmaPrlVersion = null;
4653 try {
4654 cdmaPrlVersion = phone.getCdmaPrlVersion();
4655 } catch (Exception e) {
4656 Log.e(LOG_TAG, "Not getting PRLVersion", e);
4657 }
4658 return cdmaPrlVersion;
4659 } finally {
4660 Binder.restoreCallingIdentity(identity);
Youhan Wang66ad5d72016-07-18 17:56:58 -07004661 }
Youhan Wang66ad5d72016-07-18 17:56:58 -07004662 }
4663
4664 /**
Sanket Padawe99ef1e32016-05-18 16:12:33 -07004665 * Get snapshot of Telephony histograms
4666 * @return List of Telephony histograms
4667 * @hide
4668 */
4669 @Override
4670 public List<TelephonyHistogram> getTelephonyHistograms() {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004671 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4672 mApp, getDefaultSubscription(), "getTelephonyHistograms");
Malcolm Chenaabec062018-02-28 15:00:40 -08004673
4674 final long identity = Binder.clearCallingIdentity();
4675 try {
4676 return RIL.getTelephonyRILTimingHistograms();
4677 } finally {
4678 Binder.restoreCallingIdentity(identity);
4679 }
Sanket Padawe99ef1e32016-05-18 16:12:33 -07004680 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07004681
4682 /**
4683 * {@hide}
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004684 * Set the allowed carrier list for slotIndex
Meng Wang1a7c35a2016-05-05 20:56:15 -07004685 * Require system privileges. In the future we may add this to carrier APIs.
4686 *
4687 * @return The number of carriers set successfully, should match length of carriers
4688 */
4689 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004690 public int setAllowedCarriers(int slotIndex, List<CarrierIdentifier> carriers) {
Meng Wang1a7c35a2016-05-05 20:56:15 -07004691 enforceModifyPermission();
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004692
Meng Wang9b7c4e92017-02-17 11:41:27 -08004693 if (carriers == null) {
4694 throw new NullPointerException("carriers cannot be null");
4695 }
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004696
Malcolm Chenaabec062018-02-28 15:00:40 -08004697 final long identity = Binder.clearCallingIdentity();
4698 try {
4699 int subId = SubscriptionManager.getSubId(slotIndex)[0];
4700 int[] retVal = (int[]) sendRequest(CMD_SET_ALLOWED_CARRIERS, carriers, subId);
4701 return retVal[0];
4702 } finally {
4703 Binder.restoreCallingIdentity(identity);
4704 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07004705 }
4706
4707 /**
4708 * {@hide}
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004709 * Get the allowed carrier list for slotIndex.
Meng Wang1a7c35a2016-05-05 20:56:15 -07004710 * Require system privileges. In the future we may add this to carrier APIs.
4711 *
4712 * @return List of {@link android.service.telephony.CarrierIdentifier}; empty list
4713 * means all carriers are allowed.
4714 */
4715 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004716 public List<CarrierIdentifier> getAllowedCarriers(int slotIndex) {
Meng Wang1a7c35a2016-05-05 20:56:15 -07004717 enforceReadPrivilegedPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08004718
4719 final long identity = Binder.clearCallingIdentity();
4720 try {
4721 int subId = SubscriptionManager.getSubId(slotIndex)[0];
4722 return (List<CarrierIdentifier>) sendRequest(CMD_GET_ALLOWED_CARRIERS, null, subId);
4723 } finally {
4724 Binder.restoreCallingIdentity(identity);
4725 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07004726 }
4727
fionaxu59545b42016-05-25 15:53:37 -07004728 /**
4729 * Action set from carrier signalling broadcast receivers to enable/disable metered apns
4730 * @param subId the subscription ID that this action applies to.
4731 * @param enabled control enable or disable metered apns.
4732 * {@hide}
4733 */
4734 @Override
4735 public void carrierActionSetMeteredApnsEnabled(int subId, boolean enabled) {
4736 enforceModifyPermission();
4737 final Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08004738
4739 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07004740 if (phone == null) {
4741 loge("carrierAction: SetMeteredApnsEnabled fails with invalid subId: " + subId);
4742 return;
4743 }
4744 try {
4745 phone.carrierActionSetMeteredApnsEnabled(enabled);
4746 } catch (Exception e) {
4747 Log.e(LOG_TAG, "carrierAction: SetMeteredApnsEnabled fails. Exception ex=" + e);
Malcolm Chenaabec062018-02-28 15:00:40 -08004748 } finally {
4749 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07004750 }
4751 }
4752
4753 /**
4754 * Action set from carrier signalling broadcast receivers to enable/disable radio
4755 * @param subId the subscription ID that this action applies to.
4756 * @param enabled control enable or disable radio.
4757 * {@hide}
4758 */
4759 @Override
4760 public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
4761 enforceModifyPermission();
4762 final Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08004763
4764 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07004765 if (phone == null) {
4766 loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
4767 return;
4768 }
4769 try {
4770 phone.carrierActionSetRadioEnabled(enabled);
4771 } catch (Exception e) {
4772 Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
Malcolm Chenaabec062018-02-28 15:00:40 -08004773 } finally {
4774 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07004775 }
4776 }
4777
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07004778 /**
fionaxu8da9cb12017-05-23 15:02:46 -07004779 * Action set from carrier signalling broadcast receivers to start/stop reporting the default
4780 * network status based on which carrier apps could apply actions accordingly,
4781 * enable/disable default url handler for example.
4782 *
4783 * @param subId the subscription ID that this action applies to.
4784 * @param report control start/stop reporting the default network status.
4785 * {@hide}
4786 */
4787 @Override
4788 public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
4789 enforceModifyPermission();
4790 final Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08004791
4792 final long identity = Binder.clearCallingIdentity();
fionaxu8da9cb12017-05-23 15:02:46 -07004793 if (phone == null) {
4794 loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId);
4795 return;
4796 }
4797 try {
4798 phone.carrierActionReportDefaultNetworkStatus(report);
4799 } catch (Exception e) {
4800 Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e);
Malcolm Chenaabec062018-02-28 15:00:40 -08004801 } finally {
4802 Binder.restoreCallingIdentity(identity);
fionaxu8da9cb12017-05-23 15:02:46 -07004803 }
4804 }
4805
4806 /**
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07004807 * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a
4808 * bug report is being generated.
4809 */
4810 @Override
Ta-wei Yen99282e02016-06-21 18:19:35 -07004811 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
dcashman22b950d2016-06-27 11:39:02 -07004812 if (mPhone.getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
4813 != PackageManager.PERMISSION_GRANTED) {
4814 writer.println("Permission Denial: can't dump Phone from pid="
4815 + Binder.getCallingPid()
4816 + ", uid=" + Binder.getCallingUid()
4817 + "without permission "
4818 + android.Manifest.permission.DUMP);
4819 return;
4820 }
Ta-wei Yen99282e02016-06-21 18:19:35 -07004821 DumpsysHandler.dump(mPhone.getContext(), fd, writer, args);
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07004822 }
Jack Yueb89b242016-06-22 13:27:47 -07004823
Brad Ebingerdac2f002018-04-03 15:17:52 -07004824 @Override
4825 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
4826 String[] args, ShellCallback callback, ResultReceiver resultReceiver)
4827 throws RemoteException {
4828 (new TelephonyShellCommand(this)).exec(this, in, out, err, args, callback, resultReceiver);
4829 }
4830
Jack Yueb89b242016-06-22 13:27:47 -07004831 /**
Jack Yu84291ec2017-05-26 16:07:50 -07004832 * Get aggregated video call data usage since boot.
4833 *
4834 * @param perUidStats True if requesting data usage per uid, otherwise overall usage.
4835 * @return Snapshot of video call data usage
Jack Yueb89b242016-06-22 13:27:47 -07004836 * {@hide}
4837 */
4838 @Override
Jack Yu84291ec2017-05-26 16:07:50 -07004839 public NetworkStats getVtDataUsage(int subId, boolean perUidStats) {
Jack Yueb89b242016-06-22 13:27:47 -07004840 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_NETWORK_USAGE_HISTORY,
4841 null);
4842
Malcolm Chenaabec062018-02-28 15:00:40 -08004843 final long identity = Binder.clearCallingIdentity();
4844 try {
4845 // NetworkStatsService keeps tracking the active network interface and identity. It
4846 // records the delta with the corresponding network identity.
4847 // We just return the total video call data usage snapshot since boot.
4848 Phone phone = getPhone(subId);
4849 if (phone != null) {
4850 return phone.getVtDataUsage(perUidStats);
4851 }
4852 return null;
4853 } finally {
4854 Binder.restoreCallingIdentity(identity);
Jack Yueb89b242016-06-22 13:27:47 -07004855 }
Jack Yueb89b242016-06-22 13:27:47 -07004856 }
Jack Yu75ab2952016-07-08 14:29:33 -07004857
4858 /**
4859 * Policy control of data connection. Usually used when data limit is passed.
4860 * @param enabled True if enabling the data, otherwise disabling.
4861 * @param subId Subscription index
4862 * {@hide}
4863 */
4864 @Override
4865 public void setPolicyDataEnabled(boolean enabled, int subId) {
4866 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08004867
4868 final long identity = Binder.clearCallingIdentity();
4869 try {
4870 Phone phone = getPhone(subId);
4871 if (phone != null) {
4872 phone.setPolicyDataEnabled(enabled);
4873 }
4874 } finally {
4875 Binder.restoreCallingIdentity(identity);
Jack Yu75ab2952016-07-08 14:29:33 -07004876 }
4877 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004878
4879 /**
4880 * Get Client request stats
4881 * @return List of Client Request Stats
4882 * @hide
4883 */
4884 @Override
4885 public List<ClientRequestStats> getClientRequestStats(String callingPackage, int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004886 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08004887 mApp, subId, callingPackage, "getClientRequestStats")) {
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004888 return null;
4889 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004890 Phone phone = getPhone(subId);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004891
Malcolm Chenaabec062018-02-28 15:00:40 -08004892 final long identity = Binder.clearCallingIdentity();
4893 try {
4894 if (phone != null) {
4895 return phone.getClientRequestStats();
4896 }
4897
4898 return null;
4899 } finally {
4900 Binder.restoreCallingIdentity(identity);
4901 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004902 }
4903
Narayan Kamathf04b5a12018-01-09 11:47:15 +00004904 private WorkSource getWorkSource(int uid) {
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004905 String packageName = mPhone.getContext().getPackageManager().getNameForUid(uid);
Narayan Kamathf04b5a12018-01-09 11:47:15 +00004906 return new WorkSource(uid, packageName);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004907 }
Jack Yueb4124c2017-02-16 15:32:43 -08004908
4909 /**
Grace Chen70990072017-03-24 17:21:30 -07004910 * Set SIM card power state.
Jack Yueb4124c2017-02-16 15:32:43 -08004911 *
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004912 * @param slotIndex SIM slot id.
Grace Chen70990072017-03-24 17:21:30 -07004913 * @param state State of SIM (power down, power up, pass through)
4914 * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
4915 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
4916 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
Jack Yueb4124c2017-02-16 15:32:43 -08004917 *
4918 **/
4919 @Override
Grace Chen70990072017-03-24 17:21:30 -07004920 public void setSimPowerStateForSlot(int slotIndex, int state) {
Jack Yueb4124c2017-02-16 15:32:43 -08004921 enforceModifyPermission();
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004922 Phone phone = PhoneFactory.getPhone(slotIndex);
4923
Malcolm Chenaabec062018-02-28 15:00:40 -08004924 final long identity = Binder.clearCallingIdentity();
4925 try {
4926 if (phone != null) {
4927 phone.setSimPowerState(state);
4928 }
4929 } finally {
4930 Binder.restoreCallingIdentity(identity);
Jack Yueb4124c2017-02-16 15:32:43 -08004931 }
4932 }
Shuo Qiandd210312017-04-12 22:11:33 +00004933
Tyler Gunn65d45c22017-06-05 11:22:26 -07004934 private boolean isUssdApiAllowed(int subId) {
4935 CarrierConfigManager configManager =
4936 (CarrierConfigManager) mPhone.getContext().getSystemService(
4937 Context.CARRIER_CONFIG_SERVICE);
4938 if (configManager == null) {
4939 return false;
4940 }
4941 PersistableBundle pb = configManager.getConfigForSubId(subId);
4942 if (pb == null) {
4943 return false;
4944 }
4945 return pb.getBoolean(
4946 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL);
4947 }
4948
Shuo Qiandd210312017-04-12 22:11:33 +00004949 /**
4950 * Check if phone is in emergency callback mode
4951 * @return true if phone is in emergency callback mode
4952 * @param subId sub id
4953 */
goneil9c5f4872017-12-05 14:07:56 -08004954 @Override
Shuo Qiandd210312017-04-12 22:11:33 +00004955 public boolean getEmergencyCallbackMode(int subId) {
goneil9c5f4872017-12-05 14:07:56 -08004956 enforceReadPrivilegedPermission();
Shuo Qiandd210312017-04-12 22:11:33 +00004957 final Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08004958
4959 final long identity = Binder.clearCallingIdentity();
4960 try {
4961 if (phone != null) {
4962 return phone.isInEcm();
4963 } else {
4964 return false;
4965 }
4966 } finally {
4967 Binder.restoreCallingIdentity(identity);
Shuo Qiandd210312017-04-12 22:11:33 +00004968 }
4969 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08004970
4971 /**
4972 * Get the current signal strength information for the given subscription.
4973 * Because this information is not updated when the device is in a low power state
4974 * it should not be relied-upon to be current.
4975 * @param subId Subscription index
4976 * @return the most recent cached signal strength info from the modem
4977 */
4978 @Override
4979 public SignalStrength getSignalStrength(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004980 final long identity = Binder.clearCallingIdentity();
4981 try {
4982 Phone p = getPhone(subId);
4983 if (p == null) {
4984 return null;
4985 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08004986
Malcolm Chenaabec062018-02-28 15:00:40 -08004987 return p.getSignalStrength();
4988 } finally {
4989 Binder.restoreCallingIdentity(identity);
4990 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08004991 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00004992
Pengquan Meng9140aec2018-08-22 14:49:57 -07004993 /**
4994 * Checks if data roaming is enabled on the subscription with id {@code subId}.
4995 *
4996 * <p>Requires one of the following permissions:
4997 * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
4998 * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
4999 * privileges.
5000 *
5001 * @param subId subscription id
5002 * @return {@code true} if data roaming is enabled on this subscription, otherwise return
5003 * {@code false}.
5004 */
5005 @Override
5006 public boolean isDataRoamingEnabled(int subId) {
5007 try {
5008 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
5009 null);
5010 } catch (Exception e) {
5011 TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
5012 mApp, subId, "isDataRoamingEnabled");
5013 }
5014
5015 Phone phone = getPhone(subId);
5016 return phone != null ? phone.getDataRoamingEnabled() : false;
5017 }
5018
5019
5020 /**
5021 * Enables/Disables the data roaming on the subscription with id {@code subId}.
5022 *
5023 * <p> Requires permission:
5024 * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier
5025 * privileges.
5026 *
5027 * @param subId subscription id
5028 * @param isEnabled {@code true} means enable, {@code false} means disable.
5029 */
5030 @Override
5031 public void setDataRoamingEnabled(int subId, boolean isEnabled) {
5032 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5033 mApp, subId, "setDataRoamingEbaled");
5034
5035 Phone phone = getPhone(subId);
5036 if (phone != null) {
5037 phone.setDataRoamingEnabled(isEnabled);
5038 }
5039 }
5040
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005041 @Override
5042 public UiccSlotInfo[] getUiccSlotsInfo() {
5043 enforceReadPrivilegedPermission();
5044
Malcolm Chenaabec062018-02-28 15:00:40 -08005045 final long identity = Binder.clearCallingIdentity();
5046 try {
5047 UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
Malcolm Chen1cc36b62018-07-30 14:42:47 -07005048 if (slots == null) {
5049 Rlog.i(LOG_TAG, "slots is null.");
5050 return null;
5051 }
5052
Malcolm Chenaabec062018-02-28 15:00:40 -08005053 UiccSlotInfo[] infos = new UiccSlotInfo[slots.length];
5054 for (int i = 0; i < slots.length; i++) {
5055 UiccSlot slot = slots[i];
Malcolm Chen1cc36b62018-07-30 14:42:47 -07005056 if (slot == null) {
5057 continue;
5058 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005059
Malcolm Chen1cc36b62018-07-30 14:42:47 -07005060 String cardId;
5061 UiccCard card = slot.getUiccCard();
5062 if (card != null) {
5063 cardId = card.getCardId();
5064 } else {
5065 cardId = slot.getIccId();
5066 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005067
Malcolm Chenaabec062018-02-28 15:00:40 -08005068 int cardState = 0;
5069 switch (slot.getCardState()) {
5070 case CARDSTATE_ABSENT:
5071 cardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
5072 break;
5073 case CARDSTATE_PRESENT:
5074 cardState = UiccSlotInfo.CARD_STATE_INFO_PRESENT;
5075 break;
5076 case CARDSTATE_ERROR:
5077 cardState = UiccSlotInfo.CARD_STATE_INFO_ERROR;
5078 break;
5079 case CARDSTATE_RESTRICTED:
5080 cardState = UiccSlotInfo.CARD_STATE_INFO_RESTRICTED;
5081 break;
5082 default:
5083 break;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005084
Malcolm Chenaabec062018-02-28 15:00:40 -08005085 }
5086
5087 infos[i] = new UiccSlotInfo(
5088 slot.isActive(),
5089 slot.isEuicc(),
5090 cardId,
5091 cardState,
5092 slot.getPhoneId(),
5093 slot.isExtendedApduSupported());
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005094 }
Malcolm Chenaabec062018-02-28 15:00:40 -08005095 return infos;
5096 } finally {
5097 Binder.restoreCallingIdentity(identity);
Holly Jiuyu Sun1d957c52018-04-04 13:52:42 -07005098 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005099 }
5100
5101 @Override
5102 public boolean switchSlots(int[] physicalSlots) {
5103 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08005104
5105 final long identity = Binder.clearCallingIdentity();
5106 try {
5107 return (Boolean) sendRequest(CMD_SWITCH_SLOTS, physicalSlots);
5108 } finally {
5109 Binder.restoreCallingIdentity(identity);
5110 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005111 }
Jack Yu4c988042018-02-27 15:30:01 -08005112
5113 @Override
5114 public void setRadioIndicationUpdateMode(int subId, int filters, int mode) {
5115 enforceModifyPermission();
5116 final Phone phone = getPhone(subId);
5117 if (phone == null) {
5118 loge("setRadioIndicationUpdateMode fails with invalid subId: " + subId);
5119 return;
5120 }
5121
Malcolm Chenaabec062018-02-28 15:00:40 -08005122 final long identity = Binder.clearCallingIdentity();
5123 try {
5124 phone.setRadioIndicationUpdateMode(filters, mode);
5125 } finally {
5126 Binder.restoreCallingIdentity(identity);
5127 }
Jack Yu4c988042018-02-27 15:30:01 -08005128 }
Pengquan Meng85728fb2018-03-12 16:31:21 -07005129
5130 /**
goneil47ffb6e2018-04-06 15:40:58 -07005131 * A test API to reload the UICC profile.
5132 *
5133 * <p>Requires that the calling app has permission
5134 * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
5135 * @hide
5136 */
5137 @Override
5138 public void refreshUiccProfile(int subId) {
5139 enforceModifyPermission();
5140
5141 final long identity = Binder.clearCallingIdentity();
5142 try {
5143 Phone phone = getPhone(subId);
5144 if (phone == null) {
5145 return;
5146 }
5147 UiccCard uiccCard = phone.getUiccCard();
5148 if (uiccCard == null) {
5149 return;
5150 }
5151 UiccProfile uiccProfile = uiccCard.getUiccProfile();
5152 if (uiccProfile == null) {
5153 return;
5154 }
5155 uiccProfile.refresh();
5156 } finally {
5157 Binder.restoreCallingIdentity(identity);
5158 }
5159 }
5160
5161 /**
Pengquan Meng85728fb2018-03-12 16:31:21 -07005162 * Returns false if the mobile data is disabled by default, otherwise return true.
5163 */
5164 private boolean getDefaultDataEnabled() {
5165 return "true".equalsIgnoreCase(
5166 SystemProperties.get(DEFAULT_MOBILE_DATA_PROPERTY_NAME, "true"));
5167 }
5168
5169 /**
5170 * Returns true if the data roaming is enabled by default, i.e the system property
5171 * of {@link #DEFAULT_DATA_ROAMING_PROPERTY_NAME} is true or the config of
5172 * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} is true.
5173 */
5174 private boolean getDefaultDataRoamingEnabled(int subId) {
5175 final CarrierConfigManager configMgr = (CarrierConfigManager)
5176 mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
5177 boolean isDataRoamingEnabled = "true".equalsIgnoreCase(
5178 SystemProperties.get(DEFAULT_DATA_ROAMING_PROPERTY_NAME, "false"));
5179 isDataRoamingEnabled |= configMgr.getConfigForSubId(subId).getBoolean(
5180 CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
5181 return isDataRoamingEnabled;
5182 }
5183
5184 /**
5185 * Returns the default network type for the given {@code subId}, if the default network type is
5186 * not set, return {@link Phone#PREFERRED_NT_MODE}.
5187 */
5188 private int getDefaultNetworkType(int subId) {
5189 return Integer.parseInt(
5190 TelephonyManager.getTelephonyProperty(
5191 mSubscriptionController.getPhoneId(subId),
5192 DEFAULT_NETWORK_MODE_PROPERTY_NAME,
5193 String.valueOf(Phone.PREFERRED_NT_MODE)));
5194 }
fionaxua13278b2018-03-21 00:08:13 -07005195
5196 @Override
5197 public void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String
5198 gid1, String gid2, String plmn, String spn) {
5199 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08005200
5201 final long identity = Binder.clearCallingIdentity();
5202 try {
5203 final Phone phone = getPhone(subId);
5204 if (phone == null) {
5205 loge("setCarrierTestOverride fails with invalid subId: " + subId);
5206 return;
5207 }
5208 phone.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, plmn, spn);
5209 } finally {
5210 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07005211 }
fionaxua13278b2018-03-21 00:08:13 -07005212 }
5213
5214 @Override
5215 public int getCarrierIdListVersion(int subId) {
5216 enforceReadPrivilegedPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08005217
5218 final long identity = Binder.clearCallingIdentity();
5219 try {
5220 final Phone phone = getPhone(subId);
5221 if (phone == null) {
5222 loge("getCarrierIdListVersion fails with invalid subId: " + subId);
5223 return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
5224 }
5225 return phone.getCarrierIdListVersion();
5226 } finally {
5227 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07005228 }
fionaxua13278b2018-03-21 00:08:13 -07005229 }
Malcolm Chenf144d942018-08-14 16:00:53 -07005230
5231 @Override
5232 public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage) {
5233 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5234 mApp, subId, callingPackage, "getNumberOfModemsWithSimultaneousDataConnections")) {
5235 return -1;
5236 }
5237
5238 final long identity = Binder.clearCallingIdentity();
5239 try {
5240 return mPhoneConfigurationManager.getNumberOfModemsWithSimultaneousDataConnections();
5241 } finally {
5242 Binder.restoreCallingIdentity(identity);
5243 }
5244 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005245}