blob: 353f4b55a482646aaee99282476b820558e277ad [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;
Nathan Harold3ff88932018-08-14 10:19:49 -070060import android.telephony.CellLocation;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070061import android.telephony.ClientRequestStats;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -070062import android.telephony.IccOpenLogicalChannelResponse;
Hall Liu1aa510f2017-11-22 17:40:08 -080063import android.telephony.LocationAccessPolicy;
Ta-wei Yen87c49842016-05-13 21:19:52 -070064import android.telephony.ModemActivityInfo;
Jake Hambye994d462014-02-03 13:10:13 -080065import android.telephony.NeighboringCellInfo;
yinxu504e1392017-04-12 16:03:22 -070066import android.telephony.NetworkScanRequest;
Wink Saville5d475dd2014-10-17 15:00:58 -070067import android.telephony.RadioAccessFamily;
Tyler Gunn65d45c22017-06-05 11:22:26 -070068import android.telephony.Rlog;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070069import android.telephony.ServiceState;
Nathan Harold46b42aa2017-03-10 19:38:22 -080070import android.telephony.SignalStrength;
Jack Yu84291ec2017-05-26 16:07:50 -070071import android.telephony.SmsManager;
Wink Saville0f3b5fc2014-11-11 08:40:49 -080072import android.telephony.SubscriptionInfo;
Jeff Sharkey85190e62014-12-05 09:40:12 -080073import android.telephony.SubscriptionManager;
Sanket Padawe99ef1e32016-05-18 16:12:33 -070074import android.telephony.TelephonyHistogram;
Ta-wei Yenb6929602016-05-24 15:48:27 -070075import android.telephony.TelephonyManager;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +000076import android.telephony.UiccSlotInfo;
Tyler Gunn65d45c22017-06-05 11:22:26 -070077import android.telephony.UssdResponse;
Ta-wei Yenb6929602016-05-24 15:48:27 -070078import android.telephony.VisualVoicemailSmsFilterSettings;
Nathan Harold3ff88932018-08-14 10:19:49 -070079import android.telephony.cdma.CdmaCellLocation;
80import android.telephony.gsm.GsmCellLocation;
Brad Ebinger22bc3e42018-01-16 09:39:35 -080081import android.telephony.ims.aidl.IImsConfig;
82import android.telephony.ims.aidl.IImsMmTelFeature;
83import android.telephony.ims.aidl.IImsRcsFeature;
84import android.telephony.ims.aidl.IImsRegistration;
Brad Ebinger1f2b5082018-02-08 16:11:32 -080085import android.telephony.ims.stub.ImsRegistrationImplBase;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070086import android.text.TextUtils;
Jeff Sharkey85190e62014-12-05 09:40:12 -080087import android.util.ArraySet;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070088import android.util.Log;
Jake Hambye994d462014-02-03 13:10:13 -080089import android.util.Pair;
Jeff Sharkey85190e62014-12-05 09:40:12 -080090import android.util.Slog;
Ta-wei Yen30a69c82016-12-27 14:52:32 -080091
Andrew Lee312e8172014-10-23 17:01:36 -070092import com.android.ims.ImsManager;
Brad Ebinger34bef922017-11-09 10:27:08 -080093import com.android.ims.internal.IImsServiceFeatureCallback;
Shishir Agrawal566b7612013-10-28 14:41:00 -070094import com.android.internal.telephony.CallManager;
Tyler Gunn52dcf772017-04-26 11:30:31 -070095import com.android.internal.telephony.CallStateException;
pkanwar79ec0542017-07-31 14:10:01 -070096import com.android.internal.telephony.CarrierInfoManager;
Shishir Agrawal302c8692015-06-19 13:49:39 -070097import com.android.internal.telephony.CellNetworkScanResult;
Shishir Agrawal566b7612013-10-28 14:41:00 -070098import com.android.internal.telephony.CommandException;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070099import com.android.internal.telephony.DefaultPhoneNotifier;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700100import com.android.internal.telephony.ITelephony;
Jake Hambye994d462014-02-03 13:10:13 -0800101import com.android.internal.telephony.IccCard;
Jack Yu5f7092c2018-04-13 14:05:37 -0700102import com.android.internal.telephony.LocaleTracker;
Narayan Kamath1c496c22015-04-16 14:40:19 +0100103import com.android.internal.telephony.MccTable;
yinxub1bed742017-04-17 11:45:04 -0700104import com.android.internal.telephony.NetworkScanRequestTracker;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700105import com.android.internal.telephony.OperatorInfo;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700106import com.android.internal.telephony.Phone;
Malcolm Chenf144d942018-08-14 16:00:53 -0700107import com.android.internal.telephony.PhoneConfigurationManager;
Nathan Harolda667c152016-12-14 11:27:20 -0800108import com.android.internal.telephony.PhoneConstantConversions;
Ta-wei Yen87c49842016-05-13 21:19:52 -0700109import com.android.internal.telephony.PhoneConstants;
Wink Saville36469e72014-06-11 15:17:00 -0700110import com.android.internal.telephony.PhoneFactory;
Wink Saville5d475dd2014-10-17 15:00:58 -0700111import com.android.internal.telephony.ProxyController;
Sanket Padawe99ef1e32016-05-18 16:12:33 -0700112import com.android.internal.telephony.RIL;
Svet Ganovb320e182015-04-16 12:30:10 -0700113import com.android.internal.telephony.RILConstants;
Jack Yu5f7092c2018-04-13 14:05:37 -0700114import com.android.internal.telephony.ServiceStateTracker;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800115import com.android.internal.telephony.SubscriptionController;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800116import com.android.internal.telephony.TelephonyPermissions;
Derek Tan740e1672017-06-27 14:56:27 -0700117import com.android.internal.telephony.euicc.EuiccConnector;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700118import com.android.internal.telephony.uicc.IccIoResult;
119import com.android.internal.telephony.uicc.IccUtils;
Nathan Haroldb3014052017-01-25 15:57:32 -0800120import com.android.internal.telephony.uicc.SIMRecords;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700121import com.android.internal.telephony.uicc.UiccCard;
Nathan Haroldb3014052017-01-25 15:57:32 -0800122import com.android.internal.telephony.uicc.UiccCardApplication;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700123import com.android.internal.telephony.uicc.UiccController;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800124import com.android.internal.telephony.uicc.UiccProfile;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000125import com.android.internal.telephony.uicc.UiccSlot;
fionaxu7ed723d2017-05-30 18:58:54 -0700126import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
Jake Hambye994d462014-02-03 13:10:13 -0800127import com.android.internal.util.HexDump;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700128import com.android.phone.vvm.PhoneAccountHandleConverter;
Ta-wei Yen527a9c02017-01-06 15:29:25 -0800129import com.android.phone.vvm.RemoteVvmTaskManager;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700130import com.android.phone.vvm.VisualVoicemailSettingsUtil;
Ta-wei Yenc8905312017-03-28 11:14:45 -0700131import com.android.phone.vvm.VisualVoicemailSmsFilterConfig;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800132
Ta-wei Yenc236d6b2016-06-21 13:33:12 -0700133import java.io.FileDescriptor;
134import java.io.PrintWriter;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800135import java.nio.charset.StandardCharsets;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700136import java.util.ArrayList;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800137import java.util.Arrays;
Jake Hambye994d462014-02-03 13:10:13 -0800138import java.util.List;
Narayan Kamath1c496c22015-04-16 14:40:19 +0100139import java.util.Locale;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800140import java.util.Map;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700141
142/**
143 * Implementation of the ITelephony interface.
144 */
Santos Cordon117fee72014-05-16 17:56:12 -0700145public class PhoneInterfaceManager extends ITelephony.Stub {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700146 private static final String LOG_TAG = "PhoneInterfaceManager";
147 private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
148 private static final boolean DBG_LOC = false;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800149 private static final boolean DBG_MERGE = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700150
151 // Message codes used with mMainThreadHandler
152 private static final int CMD_HANDLE_PIN_MMI = 1;
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;
Pengquan Meng0c05b502018-09-06 09:59:22 -0700198 private static final int CMD_GET_NETWORK_SELECTION_MODE = 52;
199 private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 53;
200 private static final int CMD_GET_CDMA_ROAMING_MODE = 54;
201 private static final int EVENT_GET_CDMA_ROAMING_MODE_DONE = 55;
202 private static final int CMD_SET_CDMA_ROAMING_MODE = 56;
203 private static final int EVENT_SET_CDMA_ROAMING_MODE_DONE = 57;
204 private static final int CMD_SET_CDMA_SUBSCRIPTION_MODE = 58;
205 private static final int EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE = 59;
Nathan Harold3ff88932018-08-14 10:19:49 -0700206 private static final int CMD_GET_ALL_CELL_INFO = 60;
207 private static final int EVENT_GET_ALL_CELL_INFO_DONE = 61;
208 private static final int CMD_GET_CELL_LOCATION = 62;
209 private static final int EVENT_GET_CELL_LOCATION_DONE = 63;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700210
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -0800211 // Parameters of select command.
212 private static final int SELECT_COMMAND = 0xA4;
213 private static final int SELECT_P1 = 0x04;
214 private static final int SELECT_P2 = 0;
215 private static final int SELECT_P3 = 0x10;
216
Pengquan Meng85728fb2018-03-12 16:31:21 -0700217 private static final String DEFAULT_NETWORK_MODE_PROPERTY_NAME = "ro.telephony.default_network";
218 private static final String DEFAULT_DATA_ROAMING_PROPERTY_NAME = "ro.com.android.dataroaming";
219 private static final String DEFAULT_MOBILE_DATA_PROPERTY_NAME = "ro.com.android.mobiledata";
220
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700221 /** The singleton instance. */
222 private static PhoneInterfaceManager sInstance;
223
Wink Saville3ab207e2014-11-20 13:07:20 -0800224 private PhoneGlobals mApp;
225 private Phone mPhone;
226 private CallManager mCM;
Stuart Scott981d8582015-04-21 14:09:50 -0700227 private UserManager mUserManager;
Wink Saville3ab207e2014-11-20 13:07:20 -0800228 private AppOpsManager mAppOps;
229 private MainThreadHandler mMainThreadHandler;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800230 private SubscriptionController mSubscriptionController;
Wink Saville3ab207e2014-11-20 13:07:20 -0800231 private SharedPreferences mTelephonySharedPreferences;
Malcolm Chenf144d942018-08-14 16:00:53 -0700232 private PhoneConfigurationManager mPhoneConfigurationManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700233
Derek Tan97ebb422014-09-05 16:55:38 -0700234 private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
235 private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
Jeff Sharkey85190e62014-12-05 09:40:12 -0800236 private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
Derek Tan89e89d42014-07-08 17:00:10 -0700237
Derek Tan740e1672017-06-27 14:56:27 -0700238 // The AID of ISD-R.
239 private static final String ISDR_AID = "A0000005591010FFFFFFFF8900000100";
240
yinxub1bed742017-04-17 11:45:04 -0700241 private NetworkScanRequestTracker mNetworkScanRequestTracker;
242
David Kelly5e06a7f2018-03-12 14:10:59 +0000243 private static final int TYPE_ALLOCATION_CODE_LENGTH = 8;
244 private static final int MANUFACTURER_CODE_LENGTH = 8;
245
Derek Tan89e89d42014-07-08 17:00:10 -0700246 /**
Shishir Agrawal566b7612013-10-28 14:41:00 -0700247 * A request object to use for transmitting data to an ICC.
248 */
249 private static final class IccAPDUArgument {
250 public int channel, cla, command, p1, p2, p3;
251 public String data;
252
253 public IccAPDUArgument(int channel, int cla, int command,
254 int p1, int p2, int p3, String data) {
255 this.channel = channel;
256 this.cla = cla;
257 this.command = command;
258 this.p1 = p1;
259 this.p2 = p2;
260 this.p3 = p3;
261 this.data = data;
262 }
263 }
264
265 /**
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700266 * A request object to use for transmitting data to an ICC.
267 */
268 private static final class ManualNetworkSelectionArgument {
269 public OperatorInfo operatorInfo;
270 public boolean persistSelection;
271
272 public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) {
273 this.operatorInfo = operatorInfo;
274 this.persistSelection = persistSelection;
275 }
276 }
277
278 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700279 * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
280 * request after sending. The main thread will notify the request when it is complete.
281 */
282 private static final class MainThreadRequest {
283 /** The argument to use for the request */
284 public Object argument;
285 /** The result of the request that is run on the main thread */
286 public Object result;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800287 // The subscriber id that this request applies to. Defaults to
288 // SubscriptionManager.INVALID_SUBSCRIPTION_ID
289 public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700290
vagdevie435a3e2018-08-15 16:01:53 -0700291 public WorkSource workSource;
292
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700293 public MainThreadRequest(Object argument) {
294 this.argument = argument;
295 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800296
vagdevie435a3e2018-08-15 16:01:53 -0700297 MainThreadRequest(Object argument, Integer subId, WorkSource workSource) {
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800298 this.argument = argument;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800299 if (subId != null) {
300 this.subId = subId;
301 }
vagdevie435a3e2018-08-15 16:01:53 -0700302 this.workSource = workSource;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800303 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700304 }
305
Sailesh Nepalcc0375f2013-11-13 09:15:18 -0800306 private static final class IncomingThirdPartyCallArgs {
307 public final ComponentName component;
308 public final String callId;
309 public final String callerDisplayName;
310
311 public IncomingThirdPartyCallArgs(ComponentName component, String callId,
312 String callerDisplayName) {
313 this.component = component;
314 this.callId = callId;
315 this.callerDisplayName = callerDisplayName;
316 }
317 }
318
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700319 /**
320 * A handler that processes messages on the main thread in the phone process. Since many
321 * of the Phone calls are not thread safe this is needed to shuttle the requests from the
322 * inbound binder threads to the main thread in the phone process. The Binder thread
323 * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
324 * on, which will be notified when the operation completes and will contain the result of the
325 * request.
326 *
327 * <p>If a MainThreadRequest object is provided in the msg.obj field,
328 * note that request.result must be set to something non-null for the calling thread to
329 * unblock.
330 */
331 private final class MainThreadHandler extends Handler {
332 @Override
333 public void handleMessage(Message msg) {
334 MainThreadRequest request;
335 Message onCompleted;
336 AsyncResult ar;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800337 UiccCard uiccCard;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700338 IccAPDUArgument iccArgument;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700339
340 switch (msg.what) {
Pengquan Meng0c05b502018-09-06 09:59:22 -0700341 case CMD_HANDLE_USSD_REQUEST: {
342 request = (MainThreadRequest) msg.obj;
343 final Phone phone = getPhoneFromRequest(request);
344 Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
345 String ussdRequest = ussdObject.first;
346 ResultReceiver wrappedCallback = ussdObject.second;
Tyler Gunn65d45c22017-06-05 11:22:26 -0700347
Pengquan Meng0c05b502018-09-06 09:59:22 -0700348 if (!isUssdApiAllowed(request.subId)) {
349 // Carrier does not support use of this API, return failure.
350 Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
351 UssdResponse response = new UssdResponse(ussdRequest, null);
352 Bundle returnData = new Bundle();
353 returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
354 wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
Tyler Gunn65d45c22017-06-05 11:22:26 -0700355
Pengquan Meng0c05b502018-09-06 09:59:22 -0700356 request.result = true;
357 notifyRequester(request);
358 return;
359 }
Tyler Gunn65d45c22017-06-05 11:22:26 -0700360
Pengquan Meng0c05b502018-09-06 09:59:22 -0700361 try {
362 request.result = phone != null
363 ? phone.handleUssdRequest(ussdRequest, wrappedCallback) : false;
364 } catch (CallStateException cse) {
365 request.result = false;
366 }
367 // Wake up the requesting thread
368 notifyRequester(request);
369 break;
pkanwar32d516d2016-10-14 19:37:38 -0700370 }
371
Yorke Lee716f67e2015-06-17 15:39:16 -0700372 case CMD_HANDLE_PIN_MMI: {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700373 request = (MainThreadRequest) msg.obj;
Yorke Lee716f67e2015-06-17 15:39:16 -0700374 final Phone phone = getPhoneFromRequest(request);
375 request.result = phone != null ?
376 getPhoneFromRequest(request).handlePinMmi((String) request.argument)
377 : false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700378 // Wake up the requesting thread
Pengquan Meng0c05b502018-09-06 09:59:22 -0700379 notifyRequester(request);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700380 break;
Yorke Lee716f67e2015-06-17 15:39:16 -0700381 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700382
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700383 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700384 request = (MainThreadRequest) msg.obj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700385 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800386 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700387 if (uiccCard == null) {
388 loge("iccTransmitApduLogicalChannel: No UICC");
389 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Meng0c05b502018-09-06 09:59:22 -0700390 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700391 } else {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700392 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
393 request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700394 uiccCard.iccTransmitApduLogicalChannel(
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700395 iccArgument.channel, iccArgument.cla, iccArgument.command,
396 iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data,
Shishir Agrawal566b7612013-10-28 14:41:00 -0700397 onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700398 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700399 break;
400
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700401 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700402 ar = (AsyncResult) msg.obj;
403 request = (MainThreadRequest) ar.userObj;
404 if (ar.exception == null && ar.result != null) {
405 request.result = ar.result;
406 } else {
407 request.result = new IccIoResult(0x6F, 0, (byte[])null);
408 if (ar.result == null) {
409 loge("iccTransmitApduLogicalChannel: Empty response");
Jake Hambye994d462014-02-03 13:10:13 -0800410 } else if (ar.exception instanceof CommandException) {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700411 loge("iccTransmitApduLogicalChannel: CommandException: " +
Jake Hambye994d462014-02-03 13:10:13 -0800412 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700413 } else {
414 loge("iccTransmitApduLogicalChannel: Unknown exception");
415 }
416 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700417 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700418 break;
419
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700420 case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
421 request = (MainThreadRequest) msg.obj;
422 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800423 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700424 if (uiccCard == null) {
425 loge("iccTransmitApduBasicChannel: No UICC");
426 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Meng0c05b502018-09-06 09:59:22 -0700427 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700428 } else {
429 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
430 request);
431 uiccCard.iccTransmitApduBasicChannel(
432 iccArgument.cla, iccArgument.command, iccArgument.p1, iccArgument.p2,
433 iccArgument.p3, iccArgument.data, onCompleted);
434 }
435 break;
436
437 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
438 ar = (AsyncResult) msg.obj;
439 request = (MainThreadRequest) ar.userObj;
440 if (ar.exception == null && ar.result != null) {
441 request.result = ar.result;
442 } else {
443 request.result = new IccIoResult(0x6F, 0, (byte[])null);
444 if (ar.result == null) {
445 loge("iccTransmitApduBasicChannel: Empty response");
446 } else if (ar.exception instanceof CommandException) {
447 loge("iccTransmitApduBasicChannel: CommandException: " +
448 ar.exception);
449 } else {
450 loge("iccTransmitApduBasicChannel: Unknown exception");
451 }
452 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700453 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700454 break;
455
456 case CMD_EXCHANGE_SIM_IO:
457 request = (MainThreadRequest) msg.obj;
458 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800459 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700460 if (uiccCard == null) {
461 loge("iccExchangeSimIO: No UICC");
462 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Meng0c05b502018-09-06 09:59:22 -0700463 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700464 } else {
465 onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
466 request);
467 uiccCard.iccExchangeSimIO(iccArgument.cla, /* fileID */
468 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3,
469 iccArgument.data, onCompleted);
470 }
471 break;
472
473 case EVENT_EXCHANGE_SIM_IO_DONE:
474 ar = (AsyncResult) msg.obj;
475 request = (MainThreadRequest) ar.userObj;
476 if (ar.exception == null && ar.result != null) {
477 request.result = ar.result;
478 } else {
479 request.result = new IccIoResult(0x6f, 0, (byte[])null);
480 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700481 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700482 break;
483
Derek Tan4d5e5c12014-02-04 11:54:58 -0800484 case CMD_SEND_ENVELOPE:
485 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800486 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700487 if (uiccCard == null) {
488 loge("sendEnvelopeWithStatus: No UICC");
489 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Meng0c05b502018-09-06 09:59:22 -0700490 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700491 } else {
492 onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
493 uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted);
494 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800495 break;
496
497 case EVENT_SEND_ENVELOPE_DONE:
498 ar = (AsyncResult) msg.obj;
499 request = (MainThreadRequest) ar.userObj;
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700500 if (ar.exception == null && ar.result != null) {
501 request.result = ar.result;
Derek Tan4d5e5c12014-02-04 11:54:58 -0800502 } else {
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700503 request.result = new IccIoResult(0x6F, 0, (byte[])null);
504 if (ar.result == null) {
505 loge("sendEnvelopeWithStatus: Empty response");
506 } else if (ar.exception instanceof CommandException) {
507 loge("sendEnvelopeWithStatus: CommandException: " +
508 ar.exception);
509 } else {
510 loge("sendEnvelopeWithStatus: exception:" + ar.exception);
511 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800512 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700513 notifyRequester(request);
Derek Tan4d5e5c12014-02-04 11:54:58 -0800514 break;
515
Shishir Agrawal566b7612013-10-28 14:41:00 -0700516 case CMD_OPEN_CHANNEL:
517 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800518 uiccCard = getUiccCardFromRequest(request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800519 Pair<String, Integer> openChannelArgs = (Pair<String, Integer>) request.argument;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700520 if (uiccCard == null) {
521 loge("iccOpenLogicalChannel: No UICC");
Shishir Agrawalfc0492a2016-02-17 11:15:33 -0800522 request.result = new IccOpenLogicalChannelResponse(-1,
523 IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
Pengquan Meng0c05b502018-09-06 09:59:22 -0700524 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700525 } else {
526 onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800527 uiccCard.iccOpenLogicalChannel(openChannelArgs.first,
528 openChannelArgs.second, onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700529 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700530 break;
531
532 case EVENT_OPEN_CHANNEL_DONE:
533 ar = (AsyncResult) msg.obj;
534 request = (MainThreadRequest) ar.userObj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700535 IccOpenLogicalChannelResponse openChannelResp;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700536 if (ar.exception == null && ar.result != null) {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700537 int[] result = (int[]) ar.result;
538 int channelId = result[0];
539 byte[] selectResponse = null;
540 if (result.length > 1) {
541 selectResponse = new byte[result.length - 1];
542 for (int i = 1; i < result.length; ++i) {
543 selectResponse[i - 1] = (byte) result[i];
544 }
545 }
546 openChannelResp = new IccOpenLogicalChannelResponse(channelId,
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700547 IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700548 } else {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700549 if (ar.result == null) {
550 loge("iccOpenLogicalChannel: Empty response");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700551 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700552 if (ar.exception != null) {
553 loge("iccOpenLogicalChannel: Exception: " + ar.exception);
554 }
555
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700556 int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR;
Junda Liua754ba12015-05-20 01:17:52 -0700557 if (ar.exception instanceof CommandException) {
558 CommandException.Error error =
559 ((CommandException) (ar.exception)).getCommandError();
560 if (error == CommandException.Error.MISSING_RESOURCE) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700561 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE;
Junda Liua754ba12015-05-20 01:17:52 -0700562 } else if (error == CommandException.Error.NO_SUCH_ELEMENT) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700563 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700564 }
565 }
566 openChannelResp = new IccOpenLogicalChannelResponse(
567 IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700568 }
Shishir Agrawal82c8a462014-07-31 18:13:17 -0700569 request.result = openChannelResp;
Pengquan Meng0c05b502018-09-06 09:59:22 -0700570 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700571 break;
572
573 case CMD_CLOSE_CHANNEL:
574 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800575 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700576 if (uiccCard == null) {
577 loge("iccCloseLogicalChannel: No UICC");
Yoshiaki Naka2e29d822016-09-02 19:27:39 +0900578 request.result = false;
Pengquan Meng0c05b502018-09-06 09:59:22 -0700579 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700580 } else {
581 onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
582 uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
583 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700584 break;
585
586 case EVENT_CLOSE_CHANNEL_DONE:
Jake Hambye994d462014-02-03 13:10:13 -0800587 handleNullReturnEvent(msg, "iccCloseLogicalChannel");
588 break;
589
590 case CMD_NV_READ_ITEM:
591 request = (MainThreadRequest) msg.obj;
592 onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
vagdevie435a3e2018-08-15 16:01:53 -0700593 mPhone.nvReadItem((Integer) request.argument, onCompleted, request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800594 break;
595
596 case EVENT_NV_READ_ITEM_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700597 ar = (AsyncResult) msg.obj;
598 request = (MainThreadRequest) ar.userObj;
Jake Hambye994d462014-02-03 13:10:13 -0800599 if (ar.exception == null && ar.result != null) {
600 request.result = ar.result; // String
Shishir Agrawal566b7612013-10-28 14:41:00 -0700601 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800602 request.result = "";
603 if (ar.result == null) {
604 loge("nvReadItem: Empty response");
605 } else if (ar.exception instanceof CommandException) {
606 loge("nvReadItem: CommandException: " +
607 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700608 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800609 loge("nvReadItem: Unknown exception");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700610 }
611 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700612 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700613 break;
614
Jake Hambye994d462014-02-03 13:10:13 -0800615 case CMD_NV_WRITE_ITEM:
616 request = (MainThreadRequest) msg.obj;
617 onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
618 Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
vagdevie435a3e2018-08-15 16:01:53 -0700619 mPhone.nvWriteItem(idValue.first, idValue.second, onCompleted,
620 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800621 break;
622
623 case EVENT_NV_WRITE_ITEM_DONE:
624 handleNullReturnEvent(msg, "nvWriteItem");
625 break;
626
627 case CMD_NV_WRITE_CDMA_PRL:
628 request = (MainThreadRequest) msg.obj;
629 onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
630 mPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
631 break;
632
633 case EVENT_NV_WRITE_CDMA_PRL_DONE:
634 handleNullReturnEvent(msg, "nvWriteCdmaPrl");
635 break;
636
637 case CMD_NV_RESET_CONFIG:
638 request = (MainThreadRequest) msg.obj;
639 onCompleted = obtainMessage(EVENT_NV_RESET_CONFIG_DONE, request);
640 mPhone.nvResetConfig((Integer) request.argument, onCompleted);
641 break;
642
643 case EVENT_NV_RESET_CONFIG_DONE:
644 handleNullReturnEvent(msg, "nvResetConfig");
645 break;
646
Jake Hamby7c27be32014-03-03 13:25:59 -0800647 case CMD_GET_PREFERRED_NETWORK_TYPE:
648 request = (MainThreadRequest) msg.obj;
649 onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request);
Stuart Scott54788802015-03-30 13:18:01 -0700650 getPhoneFromRequest(request).getPreferredNetworkType(onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800651 break;
652
653 case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE:
654 ar = (AsyncResult) msg.obj;
655 request = (MainThreadRequest) ar.userObj;
656 if (ar.exception == null && ar.result != null) {
657 request.result = ar.result; // Integer
658 } else {
Sanket Padawecfc2d352016-01-05 19:52:14 -0800659 request.result = null;
Jake Hamby7c27be32014-03-03 13:25:59 -0800660 if (ar.result == null) {
661 loge("getPreferredNetworkType: Empty response");
662 } else if (ar.exception instanceof CommandException) {
663 loge("getPreferredNetworkType: CommandException: " +
664 ar.exception);
665 } else {
666 loge("getPreferredNetworkType: Unknown exception");
667 }
668 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700669 notifyRequester(request);
Jake Hamby7c27be32014-03-03 13:25:59 -0800670 break;
671
672 case CMD_SET_PREFERRED_NETWORK_TYPE:
673 request = (MainThreadRequest) msg.obj;
674 onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request);
675 int networkType = (Integer) request.argument;
Stuart Scott54788802015-03-30 13:18:01 -0700676 getPhoneFromRequest(request).setPreferredNetworkType(networkType, onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800677 break;
678
679 case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE:
680 handleNullReturnEvent(msg, "setPreferredNetworkType");
681 break;
682
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000683 case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
684 request = (MainThreadRequest)msg.obj;
685 onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
vagdevie435a3e2018-08-15 16:01:53 -0700686 mPhone.invokeOemRilRequestRaw((byte[]) request.argument, onCompleted);
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000687 break;
688
689 case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
690 ar = (AsyncResult)msg.obj;
691 request = (MainThreadRequest)ar.userObj;
692 request.result = ar;
Pengquan Meng0c05b502018-09-06 09:59:22 -0700693 notifyRequester(request);
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000694 break;
695
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800696 case CMD_SET_VOICEMAIL_NUMBER:
697 request = (MainThreadRequest) msg.obj;
698 onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
699 Pair<String, String> tagNum = (Pair<String, String>) request.argument;
Stuart Scott584921c2015-01-15 17:10:34 -0800700 getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
701 onCompleted);
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800702 break;
703
704 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
705 handleNullReturnEvent(msg, "setVoicemailNumber");
706 break;
707
Stuart Scott54788802015-03-30 13:18:01 -0700708 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC:
709 request = (MainThreadRequest) msg.obj;
710 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE,
711 request);
712 getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted);
713 break;
714
715 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE:
716 handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic");
717 break;
718
Shishir Agrawal302c8692015-06-19 13:49:39 -0700719 case CMD_PERFORM_NETWORK_SCAN:
720 request = (MainThreadRequest) msg.obj;
721 onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request);
722 getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
723 break;
724
725 case EVENT_PERFORM_NETWORK_SCAN_DONE:
726 ar = (AsyncResult) msg.obj;
727 request = (MainThreadRequest) ar.userObj;
728 CellNetworkScanResult cellScanResult;
729 if (ar.exception == null && ar.result != null) {
730 cellScanResult = new CellNetworkScanResult(
731 CellNetworkScanResult.STATUS_SUCCESS,
732 (List<OperatorInfo>) ar.result);
733 } else {
734 if (ar.result == null) {
735 loge("getCellNetworkScanResults: Empty response");
736 }
737 if (ar.exception != null) {
738 loge("getCellNetworkScanResults: Exception: " + ar.exception);
739 }
740 int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR;
741 if (ar.exception instanceof CommandException) {
742 CommandException.Error error =
743 ((CommandException) (ar.exception)).getCommandError();
744 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
745 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE;
746 } else if (error == CommandException.Error.GENERIC_FAILURE) {
747 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE;
748 }
749 }
750 cellScanResult = new CellNetworkScanResult(errorCode, null);
751 }
752 request.result = cellScanResult;
Pengquan Meng0c05b502018-09-06 09:59:22 -0700753 notifyRequester(request);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700754 break;
755
756 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
757 request = (MainThreadRequest) msg.obj;
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700758 ManualNetworkSelectionArgument selArg =
759 (ManualNetworkSelectionArgument) request.argument;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700760 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE,
761 request);
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700762 getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo,
763 selArg.persistSelection, onCompleted);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700764 break;
765
766 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
Pengquan Mengdd9ac822018-09-20 15:25:35 -0700767 ar = (AsyncResult) msg.obj;
768 request = (MainThreadRequest) ar.userObj;
769 if (ar.exception == null) {
770 request.result = true;
771 } else {
772 request.result = false;
773 loge("setNetworkSelectionModeManual " + ar.exception);
774 }
775 notifyRequester(request);
776 mApp.onNetworkSelectionChanged(request.subId);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700777 break;
778
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700779 case CMD_GET_MODEM_ACTIVITY_INFO:
780 request = (MainThreadRequest) msg.obj;
781 onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
vagdevie435a3e2018-08-15 16:01:53 -0700782 mPhone.getModemActivityInfo(onCompleted, request.workSource);
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700783 break;
784
785 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE:
786 ar = (AsyncResult) msg.obj;
787 request = (MainThreadRequest) ar.userObj;
788 if (ar.exception == null && ar.result != null) {
789 request.result = ar.result;
790 } else {
791 if (ar.result == null) {
792 loge("queryModemActivityInfo: Empty response");
793 } else if (ar.exception instanceof CommandException) {
794 loge("queryModemActivityInfo: CommandException: " +
795 ar.exception);
796 } else {
797 loge("queryModemActivityInfo: Unknown exception");
798 }
799 }
Amit Mahajand4766222016-01-28 15:28:28 -0800800 // Result cannot be null. Return ModemActivityInfo with all fields set to 0.
801 if (request.result == null) {
802 request.result = new ModemActivityInfo(0, 0, 0, null, 0, 0);
803 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700804 notifyRequester(request);
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700805 break;
806
Meng Wang1a7c35a2016-05-05 20:56:15 -0700807 case CMD_SET_ALLOWED_CARRIERS:
808 request = (MainThreadRequest) msg.obj;
809 onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
810 mPhone.setAllowedCarriers(
811 (List<CarrierIdentifier>) request.argument,
vagdevie435a3e2018-08-15 16:01:53 -0700812 onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700813 break;
814
815 case EVENT_SET_ALLOWED_CARRIERS_DONE:
816 ar = (AsyncResult) msg.obj;
817 request = (MainThreadRequest) ar.userObj;
818 if (ar.exception == null && ar.result != null) {
819 request.result = ar.result;
820 } else {
821 if (ar.result == null) {
822 loge("setAllowedCarriers: Empty response");
823 } else if (ar.exception instanceof CommandException) {
824 loge("setAllowedCarriers: CommandException: " +
825 ar.exception);
826 } else {
827 loge("setAllowedCarriers: Unknown exception");
828 }
829 }
830 // Result cannot be null. Return -1 on error.
831 if (request.result == null) {
832 request.result = new int[]{-1};
833 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700834 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700835 break;
836
837 case CMD_GET_ALLOWED_CARRIERS:
838 request = (MainThreadRequest) msg.obj;
839 onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
vagdevie435a3e2018-08-15 16:01:53 -0700840 mPhone.getAllowedCarriers(onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700841 break;
842
843 case EVENT_GET_ALLOWED_CARRIERS_DONE:
844 ar = (AsyncResult) msg.obj;
845 request = (MainThreadRequest) ar.userObj;
846 if (ar.exception == null && ar.result != null) {
847 request.result = ar.result;
848 } else {
849 if (ar.result == null) {
850 loge("getAllowedCarriers: Empty response");
851 } else if (ar.exception instanceof CommandException) {
852 loge("getAllowedCarriers: CommandException: " +
853 ar.exception);
854 } else {
855 loge("getAllowedCarriers: Unknown exception");
856 }
857 }
858 // Result cannot be null. Return empty list of CarrierIdentifier.
859 if (request.result == null) {
860 request.result = new ArrayList<CarrierIdentifier>(0);
861 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700862 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700863 break;
864
Nathan Haroldb3014052017-01-25 15:57:32 -0800865 case EVENT_GET_FORBIDDEN_PLMNS_DONE:
866 ar = (AsyncResult) msg.obj;
867 request = (MainThreadRequest) ar.userObj;
868 if (ar.exception == null && ar.result != null) {
869 request.result = ar.result;
870 } else {
871 request.result = new IllegalArgumentException(
872 "Failed to retrieve Forbidden Plmns");
873 if (ar.result == null) {
874 loge("getForbiddenPlmns: Empty response");
875 } else {
876 loge("getForbiddenPlmns: Unknown exception");
877 }
878 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700879 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -0800880 break;
881
882 case CMD_GET_FORBIDDEN_PLMNS:
883 request = (MainThreadRequest) msg.obj;
884 uiccCard = getUiccCardFromRequest(request);
885 if (uiccCard == null) {
886 loge("getForbiddenPlmns() UiccCard is null");
887 request.result = new IllegalArgumentException(
888 "getForbiddenPlmns() UiccCard is null");
Pengquan Meng0c05b502018-09-06 09:59:22 -0700889 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -0800890 break;
891 }
892 Integer appType = (Integer) request.argument;
893 UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType);
894 if (uiccApp == null) {
895 loge("getForbiddenPlmns() no app with specified type -- "
896 + appType);
897 request.result = new IllegalArgumentException("Failed to get UICC App");
Pengquan Meng0c05b502018-09-06 09:59:22 -0700898 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -0800899 break;
900 } else {
901 if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
902 + " specified type -- " + appType);
903 }
904 onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
905 ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
906 onCompleted);
907 break;
908
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000909 case CMD_SWITCH_SLOTS:
910 request = (MainThreadRequest) msg.obj;
911 int[] physicalSlots = (int[]) request.argument;
912 onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
913 UiccController.getInstance().switchSlots(physicalSlots, onCompleted);
914 break;
915
916 case EVENT_SWITCH_SLOTS_DONE:
917 ar = (AsyncResult) msg.obj;
918 request = (MainThreadRequest) ar.userObj;
919 request.result = (ar.exception == null);
Pengquan Meng0c05b502018-09-06 09:59:22 -0700920 notifyRequester(request);
921 break;
922 case CMD_GET_NETWORK_SELECTION_MODE:
923 request = (MainThreadRequest) msg.obj;
924 onCompleted = obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE, request);
925 getPhoneFromRequest(request).getNetworkSelectionMode(onCompleted);
926 break;
927
928 case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
929 ar = (AsyncResult) msg.obj;
930 request = (MainThreadRequest) ar.userObj;
931 if (ar.exception != null) {
932 request.result = TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
933 } else {
934 int mode = ((int[]) ar.result)[0];
935 if (mode == 0) {
936 request.result = TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
937 } else {
938 request.result = TelephonyManager.NETWORK_SELECTION_MODE_MANUAL;
939 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000940 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700941 notifyRequester(request);
942 break;
943 case CMD_GET_CDMA_ROAMING_MODE:
944 request = (MainThreadRequest) msg.obj;
945 onCompleted = obtainMessage(EVENT_GET_CDMA_ROAMING_MODE_DONE, request);
946 getPhoneFromRequest(request).queryCdmaRoamingPreference(onCompleted);
947 break;
948 case EVENT_GET_CDMA_ROAMING_MODE_DONE:
949 ar = (AsyncResult) msg.obj;
950 request = (MainThreadRequest) ar.userObj;
951 if (ar.exception != null) {
952 request.result = TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT;
953 } else {
954 request.result = ((int[]) ar.result)[0];
955 }
956 notifyRequester(request);
957 break;
958 case CMD_SET_CDMA_ROAMING_MODE:
959 request = (MainThreadRequest) msg.obj;
960 onCompleted = obtainMessage(EVENT_SET_CDMA_ROAMING_MODE_DONE, request);
961 int mode = (int) request.argument;
962 getPhoneFromRequest(request).setCdmaRoamingPreference(mode, onCompleted);
963 break;
964 case EVENT_SET_CDMA_ROAMING_MODE_DONE:
965 ar = (AsyncResult) msg.obj;
966 request = (MainThreadRequest) ar.userObj;
967 request.result = ar.exception == null;
968 notifyRequester(request);
969 break;
970 case CMD_SET_CDMA_SUBSCRIPTION_MODE:
971 request = (MainThreadRequest) msg.obj;
972 onCompleted = obtainMessage(EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE, request);
973 int subscriptionMode = (int) request.argument;
974 getPhoneFromRequest(request).setCdmaSubscription(subscriptionMode, onCompleted);
975 break;
976 case EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE:
977 ar = (AsyncResult) msg.obj;
978 request = (MainThreadRequest) ar.userObj;
979 request.result = ar.exception == null;
980 notifyRequester(request);
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000981 break;
982
Nathan Harold3ff88932018-08-14 10:19:49 -0700983 case CMD_GET_ALL_CELL_INFO:
984 request = (MainThreadRequest) msg.obj;
985 Pair<Phone, WorkSource> args = (Pair<Phone, WorkSource>) request.argument;
986 onCompleted = obtainMessage(EVENT_GET_ALL_CELL_INFO_DONE, request);
987 ((Phone) args.first).getAllCellInfo(args.second, onCompleted);
988 break;
989
990 case EVENT_GET_ALL_CELL_INFO_DONE:
991 ar = (AsyncResult) msg.obj;
992 request = (MainThreadRequest) ar.userObj;
993 request.result = (ar.exception == null) ? ar.result : new ArrayList<CellInfo>();
994 synchronized (request) {
995 request.notifyAll();
996 }
997 break;
998
999 case CMD_GET_CELL_LOCATION: {
1000 request = (MainThreadRequest) msg.obj;
1001 WorkSource ws = (WorkSource) request.argument;
1002 Phone phone = getPhoneFromRequest(request);
1003 phone.getCellLocation(ws, obtainMessage(EVENT_GET_CELL_LOCATION_DONE, request));
1004 break;
1005 }
1006
1007 case EVENT_GET_CELL_LOCATION_DONE: {
1008 ar = (AsyncResult) msg.obj;
1009 request = (MainThreadRequest) ar.userObj;
1010 if (ar.exception == null) {
1011 request.result = ar.result;
1012 } else {
1013 Phone phone = getPhoneFromRequest(request);
1014 request.result = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
1015 ? new CdmaCellLocation() : new GsmCellLocation();
1016 }
1017
1018 synchronized (request) {
1019 request.notifyAll();
1020 }
1021 break;
1022 }
1023
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001024 default:
1025 Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
1026 break;
1027 }
1028 }
Jake Hambye994d462014-02-03 13:10:13 -08001029
Pengquan Meng0c05b502018-09-06 09:59:22 -07001030 private void notifyRequester(MainThreadRequest request) {
1031 synchronized (request) {
1032 request.notifyAll();
1033 }
1034 }
1035
Jake Hambye994d462014-02-03 13:10:13 -08001036 private void handleNullReturnEvent(Message msg, String command) {
1037 AsyncResult ar = (AsyncResult) msg.obj;
1038 MainThreadRequest request = (MainThreadRequest) ar.userObj;
1039 if (ar.exception == null) {
1040 request.result = true;
1041 } else {
1042 request.result = false;
1043 if (ar.exception instanceof CommandException) {
1044 loge(command + ": CommandException: " + ar.exception);
1045 } else {
1046 loge(command + ": Unknown exception");
1047 }
1048 }
Pengquan Meng0c05b502018-09-06 09:59:22 -07001049 notifyRequester(request);
Jake Hambye994d462014-02-03 13:10:13 -08001050 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001051 }
1052
1053 /**
1054 * Posts the specified command to be executed on the main thread,
1055 * waits for the request to complete, and returns the result.
1056 * @see #sendRequestAsync
1057 */
1058 private Object sendRequest(int command, Object argument) {
vagdevie435a3e2018-08-15 16:01:53 -07001059 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, null);
1060 }
1061
1062 /**
1063 * Posts the specified command to be executed on the main thread,
1064 * waits for the request to complete, and returns the result.
1065 * @see #sendRequestAsync
1066 */
1067 private Object sendRequest(int command, Object argument, WorkSource workSource) {
1068 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
1069 workSource);
Wink Saville36469e72014-06-11 15:17:00 -07001070 }
1071
1072 /**
1073 * Posts the specified command to be executed on the main thread,
1074 * waits for the request to complete, and returns the result.
1075 * @see #sendRequestAsync
1076 */
Shishir Agrawal76d5da92014-11-09 16:17:25 -08001077 private Object sendRequest(int command, Object argument, Integer subId) {
vagdevie435a3e2018-08-15 16:01:53 -07001078 return sendRequest(command, argument, subId, null);
1079 }
1080
1081 /**
1082 * Posts the specified command to be executed on the main thread,
1083 * waits for the request to complete, and returns the result.
1084 * @see #sendRequestAsync
1085 */
1086 private Object sendRequest(int command, Object argument, Integer subId, WorkSource workSource) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001087 if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
1088 throw new RuntimeException("This method will deadlock if called from the main thread.");
1089 }
1090
vagdevie435a3e2018-08-15 16:01:53 -07001091 MainThreadRequest request = new MainThreadRequest(argument, subId, workSource);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001092 Message msg = mMainThreadHandler.obtainMessage(command, request);
1093 msg.sendToTarget();
1094
1095 // Wait for the request to complete
1096 synchronized (request) {
1097 while (request.result == null) {
1098 try {
1099 request.wait();
1100 } catch (InterruptedException e) {
1101 // Do nothing, go back and wait until the request is complete
1102 }
1103 }
1104 }
1105 return request.result;
1106 }
1107
1108 /**
1109 * Asynchronous ("fire and forget") version of sendRequest():
1110 * Posts the specified command to be executed on the main thread, and
1111 * returns immediately.
1112 * @see #sendRequest
1113 */
1114 private void sendRequestAsync(int command) {
1115 mMainThreadHandler.sendEmptyMessage(command);
1116 }
1117
1118 /**
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001119 * Same as {@link #sendRequestAsync(int)} except it takes an argument.
1120 * @see {@link #sendRequest(int,Object)}
1121 */
1122 private void sendRequestAsync(int command, Object argument) {
1123 MainThreadRequest request = new MainThreadRequest(argument);
1124 Message msg = mMainThreadHandler.obtainMessage(command, request);
1125 msg.sendToTarget();
1126 }
1127
1128 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001129 * Initialize the singleton PhoneInterfaceManager instance.
1130 * This is only done once, at startup, from PhoneApp.onCreate().
1131 */
Sailesh Nepal194161e2014-07-03 08:57:44 -07001132 /* package */ static PhoneInterfaceManager init(PhoneGlobals app, Phone phone) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001133 synchronized (PhoneInterfaceManager.class) {
1134 if (sInstance == null) {
Sailesh Nepal194161e2014-07-03 08:57:44 -07001135 sInstance = new PhoneInterfaceManager(app, phone);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001136 } else {
1137 Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
1138 }
1139 return sInstance;
1140 }
1141 }
1142
1143 /** Private constructor; @see init() */
Sailesh Nepal194161e2014-07-03 08:57:44 -07001144 private PhoneInterfaceManager(PhoneGlobals app, Phone phone) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001145 mApp = app;
1146 mPhone = phone;
1147 mCM = PhoneGlobals.getInstance().mCM;
Stuart Scott981d8582015-04-21 14:09:50 -07001148 mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001149 mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
1150 mMainThreadHandler = new MainThreadHandler();
Andrew Leedf14ead2014-10-17 14:22:52 -07001151 mTelephonySharedPreferences =
Derek Tan97ebb422014-09-05 16:55:38 -07001152 PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
Wink Savilleac1bdfd2014-11-20 23:04:44 -08001153 mSubscriptionController = SubscriptionController.getInstance();
yinxub1bed742017-04-17 11:45:04 -07001154 mNetworkScanRequestTracker = new NetworkScanRequestTracker();
Malcolm Chenf144d942018-08-14 16:00:53 -07001155 mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
Wink Saville3ab207e2014-11-20 13:07:20 -08001156
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001157 publish();
1158 }
1159
1160 private void publish() {
1161 if (DBG) log("publish: " + this);
1162
1163 ServiceManager.addService("phone", this);
1164 }
1165
Stuart Scott584921c2015-01-15 17:10:34 -08001166 private Phone getPhoneFromRequest(MainThreadRequest request) {
Sanket Padawe56e75a32016-02-08 12:18:19 -08001167 return (request.subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
1168 ? mPhone : getPhone(request.subId);
Stuart Scott584921c2015-01-15 17:10:34 -08001169 }
1170
Shishir Agrawalc04d9752016-02-19 10:41:00 -08001171 private UiccCard getUiccCardFromRequest(MainThreadRequest request) {
1172 Phone phone = getPhoneFromRequest(request);
1173 return phone == null ? null :
1174 UiccController.getInstance().getUiccCard(phone.getPhoneId());
1175 }
1176
Wink Saville36469e72014-06-11 15:17:00 -07001177 // returns phone associated with the subId.
Wink Savilleb564aae2014-10-23 10:18:09 -07001178 private Phone getPhone(int subId) {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08001179 return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId));
Wink Saville36469e72014-06-11 15:17:00 -07001180 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001181
1182 public void dial(String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001183 dialForSubscriber(getPreferredVoiceSubscription(), number);
Wink Saville36469e72014-06-11 15:17:00 -07001184 }
1185
Wink Savilleb564aae2014-10-23 10:18:09 -07001186 public void dialForSubscriber(int subId, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001187 if (DBG) log("dial: " + number);
1188 // No permission check needed here: This is just a wrapper around the
1189 // ACTION_DIAL intent, which is available to any app since it puts up
1190 // the UI before it does anything.
1191
Malcolm Chenaabec062018-02-28 15:00:40 -08001192 final long identity = Binder.clearCallingIdentity();
1193 try {
1194 String url = createTelUrl(number);
1195 if (url == null) {
1196 return;
1197 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001198
Malcolm Chenaabec062018-02-28 15:00:40 -08001199 // PENDING: should we just silently fail if phone is offhook or ringing?
1200 PhoneConstants.State state = mCM.getState(subId);
1201 if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
1202 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
1203 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1204 mApp.startActivity(intent);
1205 }
1206 } finally {
1207 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001208 }
1209 }
1210
1211 public void call(String callingPackage, String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001212 callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number);
Wink Saville36469e72014-06-11 15:17:00 -07001213 }
1214
Wink Savilleb564aae2014-10-23 10:18:09 -07001215 public void callForSubscriber(int subId, String callingPackage, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001216 if (DBG) log("call: " + number);
1217
1218 // This is just a wrapper around the ACTION_CALL intent, but we still
1219 // need to do a permission check since we're calling startActivity()
1220 // from the context of the phone app.
1221 enforceCallPermission();
1222
1223 if (mAppOps.noteOp(AppOpsManager.OP_CALL_PHONE, Binder.getCallingUid(), callingPackage)
1224 != AppOpsManager.MODE_ALLOWED) {
1225 return;
1226 }
1227
Malcolm Chenaabec062018-02-28 15:00:40 -08001228 final long identity = Binder.clearCallingIdentity();
1229 try {
1230 String url = createTelUrl(number);
1231 if (url == null) {
1232 return;
1233 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001234
Malcolm Chenaabec062018-02-28 15:00:40 -08001235 boolean isValid = false;
1236 final List<SubscriptionInfo> slist = getActiveSubscriptionInfoListPrivileged();
1237 if (slist != null) {
1238 for (SubscriptionInfo subInfoRecord : slist) {
1239 if (subInfoRecord.getSubscriptionId() == subId) {
1240 isValid = true;
1241 break;
1242 }
Wink Saville3ab207e2014-11-20 13:07:20 -08001243 }
Wink Saville08874612014-08-31 19:19:58 -07001244 }
Malcolm Chenaabec062018-02-28 15:00:40 -08001245 if (!isValid) {
1246 return;
1247 }
Wink Saville08874612014-08-31 19:19:58 -07001248
Malcolm Chenaabec062018-02-28 15:00:40 -08001249 Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
1250 intent.putExtra(SUBSCRIPTION_KEY, subId);
1251 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1252 mApp.startActivity(intent);
1253 } finally {
1254 Binder.restoreCallingIdentity(identity);
1255 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001256 }
1257
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001258 /**
1259 * End a call based on call state
1260 * @return true is a call was ended
1261 */
1262 public boolean endCall() {
Hall Liu91943182018-09-14 17:42:41 -07001263 return false;
Wink Saville36469e72014-06-11 15:17:00 -07001264 }
1265
1266 /**
1267 * End a call based on the call state of the subId
1268 * @return true is a call was ended
1269 */
Wink Savilleb564aae2014-10-23 10:18:09 -07001270 public boolean endCallForSubscriber(int subId) {
Hall Liu91943182018-09-14 17:42:41 -07001271 return false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001272 }
1273
1274 public void answerRingingCall() {
Hall Liu91943182018-09-14 17:42:41 -07001275 // Deprecated.
Wink Saville36469e72014-06-11 15:17:00 -07001276 }
1277
Wink Savilleb564aae2014-10-23 10:18:09 -07001278 public void answerRingingCallForSubscriber(int subId) {
Hall Liu91943182018-09-14 17:42:41 -07001279 // Deprecated
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001280 }
1281
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001282 /**
Santos Cordon5422a8d2014-09-12 04:20:56 -07001283 * This method is no longer used and can be removed once TelephonyManager stops referring to it.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001284 */
Santos Cordon5422a8d2014-09-12 04:20:56 -07001285 public void silenceRinger() {
1286 Log.e(LOG_TAG, "silenseRinger not supported");
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001287 }
1288
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001289 @Override
1290 public boolean isOffhook(String callingPackage) {
1291 return isOffhookForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07001292 }
1293
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001294 @Override
1295 public boolean isOffhookForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08001296 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08001297 mApp, subId, callingPackage, "isOffhookForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001298 return false;
1299 }
1300
Malcolm Chenaabec062018-02-28 15:00:40 -08001301 final long identity = Binder.clearCallingIdentity();
1302 try {
1303 final Phone phone = getPhone(subId);
1304 if (phone != null) {
1305 return (phone.getState() == PhoneConstants.State.OFFHOOK);
1306 } else {
1307 return false;
1308 }
1309 } finally {
1310 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001311 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001312 }
1313
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001314 @Override
1315 public boolean isRinging(String callingPackage) {
1316 return (isRingingForSubscriber(getDefaultSubscription(), callingPackage));
Wink Saville36469e72014-06-11 15:17:00 -07001317 }
1318
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001319 @Override
1320 public boolean isRingingForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08001321 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08001322 mApp, subId, callingPackage, "isRingingForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001323 return false;
1324 }
1325
Malcolm Chenaabec062018-02-28 15:00:40 -08001326 final long identity = Binder.clearCallingIdentity();
1327 try {
1328 final Phone phone = getPhone(subId);
1329 if (phone != null) {
1330 return (phone.getState() == PhoneConstants.State.RINGING);
1331 } else {
1332 return false;
1333 }
1334 } finally {
1335 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001336 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001337 }
1338
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001339 @Override
1340 public boolean isIdle(String callingPackage) {
1341 return isIdleForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07001342 }
1343
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001344 @Override
1345 public boolean isIdleForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08001346 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08001347 mApp, subId, callingPackage, "isIdleForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001348 return false;
1349 }
1350
Malcolm Chenaabec062018-02-28 15:00:40 -08001351 final long identity = Binder.clearCallingIdentity();
1352 try {
1353 final Phone phone = getPhone(subId);
1354 if (phone != null) {
1355 return (phone.getState() == PhoneConstants.State.IDLE);
1356 } else {
1357 return false;
1358 }
1359 } finally {
1360 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001361 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001362 }
1363
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001364 public boolean supplyPin(String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001365 return supplyPinForSubscriber(getDefaultSubscription(), pin);
Wink Saville36469e72014-06-11 15:17:00 -07001366 }
1367
Wink Savilleb564aae2014-10-23 10:18:09 -07001368 public boolean supplyPinForSubscriber(int subId, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001369 int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07001370 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1371 }
1372
1373 public boolean supplyPuk(String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001374 return supplyPukForSubscriber(getDefaultSubscription(), puk, pin);
Wink Saville36469e72014-06-11 15:17:00 -07001375 }
1376
Wink Savilleb564aae2014-10-23 10:18:09 -07001377 public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001378 int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07001379 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1380 }
1381
1382 /** {@hide} */
1383 public int[] supplyPinReportResult(String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001384 return supplyPinReportResultForSubscriber(getDefaultSubscription(), pin);
Wink Saville36469e72014-06-11 15:17:00 -07001385 }
1386
Wink Savilleb564aae2014-10-23 10:18:09 -07001387 public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001388 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001389
1390 final long identity = Binder.clearCallingIdentity();
1391 try {
1392 final UnlockSim checkSimPin = new UnlockSim(getPhone(subId).getIccCard());
1393 checkSimPin.start();
1394 return checkSimPin.unlockSim(null, pin);
1395 } finally {
1396 Binder.restoreCallingIdentity(identity);
1397 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001398 }
1399
Wink Saville9de0f752013-10-22 19:04:03 -07001400 /** {@hide} */
1401 public int[] supplyPukReportResult(String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001402 return supplyPukReportResultForSubscriber(getDefaultSubscription(), puk, pin);
Wink Saville36469e72014-06-11 15:17:00 -07001403 }
1404
Wink Savilleb564aae2014-10-23 10:18:09 -07001405 public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001406 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001407
1408 final long identity = Binder.clearCallingIdentity();
1409 try {
1410 final UnlockSim checkSimPuk = new UnlockSim(getPhone(subId).getIccCard());
1411 checkSimPuk.start();
1412 return checkSimPuk.unlockSim(puk, pin);
1413 } finally {
1414 Binder.restoreCallingIdentity(identity);
1415 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001416 }
1417
1418 /**
Wink Saville9de0f752013-10-22 19:04:03 -07001419 * Helper thread to turn async call to SimCard#supplyPin into
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001420 * a synchronous one.
1421 */
1422 private static class UnlockSim extends Thread {
1423
1424 private final IccCard mSimCard;
1425
1426 private boolean mDone = false;
Wink Saville9de0f752013-10-22 19:04:03 -07001427 private int mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1428 private int mRetryCount = -1;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001429
1430 // For replies from SimCard interface
1431 private Handler mHandler;
1432
1433 // For async handler to identify request type
1434 private static final int SUPPLY_PIN_COMPLETE = 100;
1435
1436 public UnlockSim(IccCard simCard) {
1437 mSimCard = simCard;
1438 }
1439
1440 @Override
1441 public void run() {
1442 Looper.prepare();
1443 synchronized (UnlockSim.this) {
1444 mHandler = new Handler() {
1445 @Override
1446 public void handleMessage(Message msg) {
1447 AsyncResult ar = (AsyncResult) msg.obj;
1448 switch (msg.what) {
1449 case SUPPLY_PIN_COMPLETE:
1450 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
1451 synchronized (UnlockSim.this) {
Wink Saville9de0f752013-10-22 19:04:03 -07001452 mRetryCount = msg.arg1;
1453 if (ar.exception != null) {
1454 if (ar.exception instanceof CommandException &&
1455 ((CommandException)(ar.exception)).getCommandError()
1456 == CommandException.Error.PASSWORD_INCORRECT) {
1457 mResult = PhoneConstants.PIN_PASSWORD_INCORRECT;
1458 } else {
1459 mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1460 }
1461 } else {
1462 mResult = PhoneConstants.PIN_RESULT_SUCCESS;
1463 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001464 mDone = true;
1465 UnlockSim.this.notifyAll();
1466 }
1467 break;
1468 }
1469 }
1470 };
1471 UnlockSim.this.notifyAll();
1472 }
1473 Looper.loop();
1474 }
1475
1476 /*
1477 * Use PIN or PUK to unlock SIM card
1478 *
1479 * If PUK is null, unlock SIM card with PIN
1480 *
1481 * If PUK is not null, unlock SIM card with PUK and set PIN code
1482 */
Wink Saville9de0f752013-10-22 19:04:03 -07001483 synchronized int[] unlockSim(String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001484
1485 while (mHandler == null) {
1486 try {
1487 wait();
1488 } catch (InterruptedException e) {
1489 Thread.currentThread().interrupt();
1490 }
1491 }
1492 Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
1493
1494 if (puk == null) {
1495 mSimCard.supplyPin(pin, callback);
1496 } else {
1497 mSimCard.supplyPuk(puk, pin, callback);
1498 }
1499
1500 while (!mDone) {
1501 try {
1502 Log.d(LOG_TAG, "wait for done");
1503 wait();
1504 } catch (InterruptedException e) {
1505 // Restore the interrupted status
1506 Thread.currentThread().interrupt();
1507 }
1508 }
1509 Log.d(LOG_TAG, "done");
Wink Saville9de0f752013-10-22 19:04:03 -07001510 int[] resultArray = new int[2];
1511 resultArray[0] = mResult;
1512 resultArray[1] = mRetryCount;
1513 return resultArray;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001514 }
1515 }
1516
1517 public void updateServiceLocation() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001518 updateServiceLocationForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001519
1520 }
1521
Wink Savilleb564aae2014-10-23 10:18:09 -07001522 public void updateServiceLocationForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001523 // No permission check needed here: this call is harmless, and it's
1524 // needed for the ServiceState.requestStateUpdate() call (which is
1525 // already intentionally exposed to 3rd parties.)
Malcolm Chenaabec062018-02-28 15:00:40 -08001526 final long identity = Binder.clearCallingIdentity();
1527 try {
1528 final Phone phone = getPhone(subId);
1529 if (phone != null) {
1530 phone.updateServiceLocation();
1531 }
1532 } finally {
1533 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001534 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001535 }
1536
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001537 @Override
1538 public boolean isRadioOn(String callingPackage) {
1539 return isRadioOnForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07001540 }
1541
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001542 @Override
1543 public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08001544 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08001545 mApp, subId, callingPackage, "isRadioOnForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001546 return false;
1547 }
Malcolm Chenaabec062018-02-28 15:00:40 -08001548
1549 final long identity = Binder.clearCallingIdentity();
1550 try {
1551 return isRadioOnForSubscriber(subId);
1552 } finally {
1553 Binder.restoreCallingIdentity(identity);
1554 }
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001555 }
1556
1557 private boolean isRadioOnForSubscriber(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08001558 final long identity = Binder.clearCallingIdentity();
1559 try {
1560 final Phone phone = getPhone(subId);
1561 if (phone != null) {
1562 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
1563 } else {
1564 return false;
1565 }
1566 } finally {
1567 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001568 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001569 }
1570
1571 public void toggleRadioOnOff() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001572 toggleRadioOnOffForSubscriber(getDefaultSubscription());
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001573 }
Wink Saville36469e72014-06-11 15:17:00 -07001574
Wink Savilleb564aae2014-10-23 10:18:09 -07001575 public void toggleRadioOnOffForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001576 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001577
1578 final long identity = Binder.clearCallingIdentity();
1579 try {
1580 final Phone phone = getPhone(subId);
1581 if (phone != null) {
1582 phone.setRadioPower(!isRadioOnForSubscriber(subId));
1583 }
1584 } finally {
1585 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001586 }
Wink Saville36469e72014-06-11 15:17:00 -07001587 }
1588
1589 public boolean setRadio(boolean turnOn) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001590 return setRadioForSubscriber(getDefaultSubscription(), turnOn);
Wink Saville36469e72014-06-11 15:17:00 -07001591 }
1592
Wink Savilleb564aae2014-10-23 10:18:09 -07001593 public boolean setRadioForSubscriber(int subId, boolean turnOn) {
Wink Saville36469e72014-06-11 15:17:00 -07001594 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001595
1596 final long identity = Binder.clearCallingIdentity();
1597 try {
1598 final Phone phone = getPhone(subId);
1599 if (phone == null) {
1600 return false;
1601 }
1602 if ((phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF) != turnOn) {
1603 toggleRadioOnOffForSubscriber(subId);
1604 }
1605 return true;
1606 } finally {
1607 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001608 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001609 }
Wink Saville36469e72014-06-11 15:17:00 -07001610
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001611 public boolean needMobileRadioShutdown() {
1612 /*
1613 * If any of the Radios are available, it will need to be
1614 * shutdown. So return true if any Radio is available.
1615 */
Malcolm Chenaabec062018-02-28 15:00:40 -08001616 final long identity = Binder.clearCallingIdentity();
1617 try {
1618 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1619 Phone phone = PhoneFactory.getPhone(i);
1620 if (phone != null && phone.isRadioAvailable()) return true;
1621 }
1622 logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown.");
1623 return false;
1624 } finally {
1625 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001626 }
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001627 }
1628
Malcolm Chenaabec062018-02-28 15:00:40 -08001629 @Override
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001630 public void shutdownMobileRadios() {
Malcolm Chenaabec062018-02-28 15:00:40 -08001631 enforceModifyPermission();
1632
1633 final long identity = Binder.clearCallingIdentity();
1634 try {
1635 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1636 logv("Shutting down Phone " + i);
1637 shutdownRadioUsingPhoneId(i);
1638 }
1639 } finally {
1640 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001641 }
1642 }
1643
1644 private void shutdownRadioUsingPhoneId(int phoneId) {
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001645 Phone phone = PhoneFactory.getPhone(phoneId);
1646 if (phone != null && phone.isRadioAvailable()) {
1647 phone.shutdownRadio();
1648 }
1649 }
1650
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001651 public boolean setRadioPower(boolean turnOn) {
Jack Yub4e16162017-05-15 12:48:40 -07001652 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001653
1654 final long identity = Binder.clearCallingIdentity();
1655 try {
1656 final Phone defaultPhone = PhoneFactory.getDefaultPhone();
1657 if (defaultPhone != null) {
1658 defaultPhone.setRadioPower(turnOn);
1659 return true;
1660 } else {
1661 loge("There's no default phone.");
1662 return false;
1663 }
1664 } finally {
1665 Binder.restoreCallingIdentity(identity);
Wei Liu9ae2a062016-08-08 11:09:34 -07001666 }
Wink Saville36469e72014-06-11 15:17:00 -07001667 }
1668
Wink Savilleb564aae2014-10-23 10:18:09 -07001669 public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001670 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001671
1672 final long identity = Binder.clearCallingIdentity();
1673 try {
1674 final Phone phone = getPhone(subId);
1675 if (phone != null) {
1676 phone.setRadioPower(turnOn);
1677 return true;
1678 } else {
1679 return false;
1680 }
1681 } finally {
1682 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001683 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001684 }
1685
Wink Saville36469e72014-06-11 15:17:00 -07001686 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07001687 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001688 public boolean enableDataConnectivity() {
1689 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001690
1691 final long identity = Binder.clearCallingIdentity();
1692 try {
1693 int subId = mSubscriptionController.getDefaultDataSubId();
1694 final Phone phone = getPhone(subId);
1695 if (phone != null) {
1696 phone.setUserDataEnabled(true);
1697 return true;
1698 } else {
1699 return false;
1700 }
1701 } finally {
1702 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001703 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001704 }
1705
Wink Saville36469e72014-06-11 15:17:00 -07001706 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07001707 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001708 public boolean disableDataConnectivity() {
1709 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001710
1711 final long identity = Binder.clearCallingIdentity();
1712 try {
1713 int subId = mSubscriptionController.getDefaultDataSubId();
1714 final Phone phone = getPhone(subId);
1715 if (phone != null) {
1716 phone.setUserDataEnabled(false);
1717 return true;
1718 } else {
1719 return false;
1720 }
1721 } finally {
1722 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001723 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001724 }
1725
Sanket Padawe356d7632015-06-22 14:03:32 -07001726 @Override
Jack Yuacf8a132017-05-01 17:00:48 -07001727 public boolean isDataConnectivityPossible(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08001728 final long identity = Binder.clearCallingIdentity();
1729 try {
1730 final Phone phone = getPhone(subId);
1731 if (phone != null) {
1732 return phone.isDataAllowed();
1733 } else {
1734 return false;
1735 }
1736 } finally {
1737 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001738 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001739 }
1740
1741 public boolean handlePinMmi(String dialString) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001742 return handlePinMmiForSubscriber(getDefaultSubscription(), dialString);
Wink Saville36469e72014-06-11 15:17:00 -07001743 }
1744
pkanwarae03a6b2016-11-06 20:37:09 -08001745 public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
Malcolm Chenaabec062018-02-28 15:00:40 -08001746 enforceCallPermission();
1747
1748 final long identity = Binder.clearCallingIdentity();
1749 try {
1750 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1751 return;
1752 }
1753 Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback);
1754 sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId);
1755 } finally {
1756 Binder.restoreCallingIdentity(identity);
1757 }
pkanwar32d516d2016-10-14 19:37:38 -07001758 };
1759
Wink Savilleb564aae2014-10-23 10:18:09 -07001760 public boolean handlePinMmiForSubscriber(int subId, String dialString) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001761 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001762
1763 final long identity = Binder.clearCallingIdentity();
1764 try {
1765 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1766 return false;
1767 }
1768 return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
1769 } finally {
1770 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001771 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001772 }
1773
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001774 public int getCallState() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07001775 return getCallStateForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001776 }
1777
Sanket Padawe13bac7b2017-03-20 15:04:47 -07001778 public int getCallStateForSlot(int slotIndex) {
Malcolm Chenaabec062018-02-28 15:00:40 -08001779 final long identity = Binder.clearCallingIdentity();
1780 try {
1781 Phone phone = PhoneFactory.getPhone(slotIndex);
1782 return phone == null ? TelephonyManager.CALL_STATE_IDLE :
1783 PhoneConstantConversions.convertCallState(phone.getState());
1784 } finally {
1785 Binder.restoreCallingIdentity(identity);
1786 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001787 }
1788
Sanket Padawe356d7632015-06-22 14:03:32 -07001789 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001790 public int getDataState() {
Malcolm Chenaabec062018-02-28 15:00:40 -08001791 final long identity = Binder.clearCallingIdentity();
1792 try {
1793 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1794 if (phone != null) {
1795 return PhoneConstantConversions.convertDataState(phone.getDataConnectionState());
1796 } else {
1797 return PhoneConstantConversions.convertDataState(
1798 PhoneConstants.DataState.DISCONNECTED);
1799 }
1800 } finally {
1801 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001802 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001803 }
1804
Sanket Padawe356d7632015-06-22 14:03:32 -07001805 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001806 public int getDataActivity() {
Malcolm Chenaabec062018-02-28 15:00:40 -08001807 final long identity = Binder.clearCallingIdentity();
1808 try {
1809 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1810 if (phone != null) {
1811 return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState());
1812 } else {
1813 return TelephonyManager.DATA_ACTIVITY_NONE;
1814 }
1815 } finally {
1816 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001817 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001818 }
1819
1820 @Override
Svetoslav64fad262015-04-14 14:35:21 -07001821 public Bundle getCellLocation(String callingPackage) {
Hall Liu1aa510f2017-11-22 17:40:08 -08001822 mPhone.getContext().getSystemService(AppOpsManager.class)
1823 .checkPackage(Binder.getCallingUid(), callingPackage);
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001824 if (!LocationAccessPolicy.canAccessCellLocation(mPhone.getContext(),
Svet Ganov4af66282018-03-07 19:57:05 -08001825 callingPackage, Binder.getCallingUid(), Binder.getCallingPid(), true)) {
Svetoslav64fad262015-04-14 14:35:21 -07001826 return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001827 }
1828
Narayan Kamathf04b5a12018-01-09 11:47:15 +00001829 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaabec062018-02-28 15:00:40 -08001830 final long identity = Binder.clearCallingIdentity();
1831 try {
1832 if (DBG_LOC) log("getCellLocation: is active user");
1833 Bundle data = new Bundle();
Nathan Harold3ff88932018-08-14 10:19:49 -07001834 int subId = mSubscriptionController.getDefaultDataSubId();
1835 CellLocation cl = (CellLocation) sendRequest(CMD_GET_CELL_LOCATION, workSource, subId);
1836 cl.fillInNotifierBundle(data);
Malcolm Chenaabec062018-02-28 15:00:40 -08001837 return data;
1838 } finally {
1839 Binder.restoreCallingIdentity(identity);
1840 }
Svetoslav64fad262015-04-14 14:35:21 -07001841 }
1842
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001843 @Override
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001844 public String getNetworkCountryIsoForPhone(int phoneId) {
1845 // Reporting the correct network country is ambiguous when IWLAN could conflict with
1846 // registered cell info, so return a NULL country instead.
1847 final long identity = Binder.clearCallingIdentity();
1848 try {
1849 final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
Jack Yu5f7092c2018-04-13 14:05:37 -07001850 // Todo: fix this when we can get the actual cellular network info when the device
1851 // is on IWLAN.
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001852 if (TelephonyManager.NETWORK_TYPE_IWLAN
1853 == getVoiceNetworkTypeForSubscriber(subId, mApp.getPackageName())) {
1854 return "";
1855 }
Malcolm Chenaabec062018-02-28 15:00:40 -08001856 Phone phone = PhoneFactory.getPhone(phoneId);
1857 if (phone != null) {
1858 ServiceStateTracker sst = phone.getServiceStateTracker();
1859 if (sst != null) {
1860 LocaleTracker lt = sst.getLocaleTracker();
1861 if (lt != null) {
1862 return lt.getCurrentCountry();
1863 }
1864 }
1865 }
1866 return "";
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001867 } finally {
1868 Binder.restoreCallingIdentity(identity);
1869 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001870 }
1871
1872 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001873 public void enableLocationUpdates() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001874 enableLocationUpdatesForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001875 }
1876
Sanket Padawe356d7632015-06-22 14:03:32 -07001877 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07001878 public void enableLocationUpdatesForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001879 mApp.enforceCallingOrSelfPermission(
1880 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Malcolm Chenaabec062018-02-28 15:00:40 -08001881
1882 final long identity = Binder.clearCallingIdentity();
1883 try {
1884 final Phone phone = getPhone(subId);
1885 if (phone != null) {
1886 phone.enableLocationUpdates();
1887 }
1888 } finally {
1889 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001890 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001891 }
1892
1893 @Override
1894 public void disableLocationUpdates() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001895 disableLocationUpdatesForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001896 }
1897
Sanket Padawe356d7632015-06-22 14:03:32 -07001898 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07001899 public void disableLocationUpdatesForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001900 mApp.enforceCallingOrSelfPermission(
1901 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Malcolm Chenaabec062018-02-28 15:00:40 -08001902
1903 final long identity = Binder.clearCallingIdentity();
1904 try {
1905 final Phone phone = getPhone(subId);
1906 if (phone != null) {
1907 phone.disableLocationUpdates();
1908 }
1909 } finally {
1910 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001911 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001912 }
1913
1914 @Override
1915 @SuppressWarnings("unchecked")
Nathan Haroldb4d55612018-07-20 13:13:08 -07001916 public List<NeighboringCellInfo>
1917 getNeighboringCellInfo(String callingPackage, int targetSdk) {
Nathan Harolddbea45a2018-08-30 14:35:07 -07001918 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
1919 throw new SecurityException(
1920 "getNeighboringCellInfo() is unavailable to callers targeting Q+ SDK levels.");
1921 }
Nathan Haroldb4d55612018-07-20 13:13:08 -07001922
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001923 if (mAppOps.noteOp(AppOpsManager.OP_NEIGHBORING_CELLS, Binder.getCallingUid(),
1924 callingPackage) != AppOpsManager.MODE_ALLOWED) {
1925 return null;
1926 }
Svetoslav64fad262015-04-14 14:35:21 -07001927
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001928 if (DBG_LOC) log("getNeighboringCellInfo: is active user");
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001929
Nathan Haroldf180aac2018-06-01 18:43:55 -07001930 List<CellInfo> info = getAllCellInfo(callingPackage);
1931 if (info == null) return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001932
Nathan Haroldf180aac2018-06-01 18:43:55 -07001933 List<NeighboringCellInfo> neighbors = new ArrayList<NeighboringCellInfo>();
1934 for (CellInfo ci : info) {
1935 if (ci instanceof CellInfoGsm) {
1936 neighbors.add(new NeighboringCellInfo((CellInfoGsm) ci));
1937 } else if (ci instanceof CellInfoWcdma) {
1938 neighbors.add(new NeighboringCellInfo((CellInfoWcdma) ci));
1939 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001940 }
Nathan Haroldf180aac2018-06-01 18:43:55 -07001941 return (neighbors.size()) > 0 ? neighbors : null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001942 }
1943
1944
1945 @Override
Svetoslav64fad262015-04-14 14:35:21 -07001946 public List<CellInfo> getAllCellInfo(String callingPackage) {
Hall Liu1aa510f2017-11-22 17:40:08 -08001947 mPhone.getContext().getSystemService(AppOpsManager.class)
1948 .checkPackage(Binder.getCallingUid(), callingPackage);
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001949 if (!LocationAccessPolicy.canAccessCellLocation(mPhone.getContext(),
Svet Ganov4af66282018-03-07 19:57:05 -08001950 callingPackage, Binder.getCallingUid(), Binder.getCallingPid(), true)) {
Svetoslav64fad262015-04-14 14:35:21 -07001951 return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001952 }
1953
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001954 if (DBG_LOC) log("getAllCellInfo: is active user");
Narayan Kamathf04b5a12018-01-09 11:47:15 +00001955 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaabec062018-02-28 15:00:40 -08001956 final long identity = Binder.clearCallingIdentity();
1957 try {
1958 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
1959 for (Phone phone : PhoneFactory.getPhones()) {
Nathan Harold3ff88932018-08-14 10:19:49 -07001960 final List<CellInfo> info = (List<CellInfo>) sendRequest(
1961 CMD_GET_ALL_CELL_INFO,
1962 new Pair<Phone, WorkSource>(phone, workSource));
Malcolm Chenaabec062018-02-28 15:00:40 -08001963 if (info != null) cellInfos.addAll(info);
1964 }
1965 return cellInfos;
1966 } finally {
1967 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001968 }
1969 }
1970
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001971 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001972 public void setCellInfoListRate(int rateInMillis) {
Jack Yua8d8cb82017-01-16 10:15:34 -08001973 enforceModifyPermission();
Narayan Kamathf04b5a12018-01-09 11:47:15 +00001974 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaabec062018-02-28 15:00:40 -08001975
1976 final long identity = Binder.clearCallingIdentity();
1977 try {
1978 mPhone.setCellInfoListRate(rateInMillis, workSource);
1979 } finally {
1980 Binder.restoreCallingIdentity(identity);
1981 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001982 }
1983
Shishir Agrawala9f32182016-04-12 12:00:16 -07001984 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07001985 public String getImeiForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08001986 Phone phone = PhoneFactory.getPhone(slotIndex);
1987 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08001988 return null;
1989 }
Jeff Davidson913390f2018-02-23 17:11:49 -08001990 int subId = phone.getSubId();
1991 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
1992 mApp, subId, callingPackage, "getImeiForSlot")) {
1993 return null;
1994 }
Malcolm Chenaabec062018-02-28 15:00:40 -08001995
1996 final long identity = Binder.clearCallingIdentity();
1997 try {
1998 return phone.getImei();
1999 } finally {
2000 Binder.restoreCallingIdentity(identity);
2001 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002002 }
2003
2004 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002005 public String getTypeAllocationCodeForSlot(int slotIndex) {
2006 Phone phone = PhoneFactory.getPhone(slotIndex);
2007 String tac = null;
2008 if (phone != null) {
2009 String imei = phone.getImei();
2010 tac = imei == null ? null : imei.substring(0, TYPE_ALLOCATION_CODE_LENGTH);
2011 }
2012 return tac;
2013 }
2014
2015 @Override
Jack Yu2af8d712017-03-15 17:14:14 -07002016 public String getMeidForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002017 Phone phone = PhoneFactory.getPhone(slotIndex);
2018 if (phone == null) {
Jack Yu2af8d712017-03-15 17:14:14 -07002019 return null;
2020 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002021 int subId = phone.getSubId();
2022 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2023 mApp, subId, callingPackage, "getMeidForSlot")) {
2024 return null;
2025 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002026
2027 final long identity = Binder.clearCallingIdentity();
2028 try {
2029 return phone.getMeid();
2030 } finally {
2031 Binder.restoreCallingIdentity(identity);
2032 }
Jack Yu2af8d712017-03-15 17:14:14 -07002033 }
2034
2035 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002036 public String getManufacturerCodeForSlot(int slotIndex) {
2037 Phone phone = PhoneFactory.getPhone(slotIndex);
2038 String manufacturerCode = null;
2039 if (phone != null) {
2040 String meid = phone.getMeid();
2041 manufacturerCode = meid == null ? null : meid.substring(0, MANUFACTURER_CODE_LENGTH);
2042 }
2043 return manufacturerCode;
2044 }
2045
2046 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002047 public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002048 Phone phone = PhoneFactory.getPhone(slotIndex);
2049 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002050 return null;
2051 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002052 int subId = phone.getSubId();
2053 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2054 mApp, subId, callingPackage, "getDeviceSoftwareVersionForSlot")) {
2055 return null;
2056 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002057
2058 final long identity = Binder.clearCallingIdentity();
2059 try {
2060 return phone.getDeviceSvn();
2061 } finally {
2062 Binder.restoreCallingIdentity(identity);
2063 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002064 }
2065
fionaxu43304da2017-11-27 22:51:16 -08002066 @Override
2067 public int getSubscriptionCarrierId(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08002068 final long identity = Binder.clearCallingIdentity();
2069 try {
2070 final Phone phone = getPhone(subId);
2071 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getCarrierId();
2072 } finally {
2073 Binder.restoreCallingIdentity(identity);
2074 }
fionaxu43304da2017-11-27 22:51:16 -08002075 }
2076
2077 @Override
2078 public String getSubscriptionCarrierName(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08002079 final long identity = Binder.clearCallingIdentity();
2080 try {
2081 final Phone phone = getPhone(subId);
2082 return phone == null ? null : phone.getCarrierName();
2083 } finally {
2084 Binder.restoreCallingIdentity(identity);
2085 }
fionaxu43304da2017-11-27 22:51:16 -08002086 }
2087
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002088 //
2089 // Internal helper methods.
2090 //
2091
Sanket Padaweee13a9b2016-03-08 17:30:28 -08002092 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002093 * Make sure the caller has the MODIFY_PHONE_STATE permission.
2094 *
2095 * @throws SecurityException if the caller does not have the required permission
2096 */
2097 private void enforceModifyPermission() {
2098 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
2099 }
2100
2101 /**
2102 * Make sure the caller has the CALL_PHONE permission.
2103 *
2104 * @throws SecurityException if the caller does not have the required permission
2105 */
2106 private void enforceCallPermission() {
2107 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
2108 }
2109
Stuart Scott8eef64f2015-04-08 15:13:54 -07002110 private void enforceConnectivityInternalPermission() {
2111 mApp.enforceCallingOrSelfPermission(
2112 android.Manifest.permission.CONNECTIVITY_INTERNAL,
2113 "ConnectivityService");
2114 }
2115
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002116 private String createTelUrl(String number) {
2117 if (TextUtils.isEmpty(number)) {
2118 return null;
2119 }
2120
Jake Hambye994d462014-02-03 13:10:13 -08002121 return "tel:" + number;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002122 }
2123
Ihab Awadf9e92732013-12-05 18:02:52 -08002124 private static void log(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002125 Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg);
2126 }
2127
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002128 private static void logv(String msg) {
2129 Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg);
2130 }
2131
Ihab Awadf9e92732013-12-05 18:02:52 -08002132 private static void loge(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002133 Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg);
2134 }
2135
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002136 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002137 public int getActivePhoneType() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07002138 return getActivePhoneTypeForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002139 }
2140
Sanket Padawe356d7632015-06-22 14:03:32 -07002141 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002142 public int getActivePhoneTypeForSlot(int slotIndex) {
Malcolm Chenaabec062018-02-28 15:00:40 -08002143 final long identity = Binder.clearCallingIdentity();
2144 try {
2145 final Phone phone = PhoneFactory.getPhone(slotIndex);
2146 if (phone == null) {
2147 return PhoneConstants.PHONE_TYPE_NONE;
2148 } else {
2149 return phone.getPhoneType();
2150 }
2151 } finally {
2152 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002153 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002154 }
2155
2156 /**
2157 * Returns the CDMA ERI icon index to display
2158 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002159 @Override
2160 public int getCdmaEriIconIndex(String callingPackage) {
2161 return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002162 }
2163
Sanket Padawe356d7632015-06-22 14:03:32 -07002164 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002165 public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002166 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002167 mApp, subId, callingPackage, "getCdmaEriIconIndexForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002168 return -1;
2169 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002170
2171 final long identity = Binder.clearCallingIdentity();
2172 try {
2173 final Phone phone = getPhone(subId);
2174 if (phone != null) {
2175 return phone.getCdmaEriIconIndex();
2176 } else {
2177 return -1;
2178 }
2179 } finally {
2180 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002181 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002182 }
2183
2184 /**
2185 * Returns the CDMA ERI icon mode,
2186 * 0 - ON
2187 * 1 - FLASHING
2188 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002189 @Override
2190 public int getCdmaEriIconMode(String callingPackage) {
2191 return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002192 }
2193
Sanket Padawe356d7632015-06-22 14:03:32 -07002194 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002195 public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002196 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002197 mApp, subId, callingPackage, "getCdmaEriIconModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002198 return -1;
2199 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002200
2201 final long identity = Binder.clearCallingIdentity();
2202 try {
2203 final Phone phone = getPhone(subId);
2204 if (phone != null) {
2205 return phone.getCdmaEriIconMode();
2206 } else {
2207 return -1;
2208 }
2209 } finally {
2210 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002211 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002212 }
2213
2214 /**
2215 * Returns the CDMA ERI text,
2216 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002217 @Override
2218 public String getCdmaEriText(String callingPackage) {
2219 return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002220 }
2221
Sanket Padawe356d7632015-06-22 14:03:32 -07002222 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002223 public String getCdmaEriTextForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002224 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002225 mApp, subId, callingPackage, "getCdmaEriIconTextForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002226 return null;
2227 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002228
2229 final long identity = Binder.clearCallingIdentity();
2230 try {
2231 final Phone phone = getPhone(subId);
2232 if (phone != null) {
2233 return phone.getCdmaEriText();
2234 } else {
2235 return null;
2236 }
2237 } finally {
2238 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002239 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002240 }
2241
2242 /**
Junda Liuca05d5d2014-08-14 22:36:34 -07002243 * Returns the CDMA MDN.
2244 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002245 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002246 public String getCdmaMdn(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002247 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2248 mApp, subId, "getCdmaMdn");
Malcolm Chenaabec062018-02-28 15:00:40 -08002249
2250 final long identity = Binder.clearCallingIdentity();
2251 try {
2252 final Phone phone = getPhone(subId);
2253 if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA && phone != null) {
2254 return phone.getLine1Number();
2255 } else {
2256 return null;
2257 }
2258 } finally {
2259 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07002260 }
2261 }
2262
2263 /**
2264 * Returns the CDMA MIN.
2265 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002266 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002267 public String getCdmaMin(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002268 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2269 mApp, subId, "getCdmaMin");
Malcolm Chenaabec062018-02-28 15:00:40 -08002270
2271 final long identity = Binder.clearCallingIdentity();
2272 try {
2273 final Phone phone = getPhone(subId);
2274 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
2275 return phone.getCdmaMin();
2276 } else {
2277 return null;
2278 }
2279 } finally {
2280 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07002281 }
2282 }
2283
2284 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002285 * Returns true if CDMA provisioning needs to run.
2286 */
2287 public boolean needsOtaServiceProvisioning() {
Malcolm Chenaabec062018-02-28 15:00:40 -08002288 final long identity = Binder.clearCallingIdentity();
2289 try {
2290 return mPhone.needsOtaServiceProvisioning();
2291 } finally {
2292 Binder.restoreCallingIdentity(identity);
2293 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002294 }
2295
2296 /**
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002297 * Sets the voice mail number of a given subId.
2298 */
2299 @Override
2300 public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002301 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setVoiceMailNumber");
Malcolm Chenaabec062018-02-28 15:00:40 -08002302
2303 final long identity = Binder.clearCallingIdentity();
2304 try {
2305 Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
2306 new Pair<String, String>(alphaTag, number), new Integer(subId));
2307 return success;
2308 } finally {
2309 Binder.restoreCallingIdentity(identity);
2310 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002311 }
2312
Ta-wei Yen87c49842016-05-13 21:19:52 -07002313 @Override
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002314 public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
2315 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2316 String systemDialer = TelecomManager.from(mPhone.getContext()).getSystemDialerPackage();
2317 if (!TextUtils.equals(callingPackage, systemDialer)) {
2318 throw new SecurityException("caller must be system dialer");
2319 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002320
2321 final long identity = Binder.clearCallingIdentity();
2322 try {
2323 PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
2324 if (phoneAccountHandle == null) {
2325 return null;
2326 }
2327 return VisualVoicemailSettingsUtil.dump(mPhone.getContext(), phoneAccountHandle);
2328 } finally {
2329 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002330 }
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002331 }
2332
2333 @Override
Ta-wei Yen409ac562017-03-06 16:00:44 -08002334 public String getVisualVoicemailPackageName(String callingPackage, int subId) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08002335 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jeff Davidson7e17e312018-02-13 18:17:36 -08002336 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002337 mApp, subId, callingPackage, "getVisualVoicemailPackageName")) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08002338 return null;
2339 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002340
Jeff Davidsona8e4e242018-03-15 17:16:18 -07002341 final long identity = Binder.clearCallingIdentity();
2342 try {
2343 return RemoteVvmTaskManager
2344 .getRemotePackage(mPhone.getContext(), subId).getPackageName();
2345 } finally {
2346 Binder.restoreCallingIdentity(identity);
2347 }
Ta-wei Yendca928f2017-01-10 16:17:08 -08002348 }
2349
2350 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002351 public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
2352 VisualVoicemailSmsFilterSettings settings) {
2353 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaabec062018-02-28 15:00:40 -08002354
2355 final long identity = Binder.clearCallingIdentity();
2356 try {
2357 VisualVoicemailSmsFilterConfig.enableVisualVoicemailSmsFilter(
2358 mPhone.getContext(), callingPackage, subId, settings);
2359 } finally {
2360 Binder.restoreCallingIdentity(identity);
2361 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002362 }
2363
2364 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002365 public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
2366 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaabec062018-02-28 15:00:40 -08002367
2368 final long identity = Binder.clearCallingIdentity();
2369 try {
2370 VisualVoicemailSmsFilterConfig.disableVisualVoicemailSmsFilter(
2371 mPhone.getContext(), callingPackage, subId);
2372 } finally {
2373 Binder.restoreCallingIdentity(identity);
2374 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002375 }
2376
2377 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002378 public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
2379 String callingPackage, int subId) {
2380 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaabec062018-02-28 15:00:40 -08002381
2382 final long identity = Binder.clearCallingIdentity();
2383 try {
2384 return VisualVoicemailSmsFilterConfig.getVisualVoicemailSmsFilterSettings(
2385 mPhone.getContext(), callingPackage, subId);
2386 } finally {
2387 Binder.restoreCallingIdentity(identity);
2388 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002389 }
2390
2391 @Override
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002392 public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
Ta-wei Yenb6929602016-05-24 15:48:27 -07002393 enforceReadPrivilegedPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08002394
2395 final long identity = Binder.clearCallingIdentity();
2396 try {
2397 return VisualVoicemailSmsFilterConfig.getActiveVisualVoicemailSmsFilterSettings(
2398 mPhone.getContext(), subId);
2399 } finally {
2400 Binder.restoreCallingIdentity(identity);
2401 }
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002402 }
2403
2404 @Override
2405 public void sendVisualVoicemailSmsForSubscriber(String callingPackage, int subId,
2406 String number, int port, String text, PendingIntent sentIntent) {
2407 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Ta-wei Yen527a9c02017-01-06 15:29:25 -08002408 enforceVisualVoicemailPackage(callingPackage, subId);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002409 enforceSendSmsPermission();
2410 // Make the calls as the phone process.
2411 final long identity = Binder.clearCallingIdentity();
2412 try {
2413 SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(subId);
2414 if (port == 0) {
2415 smsManager.sendTextMessageWithSelfPermissions(number, null, text,
2416 sentIntent, null, false);
2417 } else {
2418 byte[] data = text.getBytes(StandardCharsets.UTF_8);
2419 smsManager.sendDataMessageWithSelfPermissions(number, null,
2420 (short) port, data, sentIntent, null);
2421 }
2422 } finally {
2423 Binder.restoreCallingIdentity(identity);
2424 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002425 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002426 /**
fionaxu0152e512016-11-14 13:36:14 -08002427 * Sets the voice activation state of a given subId.
2428 */
2429 @Override
2430 public void setVoiceActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002431 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2432 mApp, subId, "setVoiceActivationState");
Malcolm Chenaabec062018-02-28 15:00:40 -08002433
2434 final long identity = Binder.clearCallingIdentity();
2435 try {
2436 final Phone phone = getPhone(subId);
2437 if (phone != null) {
2438 phone.setVoiceActivationState(activationState);
2439 } else {
2440 loge("setVoiceActivationState fails with invalid subId: " + subId);
2441 }
2442 } finally {
2443 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002444 }
2445 }
2446
2447 /**
2448 * Sets the data activation state of a given subId.
2449 */
2450 @Override
2451 public void setDataActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002452 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2453 mApp, subId, "setDataActivationState");
Malcolm Chenaabec062018-02-28 15:00:40 -08002454
2455 final long identity = Binder.clearCallingIdentity();
2456 try {
2457 final Phone phone = getPhone(subId);
2458 if (phone != null) {
2459 phone.setDataActivationState(activationState);
2460 } else {
2461 loge("setVoiceActivationState fails with invalid subId: " + subId);
2462 }
2463 } finally {
2464 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002465 }
2466 }
2467
2468 /**
2469 * Returns the voice activation state of a given subId.
2470 */
2471 @Override
2472 public int getVoiceActivationState(int subId, String callingPackage) {
goneil799f6e92017-12-13 12:57:23 -08002473 enforceReadPrivilegedPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08002474
fionaxu0152e512016-11-14 13:36:14 -08002475 final Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08002476 final long identity = Binder.clearCallingIdentity();
2477 try {
2478 if (phone != null) {
2479 return phone.getVoiceActivationState();
2480 } else {
2481 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2482 }
2483 } finally {
2484 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002485 }
2486 }
2487
2488 /**
2489 * Returns the data activation state of a given subId.
2490 */
2491 @Override
2492 public int getDataActivationState(int subId, String callingPackage) {
goneil799f6e92017-12-13 12:57:23 -08002493 enforceReadPrivilegedPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08002494
fionaxu0152e512016-11-14 13:36:14 -08002495 final Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08002496 final long identity = Binder.clearCallingIdentity();
2497 try {
2498 if (phone != null) {
2499 return phone.getDataActivationState();
2500 } else {
2501 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2502 }
2503 } finally {
2504 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002505 }
2506 }
2507
2508 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002509 * Returns the unread count of voicemails
2510 */
2511 public int getVoiceMessageCount() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002512 return getVoiceMessageCountForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002513 }
2514
2515 /**
2516 * Returns the unread count of voicemails for a subId
2517 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002518 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002519 public int getVoiceMessageCountForSubscriber( int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08002520 final long identity = Binder.clearCallingIdentity();
2521 try {
2522 final Phone phone = getPhone(subId);
2523 if (phone != null) {
2524 return phone.getVoiceMessageCount();
2525 } else {
2526 return 0;
2527 }
2528 } finally {
2529 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002530 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002531 }
2532
2533 /**
pkanwar8a4dcfb2017-01-19 13:43:16 -08002534 * returns true, if the device is in a state where both voice and data
2535 * are supported simultaneously. This can change based on location or network condition.
2536 */
2537 @Override
2538 public boolean isConcurrentVoiceAndDataAllowed(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08002539 final long identity = Binder.clearCallingIdentity();
2540 try {
2541 final Phone phone = getPhone(subId);
2542 return (phone == null ? false : phone.isConcurrentVoiceAndDataAllowed());
2543 } finally {
2544 Binder.restoreCallingIdentity(identity);
2545 }
pkanwar8a4dcfb2017-01-19 13:43:16 -08002546 }
2547
2548 /**
fionaxu235cc5e2017-03-06 22:25:57 -08002549 * Send the dialer code if called from the current default dialer or the caller has
2550 * carrier privilege.
2551 * @param inputCode The dialer code to send
2552 */
2553 @Override
2554 public void sendDialerSpecialCode(String callingPackage, String inputCode) {
2555 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2556 String defaultDialer = TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage();
2557 if (!TextUtils.equals(callingPackage, defaultDialer)) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002558 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
2559 getDefaultSubscription(), "sendDialerSpecialCode");
fionaxu235cc5e2017-03-06 22:25:57 -08002560 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002561
2562 final long identity = Binder.clearCallingIdentity();
2563 try {
2564 mPhone.sendDialerSpecialCode(inputCode);
2565 } finally {
2566 Binder.restoreCallingIdentity(identity);
2567 }
fionaxu235cc5e2017-03-06 22:25:57 -08002568 }
2569
2570 /**
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002571 * Returns the data network type.
2572 * Legacy call, permission-free.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002573 *
2574 * @Deprecated to be removed Q3 2013 use {@link #getDataNetworkType}.
2575 */
2576 @Override
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002577 public int getNetworkType() {
Malcolm Chenaabec062018-02-28 15:00:40 -08002578 final long identity = Binder.clearCallingIdentity();
2579 try {
2580 final Phone phone = getPhone(getDefaultSubscription());
2581 if (phone != null) {
2582 return phone.getServiceState().getDataNetworkType();
2583 } else {
2584 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2585 }
2586 } finally {
2587 Binder.restoreCallingIdentity(identity);
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002588 }
Wink Saville36469e72014-06-11 15:17:00 -07002589 }
2590
Pengquan Meng0c05b502018-09-06 09:59:22 -07002591 @Override
2592 public int getNetworkSelectionMode(int subId) {
Pengquan Meng466e2482018-09-21 15:54:48 -07002593 if (!isActiveSubscription(subId)) {
2594 return TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
2595 }
2596
Pengquan Meng0c05b502018-09-06 09:59:22 -07002597 return (int) sendRequest(CMD_GET_NETWORK_SELECTION_MODE, null /* argument */, subId);
2598 }
2599
Wink Saville36469e72014-06-11 15:17:00 -07002600 /**
2601 * Returns the network type for a subId
2602 */
2603 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002604 public int getNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002605 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002606 mApp, subId, callingPackage, "getNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002607 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2608 }
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002609
Malcolm Chenaabec062018-02-28 15:00:40 -08002610 final long identity = Binder.clearCallingIdentity();
2611 try {
2612 final Phone phone = getPhone(subId);
2613 if (phone != null) {
2614 return phone.getServiceState().getDataNetworkType();
2615 } else {
2616 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2617 }
2618 } finally {
2619 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002620 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002621 }
2622
2623 /**
2624 * Returns the data network type
2625 */
2626 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002627 public int getDataNetworkType(String callingPackage) {
2628 return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002629 }
2630
2631 /**
2632 * Returns the data network type for a subId
2633 */
2634 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002635 public int getDataNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002636 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002637 mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002638 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2639 }
2640
Malcolm Chenaabec062018-02-28 15:00:40 -08002641 final long identity = Binder.clearCallingIdentity();
2642 try {
2643 final Phone phone = getPhone(subId);
2644 if (phone != null) {
2645 return phone.getServiceState().getDataNetworkType();
2646 } else {
2647 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2648 }
2649 } finally {
2650 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002651 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002652 }
2653
2654 /**
Wink Saville36469e72014-06-11 15:17:00 -07002655 * Returns the Voice network type for a subId
2656 */
2657 @Override
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002658 public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002659 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002660 mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002661 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2662 }
2663
Malcolm Chenaabec062018-02-28 15:00:40 -08002664 final long identity = Binder.clearCallingIdentity();
2665 try {
2666 final Phone phone = getPhone(subId);
2667 if (phone != null) {
2668 return phone.getServiceState().getVoiceNetworkType();
2669 } else {
2670 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2671 }
2672 } finally {
2673 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002674 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002675 }
2676
2677 /**
2678 * @return true if a ICC card is present
2679 */
2680 public boolean hasIccCard() {
Wink Saville36469e72014-06-11 15:17:00 -07002681 // FIXME Make changes to pass defaultSimId of type int
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002682 return hasIccCardUsingSlotIndex(mSubscriptionController.getSlotIndex(
2683 getDefaultSubscription()));
Wink Saville36469e72014-06-11 15:17:00 -07002684 }
2685
2686 /**
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002687 * @return true if a ICC card is present for a slotIndex
Wink Saville36469e72014-06-11 15:17:00 -07002688 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002689 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002690 public boolean hasIccCardUsingSlotIndex(int slotIndex) {
Malcolm Chenaabec062018-02-28 15:00:40 -08002691 final long identity = Binder.clearCallingIdentity();
2692 try {
2693 final Phone phone = PhoneFactory.getPhone(slotIndex);
2694 if (phone != null) {
2695 return phone.getIccCard().hasIccCard();
2696 } else {
2697 return false;
2698 }
2699 } finally {
2700 Binder.restoreCallingIdentity(identity);
Amit Mahajana6fc2a82015-01-06 11:53:51 -08002701 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002702 }
2703
2704 /**
2705 * Return if the current radio is LTE on CDMA. This
2706 * is a tri-state return value as for a period of time
2707 * the mode may be unknown.
2708 *
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002709 * @param callingPackage the name of the package making the call.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002710 * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
Jake Hambye994d462014-02-03 13:10:13 -08002711 * or {@link Phone#LTE_ON_CDMA_TRUE}
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002712 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002713 @Override
2714 public int getLteOnCdmaMode(String callingPackage) {
2715 return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002716 }
2717
Sanket Padawe356d7632015-06-22 14:03:32 -07002718 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002719 public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002720 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002721 mApp, subId, callingPackage, "getLteOnCdmaModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002722 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
2723 }
2724
Malcolm Chenaabec062018-02-28 15:00:40 -08002725 final long identity = Binder.clearCallingIdentity();
2726 try {
2727 final Phone phone = getPhone(subId);
2728 if (phone == null) {
2729 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
2730 } else {
2731 return phone.getLteOnCdmaMode();
2732 }
2733 } finally {
2734 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002735 }
Wink Saville36469e72014-06-11 15:17:00 -07002736 }
2737
2738 public void setPhone(Phone phone) {
2739 mPhone = phone;
2740 }
2741
2742 /**
2743 * {@hide}
2744 * Returns Default subId, 0 in the case of single standby.
2745 */
Wink Savilleb564aae2014-10-23 10:18:09 -07002746 private int getDefaultSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08002747 return mSubscriptionController.getDefaultSubId();
Wink Saville36469e72014-06-11 15:17:00 -07002748 }
2749
Shishir Agrawala9f32182016-04-12 12:00:16 -07002750 private int getSlotForDefaultSubscription() {
2751 return mSubscriptionController.getPhoneId(getDefaultSubscription());
2752 }
2753
Wink Savilleb564aae2014-10-23 10:18:09 -07002754 private int getPreferredVoiceSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08002755 return mSubscriptionController.getDefaultVoiceSubId();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002756 }
Ihab Awadf2177b72013-11-25 13:33:23 -08002757
Pengquan Meng466e2482018-09-21 15:54:48 -07002758 private boolean isActiveSubscription(int subId) {
2759 return mSubscriptionController.isActiveSubId(subId);
2760 }
2761
Ihab Awadf2177b72013-11-25 13:33:23 -08002762 /**
2763 * @see android.telephony.TelephonyManager.WifiCallingChoices
2764 */
2765 public int getWhenToMakeWifiCalls() {
Malcolm Chenaabec062018-02-28 15:00:40 -08002766 final long identity = Binder.clearCallingIdentity();
2767 try {
2768 return Settings.System.getInt(mPhone.getContext().getContentResolver(),
2769 Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
2770 getWhenToMakeWifiCallsDefaultPreference());
2771 } finally {
2772 Binder.restoreCallingIdentity(identity);
2773 }
Ihab Awadf2177b72013-11-25 13:33:23 -08002774 }
2775
2776 /**
2777 * @see android.telephony.TelephonyManager.WifiCallingChoices
2778 */
2779 public void setWhenToMakeWifiCalls(int preference) {
Malcolm Chenaabec062018-02-28 15:00:40 -08002780 final long identity = Binder.clearCallingIdentity();
2781 try {
2782 if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference);
2783 Settings.System.putInt(mPhone.getContext().getContentResolver(),
2784 Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference);
2785 } finally {
2786 Binder.restoreCallingIdentity(identity);
2787 }
Ihab Awadf9e92732013-12-05 18:02:52 -08002788 }
2789
Sailesh Nepald1e68152013-12-12 19:08:02 -08002790 private static int getWhenToMakeWifiCallsDefaultPreference() {
Santos Cordonda120f42014-08-06 04:44:34 -07002791 // TODO: Use a build property to choose this value.
Evan Charlton9829e882013-12-19 15:30:38 -08002792 return TelephonyManager.WifiCallingChoices.ALWAYS_USE;
Ihab Awadf2177b72013-11-25 13:33:23 -08002793 }
Shishir Agrawal69f68122013-12-16 17:25:49 -08002794
Shishir Agrawal566b7612013-10-28 14:41:00 -07002795 @Override
Derek Tan740e1672017-06-27 14:56:27 -07002796 public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
2797 int subId, String callingPackage, String aid, int p2) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002798 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2799 mApp, subId, "iccOpenLogicalChannel");
Malcolm Chenaabec062018-02-28 15:00:40 -08002800 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Shishir Agrawal566b7612013-10-28 14:41:00 -07002801
Malcolm Chenaabec062018-02-28 15:00:40 -08002802 final long identity = Binder.clearCallingIdentity();
2803 try {
2804 if (TextUtils.equals(ISDR_AID, aid)) {
2805 // Only allows LPA to open logical channel to ISD-R.
2806 ComponentInfo bestComponent =
2807 EuiccConnector.findBestComponent(mPhone.getContext().getPackageManager());
2808 if (bestComponent == null
2809 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
2810 loge("The calling package is not allowed to access ISD-R.");
2811 throw new SecurityException(
2812 "The calling package is not allowed to access ISD-R.");
2813 }
Derek Tan740e1672017-06-27 14:56:27 -07002814 }
Derek Tan740e1672017-06-27 14:56:27 -07002815
Malcolm Chenaabec062018-02-28 15:00:40 -08002816 if (DBG) {
2817 log("iccOpenLogicalChannel: subId=" + subId + " aid=" + aid + " p2=" + p2);
2818 }
2819 IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse) sendRequest(
2820 CMD_OPEN_CHANNEL, new Pair<String, Integer>(aid, p2), subId);
2821 if (DBG) log("iccOpenLogicalChannel: " + response);
2822 return response;
2823 } finally {
2824 Binder.restoreCallingIdentity(identity);
2825 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07002826 }
2827
2828 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08002829 public boolean iccCloseLogicalChannel(int subId, int channel) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002830 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2831 mApp, subId, "iccCloseLogicalChannel");
Shishir Agrawal566b7612013-10-28 14:41:00 -07002832
Malcolm Chenaabec062018-02-28 15:00:40 -08002833 final long identity = Binder.clearCallingIdentity();
2834 try {
2835 if (DBG) log("iccCloseLogicalChannel: subId=" + subId + " chnl=" + channel);
2836 if (channel < 0) {
2837 return false;
2838 }
2839 Boolean success = (Boolean) sendRequest(CMD_CLOSE_CHANNEL, channel, subId);
2840 if (DBG) log("iccCloseLogicalChannel: " + success);
2841 return success;
2842 } finally {
2843 Binder.restoreCallingIdentity(identity);
Shishir Agrawal566b7612013-10-28 14:41:00 -07002844 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07002845 }
2846
2847 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08002848 public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
Shishir Agrawal566b7612013-10-28 14:41:00 -07002849 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002850 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2851 mApp, subId, "iccTransmitApduLogicalChannel");
Shishir Agrawal566b7612013-10-28 14:41:00 -07002852
Malcolm Chenaabec062018-02-28 15:00:40 -08002853 final long identity = Binder.clearCallingIdentity();
2854 try {
2855 if (DBG) {
2856 log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel
2857 + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
2858 + p3 + " data=" + data);
2859 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07002860
Malcolm Chenaabec062018-02-28 15:00:40 -08002861 if (channel < 0) {
2862 return "";
2863 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07002864
Malcolm Chenaabec062018-02-28 15:00:40 -08002865 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL,
2866 new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), subId);
2867 if (DBG) log("iccTransmitApduLogicalChannel: " + response);
Shishir Agrawal566b7612013-10-28 14:41:00 -07002868
Malcolm Chenaabec062018-02-28 15:00:40 -08002869 // Append the returned status code to the end of the response payload.
2870 String s = Integer.toHexString(
2871 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
2872 if (response.payload != null) {
2873 s = IccUtils.bytesToHexString(response.payload) + s;
2874 }
2875 return s;
2876 } finally {
2877 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07002878 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07002879 }
Jake Hambye994d462014-02-03 13:10:13 -08002880
Evan Charltonc66da362014-05-16 14:06:40 -07002881 @Override
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08002882 public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
2883 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002884 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2885 mApp, subId, "iccTransmitApduBasicChannel");
Malcolm Chenaabec062018-02-28 15:00:40 -08002886 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002887
Malcolm Chenaabec062018-02-28 15:00:40 -08002888 final long identity = Binder.clearCallingIdentity();
2889 try {
2890 if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
2891 && TextUtils.equals(ISDR_AID, data)) {
2892 // Only allows LPA to select ISD-R.
2893 ComponentInfo bestComponent =
2894 EuiccConnector.findBestComponent(mPhone.getContext().getPackageManager());
2895 if (bestComponent == null
2896 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
2897 loge("The calling package is not allowed to select ISD-R.");
2898 throw new SecurityException(
2899 "The calling package is not allowed to select ISD-R.");
2900 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08002901 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08002902
Malcolm Chenaabec062018-02-28 15:00:40 -08002903 if (DBG) {
2904 log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd="
2905 + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
2906 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002907
Malcolm Chenaabec062018-02-28 15:00:40 -08002908 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL,
2909 new IccAPDUArgument(0, cla, command, p1, p2, p3, data), subId);
2910 if (DBG) log("iccTransmitApduBasicChannel: " + response);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002911
Malcolm Chenaabec062018-02-28 15:00:40 -08002912 // Append the returned status code to the end of the response payload.
2913 String s = Integer.toHexString(
2914 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
2915 if (response.payload != null) {
2916 s = IccUtils.bytesToHexString(response.payload) + s;
2917 }
2918 return s;
2919 } finally {
2920 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07002921 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002922 }
2923
2924 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08002925 public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002926 String filePath) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002927 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2928 mApp, subId, "iccExchangeSimIO");
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002929
Malcolm Chenaabec062018-02-28 15:00:40 -08002930 final long identity = Binder.clearCallingIdentity();
2931 try {
2932 if (DBG) {
2933 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " "
2934 + p1 + " " + p2 + " " + p3 + ":" + filePath);
2935 }
2936
2937 IccIoResult response =
2938 (IccIoResult) sendRequest(CMD_EXCHANGE_SIM_IO,
2939 new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath),
2940 subId);
2941
2942 if (DBG) {
2943 log("Exchange SIM_IO [R]" + response);
2944 }
2945
2946 byte[] result = null;
2947 int length = 2;
2948 if (response.payload != null) {
2949 length = 2 + response.payload.length;
2950 result = new byte[length];
2951 System.arraycopy(response.payload, 0, result, 0, response.payload.length);
2952 } else {
2953 result = new byte[length];
2954 }
2955
2956 result[length - 1] = (byte) response.sw2;
2957 result[length - 2] = (byte) response.sw1;
2958 return result;
2959 } finally {
2960 Binder.restoreCallingIdentity(identity);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002961 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002962 }
2963
Nathan Haroldb3014052017-01-25 15:57:32 -08002964 /**
2965 * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
2966 * on a particular subscription
2967 */
sqianb6e41952018-03-12 14:54:01 -07002968 public String[] getForbiddenPlmns(int subId, int appType, String callingPackage) {
2969 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2970 mApp, subId, callingPackage, "getForbiddenPlmns")) {
2971 return null;
2972 }
Nathan Haroldb3014052017-01-25 15:57:32 -08002973 if (appType != TelephonyManager.APPTYPE_USIM && appType != TelephonyManager.APPTYPE_SIM) {
2974 loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
2975 return null;
2976 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002977
2978 final long identity = Binder.clearCallingIdentity();
2979 try {
2980 Object response = sendRequest(CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
2981 if (response instanceof String[]) {
2982 return (String[]) response;
2983 }
2984 // Response is an Exception of some kind,
2985 // which is signalled to the user as a NULL retval
2986 return null;
2987 } finally {
2988 Binder.restoreCallingIdentity(identity);
Nathan Haroldb3014052017-01-25 15:57:32 -08002989 }
Nathan Haroldb3014052017-01-25 15:57:32 -08002990 }
2991
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002992 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08002993 public String sendEnvelopeWithStatus(int subId, String content) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002994 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2995 mApp, subId, "sendEnvelopeWithStatus");
Evan Charltonc66da362014-05-16 14:06:40 -07002996
Malcolm Chenaabec062018-02-28 15:00:40 -08002997 final long identity = Binder.clearCallingIdentity();
2998 try {
2999 IccIoResult response = (IccIoResult) sendRequest(CMD_SEND_ENVELOPE, content, subId);
3000 if (response.payload == null) {
3001 return "";
3002 }
Evan Charltonc66da362014-05-16 14:06:40 -07003003
Malcolm Chenaabec062018-02-28 15:00:40 -08003004 // Append the returned status code to the end of the response payload.
3005 String s = Integer.toHexString(
3006 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
3007 s = IccUtils.bytesToHexString(response.payload) + s;
3008 return s;
3009 } finally {
3010 Binder.restoreCallingIdentity(identity);
3011 }
Evan Charltonc66da362014-05-16 14:06:40 -07003012 }
3013
Jake Hambye994d462014-02-03 13:10:13 -08003014 /**
3015 * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
3016 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
3017 *
3018 * @param itemID the ID of the item to read
3019 * @return the NV item as a String, or null on error.
3020 */
3021 @Override
3022 public String nvReadItem(int itemID) {
vagdevie435a3e2018-08-15 16:01:53 -07003023 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08003024 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3025 mApp, getDefaultSubscription(), "nvReadItem");
Malcolm Chenaabec062018-02-28 15:00:40 -08003026
3027 final long identity = Binder.clearCallingIdentity();
3028 try {
3029 if (DBG) log("nvReadItem: item " + itemID);
vagdevie435a3e2018-08-15 16:01:53 -07003030 String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID, workSource);
Malcolm Chenaabec062018-02-28 15:00:40 -08003031 if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
3032 return value;
3033 } finally {
3034 Binder.restoreCallingIdentity(identity);
3035 }
Jake Hambye994d462014-02-03 13:10:13 -08003036 }
3037
3038 /**
3039 * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
3040 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
3041 *
3042 * @param itemID the ID of the item to read
3043 * @param itemValue the value to write, as a String
3044 * @return true on success; false on any failure
3045 */
3046 @Override
3047 public boolean nvWriteItem(int itemID, String itemValue) {
vagdevie435a3e2018-08-15 16:01:53 -07003048 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08003049 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3050 mApp, getDefaultSubscription(), "nvWriteItem");
Malcolm Chenaabec062018-02-28 15:00:40 -08003051
3052 final long identity = Binder.clearCallingIdentity();
3053 try {
3054 if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
3055 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
vagdevie435a3e2018-08-15 16:01:53 -07003056 new Pair<Integer, String>(itemID, itemValue), workSource);
Malcolm Chenaabec062018-02-28 15:00:40 -08003057 if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
3058 return success;
3059 } finally {
3060 Binder.restoreCallingIdentity(identity);
3061 }
Jake Hambye994d462014-02-03 13:10:13 -08003062 }
3063
3064 /**
3065 * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
3066 * Used for device configuration by some CDMA operators.
3067 *
3068 * @param preferredRoamingList byte array containing the new PRL
3069 * @return true on success; false on any failure
3070 */
3071 @Override
3072 public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003073 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3074 mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
Malcolm Chenaabec062018-02-28 15:00:40 -08003075
3076 final long identity = Binder.clearCallingIdentity();
3077 try {
3078 if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
3079 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
3080 if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
3081 return success;
3082 } finally {
3083 Binder.restoreCallingIdentity(identity);
3084 }
Jake Hambye994d462014-02-03 13:10:13 -08003085 }
3086
3087 /**
3088 * Perform the specified type of NV config reset.
3089 * Used for device configuration by some CDMA operators.
3090 *
3091 * @param resetType the type of reset to perform (1 == factory reset; 2 == NV-only reset)
3092 * @return true on success; false on any failure
3093 */
3094 @Override
3095 public boolean nvResetConfig(int resetType) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003096 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3097 mApp, getDefaultSubscription(), "nvResetConfig");
Malcolm Chenaabec062018-02-28 15:00:40 -08003098
3099 final long identity = Binder.clearCallingIdentity();
3100 try {
3101 if (DBG) log("nvResetConfig: type " + resetType);
3102 Boolean success = (Boolean) sendRequest(CMD_NV_RESET_CONFIG, resetType);
3103 if (DBG) log("nvResetConfig: type " + resetType + ' ' + (success ? "ok" : "fail"));
3104 return success;
3105 } finally {
3106 Binder.restoreCallingIdentity(identity);
3107 }
Jake Hambye994d462014-02-03 13:10:13 -08003108 }
Jake Hamby7c27be32014-03-03 13:25:59 -08003109
Svet Ganovb320e182015-04-16 12:30:10 -07003110 public String[] getPcscfAddress(String apnType, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003111 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003112 mApp, mPhone.getSubId(), callingPackage, "getPcscfAddress")) {
Svet Ganovb320e182015-04-16 12:30:10 -07003113 return new String[0];
3114 }
3115
Malcolm Chenaabec062018-02-28 15:00:40 -08003116 final long identity = Binder.clearCallingIdentity();
3117 try {
3118 return mPhone.getPcscfAddress(apnType);
3119 } finally {
3120 Binder.restoreCallingIdentity(identity);
3121 }
Wink Saville36469e72014-06-11 15:17:00 -07003122 }
3123
Brad Ebinger51f743a2017-01-23 13:50:20 -08003124 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003125 * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
3126 * status updates, if not already enabled.
Brad Ebinger51f743a2017-01-23 13:50:20 -08003127 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003128 public void enableIms(int slotId) {
Brad Ebinger51f743a2017-01-23 13:50:20 -08003129 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003130
3131 final long identity = Binder.clearCallingIdentity();
3132 try {
3133 PhoneFactory.getImsResolver().enableIms(slotId);
3134 } finally {
3135 Binder.restoreCallingIdentity(identity);
3136 }
Brad Ebinger34bef922017-11-09 10:27:08 -08003137 }
3138
3139 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003140 * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
3141 * status updates to disabled.
Brad Ebinger34bef922017-11-09 10:27:08 -08003142 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003143 public void disableIms(int slotId) {
3144 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003145
3146 final long identity = Binder.clearCallingIdentity();
3147 try {
3148 PhoneFactory.getImsResolver().disableIms(slotId);
3149 } finally {
3150 Binder.restoreCallingIdentity(identity);
3151 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003152 }
3153
3154 /**
3155 * Returns the {@link IImsMmTelFeature} that corresponds to the given slot Id for the MMTel
3156 * feature or {@link null} if the service is not available. If the feature is available, the
3157 * {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates.
3158 */
3159 public IImsMmTelFeature getMmTelFeatureAndListen(int slotId,
Brad Ebinger34bef922017-11-09 10:27:08 -08003160 IImsServiceFeatureCallback callback) {
3161 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003162
3163 final long identity = Binder.clearCallingIdentity();
3164 try {
3165 return PhoneFactory.getImsResolver().getMmTelFeatureAndListen(slotId, callback);
3166 } finally {
3167 Binder.restoreCallingIdentity(identity);
3168 }
Brad Ebinger34bef922017-11-09 10:27:08 -08003169 }
3170
3171 /**
3172 * Returns the {@link IImsRcsFeature} that corresponds to the given slot Id for the RCS
3173 * feature during emergency calling or {@link null} if the service is not available. If the
3174 * feature is available, the {@link IImsServiceFeatureCallback} callback is registered as a
3175 * listener for feature updates.
3176 */
3177 public IImsRcsFeature getRcsFeatureAndListen(int slotId, IImsServiceFeatureCallback callback) {
3178 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003179
3180 final long identity = Binder.clearCallingIdentity();
3181 try {
3182 return PhoneFactory.getImsResolver().getRcsFeatureAndListen(slotId, callback);
3183 } finally {
3184 Binder.restoreCallingIdentity(identity);
3185 }
Brad Ebinger51f743a2017-01-23 13:50:20 -08003186 }
3187
Brad Ebinger5f64b052017-12-14 14:26:15 -08003188 /**
3189 * Returns the {@link IImsRegistration} structure associated with the slotId and feature
3190 * specified.
3191 */
3192 public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
3193 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003194
3195 final long identity = Binder.clearCallingIdentity();
3196 try {
3197 return PhoneFactory.getImsResolver().getImsRegistration(slotId, feature);
3198 } finally {
3199 Binder.restoreCallingIdentity(identity);
3200 }
Brad Ebinger5f64b052017-12-14 14:26:15 -08003201 }
3202
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003203 /**
3204 * Returns the {@link IImsConfig} structure associated with the slotId and feature
3205 * specified.
3206 */
3207 public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
3208 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003209
3210 final long identity = Binder.clearCallingIdentity();
3211 try {
3212 return PhoneFactory.getImsResolver().getImsConfig(slotId, feature);
3213 } finally {
3214 Binder.restoreCallingIdentity(identity);
3215 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003216 }
3217
Brad Ebinger884c07b2018-02-15 16:17:40 -08003218 /**
Brad Ebinger67801702018-03-02 13:43:36 -08003219 * @return true if the IMS resolver is busy resolving a binding and should not be considered
3220 * available, false if the IMS resolver is idle.
3221 */
3222 public boolean isResolvingImsBinding() {
3223 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003224
3225 final long identity = Binder.clearCallingIdentity();
3226 try {
3227 return PhoneFactory.getImsResolver().isResolvingBinding();
3228 } finally {
3229 Binder.restoreCallingIdentity(identity);
3230 }
Brad Ebinger67801702018-03-02 13:43:36 -08003231 }
3232
Brad Ebingerdac2f002018-04-03 15:17:52 -07003233 /**
3234 * Sets the ImsService Package Name that Telephony will bind to.
3235 *
3236 * @param slotId the slot ID that the ImsService should bind for.
3237 * @param isCarrierImsService true if the ImsService is the carrier override, false if the
3238 * ImsService is the device default ImsService.
3239 * @param packageName The package name of the application that contains the ImsService to bind
3240 * to.
3241 * @return true if setting the ImsService to bind to succeeded, false if it did not.
3242 * @hide
3243 */
3244 public boolean setImsService(int slotId, boolean isCarrierImsService, String packageName) {
Brad Ebingerde696de2018-04-06 09:56:40 -07003245 int[] subIds = SubscriptionManager.getSubId(slotId);
3246 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
3247 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
3248 "setImsService");
3249
Malcolm Chenaabec062018-02-28 15:00:40 -08003250 final long identity = Binder.clearCallingIdentity();
3251 try {
3252 return PhoneFactory.getImsResolver().overrideImsServiceConfiguration(slotId,
3253 isCarrierImsService, packageName);
3254 } finally {
3255 Binder.restoreCallingIdentity(identity);
3256 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07003257 }
3258
3259 /**
3260 * Return the ImsService configuration.
3261 *
3262 * @param slotId The slot that the ImsService is associated with.
3263 * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
3264 * the device default.
3265 * @return the package name of the ImsService configuration.
3266 */
3267 public String getImsService(int slotId, boolean isCarrierImsService) {
Brad Ebingerde696de2018-04-06 09:56:40 -07003268 int[] subIds = SubscriptionManager.getSubId(slotId);
3269 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
3270 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
3271 "getImsService");
3272
Malcolm Chenaabec062018-02-28 15:00:40 -08003273 final long identity = Binder.clearCallingIdentity();
3274 try {
3275 return PhoneFactory.getImsResolver().getImsServiceConfiguration(slotId,
3276 isCarrierImsService);
3277 } finally {
3278 Binder.restoreCallingIdentity(identity);
3279 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07003280 }
3281
Wink Saville36469e72014-06-11 15:17:00 -07003282 public void setImsRegistrationState(boolean registered) {
3283 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003284
3285 final long identity = Binder.clearCallingIdentity();
3286 try {
3287 mPhone.setImsRegistrationState(registered);
3288 } finally {
3289 Binder.restoreCallingIdentity(identity);
3290 }
Wink Saville36469e72014-06-11 15:17:00 -07003291 }
3292
3293 /**
Stuart Scott54788802015-03-30 13:18:01 -07003294 * Set the network selection mode to automatic.
3295 *
3296 */
3297 @Override
3298 public void setNetworkSelectionModeAutomatic(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003299 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3300 mApp, subId, "setNetworkSelectionModeAutomatic");
Malcolm Chenaabec062018-02-28 15:00:40 -08003301
Pengquan Meng466e2482018-09-21 15:54:48 -07003302 if (!isActiveSubscription(subId)) {
3303 return;
3304 }
3305
Malcolm Chenaabec062018-02-28 15:00:40 -08003306 final long identity = Binder.clearCallingIdentity();
3307 try {
3308 if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
3309 sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId);
3310 } finally {
3311 Binder.restoreCallingIdentity(identity);
3312 }
Stuart Scott54788802015-03-30 13:18:01 -07003313 }
3314
Pengquan Menga4d9cff2018-09-20 14:57:26 -07003315 /**
3316 * Ask the radio to connect to the input network and change selection mode to manual.
3317 *
3318 * @param subId the id of the subscription.
3319 * @param operatorInfo the operator information, included the PLMN, long name and short name of
3320 * the operator to attach to.
3321 * @param persistSelection whether the selection will persist until reboot. If true, only allows
3322 * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
3323 * normal network selection next time.
3324 * @return {@code true} on success; {@code true} on any failure.
Shishir Agrawal302c8692015-06-19 13:49:39 -07003325 */
3326 @Override
Pengquan Menga4d9cff2018-09-20 14:57:26 -07003327 public boolean setNetworkSelectionModeManual(
3328 int subId, OperatorInfo operatorInfo, boolean persistSelection) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003329 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3330 mApp, subId, "setNetworkSelectionModeManual");
Pengquan Meng466e2482018-09-21 15:54:48 -07003331
3332 if (!isActiveSubscription(subId)) {
3333 return false;
3334 }
3335
Malcolm Chenaabec062018-02-28 15:00:40 -08003336 final long identity = Binder.clearCallingIdentity();
3337 try {
Pengquan Menga4d9cff2018-09-20 14:57:26 -07003338 ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operatorInfo,
Malcolm Chenaabec062018-02-28 15:00:40 -08003339 persistSelection);
Pengquan Menga4d9cff2018-09-20 14:57:26 -07003340 if (DBG) {
3341 log("setNetworkSelectionModeManual: subId: " + subId
3342 + " operator: " + operatorInfo);
3343 }
Malcolm Chenaabec062018-02-28 15:00:40 -08003344 return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
3345 } finally {
3346 Binder.restoreCallingIdentity(identity);
3347 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07003348 }
3349
3350 /**
3351 * Scans for available networks.
3352 */
3353 @Override
3354 public CellNetworkScanResult getCellNetworkScanResults(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003355 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3356 mApp, subId, "getCellNetworkScanResults");
Malcolm Chenaabec062018-02-28 15:00:40 -08003357
Pengquan Meng0c05b502018-09-06 09:59:22 -07003358 long identity = Binder.clearCallingIdentity();
Malcolm Chenaabec062018-02-28 15:00:40 -08003359 try {
3360 if (DBG) log("getCellNetworkScanResults: subId " + subId);
Pengquan Meng0c05b502018-09-06 09:59:22 -07003361 return (CellNetworkScanResult) sendRequest(
Malcolm Chenaabec062018-02-28 15:00:40 -08003362 CMD_PERFORM_NETWORK_SCAN, null, subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08003363 } finally {
3364 Binder.restoreCallingIdentity(identity);
3365 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07003366 }
3367
3368 /**
yinxub1bed742017-04-17 11:45:04 -07003369 * Starts a new network scan and returns the id of this scan.
yinxu504e1392017-04-12 16:03:22 -07003370 *
yinxub1bed742017-04-17 11:45:04 -07003371 * @param subId id of the subscription
3372 * @param request contains the radio access networks with bands/channels to scan
3373 * @param messenger callback messenger for scan results or errors
3374 * @param binder for the purpose of auto clean when the user thread crashes
yinxu504e1392017-04-12 16:03:22 -07003375 * @return the id of the requested scan which can be used to stop the scan.
3376 */
3377 @Override
3378 public int requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger,
3379 IBinder binder) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003380 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3381 mApp, subId, "requestNetworkScan");
Malcolm Chenaabec062018-02-28 15:00:40 -08003382
3383 final long identity = Binder.clearCallingIdentity();
3384 try {
3385 return mNetworkScanRequestTracker.startNetworkScan(
3386 request, messenger, binder, getPhone(subId));
3387 } finally {
3388 Binder.restoreCallingIdentity(identity);
3389 }
yinxu504e1392017-04-12 16:03:22 -07003390 }
3391
3392 /**
3393 * Stops an existing network scan with the given scanId.
yinxub1bed742017-04-17 11:45:04 -07003394 *
3395 * @param subId id of the subscription
3396 * @param scanId id of the scan that needs to be stopped
yinxu504e1392017-04-12 16:03:22 -07003397 */
3398 @Override
3399 public void stopNetworkScan(int subId, int scanId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003400 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3401 mApp, subId, "stopNetworkScan");
Malcolm Chenaabec062018-02-28 15:00:40 -08003402
3403 final long identity = Binder.clearCallingIdentity();
3404 try {
3405 mNetworkScanRequestTracker.stopNetworkScan(scanId);
3406 } finally {
3407 Binder.restoreCallingIdentity(identity);
3408 }
yinxu504e1392017-04-12 16:03:22 -07003409 }
3410
3411 /**
Junda Liu84d15a22014-07-02 11:21:04 -07003412 * Get the calculated preferred network type.
3413 * Used for debugging incorrect network type.
3414 *
3415 * @return the preferred network type, defined in RILConstants.java.
3416 */
3417 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07003418 public int getCalculatedPreferredNetworkType(String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003419 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003420 mApp, mPhone.getSubId(), callingPackage, "getCalculatedPreferredNetworkType")) {
Svet Ganovb320e182015-04-16 12:30:10 -07003421 return RILConstants.PREFERRED_NETWORK_MODE;
3422 }
3423
Malcolm Chenaabec062018-02-28 15:00:40 -08003424 final long identity = Binder.clearCallingIdentity();
3425 try {
3426 // FIXME: need to get SubId from somewhere.
3427 return PhoneFactory.calculatePreferredNetworkType(mPhone.getContext(), 0);
3428 } finally {
3429 Binder.restoreCallingIdentity(identity);
3430 }
Junda Liu84d15a22014-07-02 11:21:04 -07003431 }
3432
3433 /**
Jake Hamby7c27be32014-03-03 13:25:59 -08003434 * Get the preferred network type.
3435 * Used for device configuration by some CDMA operators.
3436 *
3437 * @return the preferred network type, defined in RILConstants.java.
3438 */
3439 @Override
Stuart Scott54788802015-03-30 13:18:01 -07003440 public int getPreferredNetworkType(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003441 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3442 mApp, subId, "getPreferredNetworkType");
Malcolm Chenaabec062018-02-28 15:00:40 -08003443
3444 final long identity = Binder.clearCallingIdentity();
3445 try {
3446 if (DBG) log("getPreferredNetworkType");
3447 int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null, subId);
3448 int networkType = (result != null ? result[0] : -1);
3449 if (DBG) log("getPreferredNetworkType: " + networkType);
3450 return networkType;
3451 } finally {
3452 Binder.restoreCallingIdentity(identity);
3453 }
Jake Hamby7c27be32014-03-03 13:25:59 -08003454 }
3455
3456 /**
3457 * Set the preferred network type.
3458 * Used for device configuration by some CDMA operators.
3459 *
3460 * @param networkType the preferred network type, defined in RILConstants.java.
3461 * @return true on success; false on any failure.
3462 */
3463 @Override
Stuart Scott54788802015-03-30 13:18:01 -07003464 public boolean setPreferredNetworkType(int subId, int networkType) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003465 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3466 mApp, subId, "setPreferredNetworkType");
Malcolm Chenaabec062018-02-28 15:00:40 -08003467
3468 final long identity = Binder.clearCallingIdentity();
3469 try {
3470 if (DBG) log("setPreferredNetworkType: subId " + subId + " type " + networkType);
3471 Boolean success = (Boolean) sendRequest(
3472 CMD_SET_PREFERRED_NETWORK_TYPE, networkType, subId);
3473 if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail"));
3474 if (success) {
3475 Settings.Global.putInt(mPhone.getContext().getContentResolver(),
3476 Settings.Global.PREFERRED_NETWORK_MODE + subId, networkType);
3477 }
3478 return success;
3479 } finally {
3480 Binder.restoreCallingIdentity(identity);
Junda Liu80bc0d12014-07-14 16:36:44 -07003481 }
Jake Hamby7c27be32014-03-03 13:25:59 -08003482 }
Robert Greenwalted86e582014-05-21 20:03:20 -07003483
3484 /**
Junda Liu475951f2014-11-07 16:45:03 -08003485 * Check TETHER_DUN_REQUIRED and TETHER_DUN_APN settings, net.tethering.noprovisioning
3486 * SystemProperty, and config_tether_apndata to decide whether DUN APN is required for
3487 * tethering.
3488 *
3489 * @return 0: Not required. 1: required. 2: Not set.
3490 * @hide
3491 */
3492 @Override
3493 public int getTetherApnRequired() {
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003494 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003495
3496 final long identity = Binder.clearCallingIdentity();
3497 try {
3498 int dunRequired = Settings.Global.getInt(mPhone.getContext().getContentResolver(),
3499 Settings.Global.TETHER_DUN_REQUIRED, 2);
3500 // If not set, check net.tethering.noprovisioning, TETHER_DUN_APN setting and
3501 // config_tether_apndata.
3502 if (dunRequired == 2 && mPhone.hasMatchedTetherApnSetting()) {
3503 dunRequired = 1;
3504 }
3505 return dunRequired;
3506 } finally {
3507 Binder.restoreCallingIdentity(identity);
Junda Liu475951f2014-11-07 16:45:03 -08003508 }
Junda Liu475951f2014-11-07 16:45:03 -08003509 }
3510
3511 /**
Robert Greenwalted86e582014-05-21 20:03:20 -07003512 * Set mobile data enabled
3513 * Used by the user through settings etc to turn on/off mobile data
3514 *
3515 * @param enable {@code true} turn turn data on, else {@code false}
3516 */
3517 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08003518 public void setUserDataEnabled(int subId, boolean enable) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003519 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3520 mApp, subId, "setUserDataEnabled");
Malcolm Chenaabec062018-02-28 15:00:40 -08003521
3522 final long identity = Binder.clearCallingIdentity();
3523 try {
3524 int phoneId = mSubscriptionController.getPhoneId(subId);
3525 if (DBG) log("setUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
3526 Phone phone = PhoneFactory.getPhone(phoneId);
3527 if (phone != null) {
3528 if (DBG) log("setUserDataEnabled: subId=" + subId + " enable=" + enable);
3529 phone.setUserDataEnabled(enable);
3530 } else {
3531 loge("setUserDataEnabled: no phone for subId=" + subId);
3532 }
3533 } finally {
3534 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08003535 }
Robert Greenwalted86e582014-05-21 20:03:20 -07003536 }
3537
3538 /**
Malcolm Chen964682d2017-11-28 16:20:07 -08003539 * Get the user enabled state of Mobile Data.
3540 *
3541 * TODO: remove and use isUserDataEnabled.
3542 * This can't be removed now because some vendor codes
3543 * calls through ITelephony directly while they should
3544 * use TelephonyManager.
3545 *
3546 * @return true on enabled
3547 */
3548 @Override
3549 public boolean getDataEnabled(int subId) {
3550 return isUserDataEnabled(subId);
3551 }
3552
3553 /**
3554 * Get whether mobile data is enabled per user setting.
3555 *
3556 * There are other factors deciding whether mobile data is actually enabled, but they are
3557 * not considered here. See {@link #isDataEnabled(int)} for more details.
Robert Greenwalt646120a2014-05-23 11:54:03 -07003558 *
Jeff Davidsona1920712016-11-18 17:05:56 -08003559 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
Robert Greenwalted86e582014-05-21 20:03:20 -07003560 *
3561 * @return {@code true} if data is enabled else {@code false}
3562 */
3563 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08003564 public boolean isUserDataEnabled(int subId) {
Robert Greenwalt646120a2014-05-23 11:54:03 -07003565 try {
3566 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
3567 null);
3568 } catch (Exception e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003569 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3570 mApp, subId, "isUserDataEnabled");
Robert Greenwalt646120a2014-05-23 11:54:03 -07003571 }
Malcolm Chenaabec062018-02-28 15:00:40 -08003572
3573 final long identity = Binder.clearCallingIdentity();
3574 try {
3575 int phoneId = mSubscriptionController.getPhoneId(subId);
3576 if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
3577 Phone phone = PhoneFactory.getPhone(phoneId);
3578 if (phone != null) {
3579 boolean retVal = phone.isUserDataEnabled();
3580 if (DBG) log("isUserDataEnabled: subId=" + subId + " retVal=" + retVal);
3581 return retVal;
3582 } else {
3583 if (DBG) loge("isUserDataEnabled: no phone subId=" + subId + " retVal=false");
3584 return false;
3585 }
3586 } finally {
3587 Binder.restoreCallingIdentity(identity);
Malcolm Chen964682d2017-11-28 16:20:07 -08003588 }
3589 }
3590
3591 /**
3592 * Get whether mobile data is enabled.
3593 *
3594 * Comparable to {@link #isUserDataEnabled(int)}, this considers all factors deciding
3595 * whether mobile data is actually enabled.
3596 *
3597 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
3598 *
3599 * @return {@code true} if data is enabled else {@code false}
3600 */
3601 @Override
3602 public boolean isDataEnabled(int subId) {
3603 try {
3604 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
3605 null);
3606 } catch (Exception e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003607 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3608 mApp, subId, "isDataEnabled");
Malcolm Chen964682d2017-11-28 16:20:07 -08003609 }
Malcolm Chenaabec062018-02-28 15:00:40 -08003610
3611 final long identity = Binder.clearCallingIdentity();
3612 try {
3613 int phoneId = mSubscriptionController.getPhoneId(subId);
3614 if (DBG) log("isDataEnabled: subId=" + subId + " phoneId=" + phoneId);
3615 Phone phone = PhoneFactory.getPhone(phoneId);
3616 if (phone != null) {
3617 boolean retVal = phone.isDataEnabled();
3618 if (DBG) log("isDataEnabled: subId=" + subId + " retVal=" + retVal);
3619 return retVal;
3620 } else {
3621 if (DBG) loge("isDataEnabled: no phone subId=" + subId + " retVal=false");
3622 return false;
3623 }
3624 } finally {
3625 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08003626 }
Robert Greenwalted86e582014-05-21 20:03:20 -07003627 }
Shishir Agrawal60f9c952014-06-23 12:00:43 -07003628
3629 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003630 public int getCarrierPrivilegeStatus(int subId) {
3631 final Phone phone = getPhone(subId);
3632 if (phone == null) {
3633 loge("getCarrierPrivilegeStatus: Invalid subId");
3634 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
3635 }
3636 UiccCard card = UiccController.getInstance().getUiccCard(phone.getPhoneId());
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07003637 if (card == null) {
Shishir Agrawal5e5becd2014-11-18 11:38:23 -08003638 loge("getCarrierPrivilegeStatus: No UICC");
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07003639 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3640 }
3641 return card.getCarrierPrivilegeStatusForCurrentTransaction(
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003642 phone.getContext().getPackageManager());
Shishir Agrawal60f9c952014-06-23 12:00:43 -07003643 }
Junda Liu29340342014-07-10 15:23:27 -07003644
3645 @Override
Jeff Davidson7e17e312018-02-13 18:17:36 -08003646 public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
3647 final Phone phone = getPhone(subId);
3648 if (phone == null) {
3649 loge("getCarrierPrivilegeStatus: Invalid subId");
3650 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
3651 }
3652 UiccProfile profile =
3653 UiccController.getInstance().getUiccProfileForPhone(phone.getPhoneId());
3654 if (profile == null) {
3655 loge("getCarrierPrivilegeStatus: No UICC");
3656 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3657 }
3658 return profile.getCarrierPrivilegeStatusForUid(phone.getContext().getPackageManager(), uid);
3659 }
3660
3661 @Override
Zach Johnson50ecba32015-05-19 00:24:21 -07003662 public int checkCarrierPrivilegesForPackage(String pkgName) {
Junda Liu317d70b2016-03-08 09:33:53 -08003663 if (TextUtils.isEmpty(pkgName))
3664 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Shishir Agrawal21409252015-01-15 23:33:50 -08003665 UiccCard card = UiccController.getInstance().getUiccCard(mPhone.getPhoneId());
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07003666 if (card == null) {
3667 loge("checkCarrierPrivilegesForPackage: No UICC");
3668 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3669 }
Zach Johnson50ecba32015-05-19 00:24:21 -07003670 return card.getCarrierPrivilegeStatus(mPhone.getContext().getPackageManager(), pkgName);
3671 }
3672
3673 @Override
3674 public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
Junda Liu317d70b2016-03-08 09:33:53 -08003675 if (TextUtils.isEmpty(pkgName))
3676 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Zach Johnson50ecba32015-05-19 00:24:21 -07003677 int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3678 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
3679 UiccCard card = UiccController.getInstance().getUiccCard(i);
3680 if (card == null) {
Jonathan Basseri7d320df2015-06-16 12:17:08 -07003681 // No UICC in that slot.
Zach Johnson50ecba32015-05-19 00:24:21 -07003682 continue;
3683 }
3684
3685 result = card.getCarrierPrivilegeStatus(
3686 mPhone.getContext().getPackageManager(), pkgName);
3687 if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
3688 break;
3689 }
3690 }
3691
3692 return result;
Junda Liu29340342014-07-10 15:23:27 -07003693 }
Derek Tan89e89d42014-07-08 17:00:10 -07003694
3695 @Override
Junda Liue64de782015-04-16 17:19:16 -07003696 public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
3697 if (!SubscriptionManager.isValidPhoneId(phoneId)) {
3698 loge("phoneId " + phoneId + " is not valid.");
3699 return null;
3700 }
3701 UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07003702 if (card == null) {
Diego Pontorieroaf74c862014-08-28 11:51:16 -07003703 loge("getCarrierPackageNamesForIntent: No UICC");
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07003704 return null ;
3705 }
Diego Pontorieroaf74c862014-08-28 11:51:16 -07003706 return card.getCarrierPackageNamesForIntent(
Svetoslav483aff72015-04-21 14:16:07 -07003707 mPhone.getContext().getPackageManager(), intent);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07003708 }
3709
Amith Yamasani6e118872016-02-19 12:53:51 -08003710 @Override
3711 public List<String> getPackagesWithCarrierPrivileges() {
3712 PackageManager pm = mPhone.getContext().getPackageManager();
3713 List<String> privilegedPackages = new ArrayList<>();
3714 List<PackageInfo> packages = null;
3715 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
3716 UiccCard card = UiccController.getInstance().getUiccCard(i);
3717 if (card == null) {
3718 // No UICC in that slot.
3719 continue;
3720 }
3721 if (card.hasCarrierPrivilegeRules()) {
3722 if (packages == null) {
3723 // Only check packages in user 0 for now
3724 packages = pm.getInstalledPackagesAsUser(
3725 PackageManager.MATCH_DISABLED_COMPONENTS
3726 | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
3727 | PackageManager.GET_SIGNATURES, UserHandle.USER_SYSTEM);
3728 }
3729 for (int p = packages.size() - 1; p >= 0; p--) {
3730 PackageInfo pkgInfo = packages.get(p);
3731 if (pkgInfo != null && pkgInfo.packageName != null
3732 && card.getCarrierPrivilegeStatus(pkgInfo)
3733 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
3734 privilegedPackages.add(pkgInfo.packageName);
3735 }
3736 }
3737 }
3738 }
3739 return privilegedPackages;
3740 }
3741
Wink Savilleb564aae2014-10-23 10:18:09 -07003742 private String getIccId(int subId) {
Sanket Padawe356d7632015-06-22 14:03:32 -07003743 final Phone phone = getPhone(subId);
3744 UiccCard card = phone == null ? null : phone.getUiccCard();
Derek Tan97ebb422014-09-05 16:55:38 -07003745 if (card == null) {
3746 loge("getIccId: No UICC");
3747 return null;
3748 }
3749 String iccId = card.getIccId();
3750 if (TextUtils.isEmpty(iccId)) {
3751 loge("getIccId: ICC ID is null or empty.");
3752 return null;
3753 }
3754 return iccId;
3755 }
3756
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07003757 @Override
Jeff Sharkey85190e62014-12-05 09:40:12 -08003758 public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
3759 String number) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003760 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
3761 subId, "setLine1NumberForDisplayForSubscriber");
Derek Tan97ebb422014-09-05 16:55:38 -07003762
Malcolm Chenaabec062018-02-28 15:00:40 -08003763 final long identity = Binder.clearCallingIdentity();
3764 try {
3765 final String iccId = getIccId(subId);
3766 final Phone phone = getPhone(subId);
3767 if (phone == null) {
3768 return false;
3769 }
3770 final String subscriberId = phone.getSubscriberId();
3771
3772 if (DBG_MERGE) {
3773 Slog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId="
3774 + subscriberId + " to " + number);
3775 }
3776
3777 if (TextUtils.isEmpty(iccId)) {
3778 return false;
3779 }
3780
3781 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
3782
3783 final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
3784 if (alphaTag == null) {
3785 editor.remove(alphaTagPrefKey);
3786 } else {
3787 editor.putString(alphaTagPrefKey, alphaTag);
3788 }
3789
3790 // Record both the line number and IMSI for this ICCID, since we need to
3791 // track all merged IMSIs based on line number
3792 final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
3793 final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
3794 if (number == null) {
3795 editor.remove(numberPrefKey);
3796 editor.remove(subscriberPrefKey);
3797 } else {
3798 editor.putString(numberPrefKey, number);
3799 editor.putString(subscriberPrefKey, subscriberId);
3800 }
3801
3802 editor.commit();
3803 return true;
3804 } finally {
3805 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003806 }
Derek Tan7226c842014-07-02 17:42:23 -07003807 }
3808
3809 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07003810 public String getLine1NumberForDisplay(int subId, String callingPackage) {
Makoto Onukifee69342015-06-29 14:44:50 -07003811 // This is open to apps with WRITE_SMS.
Jeff Davidson7e17e312018-02-13 18:17:36 -08003812 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
Jeff Davidson913390f2018-02-23 17:11:49 -08003813 mApp, subId, callingPackage, "getLine1NumberForDisplay")) {
Amit Mahajan9cf11512015-11-09 11:40:48 -08003814 if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
Svet Ganovb320e182015-04-16 12:30:10 -07003815 return null;
3816 }
Derek Tan97ebb422014-09-05 16:55:38 -07003817
Malcolm Chenaabec062018-02-28 15:00:40 -08003818 final long identity = Binder.clearCallingIdentity();
3819 try {
3820 String iccId = getIccId(subId);
3821 if (iccId != null) {
3822 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
3823 if (DBG_MERGE) {
3824 log("getLine1NumberForDisplay returning "
3825 + mTelephonySharedPreferences.getString(numberPrefKey, null));
3826 }
3827 return mTelephonySharedPreferences.getString(numberPrefKey, null);
Amit Mahajan9cf11512015-11-09 11:40:48 -08003828 }
Malcolm Chenaabec062018-02-28 15:00:40 -08003829 if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null");
3830 return null;
3831 } finally {
3832 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07003833 }
Derek Tan7226c842014-07-02 17:42:23 -07003834 }
3835
3836 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07003837 public String getLine1AlphaTagForDisplay(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003838 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003839 mApp, subId, callingPackage, "getLine1AlphaTagForDisplay")) {
Svet Ganovb320e182015-04-16 12:30:10 -07003840 return null;
3841 }
Derek Tan97ebb422014-09-05 16:55:38 -07003842
Malcolm Chenaabec062018-02-28 15:00:40 -08003843 final long identity = Binder.clearCallingIdentity();
3844 try {
3845 String iccId = getIccId(subId);
3846 if (iccId != null) {
3847 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
3848 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null);
3849 }
3850 return null;
3851 } finally {
3852 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07003853 }
Derek Tan7226c842014-07-02 17:42:23 -07003854 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07003855
3856 @Override
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07003857 public String[] getMergedSubscriberIds(String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08003858 // This API isn't public, so no need to provide a valid subscription ID - we're not worried
3859 // about carrier-privileged callers not having access.
Jeff Davidson7e17e312018-02-13 18:17:36 -08003860 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003861 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
3862 "getMergedSubscriberIds")) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07003863 return null;
3864 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08003865
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07003866 final long identity = Binder.clearCallingIdentity();
3867 try {
Malcolm Chenaabec062018-02-28 15:00:40 -08003868 final Context context = mPhone.getContext();
3869 final TelephonyManager tele = TelephonyManager.from(context);
3870 final SubscriptionManager sub = SubscriptionManager.from(context);
3871
3872 // Figure out what subscribers are currently active
3873 final ArraySet<String> activeSubscriberIds = new ArraySet<>();
3874 // Clear calling identity, when calling TelephonyManager, because callerUid must be
3875 // the process, where TelephonyManager was instantiated.
3876 // Otherwise AppOps check will fail.
3877
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07003878 final int[] subIds = sub.getActiveSubscriptionIdList();
3879 for (int subId : subIds) {
3880 activeSubscriberIds.add(tele.getSubscriberId(subId));
3881 }
Malcolm Chenaabec062018-02-28 15:00:40 -08003882
3883 // First pass, find a number override for an active subscriber
3884 String mergeNumber = null;
3885 final Map<String, ?> prefs = mTelephonySharedPreferences.getAll();
3886 for (String key : prefs.keySet()) {
3887 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) {
3888 final String subscriberId = (String) prefs.get(key);
3889 if (activeSubscriberIds.contains(subscriberId)) {
3890 final String iccId = key.substring(
3891 PREF_CARRIERS_SUBSCRIBER_PREFIX.length());
3892 final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
3893 mergeNumber = (String) prefs.get(numberKey);
3894 if (DBG_MERGE) {
3895 Slog.d(LOG_TAG, "Found line number " + mergeNumber
3896 + " for active subscriber " + subscriberId);
3897 }
3898 if (!TextUtils.isEmpty(mergeNumber)) {
3899 break;
3900 }
3901 }
3902 }
3903 }
3904
3905 // Shortcut when no active merged subscribers
3906 if (TextUtils.isEmpty(mergeNumber)) {
3907 return null;
3908 }
3909
3910 // Second pass, find all subscribers under that line override
3911 final ArraySet<String> result = new ArraySet<>();
3912 for (String key : prefs.keySet()) {
3913 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) {
3914 final String number = (String) prefs.get(key);
3915 if (mergeNumber.equals(number)) {
3916 final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length());
3917 final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
3918 final String subscriberId = (String) prefs.get(subscriberKey);
3919 if (!TextUtils.isEmpty(subscriberId)) {
3920 result.add(subscriberId);
3921 }
3922 }
3923 }
3924 }
3925
3926 final String[] resultArray = result.toArray(new String[result.size()]);
3927 Arrays.sort(resultArray);
3928 if (DBG_MERGE) {
3929 Slog.d(LOG_TAG,
3930 "Found subscribers " + Arrays.toString(resultArray) + " after merge");
3931 }
3932 return resultArray;
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07003933 } finally {
3934 Binder.restoreCallingIdentity(identity);
Jeff Sharkey85190e62014-12-05 09:40:12 -08003935 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08003936 }
3937
3938 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003939 public boolean setOperatorBrandOverride(int subId, String brand) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003940 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
3941 subId, "setOperatorBrandOverride");
Malcolm Chenaabec062018-02-28 15:00:40 -08003942
3943 final long identity = Binder.clearCallingIdentity();
3944 try {
3945 final Phone phone = getPhone(subId);
3946 return phone == null ? false : phone.setOperatorBrandOverride(brand);
3947 } finally {
3948 Binder.restoreCallingIdentity(identity);
3949 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07003950 }
Steven Liu4bf01bc2014-07-17 11:05:29 -05003951
3952 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003953 public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
Shishir Agrawal621a47c2014-12-01 10:25:09 -08003954 List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
3955 List<String> cdmaNonRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003956 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setRoamingOverride");
Malcolm Chenaabec062018-02-28 15:00:40 -08003957
3958 final long identity = Binder.clearCallingIdentity();
3959 try {
3960 final Phone phone = getPhone(subId);
3961 if (phone == null) {
3962 return false;
3963 }
3964 return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList,
3965 cdmaNonRoamingList);
3966 } finally {
3967 Binder.restoreCallingIdentity(identity);
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003968 }
Shishir Agrawal621a47c2014-12-01 10:25:09 -08003969 }
3970
3971 @Override
Shuo Qian850e4d6a2018-04-25 21:02:08 +00003972 @Deprecated
3973 public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
3974 enforceModifyPermission();
3975
3976 int returnValue = 0;
3977 try {
vagdevie435a3e2018-08-15 16:01:53 -07003978 AsyncResult result = (AsyncResult) sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
Shuo Qian850e4d6a2018-04-25 21:02:08 +00003979 if(result.exception == null) {
3980 if (result.result != null) {
3981 byte[] responseData = (byte[])(result.result);
3982 if(responseData.length > oemResp.length) {
3983 Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +
3984 responseData.length + "bytes. Buffer Size is " +
3985 oemResp.length + "bytes.");
3986 }
3987 System.arraycopy(responseData, 0, oemResp, 0, responseData.length);
3988 returnValue = responseData.length;
3989 }
3990 } else {
3991 CommandException ex = (CommandException) result.exception;
3992 returnValue = ex.getCommandError().ordinal();
3993 if(returnValue > 0) returnValue *= -1;
3994 }
3995 } catch (RuntimeException e) {
3996 Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");
3997 returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());
3998 if(returnValue > 0) returnValue *= -1;
3999 }
4000
4001 return returnValue;
4002 }
4003
4004 @Override
Wink Saville5d475dd2014-10-17 15:00:58 -07004005 public void setRadioCapability(RadioAccessFamily[] rafs) {
4006 try {
4007 ProxyController.getInstance().setRadioCapability(rafs);
4008 } catch (RuntimeException e) {
4009 Log.w(LOG_TAG, "setRadioCapability: Runtime Exception");
4010 }
4011 }
4012
4013 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004014 public int getRadioAccessFamily(int phoneId, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08004015 Phone phone = PhoneFactory.getPhone(phoneId);
4016 if (phone == null) {
4017 return RadioAccessFamily.RAF_UNKNOWN;
4018 }
4019 int subId = phone.getSubId();
Jeff Davidson7e17e312018-02-13 18:17:36 -08004020 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08004021 mApp, subId, callingPackage, "getRadioAccessFamily")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004022 return RadioAccessFamily.RAF_UNKNOWN;
4023 }
4024
Malcolm Chenaabec062018-02-28 15:00:40 -08004025 final long identity = Binder.clearCallingIdentity();
4026 try {
4027 return ProxyController.getInstance().getRadioAccessFamily(phoneId);
4028 } finally {
4029 Binder.restoreCallingIdentity(identity);
4030 }
Wink Saville5d475dd2014-10-17 15:00:58 -07004031 }
Andrew Leedf14ead2014-10-17 14:22:52 -07004032
4033 @Override
4034 public void enableVideoCalling(boolean enable) {
4035 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08004036
4037 final long identity = Binder.clearCallingIdentity();
4038 try {
4039 ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId()).setVtSetting(enable);
4040 } finally {
4041 Binder.restoreCallingIdentity(identity);
4042 }
Andrew Leedf14ead2014-10-17 14:22:52 -07004043 }
4044
4045 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004046 public boolean isVideoCallingEnabled(String callingPackage) {
Amit Mahajan578e53d2018-03-20 16:18:38 +00004047 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4048 mApp, mPhone.getSubId(), callingPackage, "isVideoCallingEnabled")) {
4049 return false;
4050 }
Svet Ganovb320e182015-04-16 12:30:10 -07004051
Malcolm Chenaabec062018-02-28 15:00:40 -08004052 final long identity = Binder.clearCallingIdentity();
4053 try {
4054 // Check the user preference and the system-level IMS setting. Even if the user has
4055 // enabled video calling, if IMS is disabled we aren't able to support video calling.
4056 // In the long run, we may instead need to check if there exists a connection service
4057 // which can support video calling.
4058 ImsManager imsManager =
4059 ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId());
4060 return imsManager.isVtEnabledByPlatform()
4061 && imsManager.isEnhanced4gLteModeSettingEnabledByUser()
4062 && imsManager.isVtEnabledByUser();
4063 } finally {
4064 Binder.restoreCallingIdentity(identity);
4065 }
Andrew Leedf14ead2014-10-17 14:22:52 -07004066 }
Libin.Tang@motorola.comafe82642014-12-18 13:27:53 -06004067
Andrew Leea1239f22015-03-02 17:44:07 -08004068 @Override
Malcolm Chenaabec062018-02-28 15:00:40 -08004069 public boolean canChangeDtmfToneLength(int subId, String callingPackage) {
4070 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4071 mApp, subId, callingPackage, "isVideoCallingEnabled")) {
4072 return false;
4073 }
4074
4075 final long identity = Binder.clearCallingIdentity();
4076 try {
4077 CarrierConfigManager configManager =
4078 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
4079 return configManager.getConfigForSubId(mPhone.getSubId())
4080 .getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL);
4081 } finally {
4082 Binder.restoreCallingIdentity(identity);
4083 }
Andrew Leea1239f22015-03-02 17:44:07 -08004084 }
4085
4086 @Override
Malcolm Chenaabec062018-02-28 15:00:40 -08004087 public boolean isWorldPhone(int subId, String callingPackage) {
4088 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4089 mApp, subId, callingPackage, "isVideoCallingEnabled")) {
4090 return false;
4091 }
4092
4093 final long identity = Binder.clearCallingIdentity();
4094 try {
4095 CarrierConfigManager configManager =
4096 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
4097 return configManager.getConfigForSubId(mPhone.getSubId())
4098 .getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL);
4099 } finally {
4100 Binder.restoreCallingIdentity(identity);
4101 }
Andrew Leea1239f22015-03-02 17:44:07 -08004102 }
4103
Andrew Lee9431b832015-03-09 18:46:45 -07004104 @Override
4105 public boolean isTtyModeSupported() {
4106 TelecomManager telecomManager = TelecomManager.from(mPhone.getContext());
Wooki Wu1f82f7a2016-02-15 15:59:58 +08004107 return telecomManager.isTtySupported();
Andrew Lee9431b832015-03-09 18:46:45 -07004108 }
4109
4110 @Override
4111 public boolean isHearingAidCompatibilitySupported() {
Malcolm Chenaabec062018-02-28 15:00:40 -08004112 final long identity = Binder.clearCallingIdentity();
4113 try {
4114 return mPhone.getContext().getResources().getBoolean(R.bool.hac_enabled);
4115 } finally {
4116 Binder.restoreCallingIdentity(identity);
4117 }
Andrew Lee9431b832015-03-09 18:46:45 -07004118 }
4119
Hall Liu98187582018-01-22 19:15:32 -08004120 public boolean isRttSupported() {
Malcolm Chenaabec062018-02-28 15:00:40 -08004121 final long identity = Binder.clearCallingIdentity();
4122 try {
4123 boolean isCarrierSupported = mApp.getCarrierConfigForSubId(
4124 mPhone.getSubId()).getBoolean(
4125 CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
4126 boolean isDeviceSupported =
4127 mPhone.getContext().getResources().getBoolean(R.bool.config_support_rtt);
4128 return isCarrierSupported && isDeviceSupported;
4129 } finally {
4130 Binder.restoreCallingIdentity(identity);
4131 }
Hall Liu98187582018-01-22 19:15:32 -08004132 }
4133
Hall Liu3ad5f012018-04-06 16:23:39 -07004134 public boolean isRttEnabled() {
Malcolm Chenaabec062018-02-28 15:00:40 -08004135 final long identity = Binder.clearCallingIdentity();
4136 try {
4137 return isRttSupported() && Settings.Secure.getInt(
4138 mPhone.getContext().getContentResolver(),
4139 Settings.Secure.RTT_CALLING_MODE, 0) != 0;
4140 } finally {
4141 Binder.restoreCallingIdentity(identity);
4142 }
Hall Liu3ad5f012018-04-06 16:23:39 -07004143 }
4144
Sanket Padawe7310cc72015-01-14 09:53:20 -08004145 /**
4146 * Returns the unique device ID of phone, for example, the IMEI for
4147 * GSM and the MEID for CDMA phones. Return null if device ID is not available.
4148 *
4149 * <p>Requires Permission:
4150 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
4151 */
4152 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004153 public String getDeviceId(String callingPackage) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08004154 final Phone phone = PhoneFactory.getPhone(0);
Jeff Davidson913390f2018-02-23 17:11:49 -08004155 if (phone == null) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08004156 return null;
4157 }
Jeff Davidson913390f2018-02-23 17:11:49 -08004158 int subId = phone.getSubId();
4159 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4160 mApp, subId, callingPackage, "getDeviceId")) {
4161 return null;
4162 }
Malcolm Chenaabec062018-02-28 15:00:40 -08004163
4164 final long identity = Binder.clearCallingIdentity();
4165 try {
4166 return phone.getDeviceId();
4167 } finally {
4168 Binder.restoreCallingIdentity(identity);
4169 }
Sanket Padawe7310cc72015-01-14 09:53:20 -08004170 }
4171
Ping Sunc67b7c22016-03-02 19:16:45 +08004172 /**
4173 * {@hide}
4174 * Returns the IMS Registration Status on a particular subid
4175 *
4176 * @param subId
4177 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004178 public boolean isImsRegistered(int subId) {
Ping Sunc67b7c22016-03-02 19:16:45 +08004179 Phone phone = getPhone(subId);
4180 if (phone != null) {
4181 return phone.isImsRegistered();
4182 } else {
4183 return false;
4184 }
4185 }
4186
Santos Cordon7a1885b2015-02-03 11:15:19 -08004187 @Override
4188 public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004189 final long identity = Binder.clearCallingIdentity();
4190 try {
4191 return PhoneUtils.getSubIdForPhoneAccount(phoneAccount);
4192 } finally {
4193 Binder.restoreCallingIdentity(identity);
4194 }
Santos Cordon7a1885b2015-02-03 11:15:19 -08004195 }
Nathan Harolddcfc7932015-03-18 10:01:20 -07004196
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004197 /**
4198 * @return the VoWiFi calling availability.
Nathan Haroldc55097a2015-03-11 18:14:50 -07004199 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004200 public boolean isWifiCallingAvailable(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004201 final long identity = Binder.clearCallingIdentity();
4202 try {
4203 Phone phone = getPhone(subId);
4204 if (phone != null) {
4205 return phone.isWifiCallingEnabled();
4206 } else {
4207 return false;
4208 }
4209 } finally {
4210 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004211 }
Nathan Haroldc55097a2015-03-11 18:14:50 -07004212 }
4213
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004214 /**
4215 * @return the VoLTE availability.
Nathan Haroldc55097a2015-03-11 18:14:50 -07004216 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004217 public boolean isVolteAvailable(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004218 final long identity = Binder.clearCallingIdentity();
4219 try {
4220 Phone phone = getPhone(subId);
4221 if (phone != null) {
4222 return phone.isVolteEnabled();
4223 } else {
4224 return false;
4225 }
4226 } finally {
4227 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004228 }
Nathan Haroldc55097a2015-03-11 18:14:50 -07004229 }
Svet Ganovb320e182015-04-16 12:30:10 -07004230
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004231 /**
4232 * @return the VT calling availability.
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07004233 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004234 public boolean isVideoTelephonyAvailable(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004235 final long identity = Binder.clearCallingIdentity();
4236 try {
4237 Phone phone = getPhone(subId);
4238 if (phone != null) {
4239 return phone.isVideoEnabled();
4240 } else {
4241 return false;
4242 }
4243 } finally {
4244 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004245 }
4246 }
4247
4248 /**
4249 * @return the IMS registration technology for the MMTEL feature. Valid return values are
4250 * defined in {@link ImsRegistrationImplBase}.
4251 */
4252 public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004253 final long identity = Binder.clearCallingIdentity();
4254 try {
4255 Phone phone = getPhone(subId);
4256 if (phone != null) {
4257 return phone.getImsRegistrationTech();
4258 } else {
4259 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
4260 }
4261 } finally {
4262 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004263 }
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07004264 }
4265
Stuart Scott8eef64f2015-04-08 15:13:54 -07004266 @Override
4267 public void factoryReset(int subId) {
4268 enforceConnectivityInternalPermission();
Stuart Scott981d8582015-04-21 14:09:50 -07004269 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
4270 return;
4271 }
4272
Svet Ganovcc087f82015-05-12 20:35:54 -07004273 final long identity = Binder.clearCallingIdentity();
4274 try {
Stuart Scott981d8582015-04-21 14:09:50 -07004275 if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
4276 UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
Pengquan Meng85728fb2018-03-12 16:31:21 -07004277 setUserDataEnabled(subId, getDefaultDataEnabled());
Svet Ganovcc087f82015-05-12 20:35:54 -07004278 setNetworkSelectionModeAutomatic(subId);
Pengquan Meng85728fb2018-03-12 16:31:21 -07004279 setPreferredNetworkType(subId, getDefaultNetworkType(subId));
4280 mPhone.setDataRoamingEnabled(getDefaultDataRoamingEnabled(subId));
pkanwar79ec0542017-07-31 14:10:01 -07004281 CarrierInfoManager.deleteAllCarrierKeysForImsiEncryption(mPhone.getContext());
Svet Ganovcc087f82015-05-12 20:35:54 -07004282 }
4283 } finally {
4284 Binder.restoreCallingIdentity(identity);
Stuart Scott8eef64f2015-04-08 15:13:54 -07004285 }
4286 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004287
4288 @Override
4289 public String getLocaleFromDefaultSim() {
Malcolm Chenaabec062018-02-28 15:00:40 -08004290 final long identity = Binder.clearCallingIdentity();
4291 try {
4292 // We query all subscriptions instead of just the active ones, because
4293 // this might be called early on in the provisioning flow when the
4294 // subscriptions potentially aren't active yet.
4295 final List<SubscriptionInfo> slist = getAllSubscriptionInfoList();
4296 if (slist == null || slist.isEmpty()) {
Narayan Kamath1c496c22015-04-16 14:40:19 +01004297 return null;
4298 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004299
Malcolm Chenaabec062018-02-28 15:00:40 -08004300 // This function may be called very early, say, from the setup wizard, at
4301 // which point we won't have a default subscription set. If that's the case
4302 // we just choose the first, which will be valid in "most cases".
4303 final int defaultSubId = getDefaultSubscription();
4304 SubscriptionInfo info = null;
4305 if (defaultSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
4306 info = slist.get(0);
4307 } else {
4308 for (SubscriptionInfo item : slist) {
4309 if (item.getSubscriptionId() == defaultSubId) {
4310 info = item;
4311 break;
4312 }
4313 }
4314
4315 if (info == null) {
4316 return null;
Tony Hill183b2de2015-06-24 14:53:58 +01004317 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004318 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004319
Malcolm Chenaabec062018-02-28 15:00:40 -08004320 // Try and fetch the locale from the carrier properties or from the SIM language
4321 // preferences (EF-PL and EF-LI)...
4322 final int mcc = info.getMcc();
4323 final Phone defaultPhone = getPhone(info.getSubscriptionId());
4324 String simLanguage = null;
4325 if (defaultPhone != null) {
4326 final Locale localeFromDefaultSim = defaultPhone.getLocaleFromSimAndCarrierPrefs();
4327 if (localeFromDefaultSim != null) {
4328 if (!localeFromDefaultSim.getCountry().isEmpty()) {
4329 if (DBG) log("Using locale from default SIM:" + localeFromDefaultSim);
4330 return localeFromDefaultSim.toLanguageTag();
4331 } else {
4332 simLanguage = localeFromDefaultSim.getLanguage();
4333 }
4334 }
4335 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004336
Malcolm Chenaabec062018-02-28 15:00:40 -08004337 // The SIM language preferences only store a language (e.g. fr = French), not an
4338 // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
4339 // the SIM and carrier preferences does not include a country we add the country
4340 // determined from the SIM MCC to provide an exact locale.
4341 final Locale mccLocale = MccTable.getLocaleFromMcc(mPhone.getContext(), mcc,
4342 simLanguage);
4343 if (mccLocale != null) {
4344 if (DBG) log("No locale from default SIM, using mcc locale:" + mccLocale);
4345 return mccLocale.toLanguageTag();
4346 }
4347
4348 if (DBG) log("No locale found - returning null");
4349 return null;
4350 } finally {
4351 Binder.restoreCallingIdentity(identity);
4352 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004353 }
4354
4355 private List<SubscriptionInfo> getAllSubscriptionInfoList() {
Malcolm Chenaabec062018-02-28 15:00:40 -08004356 return mSubscriptionController.getAllSubInfoList(
4357 mPhone.getContext().getOpPackageName());
Narayan Kamath1c496c22015-04-16 14:40:19 +01004358 }
4359
Malcolm Chenaabec062018-02-28 15:00:40 -08004360 /**
4361 * NOTE: this method assumes permission checks are done and caller identity has been cleared.
4362 */
4363 private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
4364 return mSubscriptionController.getActiveSubscriptionInfoList(
4365 mPhone.getContext().getOpPackageName());
Narayan Kamath1c496c22015-04-16 14:40:19 +01004366 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004367
Chenjie Yu1ba97252018-01-11 18:16:20 -08004368 private final ModemActivityInfo mLastModemActivityInfo =
4369 new ModemActivityInfo(0, 0, 0, new int[0], 0, 0);
4370
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004371 /**
Adam Lesinski903a54c2016-04-11 14:49:52 -07004372 * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
4373 * representing the state of the modem.
4374 *
Chenjie Yu1ba97252018-01-11 18:16:20 -08004375 * NOTE: The underlying implementation clears the modem state, so there should only ever be one
4376 * caller to it. Everyone should call this class to get cumulative data.
Adam Lesinski903a54c2016-04-11 14:49:52 -07004377 * @hide
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004378 */
4379 @Override
Adam Lesinski903a54c2016-04-11 14:49:52 -07004380 public void requestModemActivityInfo(ResultReceiver result) {
4381 enforceModifyPermission();
Chenjie Yu1ba97252018-01-11 18:16:20 -08004382 ModemActivityInfo ret = null;
vagdevie435a3e2018-08-15 16:01:53 -07004383 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Adam Lesinski903a54c2016-04-11 14:49:52 -07004384
Malcolm Chenaabec062018-02-28 15:00:40 -08004385 final long identity = Binder.clearCallingIdentity();
4386 try {
Malcolm Chen1cc36b62018-07-30 14:42:47 -07004387 synchronized (mLastModemActivityInfo) {
vagdevie435a3e2018-08-15 16:01:53 -07004388 ModemActivityInfo info = (ModemActivityInfo) sendRequest(
4389 CMD_GET_MODEM_ACTIVITY_INFO,
4390 null, workSource);
Siddharth Rayc339f892018-06-17 15:02:38 -07004391 if (isModemActivityInfoValid(info)) {
Malcolm Chen1cc36b62018-07-30 14:42:47 -07004392 int[] mergedTxTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
4393 for (int i = 0; i < mergedTxTimeMs.length; i++) {
4394 mergedTxTimeMs[i] =
4395 info.getTxTimeMillis()[i] + mLastModemActivityInfo.getTxTimeMillis()[i];
4396 }
4397 mLastModemActivityInfo.setTimestamp(info.getTimestamp());
4398 mLastModemActivityInfo.setSleepTimeMillis(
4399 info.getSleepTimeMillis() + mLastModemActivityInfo.getSleepTimeMillis());
4400 mLastModemActivityInfo.setIdleTimeMillis(
4401 info.getIdleTimeMillis() + mLastModemActivityInfo.getIdleTimeMillis());
4402 mLastModemActivityInfo.setTxTimeMillis(mergedTxTimeMs);
4403 mLastModemActivityInfo.setRxTimeMillis(
4404 info.getRxTimeMillis() + mLastModemActivityInfo.getRxTimeMillis());
4405 mLastModemActivityInfo.setEnergyUsed(
4406 info.getEnergyUsed() + mLastModemActivityInfo.getEnergyUsed());
Chenjie Yu1ba97252018-01-11 18:16:20 -08004407 }
Malcolm Chen1cc36b62018-07-30 14:42:47 -07004408 ret = new ModemActivityInfo(mLastModemActivityInfo.getTimestamp(),
4409 mLastModemActivityInfo.getSleepTimeMillis(),
4410 mLastModemActivityInfo.getIdleTimeMillis(),
4411 mLastModemActivityInfo.getTxTimeMillis(),
4412 mLastModemActivityInfo.getRxTimeMillis(),
4413 mLastModemActivityInfo.getEnergyUsed());
Chenjie Yu1ba97252018-01-11 18:16:20 -08004414 }
Malcolm Chenaabec062018-02-28 15:00:40 -08004415 Bundle bundle = new Bundle();
Malcolm Chen1cc36b62018-07-30 14:42:47 -07004416 bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, ret);
Malcolm Chenaabec062018-02-28 15:00:40 -08004417 result.send(0, bundle);
4418 } finally {
4419 Binder.restoreCallingIdentity(identity);
Chenjie Yu1ba97252018-01-11 18:16:20 -08004420 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004421 }
Jack Yu85bd38a2015-11-09 11:34:32 -08004422
Siddharth Rayc339f892018-06-17 15:02:38 -07004423 // Checks that ModemActivityInfo is valid. Sleep time, Idle time, Rx time and Tx time should be
4424 // less than total activity duration.
4425 private boolean isModemActivityInfoValid(ModemActivityInfo info) {
4426 if (info == null) {
4427 return false;
4428 }
4429 int activityDurationMs =
4430 (int) (info.getTimestamp() - mLastModemActivityInfo.getTimestamp());
4431 int totalTxTimeMs = 0;
4432 for (int i = 0; i < info.getTxTimeMillis().length; i++) {
4433 totalTxTimeMs += info.getTxTimeMillis()[i];
4434 }
4435 return (info.isValid()
4436 && (info.getSleepTimeMillis() <= activityDurationMs)
4437 && (info.getIdleTimeMillis() <= activityDurationMs)
4438 && (info.getRxTimeMillis() <= activityDurationMs)
4439 && (totalTxTimeMs <= activityDurationMs));
4440 }
4441
Jack Yu85bd38a2015-11-09 11:34:32 -08004442 /**
4443 * {@hide}
4444 * Returns the service state information on specified subscription.
4445 */
4446 @Override
4447 public ServiceState getServiceStateForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004448 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08004449 mApp, subId, callingPackage, "getServiceStateForSubscriber")) {
Jack Yu85bd38a2015-11-09 11:34:32 -08004450 return null;
4451 }
4452
Malcolm Chenaabec062018-02-28 15:00:40 -08004453 final long identity = Binder.clearCallingIdentity();
4454 try {
4455 final Phone phone = getPhone(subId);
4456 if (phone == null) {
4457 return null;
4458 }
Jack Yu85bd38a2015-11-09 11:34:32 -08004459
Malcolm Chenaabec062018-02-28 15:00:40 -08004460 return phone.getServiceState();
4461 } finally {
4462 Binder.restoreCallingIdentity(identity);
4463 }
Jack Yu85bd38a2015-11-09 11:34:32 -08004464 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004465
4466 /**
4467 * Returns the URI for the per-account voicemail ringtone set in Phone settings.
4468 *
4469 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
4470 * voicemail ringtone.
4471 * @return The URI for the ringtone to play when receiving a voicemail from a specific
4472 * PhoneAccount.
4473 */
4474 @Override
4475 public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004476 final long identity = Binder.clearCallingIdentity();
4477 try {
4478 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
4479 if (phone == null) {
4480 phone = mPhone;
4481 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004482
Malcolm Chenaabec062018-02-28 15:00:40 -08004483 return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext());
4484 } finally {
4485 Binder.restoreCallingIdentity(identity);
4486 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004487 }
4488
4489 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004490 * Sets the per-account voicemail ringtone.
4491 *
4492 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
4493 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
4494 *
4495 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
4496 * voicemail ringtone.
4497 * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
4498 * PhoneAccount.
4499 */
4500 @Override
4501 public void setVoicemailRingtoneUri(String callingPackage,
4502 PhoneAccountHandle phoneAccountHandle, Uri uri) {
4503 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4504 if (!TextUtils.equals(callingPackage,
4505 TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004506 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4507 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
4508 "setVoicemailRingtoneUri");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004509 }
Malcolm Chenaabec062018-02-28 15:00:40 -08004510
4511 final long identity = Binder.clearCallingIdentity();
4512 try {
4513 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
4514 if (phone == null) {
4515 phone = mPhone;
4516 }
4517 VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri);
4518 } finally {
4519 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004520 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004521 }
4522
4523 /**
Nancy Chen31f9ba12016-01-06 11:42:12 -08004524 * Returns whether vibration is set for voicemail notification in Phone settings.
4525 *
4526 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
4527 * voicemail vibration setting.
4528 * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
4529 */
4530 @Override
4531 public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004532 final long identity = Binder.clearCallingIdentity();
4533 try {
4534 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
4535 if (phone == null) {
4536 phone = mPhone;
4537 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004538
Malcolm Chenaabec062018-02-28 15:00:40 -08004539 return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext());
4540 } finally {
4541 Binder.restoreCallingIdentity(identity);
4542 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004543 }
4544
Youhan Wange64578a2016-05-02 15:32:42 -07004545 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004546 * Sets the per-account voicemail vibration.
4547 *
4548 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
4549 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
4550 *
4551 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
4552 * voicemail vibration setting.
4553 * @param enabled Whether to enable or disable vibration for voicemail notifications from a
4554 * specific PhoneAccount.
4555 */
4556 @Override
4557 public void setVoicemailVibrationEnabled(String callingPackage,
4558 PhoneAccountHandle phoneAccountHandle, boolean enabled) {
4559 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4560 if (!TextUtils.equals(callingPackage,
4561 TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004562 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4563 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
4564 "setVoicemailVibrationEnabled");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004565 }
4566
Malcolm Chenaabec062018-02-28 15:00:40 -08004567 final long identity = Binder.clearCallingIdentity();
4568 try {
4569 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
4570 if (phone == null) {
4571 phone = mPhone;
4572 }
4573 VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled);
4574 } finally {
4575 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004576 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004577 }
4578
4579 /**
Youhan Wange64578a2016-05-02 15:32:42 -07004580 * Make sure either called from same process as self (phone) or IPC caller has read privilege.
4581 *
4582 * @throws SecurityException if the caller does not have the required permission
4583 */
4584 private void enforceReadPrivilegedPermission() {
4585 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
4586 null);
4587 }
4588
4589 /**
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004590 * Make sure either called from same process as self (phone) or IPC caller has send SMS
4591 * permission.
4592 *
4593 * @throws SecurityException if the caller does not have the required permission
4594 */
4595 private void enforceSendSmsPermission() {
4596 mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null);
4597 }
4598
4599 /**
Ta-wei Yen527a9c02017-01-06 15:29:25 -08004600 * Make sure called from the package in charge of visual voicemail.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004601 *
Ta-wei Yen527a9c02017-01-06 15:29:25 -08004602 * @throws SecurityException if the caller is not the visual voicemail package.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004603 */
Ta-wei Yen527a9c02017-01-06 15:29:25 -08004604 private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004605 final long identity = Binder.clearCallingIdentity();
4606 try {
4607 ComponentName componentName =
4608 RemoteVvmTaskManager.getRemotePackage(mPhone.getContext(), subId);
4609 if (componentName == null) {
4610 throw new SecurityException(
4611 "Caller not current active visual voicemail package[null]");
4612 }
4613 String vvmPackage = componentName.getPackageName();
4614 if (!callingPackage.equals(vvmPackage)) {
4615 throw new SecurityException("Caller not current active visual voicemail package["
4616 + vvmPackage + "]");
4617 }
4618 } finally {
4619 Binder.restoreCallingIdentity(identity);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004620 }
4621 }
4622
4623 /**
Youhan Wange64578a2016-05-02 15:32:42 -07004624 * Return the application ID for the app type.
4625 *
4626 * @param subId the subscription ID that this request applies to.
4627 * @param appType the uicc app type.
4628 * @return Application ID for specificied app type, or null if no uicc.
4629 */
4630 @Override
4631 public String getAidForAppType(int subId, int appType) {
4632 enforceReadPrivilegedPermission();
4633 Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08004634
4635 final long identity = Binder.clearCallingIdentity();
Youhan Wange64578a2016-05-02 15:32:42 -07004636 try {
Malcolm Chenaabec062018-02-28 15:00:40 -08004637 if (phone == null) {
4638 return null;
4639 }
4640 String aid = null;
4641 try {
4642 aid = UiccController.getInstance().getUiccCard(phone.getPhoneId())
4643 .getApplicationByType(appType).getAid();
4644 } catch (Exception e) {
4645 Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e);
4646 }
4647 return aid;
4648 } finally {
4649 Binder.restoreCallingIdentity(identity);
Youhan Wange64578a2016-05-02 15:32:42 -07004650 }
Youhan Wange64578a2016-05-02 15:32:42 -07004651 }
4652
Youhan Wang4001d252016-05-11 10:29:41 -07004653 /**
4654 * Return the Electronic Serial Number.
4655 *
4656 * @param subId the subscription ID that this request applies to.
4657 * @return ESN or null if error.
4658 */
4659 @Override
4660 public String getEsn(int subId) {
4661 enforceReadPrivilegedPermission();
4662 Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08004663
4664 final long identity = Binder.clearCallingIdentity();
Youhan Wang4001d252016-05-11 10:29:41 -07004665 try {
Malcolm Chenaabec062018-02-28 15:00:40 -08004666 if (phone == null) {
4667 return null;
4668 }
4669 String esn = null;
4670 try {
4671 esn = phone.getEsn();
4672 } catch (Exception e) {
4673 Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e);
4674 }
4675 return esn;
4676 } finally {
4677 Binder.restoreCallingIdentity(identity);
Youhan Wang4001d252016-05-11 10:29:41 -07004678 }
Youhan Wang4001d252016-05-11 10:29:41 -07004679 }
4680
Sanket Padawe99ef1e32016-05-18 16:12:33 -07004681 /**
Youhan Wang66ad5d72016-07-18 17:56:58 -07004682 * Return the Preferred Roaming List Version.
4683 *
4684 * @param subId the subscription ID that this request applies to.
4685 * @return PRLVersion or null if error.
4686 */
4687 @Override
4688 public String getCdmaPrlVersion(int subId) {
4689 enforceReadPrivilegedPermission();
4690 Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08004691
4692 final long identity = Binder.clearCallingIdentity();
Youhan Wang66ad5d72016-07-18 17:56:58 -07004693 try {
Malcolm Chenaabec062018-02-28 15:00:40 -08004694 if (phone == null) {
4695 return null;
4696 }
4697 String cdmaPrlVersion = null;
4698 try {
4699 cdmaPrlVersion = phone.getCdmaPrlVersion();
4700 } catch (Exception e) {
4701 Log.e(LOG_TAG, "Not getting PRLVersion", e);
4702 }
4703 return cdmaPrlVersion;
4704 } finally {
4705 Binder.restoreCallingIdentity(identity);
Youhan Wang66ad5d72016-07-18 17:56:58 -07004706 }
Youhan Wang66ad5d72016-07-18 17:56:58 -07004707 }
4708
4709 /**
Sanket Padawe99ef1e32016-05-18 16:12:33 -07004710 * Get snapshot of Telephony histograms
4711 * @return List of Telephony histograms
4712 * @hide
4713 */
4714 @Override
4715 public List<TelephonyHistogram> getTelephonyHistograms() {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004716 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4717 mApp, getDefaultSubscription(), "getTelephonyHistograms");
Malcolm Chenaabec062018-02-28 15:00:40 -08004718
4719 final long identity = Binder.clearCallingIdentity();
4720 try {
4721 return RIL.getTelephonyRILTimingHistograms();
4722 } finally {
4723 Binder.restoreCallingIdentity(identity);
4724 }
Sanket Padawe99ef1e32016-05-18 16:12:33 -07004725 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07004726
4727 /**
4728 * {@hide}
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004729 * Set the allowed carrier list for slotIndex
Meng Wang1a7c35a2016-05-05 20:56:15 -07004730 * Require system privileges. In the future we may add this to carrier APIs.
4731 *
4732 * @return The number of carriers set successfully, should match length of carriers
4733 */
4734 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004735 public int setAllowedCarriers(int slotIndex, List<CarrierIdentifier> carriers) {
Meng Wang1a7c35a2016-05-05 20:56:15 -07004736 enforceModifyPermission();
vagdevie435a3e2018-08-15 16:01:53 -07004737 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004738
Meng Wang9b7c4e92017-02-17 11:41:27 -08004739 if (carriers == null) {
4740 throw new NullPointerException("carriers cannot be null");
4741 }
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004742
Malcolm Chenaabec062018-02-28 15:00:40 -08004743 final long identity = Binder.clearCallingIdentity();
4744 try {
4745 int subId = SubscriptionManager.getSubId(slotIndex)[0];
vagdevie435a3e2018-08-15 16:01:53 -07004746 int[] retVal = (int[]) sendRequest(CMD_SET_ALLOWED_CARRIERS, carriers, subId,
4747 workSource);
Malcolm Chenaabec062018-02-28 15:00:40 -08004748 return retVal[0];
4749 } finally {
4750 Binder.restoreCallingIdentity(identity);
4751 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07004752 }
4753
4754 /**
4755 * {@hide}
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004756 * Get the allowed carrier list for slotIndex.
Meng Wang1a7c35a2016-05-05 20:56:15 -07004757 * Require system privileges. In the future we may add this to carrier APIs.
4758 *
4759 * @return List of {@link android.service.telephony.CarrierIdentifier}; empty list
4760 * means all carriers are allowed.
4761 */
4762 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004763 public List<CarrierIdentifier> getAllowedCarriers(int slotIndex) {
Meng Wang1a7c35a2016-05-05 20:56:15 -07004764 enforceReadPrivilegedPermission();
vagdevie435a3e2018-08-15 16:01:53 -07004765 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaabec062018-02-28 15:00:40 -08004766
4767 final long identity = Binder.clearCallingIdentity();
4768 try {
4769 int subId = SubscriptionManager.getSubId(slotIndex)[0];
vagdevie435a3e2018-08-15 16:01:53 -07004770 return (List<CarrierIdentifier>) sendRequest(CMD_GET_ALLOWED_CARRIERS, null, subId,
4771 workSource);
Malcolm Chenaabec062018-02-28 15:00:40 -08004772 } finally {
4773 Binder.restoreCallingIdentity(identity);
4774 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07004775 }
4776
fionaxu59545b42016-05-25 15:53:37 -07004777 /**
4778 * Action set from carrier signalling broadcast receivers to enable/disable metered apns
4779 * @param subId the subscription ID that this action applies to.
4780 * @param enabled control enable or disable metered apns.
4781 * {@hide}
4782 */
4783 @Override
4784 public void carrierActionSetMeteredApnsEnabled(int subId, boolean enabled) {
4785 enforceModifyPermission();
4786 final Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08004787
4788 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07004789 if (phone == null) {
4790 loge("carrierAction: SetMeteredApnsEnabled fails with invalid subId: " + subId);
4791 return;
4792 }
4793 try {
4794 phone.carrierActionSetMeteredApnsEnabled(enabled);
4795 } catch (Exception e) {
4796 Log.e(LOG_TAG, "carrierAction: SetMeteredApnsEnabled fails. Exception ex=" + e);
Malcolm Chenaabec062018-02-28 15:00:40 -08004797 } finally {
4798 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07004799 }
4800 }
4801
4802 /**
4803 * Action set from carrier signalling broadcast receivers to enable/disable radio
4804 * @param subId the subscription ID that this action applies to.
4805 * @param enabled control enable or disable radio.
4806 * {@hide}
4807 */
4808 @Override
4809 public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
4810 enforceModifyPermission();
4811 final Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08004812
4813 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07004814 if (phone == null) {
4815 loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
4816 return;
4817 }
4818 try {
4819 phone.carrierActionSetRadioEnabled(enabled);
4820 } catch (Exception e) {
4821 Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
Malcolm Chenaabec062018-02-28 15:00:40 -08004822 } finally {
4823 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07004824 }
4825 }
4826
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07004827 /**
fionaxu8da9cb12017-05-23 15:02:46 -07004828 * Action set from carrier signalling broadcast receivers to start/stop reporting the default
4829 * network status based on which carrier apps could apply actions accordingly,
4830 * enable/disable default url handler for example.
4831 *
4832 * @param subId the subscription ID that this action applies to.
4833 * @param report control start/stop reporting the default network status.
4834 * {@hide}
4835 */
4836 @Override
4837 public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
4838 enforceModifyPermission();
4839 final Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08004840
4841 final long identity = Binder.clearCallingIdentity();
fionaxu8da9cb12017-05-23 15:02:46 -07004842 if (phone == null) {
4843 loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId);
4844 return;
4845 }
4846 try {
4847 phone.carrierActionReportDefaultNetworkStatus(report);
4848 } catch (Exception e) {
4849 Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e);
Malcolm Chenaabec062018-02-28 15:00:40 -08004850 } finally {
4851 Binder.restoreCallingIdentity(identity);
fionaxu8da9cb12017-05-23 15:02:46 -07004852 }
4853 }
4854
4855 /**
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07004856 * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a
4857 * bug report is being generated.
4858 */
4859 @Override
Ta-wei Yen99282e02016-06-21 18:19:35 -07004860 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
dcashman22b950d2016-06-27 11:39:02 -07004861 if (mPhone.getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
4862 != PackageManager.PERMISSION_GRANTED) {
4863 writer.println("Permission Denial: can't dump Phone from pid="
4864 + Binder.getCallingPid()
4865 + ", uid=" + Binder.getCallingUid()
4866 + "without permission "
4867 + android.Manifest.permission.DUMP);
4868 return;
4869 }
Ta-wei Yen99282e02016-06-21 18:19:35 -07004870 DumpsysHandler.dump(mPhone.getContext(), fd, writer, args);
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07004871 }
Jack Yueb89b242016-06-22 13:27:47 -07004872
Brad Ebingerdac2f002018-04-03 15:17:52 -07004873 @Override
4874 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
4875 String[] args, ShellCallback callback, ResultReceiver resultReceiver)
4876 throws RemoteException {
4877 (new TelephonyShellCommand(this)).exec(this, in, out, err, args, callback, resultReceiver);
4878 }
4879
Jack Yueb89b242016-06-22 13:27:47 -07004880 /**
Jack Yu84291ec2017-05-26 16:07:50 -07004881 * Get aggregated video call data usage since boot.
4882 *
4883 * @param perUidStats True if requesting data usage per uid, otherwise overall usage.
4884 * @return Snapshot of video call data usage
Jack Yueb89b242016-06-22 13:27:47 -07004885 * {@hide}
4886 */
4887 @Override
Jack Yu84291ec2017-05-26 16:07:50 -07004888 public NetworkStats getVtDataUsage(int subId, boolean perUidStats) {
Jack Yueb89b242016-06-22 13:27:47 -07004889 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_NETWORK_USAGE_HISTORY,
4890 null);
4891
Malcolm Chenaabec062018-02-28 15:00:40 -08004892 final long identity = Binder.clearCallingIdentity();
4893 try {
4894 // NetworkStatsService keeps tracking the active network interface and identity. It
4895 // records the delta with the corresponding network identity.
4896 // We just return the total video call data usage snapshot since boot.
4897 Phone phone = getPhone(subId);
4898 if (phone != null) {
4899 return phone.getVtDataUsage(perUidStats);
4900 }
4901 return null;
4902 } finally {
4903 Binder.restoreCallingIdentity(identity);
Jack Yueb89b242016-06-22 13:27:47 -07004904 }
Jack Yueb89b242016-06-22 13:27:47 -07004905 }
Jack Yu75ab2952016-07-08 14:29:33 -07004906
4907 /**
4908 * Policy control of data connection. Usually used when data limit is passed.
4909 * @param enabled True if enabling the data, otherwise disabling.
4910 * @param subId Subscription index
4911 * {@hide}
4912 */
4913 @Override
4914 public void setPolicyDataEnabled(boolean enabled, int subId) {
4915 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08004916
4917 final long identity = Binder.clearCallingIdentity();
4918 try {
4919 Phone phone = getPhone(subId);
4920 if (phone != null) {
4921 phone.setPolicyDataEnabled(enabled);
4922 }
4923 } finally {
4924 Binder.restoreCallingIdentity(identity);
Jack Yu75ab2952016-07-08 14:29:33 -07004925 }
4926 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004927
4928 /**
4929 * Get Client request stats
4930 * @return List of Client Request Stats
4931 * @hide
4932 */
4933 @Override
4934 public List<ClientRequestStats> getClientRequestStats(String callingPackage, int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004935 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08004936 mApp, subId, callingPackage, "getClientRequestStats")) {
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004937 return null;
4938 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004939 Phone phone = getPhone(subId);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004940
Malcolm Chenaabec062018-02-28 15:00:40 -08004941 final long identity = Binder.clearCallingIdentity();
4942 try {
4943 if (phone != null) {
4944 return phone.getClientRequestStats();
4945 }
4946
4947 return null;
4948 } finally {
4949 Binder.restoreCallingIdentity(identity);
4950 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004951 }
4952
Narayan Kamathf04b5a12018-01-09 11:47:15 +00004953 private WorkSource getWorkSource(int uid) {
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004954 String packageName = mPhone.getContext().getPackageManager().getNameForUid(uid);
Narayan Kamathf04b5a12018-01-09 11:47:15 +00004955 return new WorkSource(uid, packageName);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004956 }
Jack Yueb4124c2017-02-16 15:32:43 -08004957
4958 /**
Grace Chen70990072017-03-24 17:21:30 -07004959 * Set SIM card power state.
Jack Yueb4124c2017-02-16 15:32:43 -08004960 *
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004961 * @param slotIndex SIM slot id.
Grace Chen70990072017-03-24 17:21:30 -07004962 * @param state State of SIM (power down, power up, pass through)
4963 * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
4964 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
4965 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
Jack Yueb4124c2017-02-16 15:32:43 -08004966 *
4967 **/
4968 @Override
Grace Chen70990072017-03-24 17:21:30 -07004969 public void setSimPowerStateForSlot(int slotIndex, int state) {
Jack Yueb4124c2017-02-16 15:32:43 -08004970 enforceModifyPermission();
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004971 Phone phone = PhoneFactory.getPhone(slotIndex);
4972
vagdevie435a3e2018-08-15 16:01:53 -07004973 WorkSource workSource = getWorkSource(Binder.getCallingUid());
4974
Malcolm Chenaabec062018-02-28 15:00:40 -08004975 final long identity = Binder.clearCallingIdentity();
4976 try {
4977 if (phone != null) {
vagdevie435a3e2018-08-15 16:01:53 -07004978 phone.setSimPowerState(state, workSource);
Malcolm Chenaabec062018-02-28 15:00:40 -08004979 }
4980 } finally {
4981 Binder.restoreCallingIdentity(identity);
Jack Yueb4124c2017-02-16 15:32:43 -08004982 }
4983 }
Shuo Qiandd210312017-04-12 22:11:33 +00004984
Tyler Gunn65d45c22017-06-05 11:22:26 -07004985 private boolean isUssdApiAllowed(int subId) {
4986 CarrierConfigManager configManager =
4987 (CarrierConfigManager) mPhone.getContext().getSystemService(
4988 Context.CARRIER_CONFIG_SERVICE);
4989 if (configManager == null) {
4990 return false;
4991 }
4992 PersistableBundle pb = configManager.getConfigForSubId(subId);
4993 if (pb == null) {
4994 return false;
4995 }
4996 return pb.getBoolean(
4997 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL);
4998 }
4999
Shuo Qiandd210312017-04-12 22:11:33 +00005000 /**
5001 * Check if phone is in emergency callback mode
5002 * @return true if phone is in emergency callback mode
5003 * @param subId sub id
5004 */
goneil9c5f4872017-12-05 14:07:56 -08005005 @Override
Shuo Qiandd210312017-04-12 22:11:33 +00005006 public boolean getEmergencyCallbackMode(int subId) {
goneil9c5f4872017-12-05 14:07:56 -08005007 enforceReadPrivilegedPermission();
Shuo Qiandd210312017-04-12 22:11:33 +00005008 final Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08005009
5010 final long identity = Binder.clearCallingIdentity();
5011 try {
5012 if (phone != null) {
5013 return phone.isInEcm();
5014 } else {
5015 return false;
5016 }
5017 } finally {
5018 Binder.restoreCallingIdentity(identity);
Shuo Qiandd210312017-04-12 22:11:33 +00005019 }
5020 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08005021
5022 /**
5023 * Get the current signal strength information for the given subscription.
5024 * Because this information is not updated when the device is in a low power state
5025 * it should not be relied-upon to be current.
5026 * @param subId Subscription index
5027 * @return the most recent cached signal strength info from the modem
5028 */
5029 @Override
5030 public SignalStrength getSignalStrength(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08005031 final long identity = Binder.clearCallingIdentity();
5032 try {
5033 Phone p = getPhone(subId);
5034 if (p == null) {
5035 return null;
5036 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08005037
Malcolm Chenaabec062018-02-28 15:00:40 -08005038 return p.getSignalStrength();
5039 } finally {
5040 Binder.restoreCallingIdentity(identity);
5041 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08005042 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005043
Pengquan Meng9140aec2018-08-22 14:49:57 -07005044 /**
5045 * Checks if data roaming is enabled on the subscription with id {@code subId}.
5046 *
5047 * <p>Requires one of the following permissions:
5048 * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
5049 * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
5050 * privileges.
5051 *
5052 * @param subId subscription id
5053 * @return {@code true} if data roaming is enabled on this subscription, otherwise return
5054 * {@code false}.
5055 */
5056 @Override
5057 public boolean isDataRoamingEnabled(int subId) {
Pengquan Meng0c05b502018-09-06 09:59:22 -07005058 boolean isEnabled = false;
5059 final long identity = Binder.clearCallingIdentity();
Pengquan Meng9140aec2018-08-22 14:49:57 -07005060 try {
5061 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
Pengquan Meng0c05b502018-09-06 09:59:22 -07005062 null /* message */);
5063 Phone phone = getPhone(subId);
5064 isEnabled = phone != null ? phone.getDataRoamingEnabled() : false;
Pengquan Meng9140aec2018-08-22 14:49:57 -07005065 } catch (Exception e) {
5066 TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
5067 mApp, subId, "isDataRoamingEnabled");
Pengquan Meng0c05b502018-09-06 09:59:22 -07005068 } finally {
5069 Binder.restoreCallingIdentity(identity);
Pengquan Meng9140aec2018-08-22 14:49:57 -07005070 }
Pengquan Meng0c05b502018-09-06 09:59:22 -07005071 return isEnabled;
Pengquan Meng9140aec2018-08-22 14:49:57 -07005072 }
5073
5074
5075 /**
5076 * Enables/Disables the data roaming on the subscription with id {@code subId}.
5077 *
5078 * <p> Requires permission:
5079 * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier
5080 * privileges.
5081 *
5082 * @param subId subscription id
5083 * @param isEnabled {@code true} means enable, {@code false} means disable.
5084 */
5085 @Override
5086 public void setDataRoamingEnabled(int subId, boolean isEnabled) {
Pengquan Meng0c05b502018-09-06 09:59:22 -07005087 final long identity = Binder.clearCallingIdentity();
5088 try {
5089 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5090 mApp, subId, "setDataRoamingEnabled");
Pengquan Meng9140aec2018-08-22 14:49:57 -07005091
Pengquan Meng0c05b502018-09-06 09:59:22 -07005092 Phone phone = getPhone(subId);
5093 if (phone != null) {
5094 phone.setDataRoamingEnabled(isEnabled);
5095 }
5096 } finally {
5097 Binder.restoreCallingIdentity(identity);
Pengquan Meng9140aec2018-08-22 14:49:57 -07005098 }
5099 }
5100
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005101 @Override
5102 public UiccSlotInfo[] getUiccSlotsInfo() {
5103 enforceReadPrivilegedPermission();
5104
Malcolm Chenaabec062018-02-28 15:00:40 -08005105 final long identity = Binder.clearCallingIdentity();
5106 try {
5107 UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
Malcolm Chen1cc36b62018-07-30 14:42:47 -07005108 if (slots == null) {
5109 Rlog.i(LOG_TAG, "slots is null.");
5110 return null;
5111 }
5112
Malcolm Chenaabec062018-02-28 15:00:40 -08005113 UiccSlotInfo[] infos = new UiccSlotInfo[slots.length];
5114 for (int i = 0; i < slots.length; i++) {
5115 UiccSlot slot = slots[i];
Malcolm Chen1cc36b62018-07-30 14:42:47 -07005116 if (slot == null) {
5117 continue;
5118 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005119
Malcolm Chen1cc36b62018-07-30 14:42:47 -07005120 String cardId;
5121 UiccCard card = slot.getUiccCard();
5122 if (card != null) {
5123 cardId = card.getCardId();
5124 } else {
5125 cardId = slot.getIccId();
5126 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005127
Malcolm Chenaabec062018-02-28 15:00:40 -08005128 int cardState = 0;
5129 switch (slot.getCardState()) {
5130 case CARDSTATE_ABSENT:
5131 cardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
5132 break;
5133 case CARDSTATE_PRESENT:
5134 cardState = UiccSlotInfo.CARD_STATE_INFO_PRESENT;
5135 break;
5136 case CARDSTATE_ERROR:
5137 cardState = UiccSlotInfo.CARD_STATE_INFO_ERROR;
5138 break;
5139 case CARDSTATE_RESTRICTED:
5140 cardState = UiccSlotInfo.CARD_STATE_INFO_RESTRICTED;
5141 break;
5142 default:
5143 break;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005144
Malcolm Chenaabec062018-02-28 15:00:40 -08005145 }
5146
5147 infos[i] = new UiccSlotInfo(
5148 slot.isActive(),
5149 slot.isEuicc(),
5150 cardId,
5151 cardState,
5152 slot.getPhoneId(),
5153 slot.isExtendedApduSupported());
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005154 }
Malcolm Chenaabec062018-02-28 15:00:40 -08005155 return infos;
5156 } finally {
5157 Binder.restoreCallingIdentity(identity);
Holly Jiuyu Sun1d957c52018-04-04 13:52:42 -07005158 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005159 }
5160
5161 @Override
5162 public boolean switchSlots(int[] physicalSlots) {
5163 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08005164
5165 final long identity = Binder.clearCallingIdentity();
5166 try {
5167 return (Boolean) sendRequest(CMD_SWITCH_SLOTS, physicalSlots);
5168 } finally {
5169 Binder.restoreCallingIdentity(identity);
5170 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005171 }
Jack Yu4c988042018-02-27 15:30:01 -08005172
5173 @Override
5174 public void setRadioIndicationUpdateMode(int subId, int filters, int mode) {
5175 enforceModifyPermission();
5176 final Phone phone = getPhone(subId);
5177 if (phone == null) {
5178 loge("setRadioIndicationUpdateMode fails with invalid subId: " + subId);
5179 return;
5180 }
5181
Malcolm Chenaabec062018-02-28 15:00:40 -08005182 final long identity = Binder.clearCallingIdentity();
5183 try {
5184 phone.setRadioIndicationUpdateMode(filters, mode);
5185 } finally {
5186 Binder.restoreCallingIdentity(identity);
5187 }
Jack Yu4c988042018-02-27 15:30:01 -08005188 }
Pengquan Meng85728fb2018-03-12 16:31:21 -07005189
5190 /**
goneil47ffb6e2018-04-06 15:40:58 -07005191 * A test API to reload the UICC profile.
5192 *
5193 * <p>Requires that the calling app has permission
5194 * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
5195 * @hide
5196 */
5197 @Override
5198 public void refreshUiccProfile(int subId) {
5199 enforceModifyPermission();
5200
5201 final long identity = Binder.clearCallingIdentity();
5202 try {
5203 Phone phone = getPhone(subId);
5204 if (phone == null) {
5205 return;
5206 }
5207 UiccCard uiccCard = phone.getUiccCard();
5208 if (uiccCard == null) {
5209 return;
5210 }
5211 UiccProfile uiccProfile = uiccCard.getUiccProfile();
5212 if (uiccProfile == null) {
5213 return;
5214 }
5215 uiccProfile.refresh();
5216 } finally {
5217 Binder.restoreCallingIdentity(identity);
5218 }
5219 }
5220
5221 /**
Pengquan Meng85728fb2018-03-12 16:31:21 -07005222 * Returns false if the mobile data is disabled by default, otherwise return true.
5223 */
5224 private boolean getDefaultDataEnabled() {
5225 return "true".equalsIgnoreCase(
5226 SystemProperties.get(DEFAULT_MOBILE_DATA_PROPERTY_NAME, "true"));
5227 }
5228
5229 /**
5230 * Returns true if the data roaming is enabled by default, i.e the system property
5231 * of {@link #DEFAULT_DATA_ROAMING_PROPERTY_NAME} is true or the config of
5232 * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} is true.
5233 */
5234 private boolean getDefaultDataRoamingEnabled(int subId) {
5235 final CarrierConfigManager configMgr = (CarrierConfigManager)
5236 mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
5237 boolean isDataRoamingEnabled = "true".equalsIgnoreCase(
5238 SystemProperties.get(DEFAULT_DATA_ROAMING_PROPERTY_NAME, "false"));
5239 isDataRoamingEnabled |= configMgr.getConfigForSubId(subId).getBoolean(
5240 CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
5241 return isDataRoamingEnabled;
5242 }
5243
5244 /**
5245 * Returns the default network type for the given {@code subId}, if the default network type is
5246 * not set, return {@link Phone#PREFERRED_NT_MODE}.
5247 */
5248 private int getDefaultNetworkType(int subId) {
5249 return Integer.parseInt(
5250 TelephonyManager.getTelephonyProperty(
5251 mSubscriptionController.getPhoneId(subId),
5252 DEFAULT_NETWORK_MODE_PROPERTY_NAME,
5253 String.valueOf(Phone.PREFERRED_NT_MODE)));
5254 }
fionaxua13278b2018-03-21 00:08:13 -07005255
5256 @Override
5257 public void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String
5258 gid1, String gid2, String plmn, String spn) {
5259 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08005260
5261 final long identity = Binder.clearCallingIdentity();
5262 try {
5263 final Phone phone = getPhone(subId);
5264 if (phone == null) {
5265 loge("setCarrierTestOverride fails with invalid subId: " + subId);
5266 return;
5267 }
5268 phone.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, plmn, spn);
5269 } finally {
5270 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07005271 }
fionaxua13278b2018-03-21 00:08:13 -07005272 }
5273
5274 @Override
5275 public int getCarrierIdListVersion(int subId) {
5276 enforceReadPrivilegedPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08005277
5278 final long identity = Binder.clearCallingIdentity();
5279 try {
5280 final Phone phone = getPhone(subId);
5281 if (phone == null) {
5282 loge("getCarrierIdListVersion fails with invalid subId: " + subId);
5283 return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
5284 }
5285 return phone.getCarrierIdListVersion();
5286 } finally {
5287 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07005288 }
fionaxua13278b2018-03-21 00:08:13 -07005289 }
Malcolm Chenf144d942018-08-14 16:00:53 -07005290
5291 @Override
5292 public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage) {
5293 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5294 mApp, subId, callingPackage, "getNumberOfModemsWithSimultaneousDataConnections")) {
5295 return -1;
5296 }
5297
5298 final long identity = Binder.clearCallingIdentity();
5299 try {
5300 return mPhoneConfigurationManager.getNumberOfModemsWithSimultaneousDataConnections();
5301 } finally {
5302 Binder.restoreCallingIdentity(identity);
5303 }
5304 }
Pengquan Meng0c05b502018-09-06 09:59:22 -07005305
5306 @Override
5307 public int getCdmaRoamingMode(int subId) {
5308 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5309 mApp, subId, "getCdmaRoamingMode");
5310
5311 final long identity = Binder.clearCallingIdentity();
5312 try {
5313 return (int) sendRequest(CMD_GET_CDMA_ROAMING_MODE, null /* argument */, subId);
5314 } finally {
5315 Binder.restoreCallingIdentity(identity);
5316 }
5317 }
5318
5319 @Override
5320 public boolean setCdmaRoamingMode(int subId, int mode) {
5321 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5322 mApp, subId, "setCdmaRoamingMode");
5323
5324 final long identity = Binder.clearCallingIdentity();
5325 try {
5326 return (boolean) sendRequest(CMD_SET_CDMA_ROAMING_MODE, mode, subId);
5327 } finally {
5328 Binder.restoreCallingIdentity(identity);
5329 }
5330 }
5331
5332 @Override
5333 public boolean setCdmaSubscriptionMode(int subId, int mode) {
5334 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5335 mApp, subId, "setCdmaSubscriptionMode");
5336
5337 final long identity = Binder.clearCallingIdentity();
5338 try {
5339 return (boolean) sendRequest(CMD_SET_CDMA_SUBSCRIPTION_MODE, mode, subId);
5340 } finally {
5341 Binder.restoreCallingIdentity(identity);
5342 }
5343 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005344}