blob: 4e47bdae6b179263743b9921694542d04c9ad31e [file] [log] [blame]
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.phone;
18
Ta-wei Yen87c49842016-05-13 21:19:52 -070019import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
20
Ta-wei Yen30a69c82016-12-27 14:52:32 -080021import android.Manifest.permission;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070022import android.app.AppOpsManager;
Ta-wei Yen30a69c82016-12-27 14:52:32 -080023import android.app.PendingIntent;
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -070024import android.content.ComponentName;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070025import android.content.Context;
26import android.content.Intent;
Derek Tan97ebb422014-09-05 16:55:38 -070027import android.content.SharedPreferences;
Nathan Harold31d7ff32018-10-15 20:20:30 -070028import android.content.pm.ApplicationInfo;
Derek Tan740e1672017-06-27 14:56:27 -070029import android.content.pm.ComponentInfo;
Amith Yamasani6e118872016-02-19 12:53:51 -080030import android.content.pm.PackageInfo;
Shishir Agrawal60f9c952014-06-23 12:00:43 -070031import android.content.pm.PackageManager;
Jack Yu84291ec2017-05-26 16:07:50 -070032import android.net.NetworkStats;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070033import android.net.Uri;
34import android.os.AsyncResult;
35import android.os.Binder;
36import android.os.Bundle;
37import android.os.Handler;
yinxu504e1392017-04-12 16:03:22 -070038import android.os.IBinder;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070039import android.os.Looper;
40import android.os.Message;
yinxu504e1392017-04-12 16:03:22 -070041import android.os.Messenger;
Tyler Gunn65d45c22017-06-05 11:22:26 -070042import android.os.PersistableBundle;
Brad Ebinger5f64b052017-12-14 14:26:15 -080043import android.os.RemoteException;
Adam Lesinski903a54c2016-04-11 14:49:52 -070044import android.os.ResultReceiver;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070045import android.os.ServiceManager;
Brad Ebingerdac2f002018-04-03 15:17:52 -070046import android.os.ShellCallback;
Pengquan Meng85728fb2018-03-12 16:31:21 -070047import android.os.SystemProperties;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070048import android.os.UserHandle;
Stuart Scott981d8582015-04-21 14:09:50 -070049import android.os.UserManager;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070050import android.os.WorkSource;
Derek Tan97ebb422014-09-05 16:55:38 -070051import android.preference.PreferenceManager;
Ihab Awadf2177b72013-11-25 13:33:23 -080052import android.provider.Settings;
Meng Wang1a7c35a2016-05-05 20:56:15 -070053import android.service.carrier.CarrierIdentifier;
Santos Cordon7a1885b2015-02-03 11:15:19 -080054import android.telecom.PhoneAccount;
Nancy Chen31f9ba12016-01-06 11:42:12 -080055import android.telecom.PhoneAccountHandle;
Andrew Lee9431b832015-03-09 18:46:45 -070056import android.telecom.TelecomManager;
Junda Liu12f7d802015-05-01 12:06:44 -070057import android.telephony.CarrierConfigManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070058import android.telephony.CellInfo;
Nathan Haroldf180aac2018-06-01 18:43:55 -070059import android.telephony.CellInfoGsm;
60import android.telephony.CellInfoWcdma;
Nathan Harold3ff88932018-08-14 10:19:49 -070061import android.telephony.CellLocation;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070062import android.telephony.ClientRequestStats;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -070063import android.telephony.IccOpenLogicalChannelResponse;
Hall Liu1aa510f2017-11-22 17:40:08 -080064import android.telephony.LocationAccessPolicy;
Ta-wei Yen87c49842016-05-13 21:19:52 -070065import android.telephony.ModemActivityInfo;
Jake Hambye994d462014-02-03 13:10:13 -080066import android.telephony.NeighboringCellInfo;
yinxu504e1392017-04-12 16:03:22 -070067import android.telephony.NetworkScanRequest;
Wink Saville5d475dd2014-10-17 15:00:58 -070068import android.telephony.RadioAccessFamily;
Tyler Gunn65d45c22017-06-05 11:22:26 -070069import android.telephony.Rlog;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070070import android.telephony.ServiceState;
Nathan Harold46b42aa2017-03-10 19:38:22 -080071import android.telephony.SignalStrength;
Jack Yu84291ec2017-05-26 16:07:50 -070072import android.telephony.SmsManager;
Wink Saville0f3b5fc2014-11-11 08:40:49 -080073import android.telephony.SubscriptionInfo;
Jeff Sharkey85190e62014-12-05 09:40:12 -080074import android.telephony.SubscriptionManager;
Sanket Padawe99ef1e32016-05-18 16:12:33 -070075import android.telephony.TelephonyHistogram;
Ta-wei Yenb6929602016-05-24 15:48:27 -070076import android.telephony.TelephonyManager;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +000077import android.telephony.UiccSlotInfo;
Tyler Gunn65d45c22017-06-05 11:22:26 -070078import android.telephony.UssdResponse;
Ta-wei Yenb6929602016-05-24 15:48:27 -070079import android.telephony.VisualVoicemailSmsFilterSettings;
Nathan Harold3ff88932018-08-14 10:19:49 -070080import android.telephony.cdma.CdmaCellLocation;
81import android.telephony.gsm.GsmCellLocation;
Brad Ebinger4c460712018-10-01 10:40:55 -070082import android.telephony.ims.aidl.IImsCapabilityCallback;
Brad Ebinger22bc3e42018-01-16 09:39:35 -080083import android.telephony.ims.aidl.IImsConfig;
84import android.telephony.ims.aidl.IImsMmTelFeature;
85import android.telephony.ims.aidl.IImsRcsFeature;
86import android.telephony.ims.aidl.IImsRegistration;
Brad Ebinger4c460712018-10-01 10:40:55 -070087import android.telephony.ims.aidl.IImsRegistrationCallback;
Brad Ebinger1f2b5082018-02-08 16:11:32 -080088import android.telephony.ims.stub.ImsRegistrationImplBase;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070089import android.text.TextUtils;
Jeff Sharkey85190e62014-12-05 09:40:12 -080090import android.util.ArraySet;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070091import android.util.Log;
Jake Hambye994d462014-02-03 13:10:13 -080092import android.util.Pair;
Jeff Sharkey85190e62014-12-05 09:40:12 -080093import android.util.Slog;
Ta-wei Yen30a69c82016-12-27 14:52:32 -080094
Brad Ebinger4c460712018-10-01 10:40:55 -070095import com.android.ims.ImsException;
Andrew Lee312e8172014-10-23 17:01:36 -070096import com.android.ims.ImsManager;
Brad Ebinger34bef922017-11-09 10:27:08 -080097import com.android.ims.internal.IImsServiceFeatureCallback;
Shishir Agrawal566b7612013-10-28 14:41:00 -070098import com.android.internal.telephony.CallManager;
Tyler Gunn52dcf772017-04-26 11:30:31 -070099import com.android.internal.telephony.CallStateException;
pkanwar79ec0542017-07-31 14:10:01 -0700100import com.android.internal.telephony.CarrierInfoManager;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700101import com.android.internal.telephony.CellNetworkScanResult;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700102import com.android.internal.telephony.CommandException;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700103import com.android.internal.telephony.DefaultPhoneNotifier;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700104import com.android.internal.telephony.ITelephony;
Jake Hambye994d462014-02-03 13:10:13 -0800105import com.android.internal.telephony.IccCard;
Jack Yu5f7092c2018-04-13 14:05:37 -0700106import com.android.internal.telephony.LocaleTracker;
Narayan Kamath1c496c22015-04-16 14:40:19 +0100107import com.android.internal.telephony.MccTable;
yinxub1bed742017-04-17 11:45:04 -0700108import com.android.internal.telephony.NetworkScanRequestTracker;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700109import com.android.internal.telephony.OperatorInfo;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700110import com.android.internal.telephony.Phone;
Malcolm Chenf144d942018-08-14 16:00:53 -0700111import com.android.internal.telephony.PhoneConfigurationManager;
Nathan Harolda667c152016-12-14 11:27:20 -0800112import com.android.internal.telephony.PhoneConstantConversions;
Ta-wei Yen87c49842016-05-13 21:19:52 -0700113import com.android.internal.telephony.PhoneConstants;
Wink Saville36469e72014-06-11 15:17:00 -0700114import com.android.internal.telephony.PhoneFactory;
Wink Saville5d475dd2014-10-17 15:00:58 -0700115import com.android.internal.telephony.ProxyController;
Sanket Padawe99ef1e32016-05-18 16:12:33 -0700116import com.android.internal.telephony.RIL;
Svet Ganovb320e182015-04-16 12:30:10 -0700117import com.android.internal.telephony.RILConstants;
Jack Yu5f7092c2018-04-13 14:05:37 -0700118import com.android.internal.telephony.ServiceStateTracker;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800119import com.android.internal.telephony.SubscriptionController;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800120import com.android.internal.telephony.TelephonyPermissions;
Derek Tan740e1672017-06-27 14:56:27 -0700121import com.android.internal.telephony.euicc.EuiccConnector;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700122import com.android.internal.telephony.uicc.IccIoResult;
123import com.android.internal.telephony.uicc.IccUtils;
Nathan Haroldb3014052017-01-25 15:57:32 -0800124import com.android.internal.telephony.uicc.SIMRecords;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700125import com.android.internal.telephony.uicc.UiccCard;
Nathan Haroldb3014052017-01-25 15:57:32 -0800126import com.android.internal.telephony.uicc.UiccCardApplication;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700127import com.android.internal.telephony.uicc.UiccController;
Jeff Davidson7e17e312018-02-13 18:17:36 -0800128import com.android.internal.telephony.uicc.UiccProfile;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000129import com.android.internal.telephony.uicc.UiccSlot;
fionaxu7ed723d2017-05-30 18:58:54 -0700130import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
Jake Hambye994d462014-02-03 13:10:13 -0800131import com.android.internal.util.HexDump;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700132import com.android.phone.vvm.PhoneAccountHandleConverter;
Ta-wei Yen527a9c02017-01-06 15:29:25 -0800133import com.android.phone.vvm.RemoteVvmTaskManager;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700134import com.android.phone.vvm.VisualVoicemailSettingsUtil;
Ta-wei Yenc8905312017-03-28 11:14:45 -0700135import com.android.phone.vvm.VisualVoicemailSmsFilterConfig;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800136
Ta-wei Yenc236d6b2016-06-21 13:33:12 -0700137import java.io.FileDescriptor;
138import java.io.PrintWriter;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800139import java.nio.charset.StandardCharsets;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700140import java.util.ArrayList;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800141import java.util.Arrays;
Jake Hambye994d462014-02-03 13:10:13 -0800142import java.util.List;
Narayan Kamath1c496c22015-04-16 14:40:19 +0100143import java.util.Locale;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800144import java.util.Map;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700145
146/**
147 * Implementation of the ITelephony interface.
148 */
Santos Cordon117fee72014-05-16 17:56:12 -0700149public class PhoneInterfaceManager extends ITelephony.Stub {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700150 private static final String LOG_TAG = "PhoneInterfaceManager";
151 private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
152 private static final boolean DBG_LOC = false;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800153 private static final boolean DBG_MERGE = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700154
155 // Message codes used with mMainThreadHandler
156 private static final int CMD_HANDLE_PIN_MMI = 1;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700157 private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7;
158 private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700159 private static final int CMD_OPEN_CHANNEL = 9;
160 private static final int EVENT_OPEN_CHANNEL_DONE = 10;
161 private static final int CMD_CLOSE_CHANNEL = 11;
162 private static final int EVENT_CLOSE_CHANNEL_DONE = 12;
Jake Hambye994d462014-02-03 13:10:13 -0800163 private static final int CMD_NV_READ_ITEM = 13;
164 private static final int EVENT_NV_READ_ITEM_DONE = 14;
165 private static final int CMD_NV_WRITE_ITEM = 15;
166 private static final int EVENT_NV_WRITE_ITEM_DONE = 16;
167 private static final int CMD_NV_WRITE_CDMA_PRL = 17;
168 private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18;
169 private static final int CMD_NV_RESET_CONFIG = 19;
170 private static final int EVENT_NV_RESET_CONFIG_DONE = 20;
Jake Hamby7c27be32014-03-03 13:25:59 -0800171 private static final int CMD_GET_PREFERRED_NETWORK_TYPE = 21;
172 private static final int EVENT_GET_PREFERRED_NETWORK_TYPE_DONE = 22;
173 private static final int CMD_SET_PREFERRED_NETWORK_TYPE = 23;
174 private static final int EVENT_SET_PREFERRED_NETWORK_TYPE_DONE = 24;
Sailesh Nepal35b59452014-03-06 09:26:56 -0800175 private static final int CMD_SEND_ENVELOPE = 25;
176 private static final int EVENT_SEND_ENVELOPE_DONE = 26;
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000177 private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27;
178 private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28;
Derek Tan6b088ee2014-09-05 14:15:18 -0700179 private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29;
180 private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30;
181 private static final int CMD_EXCHANGE_SIM_IO = 31;
182 private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800183 private static final int CMD_SET_VOICEMAIL_NUMBER = 33;
184 private static final int EVENT_SET_VOICEMAIL_NUMBER_DONE = 34;
Stuart Scott54788802015-03-30 13:18:01 -0700185 private static final int CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC = 35;
186 private static final int EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE = 36;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700187 private static final int CMD_GET_MODEM_ACTIVITY_INFO = 37;
188 private static final int EVENT_GET_MODEM_ACTIVITY_INFO_DONE = 38;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700189 private static final int CMD_PERFORM_NETWORK_SCAN = 39;
190 private static final int EVENT_PERFORM_NETWORK_SCAN_DONE = 40;
191 private static final int CMD_SET_NETWORK_SELECTION_MODE_MANUAL = 41;
192 private static final int EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE = 42;
Meng Wang1a7c35a2016-05-05 20:56:15 -0700193 private static final int CMD_SET_ALLOWED_CARRIERS = 43;
194 private static final int EVENT_SET_ALLOWED_CARRIERS_DONE = 44;
195 private static final int CMD_GET_ALLOWED_CARRIERS = 45;
196 private static final int EVENT_GET_ALLOWED_CARRIERS_DONE = 46;
pkanwar32d516d2016-10-14 19:37:38 -0700197 private static final int CMD_HANDLE_USSD_REQUEST = 47;
Nathan Haroldb3014052017-01-25 15:57:32 -0800198 private static final int CMD_GET_FORBIDDEN_PLMNS = 48;
199 private static final int EVENT_GET_FORBIDDEN_PLMNS_DONE = 49;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000200 private static final int CMD_SWITCH_SLOTS = 50;
201 private static final int EVENT_SWITCH_SLOTS_DONE = 51;
Pengquan Meng0c05b502018-09-06 09:59:22 -0700202 private static final int CMD_GET_NETWORK_SELECTION_MODE = 52;
203 private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 53;
204 private static final int CMD_GET_CDMA_ROAMING_MODE = 54;
205 private static final int EVENT_GET_CDMA_ROAMING_MODE_DONE = 55;
206 private static final int CMD_SET_CDMA_ROAMING_MODE = 56;
207 private static final int EVENT_SET_CDMA_ROAMING_MODE_DONE = 57;
208 private static final int CMD_SET_CDMA_SUBSCRIPTION_MODE = 58;
209 private static final int EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE = 59;
Nathan Harold3ff88932018-08-14 10:19:49 -0700210 private static final int CMD_GET_ALL_CELL_INFO = 60;
211 private static final int EVENT_GET_ALL_CELL_INFO_DONE = 61;
212 private static final int CMD_GET_CELL_LOCATION = 62;
213 private static final int EVENT_GET_CELL_LOCATION_DONE = 63;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700214
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -0800215 // Parameters of select command.
216 private static final int SELECT_COMMAND = 0xA4;
217 private static final int SELECT_P1 = 0x04;
218 private static final int SELECT_P2 = 0;
219 private static final int SELECT_P3 = 0x10;
220
Pengquan Meng85728fb2018-03-12 16:31:21 -0700221 private static final String DEFAULT_NETWORK_MODE_PROPERTY_NAME = "ro.telephony.default_network";
222 private static final String DEFAULT_DATA_ROAMING_PROPERTY_NAME = "ro.com.android.dataroaming";
223 private static final String DEFAULT_MOBILE_DATA_PROPERTY_NAME = "ro.com.android.mobiledata";
224
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700225 /** The singleton instance. */
226 private static PhoneInterfaceManager sInstance;
227
Wink Saville3ab207e2014-11-20 13:07:20 -0800228 private PhoneGlobals mApp;
229 private Phone mPhone;
230 private CallManager mCM;
Stuart Scott981d8582015-04-21 14:09:50 -0700231 private UserManager mUserManager;
Wink Saville3ab207e2014-11-20 13:07:20 -0800232 private AppOpsManager mAppOps;
233 private MainThreadHandler mMainThreadHandler;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800234 private SubscriptionController mSubscriptionController;
Wink Saville3ab207e2014-11-20 13:07:20 -0800235 private SharedPreferences mTelephonySharedPreferences;
Malcolm Chenf144d942018-08-14 16:00:53 -0700236 private PhoneConfigurationManager mPhoneConfigurationManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700237
Derek Tan97ebb422014-09-05 16:55:38 -0700238 private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
239 private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
Jeff Sharkey85190e62014-12-05 09:40:12 -0800240 private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
Derek Tan89e89d42014-07-08 17:00:10 -0700241
Derek Tan740e1672017-06-27 14:56:27 -0700242 // The AID of ISD-R.
243 private static final String ISDR_AID = "A0000005591010FFFFFFFF8900000100";
244
yinxub1bed742017-04-17 11:45:04 -0700245 private NetworkScanRequestTracker mNetworkScanRequestTracker;
246
David Kelly5e06a7f2018-03-12 14:10:59 +0000247 private static final int TYPE_ALLOCATION_CODE_LENGTH = 8;
248 private static final int MANUFACTURER_CODE_LENGTH = 8;
249
Derek Tan89e89d42014-07-08 17:00:10 -0700250 /**
Shishir Agrawal566b7612013-10-28 14:41:00 -0700251 * A request object to use for transmitting data to an ICC.
252 */
253 private static final class IccAPDUArgument {
254 public int channel, cla, command, p1, p2, p3;
255 public String data;
256
257 public IccAPDUArgument(int channel, int cla, int command,
258 int p1, int p2, int p3, String data) {
259 this.channel = channel;
260 this.cla = cla;
261 this.command = command;
262 this.p1 = p1;
263 this.p2 = p2;
264 this.p3 = p3;
265 this.data = data;
266 }
267 }
268
269 /**
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700270 * A request object to use for transmitting data to an ICC.
271 */
272 private static final class ManualNetworkSelectionArgument {
273 public OperatorInfo operatorInfo;
274 public boolean persistSelection;
275
276 public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) {
277 this.operatorInfo = operatorInfo;
278 this.persistSelection = persistSelection;
279 }
280 }
281
282 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700283 * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
284 * request after sending. The main thread will notify the request when it is complete.
285 */
286 private static final class MainThreadRequest {
287 /** The argument to use for the request */
288 public Object argument;
289 /** The result of the request that is run on the main thread */
290 public Object result;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800291 // The subscriber id that this request applies to. Defaults to
292 // SubscriptionManager.INVALID_SUBSCRIPTION_ID
293 public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700294
Nathan Harold92bed182018-10-12 18:16:49 -0700295 // In cases where subId is unavailable, the caller needs to specify the phone.
296 public Phone phone;
297
vagdevie435a3e2018-08-15 16:01:53 -0700298 public WorkSource workSource;
299
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700300 public MainThreadRequest(Object argument) {
301 this.argument = argument;
302 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800303
Nathan Harold92bed182018-10-12 18:16:49 -0700304 MainThreadRequest(Object argument, Phone phone, WorkSource workSource) {
305 this.argument = argument;
306 if (phone != null) {
307 this.phone = phone;
308 }
309 this.workSource = workSource;
310 }
311
vagdevie435a3e2018-08-15 16:01:53 -0700312 MainThreadRequest(Object argument, Integer subId, WorkSource workSource) {
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800313 this.argument = argument;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800314 if (subId != null) {
315 this.subId = subId;
316 }
vagdevie435a3e2018-08-15 16:01:53 -0700317 this.workSource = workSource;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800318 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700319 }
320
Sailesh Nepalcc0375f2013-11-13 09:15:18 -0800321 private static final class IncomingThirdPartyCallArgs {
322 public final ComponentName component;
323 public final String callId;
324 public final String callerDisplayName;
325
326 public IncomingThirdPartyCallArgs(ComponentName component, String callId,
327 String callerDisplayName) {
328 this.component = component;
329 this.callId = callId;
330 this.callerDisplayName = callerDisplayName;
331 }
332 }
333
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700334 /**
335 * A handler that processes messages on the main thread in the phone process. Since many
336 * of the Phone calls are not thread safe this is needed to shuttle the requests from the
337 * inbound binder threads to the main thread in the phone process. The Binder thread
338 * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
339 * on, which will be notified when the operation completes and will contain the result of the
340 * request.
341 *
342 * <p>If a MainThreadRequest object is provided in the msg.obj field,
343 * note that request.result must be set to something non-null for the calling thread to
344 * unblock.
345 */
346 private final class MainThreadHandler extends Handler {
347 @Override
348 public void handleMessage(Message msg) {
349 MainThreadRequest request;
350 Message onCompleted;
351 AsyncResult ar;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800352 UiccCard uiccCard;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700353 IccAPDUArgument iccArgument;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700354
355 switch (msg.what) {
Pengquan Meng0c05b502018-09-06 09:59:22 -0700356 case CMD_HANDLE_USSD_REQUEST: {
357 request = (MainThreadRequest) msg.obj;
358 final Phone phone = getPhoneFromRequest(request);
359 Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
360 String ussdRequest = ussdObject.first;
361 ResultReceiver wrappedCallback = ussdObject.second;
Tyler Gunn65d45c22017-06-05 11:22:26 -0700362
Pengquan Meng0c05b502018-09-06 09:59:22 -0700363 if (!isUssdApiAllowed(request.subId)) {
364 // Carrier does not support use of this API, return failure.
365 Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
366 UssdResponse response = new UssdResponse(ussdRequest, null);
367 Bundle returnData = new Bundle();
368 returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
369 wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
Tyler Gunn65d45c22017-06-05 11:22:26 -0700370
Pengquan Meng0c05b502018-09-06 09:59:22 -0700371 request.result = true;
372 notifyRequester(request);
373 return;
374 }
Tyler Gunn65d45c22017-06-05 11:22:26 -0700375
Pengquan Meng0c05b502018-09-06 09:59:22 -0700376 try {
377 request.result = phone != null
378 ? phone.handleUssdRequest(ussdRequest, wrappedCallback) : false;
379 } catch (CallStateException cse) {
380 request.result = false;
381 }
382 // Wake up the requesting thread
383 notifyRequester(request);
384 break;
pkanwar32d516d2016-10-14 19:37:38 -0700385 }
386
Yorke Lee716f67e2015-06-17 15:39:16 -0700387 case CMD_HANDLE_PIN_MMI: {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700388 request = (MainThreadRequest) msg.obj;
Yorke Lee716f67e2015-06-17 15:39:16 -0700389 final Phone phone = getPhoneFromRequest(request);
390 request.result = phone != null ?
391 getPhoneFromRequest(request).handlePinMmi((String) request.argument)
392 : false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700393 // Wake up the requesting thread
Pengquan Meng0c05b502018-09-06 09:59:22 -0700394 notifyRequester(request);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700395 break;
Yorke Lee716f67e2015-06-17 15:39:16 -0700396 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700397
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700398 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700399 request = (MainThreadRequest) msg.obj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700400 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800401 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700402 if (uiccCard == null) {
403 loge("iccTransmitApduLogicalChannel: No UICC");
404 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Meng0c05b502018-09-06 09:59:22 -0700405 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700406 } else {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700407 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
408 request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700409 uiccCard.iccTransmitApduLogicalChannel(
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700410 iccArgument.channel, iccArgument.cla, iccArgument.command,
411 iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data,
Shishir Agrawal566b7612013-10-28 14:41:00 -0700412 onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700413 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700414 break;
415
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700416 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700417 ar = (AsyncResult) msg.obj;
418 request = (MainThreadRequest) ar.userObj;
419 if (ar.exception == null && ar.result != null) {
420 request.result = ar.result;
421 } else {
422 request.result = new IccIoResult(0x6F, 0, (byte[])null);
423 if (ar.result == null) {
424 loge("iccTransmitApduLogicalChannel: Empty response");
Jake Hambye994d462014-02-03 13:10:13 -0800425 } else if (ar.exception instanceof CommandException) {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700426 loge("iccTransmitApduLogicalChannel: CommandException: " +
Jake Hambye994d462014-02-03 13:10:13 -0800427 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700428 } else {
429 loge("iccTransmitApduLogicalChannel: Unknown exception");
430 }
431 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700432 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700433 break;
434
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700435 case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
436 request = (MainThreadRequest) msg.obj;
437 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800438 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700439 if (uiccCard == null) {
440 loge("iccTransmitApduBasicChannel: No UICC");
441 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Meng0c05b502018-09-06 09:59:22 -0700442 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700443 } else {
444 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
445 request);
446 uiccCard.iccTransmitApduBasicChannel(
447 iccArgument.cla, iccArgument.command, iccArgument.p1, iccArgument.p2,
448 iccArgument.p3, iccArgument.data, onCompleted);
449 }
450 break;
451
452 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
453 ar = (AsyncResult) msg.obj;
454 request = (MainThreadRequest) ar.userObj;
455 if (ar.exception == null && ar.result != null) {
456 request.result = ar.result;
457 } else {
458 request.result = new IccIoResult(0x6F, 0, (byte[])null);
459 if (ar.result == null) {
460 loge("iccTransmitApduBasicChannel: Empty response");
461 } else if (ar.exception instanceof CommandException) {
462 loge("iccTransmitApduBasicChannel: CommandException: " +
463 ar.exception);
464 } else {
465 loge("iccTransmitApduBasicChannel: Unknown exception");
466 }
467 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700468 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700469 break;
470
471 case CMD_EXCHANGE_SIM_IO:
472 request = (MainThreadRequest) msg.obj;
473 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800474 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700475 if (uiccCard == null) {
476 loge("iccExchangeSimIO: No UICC");
477 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Meng0c05b502018-09-06 09:59:22 -0700478 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700479 } else {
480 onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
481 request);
482 uiccCard.iccExchangeSimIO(iccArgument.cla, /* fileID */
483 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3,
484 iccArgument.data, onCompleted);
485 }
486 break;
487
488 case EVENT_EXCHANGE_SIM_IO_DONE:
489 ar = (AsyncResult) msg.obj;
490 request = (MainThreadRequest) ar.userObj;
491 if (ar.exception == null && ar.result != null) {
492 request.result = ar.result;
493 } else {
494 request.result = new IccIoResult(0x6f, 0, (byte[])null);
495 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700496 notifyRequester(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700497 break;
498
Derek Tan4d5e5c12014-02-04 11:54:58 -0800499 case CMD_SEND_ENVELOPE:
500 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800501 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700502 if (uiccCard == null) {
503 loge("sendEnvelopeWithStatus: No UICC");
504 request.result = new IccIoResult(0x6F, 0, (byte[])null);
Pengquan Meng0c05b502018-09-06 09:59:22 -0700505 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700506 } else {
507 onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
508 uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted);
509 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800510 break;
511
512 case EVENT_SEND_ENVELOPE_DONE:
513 ar = (AsyncResult) msg.obj;
514 request = (MainThreadRequest) ar.userObj;
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700515 if (ar.exception == null && ar.result != null) {
516 request.result = ar.result;
Derek Tan4d5e5c12014-02-04 11:54:58 -0800517 } else {
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700518 request.result = new IccIoResult(0x6F, 0, (byte[])null);
519 if (ar.result == null) {
520 loge("sendEnvelopeWithStatus: Empty response");
521 } else if (ar.exception instanceof CommandException) {
522 loge("sendEnvelopeWithStatus: CommandException: " +
523 ar.exception);
524 } else {
525 loge("sendEnvelopeWithStatus: exception:" + ar.exception);
526 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800527 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700528 notifyRequester(request);
Derek Tan4d5e5c12014-02-04 11:54:58 -0800529 break;
530
Shishir Agrawal566b7612013-10-28 14:41:00 -0700531 case CMD_OPEN_CHANNEL:
532 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800533 uiccCard = getUiccCardFromRequest(request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800534 Pair<String, Integer> openChannelArgs = (Pair<String, Integer>) request.argument;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700535 if (uiccCard == null) {
536 loge("iccOpenLogicalChannel: No UICC");
Shishir Agrawalfc0492a2016-02-17 11:15:33 -0800537 request.result = new IccOpenLogicalChannelResponse(-1,
538 IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
Pengquan Meng0c05b502018-09-06 09:59:22 -0700539 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700540 } else {
541 onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800542 uiccCard.iccOpenLogicalChannel(openChannelArgs.first,
543 openChannelArgs.second, onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700544 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700545 break;
546
547 case EVENT_OPEN_CHANNEL_DONE:
548 ar = (AsyncResult) msg.obj;
549 request = (MainThreadRequest) ar.userObj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700550 IccOpenLogicalChannelResponse openChannelResp;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700551 if (ar.exception == null && ar.result != null) {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700552 int[] result = (int[]) ar.result;
553 int channelId = result[0];
554 byte[] selectResponse = null;
555 if (result.length > 1) {
556 selectResponse = new byte[result.length - 1];
557 for (int i = 1; i < result.length; ++i) {
558 selectResponse[i - 1] = (byte) result[i];
559 }
560 }
561 openChannelResp = new IccOpenLogicalChannelResponse(channelId,
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700562 IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700563 } else {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700564 if (ar.result == null) {
565 loge("iccOpenLogicalChannel: Empty response");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700566 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700567 if (ar.exception != null) {
568 loge("iccOpenLogicalChannel: Exception: " + ar.exception);
569 }
570
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700571 int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR;
Junda Liua754ba12015-05-20 01:17:52 -0700572 if (ar.exception instanceof CommandException) {
573 CommandException.Error error =
574 ((CommandException) (ar.exception)).getCommandError();
575 if (error == CommandException.Error.MISSING_RESOURCE) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700576 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE;
Junda Liua754ba12015-05-20 01:17:52 -0700577 } else if (error == CommandException.Error.NO_SUCH_ELEMENT) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700578 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700579 }
580 }
581 openChannelResp = new IccOpenLogicalChannelResponse(
582 IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700583 }
Shishir Agrawal82c8a462014-07-31 18:13:17 -0700584 request.result = openChannelResp;
Pengquan Meng0c05b502018-09-06 09:59:22 -0700585 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700586 break;
587
588 case CMD_CLOSE_CHANNEL:
589 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800590 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700591 if (uiccCard == null) {
592 loge("iccCloseLogicalChannel: No UICC");
Yoshiaki Naka2e29d822016-09-02 19:27:39 +0900593 request.result = false;
Pengquan Meng0c05b502018-09-06 09:59:22 -0700594 notifyRequester(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700595 } else {
596 onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
597 uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
598 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700599 break;
600
601 case EVENT_CLOSE_CHANNEL_DONE:
Jake Hambye994d462014-02-03 13:10:13 -0800602 handleNullReturnEvent(msg, "iccCloseLogicalChannel");
603 break;
604
605 case CMD_NV_READ_ITEM:
606 request = (MainThreadRequest) msg.obj;
607 onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
vagdevie435a3e2018-08-15 16:01:53 -0700608 mPhone.nvReadItem((Integer) request.argument, onCompleted, request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800609 break;
610
611 case EVENT_NV_READ_ITEM_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700612 ar = (AsyncResult) msg.obj;
613 request = (MainThreadRequest) ar.userObj;
Jake Hambye994d462014-02-03 13:10:13 -0800614 if (ar.exception == null && ar.result != null) {
615 request.result = ar.result; // String
Shishir Agrawal566b7612013-10-28 14:41:00 -0700616 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800617 request.result = "";
618 if (ar.result == null) {
619 loge("nvReadItem: Empty response");
620 } else if (ar.exception instanceof CommandException) {
621 loge("nvReadItem: CommandException: " +
622 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700623 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800624 loge("nvReadItem: Unknown exception");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700625 }
626 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700627 notifyRequester(request);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700628 break;
629
Jake Hambye994d462014-02-03 13:10:13 -0800630 case CMD_NV_WRITE_ITEM:
631 request = (MainThreadRequest) msg.obj;
632 onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
633 Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
vagdevie435a3e2018-08-15 16:01:53 -0700634 mPhone.nvWriteItem(idValue.first, idValue.second, onCompleted,
635 request.workSource);
Jake Hambye994d462014-02-03 13:10:13 -0800636 break;
637
638 case EVENT_NV_WRITE_ITEM_DONE:
639 handleNullReturnEvent(msg, "nvWriteItem");
640 break;
641
642 case CMD_NV_WRITE_CDMA_PRL:
643 request = (MainThreadRequest) msg.obj;
644 onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
645 mPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
646 break;
647
648 case EVENT_NV_WRITE_CDMA_PRL_DONE:
649 handleNullReturnEvent(msg, "nvWriteCdmaPrl");
650 break;
651
652 case CMD_NV_RESET_CONFIG:
653 request = (MainThreadRequest) msg.obj;
654 onCompleted = obtainMessage(EVENT_NV_RESET_CONFIG_DONE, request);
655 mPhone.nvResetConfig((Integer) request.argument, onCompleted);
656 break;
657
658 case EVENT_NV_RESET_CONFIG_DONE:
659 handleNullReturnEvent(msg, "nvResetConfig");
660 break;
661
Jake Hamby7c27be32014-03-03 13:25:59 -0800662 case CMD_GET_PREFERRED_NETWORK_TYPE:
663 request = (MainThreadRequest) msg.obj;
664 onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request);
Stuart Scott54788802015-03-30 13:18:01 -0700665 getPhoneFromRequest(request).getPreferredNetworkType(onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800666 break;
667
668 case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE:
669 ar = (AsyncResult) msg.obj;
670 request = (MainThreadRequest) ar.userObj;
671 if (ar.exception == null && ar.result != null) {
672 request.result = ar.result; // Integer
673 } else {
Sanket Padawecfc2d352016-01-05 19:52:14 -0800674 request.result = null;
Jake Hamby7c27be32014-03-03 13:25:59 -0800675 if (ar.result == null) {
676 loge("getPreferredNetworkType: Empty response");
677 } else if (ar.exception instanceof CommandException) {
678 loge("getPreferredNetworkType: CommandException: " +
679 ar.exception);
680 } else {
681 loge("getPreferredNetworkType: Unknown exception");
682 }
683 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700684 notifyRequester(request);
Jake Hamby7c27be32014-03-03 13:25:59 -0800685 break;
686
687 case CMD_SET_PREFERRED_NETWORK_TYPE:
688 request = (MainThreadRequest) msg.obj;
689 onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request);
690 int networkType = (Integer) request.argument;
Stuart Scott54788802015-03-30 13:18:01 -0700691 getPhoneFromRequest(request).setPreferredNetworkType(networkType, onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800692 break;
693
694 case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE:
695 handleNullReturnEvent(msg, "setPreferredNetworkType");
696 break;
697
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000698 case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
699 request = (MainThreadRequest)msg.obj;
700 onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
vagdevie435a3e2018-08-15 16:01:53 -0700701 mPhone.invokeOemRilRequestRaw((byte[]) request.argument, onCompleted);
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000702 break;
703
704 case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
705 ar = (AsyncResult)msg.obj;
706 request = (MainThreadRequest)ar.userObj;
707 request.result = ar;
Pengquan Meng0c05b502018-09-06 09:59:22 -0700708 notifyRequester(request);
Shuo Qian850e4d6a2018-04-25 21:02:08 +0000709 break;
710
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800711 case CMD_SET_VOICEMAIL_NUMBER:
712 request = (MainThreadRequest) msg.obj;
713 onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
714 Pair<String, String> tagNum = (Pair<String, String>) request.argument;
Stuart Scott584921c2015-01-15 17:10:34 -0800715 getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
716 onCompleted);
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800717 break;
718
719 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
720 handleNullReturnEvent(msg, "setVoicemailNumber");
721 break;
722
Stuart Scott54788802015-03-30 13:18:01 -0700723 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC:
724 request = (MainThreadRequest) msg.obj;
725 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE,
726 request);
727 getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted);
728 break;
729
730 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE:
731 handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic");
732 break;
733
Shishir Agrawal302c8692015-06-19 13:49:39 -0700734 case CMD_PERFORM_NETWORK_SCAN:
735 request = (MainThreadRequest) msg.obj;
736 onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request);
737 getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
738 break;
739
740 case EVENT_PERFORM_NETWORK_SCAN_DONE:
741 ar = (AsyncResult) msg.obj;
742 request = (MainThreadRequest) ar.userObj;
743 CellNetworkScanResult cellScanResult;
744 if (ar.exception == null && ar.result != null) {
745 cellScanResult = new CellNetworkScanResult(
746 CellNetworkScanResult.STATUS_SUCCESS,
747 (List<OperatorInfo>) ar.result);
748 } else {
749 if (ar.result == null) {
750 loge("getCellNetworkScanResults: Empty response");
751 }
752 if (ar.exception != null) {
753 loge("getCellNetworkScanResults: Exception: " + ar.exception);
754 }
755 int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR;
756 if (ar.exception instanceof CommandException) {
757 CommandException.Error error =
758 ((CommandException) (ar.exception)).getCommandError();
759 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
760 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE;
761 } else if (error == CommandException.Error.GENERIC_FAILURE) {
762 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE;
763 }
764 }
765 cellScanResult = new CellNetworkScanResult(errorCode, null);
766 }
767 request.result = cellScanResult;
Pengquan Meng0c05b502018-09-06 09:59:22 -0700768 notifyRequester(request);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700769 break;
770
771 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
772 request = (MainThreadRequest) msg.obj;
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700773 ManualNetworkSelectionArgument selArg =
774 (ManualNetworkSelectionArgument) request.argument;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700775 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE,
776 request);
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700777 getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo,
778 selArg.persistSelection, onCompleted);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700779 break;
780
781 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
Pengquan Mengdd9ac822018-09-20 15:25:35 -0700782 ar = (AsyncResult) msg.obj;
783 request = (MainThreadRequest) ar.userObj;
784 if (ar.exception == null) {
785 request.result = true;
786 } else {
787 request.result = false;
788 loge("setNetworkSelectionModeManual " + ar.exception);
789 }
790 notifyRequester(request);
791 mApp.onNetworkSelectionChanged(request.subId);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700792 break;
793
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700794 case CMD_GET_MODEM_ACTIVITY_INFO:
795 request = (MainThreadRequest) msg.obj;
796 onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
vagdevie435a3e2018-08-15 16:01:53 -0700797 mPhone.getModemActivityInfo(onCompleted, request.workSource);
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700798 break;
799
800 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE:
801 ar = (AsyncResult) msg.obj;
802 request = (MainThreadRequest) ar.userObj;
803 if (ar.exception == null && ar.result != null) {
804 request.result = ar.result;
805 } else {
806 if (ar.result == null) {
807 loge("queryModemActivityInfo: Empty response");
808 } else if (ar.exception instanceof CommandException) {
809 loge("queryModemActivityInfo: CommandException: " +
810 ar.exception);
811 } else {
812 loge("queryModemActivityInfo: Unknown exception");
813 }
814 }
Amit Mahajand4766222016-01-28 15:28:28 -0800815 // Result cannot be null. Return ModemActivityInfo with all fields set to 0.
816 if (request.result == null) {
817 request.result = new ModemActivityInfo(0, 0, 0, null, 0, 0);
818 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700819 notifyRequester(request);
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700820 break;
821
Meng Wang1a7c35a2016-05-05 20:56:15 -0700822 case CMD_SET_ALLOWED_CARRIERS:
823 request = (MainThreadRequest) msg.obj;
824 onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
825 mPhone.setAllowedCarriers(
826 (List<CarrierIdentifier>) request.argument,
vagdevie435a3e2018-08-15 16:01:53 -0700827 onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700828 break;
829
830 case EVENT_SET_ALLOWED_CARRIERS_DONE:
831 ar = (AsyncResult) msg.obj;
832 request = (MainThreadRequest) ar.userObj;
833 if (ar.exception == null && ar.result != null) {
834 request.result = ar.result;
835 } else {
836 if (ar.result == null) {
837 loge("setAllowedCarriers: Empty response");
838 } else if (ar.exception instanceof CommandException) {
839 loge("setAllowedCarriers: CommandException: " +
840 ar.exception);
841 } else {
842 loge("setAllowedCarriers: Unknown exception");
843 }
844 }
845 // Result cannot be null. Return -1 on error.
846 if (request.result == null) {
847 request.result = new int[]{-1};
848 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700849 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700850 break;
851
852 case CMD_GET_ALLOWED_CARRIERS:
853 request = (MainThreadRequest) msg.obj;
854 onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
vagdevie435a3e2018-08-15 16:01:53 -0700855 mPhone.getAllowedCarriers(onCompleted, request.workSource);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700856 break;
857
858 case EVENT_GET_ALLOWED_CARRIERS_DONE:
859 ar = (AsyncResult) msg.obj;
860 request = (MainThreadRequest) ar.userObj;
861 if (ar.exception == null && ar.result != null) {
862 request.result = ar.result;
863 } else {
864 if (ar.result == null) {
865 loge("getAllowedCarriers: Empty response");
866 } else if (ar.exception instanceof CommandException) {
867 loge("getAllowedCarriers: CommandException: " +
868 ar.exception);
869 } else {
870 loge("getAllowedCarriers: Unknown exception");
871 }
872 }
873 // Result cannot be null. Return empty list of CarrierIdentifier.
874 if (request.result == null) {
875 request.result = new ArrayList<CarrierIdentifier>(0);
876 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700877 notifyRequester(request);
Meng Wang1a7c35a2016-05-05 20:56:15 -0700878 break;
879
Nathan Haroldb3014052017-01-25 15:57:32 -0800880 case EVENT_GET_FORBIDDEN_PLMNS_DONE:
881 ar = (AsyncResult) msg.obj;
882 request = (MainThreadRequest) ar.userObj;
883 if (ar.exception == null && ar.result != null) {
884 request.result = ar.result;
885 } else {
886 request.result = new IllegalArgumentException(
887 "Failed to retrieve Forbidden Plmns");
888 if (ar.result == null) {
889 loge("getForbiddenPlmns: Empty response");
890 } else {
891 loge("getForbiddenPlmns: Unknown exception");
892 }
893 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700894 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -0800895 break;
896
897 case CMD_GET_FORBIDDEN_PLMNS:
898 request = (MainThreadRequest) msg.obj;
899 uiccCard = getUiccCardFromRequest(request);
900 if (uiccCard == null) {
901 loge("getForbiddenPlmns() UiccCard is null");
902 request.result = new IllegalArgumentException(
903 "getForbiddenPlmns() UiccCard is null");
Pengquan Meng0c05b502018-09-06 09:59:22 -0700904 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -0800905 break;
906 }
907 Integer appType = (Integer) request.argument;
908 UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType);
909 if (uiccApp == null) {
910 loge("getForbiddenPlmns() no app with specified type -- "
911 + appType);
912 request.result = new IllegalArgumentException("Failed to get UICC App");
Pengquan Meng0c05b502018-09-06 09:59:22 -0700913 notifyRequester(request);
Nathan Haroldb3014052017-01-25 15:57:32 -0800914 break;
915 } else {
916 if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
917 + " specified type -- " + appType);
918 }
919 onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
920 ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
921 onCompleted);
922 break;
923
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000924 case CMD_SWITCH_SLOTS:
925 request = (MainThreadRequest) msg.obj;
926 int[] physicalSlots = (int[]) request.argument;
927 onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
928 UiccController.getInstance().switchSlots(physicalSlots, onCompleted);
929 break;
930
931 case EVENT_SWITCH_SLOTS_DONE:
932 ar = (AsyncResult) msg.obj;
933 request = (MainThreadRequest) ar.userObj;
934 request.result = (ar.exception == null);
Pengquan Meng0c05b502018-09-06 09:59:22 -0700935 notifyRequester(request);
936 break;
937 case CMD_GET_NETWORK_SELECTION_MODE:
938 request = (MainThreadRequest) msg.obj;
939 onCompleted = obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE, request);
940 getPhoneFromRequest(request).getNetworkSelectionMode(onCompleted);
941 break;
942
943 case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
944 ar = (AsyncResult) msg.obj;
945 request = (MainThreadRequest) ar.userObj;
946 if (ar.exception != null) {
947 request.result = TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
948 } else {
949 int mode = ((int[]) ar.result)[0];
950 if (mode == 0) {
951 request.result = TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
952 } else {
953 request.result = TelephonyManager.NETWORK_SELECTION_MODE_MANUAL;
954 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000955 }
Pengquan Meng0c05b502018-09-06 09:59:22 -0700956 notifyRequester(request);
957 break;
958 case CMD_GET_CDMA_ROAMING_MODE:
959 request = (MainThreadRequest) msg.obj;
960 onCompleted = obtainMessage(EVENT_GET_CDMA_ROAMING_MODE_DONE, request);
961 getPhoneFromRequest(request).queryCdmaRoamingPreference(onCompleted);
962 break;
963 case EVENT_GET_CDMA_ROAMING_MODE_DONE:
964 ar = (AsyncResult) msg.obj;
965 request = (MainThreadRequest) ar.userObj;
966 if (ar.exception != null) {
967 request.result = TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT;
968 } else {
969 request.result = ((int[]) ar.result)[0];
970 }
971 notifyRequester(request);
972 break;
973 case CMD_SET_CDMA_ROAMING_MODE:
974 request = (MainThreadRequest) msg.obj;
975 onCompleted = obtainMessage(EVENT_SET_CDMA_ROAMING_MODE_DONE, request);
976 int mode = (int) request.argument;
977 getPhoneFromRequest(request).setCdmaRoamingPreference(mode, onCompleted);
978 break;
979 case EVENT_SET_CDMA_ROAMING_MODE_DONE:
980 ar = (AsyncResult) msg.obj;
981 request = (MainThreadRequest) ar.userObj;
982 request.result = ar.exception == null;
983 notifyRequester(request);
984 break;
985 case CMD_SET_CDMA_SUBSCRIPTION_MODE:
986 request = (MainThreadRequest) msg.obj;
987 onCompleted = obtainMessage(EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE, request);
988 int subscriptionMode = (int) request.argument;
989 getPhoneFromRequest(request).setCdmaSubscription(subscriptionMode, onCompleted);
990 break;
991 case EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE:
992 ar = (AsyncResult) msg.obj;
993 request = (MainThreadRequest) ar.userObj;
994 request.result = ar.exception == null;
995 notifyRequester(request);
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000996 break;
997
Nathan Harold3ff88932018-08-14 10:19:49 -0700998 case CMD_GET_ALL_CELL_INFO:
999 request = (MainThreadRequest) msg.obj;
Nathan Harold3ff88932018-08-14 10:19:49 -07001000 onCompleted = obtainMessage(EVENT_GET_ALL_CELL_INFO_DONE, request);
Nathan Harold92bed182018-10-12 18:16:49 -07001001 request.phone.requestCellInfoUpdate(request.workSource, onCompleted);
Nathan Harold3ff88932018-08-14 10:19:49 -07001002 break;
1003
1004 case EVENT_GET_ALL_CELL_INFO_DONE:
1005 ar = (AsyncResult) msg.obj;
1006 request = (MainThreadRequest) ar.userObj;
Nathan Harold8d0f1742018-10-02 12:14:47 -07001007 // If a timeout occurs, the response will be null
1008 request.result = (ar.exception == null && ar.result != null)
1009 ? ar.result : new ArrayList<CellInfo>();
Nathan Harold3ff88932018-08-14 10:19:49 -07001010 synchronized (request) {
1011 request.notifyAll();
1012 }
1013 break;
1014
1015 case CMD_GET_CELL_LOCATION: {
1016 request = (MainThreadRequest) msg.obj;
1017 WorkSource ws = (WorkSource) request.argument;
1018 Phone phone = getPhoneFromRequest(request);
1019 phone.getCellLocation(ws, obtainMessage(EVENT_GET_CELL_LOCATION_DONE, request));
1020 break;
1021 }
1022
1023 case EVENT_GET_CELL_LOCATION_DONE: {
1024 ar = (AsyncResult) msg.obj;
1025 request = (MainThreadRequest) ar.userObj;
1026 if (ar.exception == null) {
1027 request.result = ar.result;
1028 } else {
1029 Phone phone = getPhoneFromRequest(request);
1030 request.result = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
1031 ? new CdmaCellLocation() : new GsmCellLocation();
1032 }
1033
1034 synchronized (request) {
1035 request.notifyAll();
1036 }
1037 break;
1038 }
1039
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001040 default:
1041 Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
1042 break;
1043 }
1044 }
Jake Hambye994d462014-02-03 13:10:13 -08001045
Pengquan Meng0c05b502018-09-06 09:59:22 -07001046 private void notifyRequester(MainThreadRequest request) {
1047 synchronized (request) {
1048 request.notifyAll();
1049 }
1050 }
1051
Jake Hambye994d462014-02-03 13:10:13 -08001052 private void handleNullReturnEvent(Message msg, String command) {
1053 AsyncResult ar = (AsyncResult) msg.obj;
1054 MainThreadRequest request = (MainThreadRequest) ar.userObj;
1055 if (ar.exception == null) {
1056 request.result = true;
1057 } else {
1058 request.result = false;
1059 if (ar.exception instanceof CommandException) {
1060 loge(command + ": CommandException: " + ar.exception);
1061 } else {
1062 loge(command + ": Unknown exception");
1063 }
1064 }
Pengquan Meng0c05b502018-09-06 09:59:22 -07001065 notifyRequester(request);
Jake Hambye994d462014-02-03 13:10:13 -08001066 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001067 }
1068
1069 /**
1070 * Posts the specified command to be executed on the main thread,
1071 * waits for the request to complete, and returns the result.
1072 * @see #sendRequestAsync
1073 */
1074 private Object sendRequest(int command, Object argument) {
Nathan Harold92bed182018-10-12 18:16:49 -07001075 return sendRequest(
1076 command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, null, null);
vagdevie435a3e2018-08-15 16:01:53 -07001077 }
1078
1079 /**
1080 * Posts the specified command to be executed on the main thread,
1081 * waits for the request to complete, and returns the result.
1082 * @see #sendRequestAsync
1083 */
1084 private Object sendRequest(int command, Object argument, WorkSource workSource) {
1085 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
Nathan Harold92bed182018-10-12 18:16:49 -07001086 null, workSource);
Wink Saville36469e72014-06-11 15:17:00 -07001087 }
1088
1089 /**
1090 * Posts the specified command to be executed on the main thread,
1091 * waits for the request to complete, and returns the result.
1092 * @see #sendRequestAsync
1093 */
Shishir Agrawal76d5da92014-11-09 16:17:25 -08001094 private Object sendRequest(int command, Object argument, Integer subId) {
Nathan Harold92bed182018-10-12 18:16:49 -07001095 return sendRequest(command, argument, subId, null, null);
vagdevie435a3e2018-08-15 16:01:53 -07001096 }
1097
1098 /**
1099 * Posts the specified command to be executed on the main thread,
1100 * waits for the request to complete, and returns the result.
1101 * @see #sendRequestAsync
1102 */
Nathan Harold92bed182018-10-12 18:16:49 -07001103 private Object sendRequest(int command, Object argument, int subId, WorkSource workSource) {
1104 return sendRequest(command, argument, subId, null, workSource);
1105 }
1106
1107 /**
1108 * Posts the specified command to be executed on the main thread,
1109 * waits for the request to complete, and returns the result.
1110 * @see #sendRequestAsync
1111 */
1112 private Object sendRequest(int command, Object argument, Phone phone, WorkSource workSource) {
1113 return sendRequest(
1114 command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phone, workSource);
1115 }
1116
1117 /**
1118 * Posts the specified command to be executed on the main thread,
1119 * waits for the request to complete, and returns the result.
1120 * @see #sendRequestAsync
1121 */
1122 private Object sendRequest(
1123 int command, Object argument, Integer subId, Phone phone, WorkSource workSource) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001124 if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
1125 throw new RuntimeException("This method will deadlock if called from the main thread.");
1126 }
1127
Nathan Harold92bed182018-10-12 18:16:49 -07001128 MainThreadRequest request = null;
1129 if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && phone != null) {
1130 throw new IllegalArgumentException("subId and phone cannot both be specified!");
1131 } else if (phone != null) {
1132 request = new MainThreadRequest(argument, phone, workSource);
1133 } else {
1134 request = new MainThreadRequest(argument, subId, workSource);
1135 }
1136
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001137 Message msg = mMainThreadHandler.obtainMessage(command, request);
1138 msg.sendToTarget();
1139
1140 // Wait for the request to complete
1141 synchronized (request) {
1142 while (request.result == null) {
1143 try {
1144 request.wait();
1145 } catch (InterruptedException e) {
1146 // Do nothing, go back and wait until the request is complete
1147 }
1148 }
1149 }
1150 return request.result;
1151 }
1152
1153 /**
1154 * Asynchronous ("fire and forget") version of sendRequest():
1155 * Posts the specified command to be executed on the main thread, and
1156 * returns immediately.
1157 * @see #sendRequest
1158 */
1159 private void sendRequestAsync(int command) {
1160 mMainThreadHandler.sendEmptyMessage(command);
1161 }
1162
1163 /**
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001164 * Same as {@link #sendRequestAsync(int)} except it takes an argument.
1165 * @see {@link #sendRequest(int,Object)}
1166 */
1167 private void sendRequestAsync(int command, Object argument) {
1168 MainThreadRequest request = new MainThreadRequest(argument);
1169 Message msg = mMainThreadHandler.obtainMessage(command, request);
1170 msg.sendToTarget();
1171 }
1172
1173 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001174 * Initialize the singleton PhoneInterfaceManager instance.
1175 * This is only done once, at startup, from PhoneApp.onCreate().
1176 */
Sailesh Nepal194161e2014-07-03 08:57:44 -07001177 /* package */ static PhoneInterfaceManager init(PhoneGlobals app, Phone phone) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001178 synchronized (PhoneInterfaceManager.class) {
1179 if (sInstance == null) {
Sailesh Nepal194161e2014-07-03 08:57:44 -07001180 sInstance = new PhoneInterfaceManager(app, phone);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001181 } else {
1182 Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
1183 }
1184 return sInstance;
1185 }
1186 }
1187
1188 /** Private constructor; @see init() */
Sailesh Nepal194161e2014-07-03 08:57:44 -07001189 private PhoneInterfaceManager(PhoneGlobals app, Phone phone) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001190 mApp = app;
1191 mPhone = phone;
1192 mCM = PhoneGlobals.getInstance().mCM;
Stuart Scott981d8582015-04-21 14:09:50 -07001193 mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001194 mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
1195 mMainThreadHandler = new MainThreadHandler();
Andrew Leedf14ead2014-10-17 14:22:52 -07001196 mTelephonySharedPreferences =
Derek Tan97ebb422014-09-05 16:55:38 -07001197 PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
Wink Savilleac1bdfd2014-11-20 23:04:44 -08001198 mSubscriptionController = SubscriptionController.getInstance();
yinxub1bed742017-04-17 11:45:04 -07001199 mNetworkScanRequestTracker = new NetworkScanRequestTracker();
Malcolm Chenf144d942018-08-14 16:00:53 -07001200 mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
Wink Saville3ab207e2014-11-20 13:07:20 -08001201
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001202 publish();
1203 }
1204
1205 private void publish() {
1206 if (DBG) log("publish: " + this);
1207
1208 ServiceManager.addService("phone", this);
1209 }
1210
Stuart Scott584921c2015-01-15 17:10:34 -08001211 private Phone getPhoneFromRequest(MainThreadRequest request) {
Sanket Padawe56e75a32016-02-08 12:18:19 -08001212 return (request.subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
1213 ? mPhone : getPhone(request.subId);
Stuart Scott584921c2015-01-15 17:10:34 -08001214 }
1215
Shishir Agrawalc04d9752016-02-19 10:41:00 -08001216 private UiccCard getUiccCardFromRequest(MainThreadRequest request) {
1217 Phone phone = getPhoneFromRequest(request);
1218 return phone == null ? null :
1219 UiccController.getInstance().getUiccCard(phone.getPhoneId());
1220 }
1221
Wink Saville36469e72014-06-11 15:17:00 -07001222 // returns phone associated with the subId.
Wink Savilleb564aae2014-10-23 10:18:09 -07001223 private Phone getPhone(int subId) {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08001224 return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId));
Wink Saville36469e72014-06-11 15:17:00 -07001225 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001226
1227 public void dial(String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001228 dialForSubscriber(getPreferredVoiceSubscription(), number);
Wink Saville36469e72014-06-11 15:17:00 -07001229 }
1230
Wink Savilleb564aae2014-10-23 10:18:09 -07001231 public void dialForSubscriber(int subId, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001232 if (DBG) log("dial: " + number);
1233 // No permission check needed here: This is just a wrapper around the
1234 // ACTION_DIAL intent, which is available to any app since it puts up
1235 // the UI before it does anything.
1236
Malcolm Chend965c8b2018-02-28 15:00:40 -08001237 final long identity = Binder.clearCallingIdentity();
1238 try {
1239 String url = createTelUrl(number);
1240 if (url == null) {
1241 return;
1242 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001243
Malcolm Chend965c8b2018-02-28 15:00:40 -08001244 // PENDING: should we just silently fail if phone is offhook or ringing?
1245 PhoneConstants.State state = mCM.getState(subId);
1246 if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
1247 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
1248 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1249 mApp.startActivity(intent);
1250 }
1251 } finally {
1252 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001253 }
1254 }
1255
1256 public void call(String callingPackage, String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001257 callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number);
Wink Saville36469e72014-06-11 15:17:00 -07001258 }
1259
Wink Savilleb564aae2014-10-23 10:18:09 -07001260 public void callForSubscriber(int subId, String callingPackage, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001261 if (DBG) log("call: " + number);
1262
1263 // This is just a wrapper around the ACTION_CALL intent, but we still
1264 // need to do a permission check since we're calling startActivity()
1265 // from the context of the phone app.
1266 enforceCallPermission();
1267
1268 if (mAppOps.noteOp(AppOpsManager.OP_CALL_PHONE, Binder.getCallingUid(), callingPackage)
1269 != AppOpsManager.MODE_ALLOWED) {
1270 return;
1271 }
1272
Malcolm Chend965c8b2018-02-28 15:00:40 -08001273 final long identity = Binder.clearCallingIdentity();
1274 try {
1275 String url = createTelUrl(number);
1276 if (url == null) {
1277 return;
1278 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001279
Malcolm Chend965c8b2018-02-28 15:00:40 -08001280 boolean isValid = false;
1281 final List<SubscriptionInfo> slist = getActiveSubscriptionInfoListPrivileged();
1282 if (slist != null) {
1283 for (SubscriptionInfo subInfoRecord : slist) {
1284 if (subInfoRecord.getSubscriptionId() == subId) {
1285 isValid = true;
1286 break;
1287 }
Wink Saville3ab207e2014-11-20 13:07:20 -08001288 }
Wink Saville08874612014-08-31 19:19:58 -07001289 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08001290 if (!isValid) {
1291 return;
1292 }
Wink Saville08874612014-08-31 19:19:58 -07001293
Malcolm Chend965c8b2018-02-28 15:00:40 -08001294 Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
1295 intent.putExtra(SUBSCRIPTION_KEY, subId);
1296 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1297 mApp.startActivity(intent);
1298 } finally {
1299 Binder.restoreCallingIdentity(identity);
1300 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001301 }
1302
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001303 public boolean supplyPin(String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001304 return supplyPinForSubscriber(getDefaultSubscription(), pin);
Wink Saville36469e72014-06-11 15:17:00 -07001305 }
1306
Wink Savilleb564aae2014-10-23 10:18:09 -07001307 public boolean supplyPinForSubscriber(int subId, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001308 int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07001309 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1310 }
1311
1312 public boolean supplyPuk(String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001313 return supplyPukForSubscriber(getDefaultSubscription(), puk, pin);
Wink Saville36469e72014-06-11 15:17:00 -07001314 }
1315
Wink Savilleb564aae2014-10-23 10:18:09 -07001316 public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001317 int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07001318 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1319 }
1320
1321 /** {@hide} */
1322 public int[] supplyPinReportResult(String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001323 return supplyPinReportResultForSubscriber(getDefaultSubscription(), pin);
Wink Saville36469e72014-06-11 15:17:00 -07001324 }
1325
Wink Savilleb564aae2014-10-23 10:18:09 -07001326 public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001327 enforceModifyPermission();
Malcolm Chend965c8b2018-02-28 15:00:40 -08001328
1329 final long identity = Binder.clearCallingIdentity();
1330 try {
1331 final UnlockSim checkSimPin = new UnlockSim(getPhone(subId).getIccCard());
1332 checkSimPin.start();
1333 return checkSimPin.unlockSim(null, pin);
1334 } finally {
1335 Binder.restoreCallingIdentity(identity);
1336 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001337 }
1338
Wink Saville9de0f752013-10-22 19:04:03 -07001339 /** {@hide} */
1340 public int[] supplyPukReportResult(String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001341 return supplyPukReportResultForSubscriber(getDefaultSubscription(), puk, pin);
Wink Saville36469e72014-06-11 15:17:00 -07001342 }
1343
Wink Savilleb564aae2014-10-23 10:18:09 -07001344 public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001345 enforceModifyPermission();
Malcolm Chend965c8b2018-02-28 15:00:40 -08001346
1347 final long identity = Binder.clearCallingIdentity();
1348 try {
1349 final UnlockSim checkSimPuk = new UnlockSim(getPhone(subId).getIccCard());
1350 checkSimPuk.start();
1351 return checkSimPuk.unlockSim(puk, pin);
1352 } finally {
1353 Binder.restoreCallingIdentity(identity);
1354 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001355 }
1356
1357 /**
Wink Saville9de0f752013-10-22 19:04:03 -07001358 * Helper thread to turn async call to SimCard#supplyPin into
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001359 * a synchronous one.
1360 */
1361 private static class UnlockSim extends Thread {
1362
1363 private final IccCard mSimCard;
1364
1365 private boolean mDone = false;
Wink Saville9de0f752013-10-22 19:04:03 -07001366 private int mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1367 private int mRetryCount = -1;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001368
1369 // For replies from SimCard interface
1370 private Handler mHandler;
1371
1372 // For async handler to identify request type
1373 private static final int SUPPLY_PIN_COMPLETE = 100;
1374
1375 public UnlockSim(IccCard simCard) {
1376 mSimCard = simCard;
1377 }
1378
1379 @Override
1380 public void run() {
1381 Looper.prepare();
1382 synchronized (UnlockSim.this) {
1383 mHandler = new Handler() {
1384 @Override
1385 public void handleMessage(Message msg) {
1386 AsyncResult ar = (AsyncResult) msg.obj;
1387 switch (msg.what) {
1388 case SUPPLY_PIN_COMPLETE:
1389 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
1390 synchronized (UnlockSim.this) {
Wink Saville9de0f752013-10-22 19:04:03 -07001391 mRetryCount = msg.arg1;
1392 if (ar.exception != null) {
1393 if (ar.exception instanceof CommandException &&
1394 ((CommandException)(ar.exception)).getCommandError()
1395 == CommandException.Error.PASSWORD_INCORRECT) {
1396 mResult = PhoneConstants.PIN_PASSWORD_INCORRECT;
1397 } else {
1398 mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1399 }
1400 } else {
1401 mResult = PhoneConstants.PIN_RESULT_SUCCESS;
1402 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001403 mDone = true;
1404 UnlockSim.this.notifyAll();
1405 }
1406 break;
1407 }
1408 }
1409 };
1410 UnlockSim.this.notifyAll();
1411 }
1412 Looper.loop();
1413 }
1414
1415 /*
1416 * Use PIN or PUK to unlock SIM card
1417 *
1418 * If PUK is null, unlock SIM card with PIN
1419 *
1420 * If PUK is not null, unlock SIM card with PUK and set PIN code
1421 */
Wink Saville9de0f752013-10-22 19:04:03 -07001422 synchronized int[] unlockSim(String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001423
1424 while (mHandler == null) {
1425 try {
1426 wait();
1427 } catch (InterruptedException e) {
1428 Thread.currentThread().interrupt();
1429 }
1430 }
1431 Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
1432
1433 if (puk == null) {
1434 mSimCard.supplyPin(pin, callback);
1435 } else {
1436 mSimCard.supplyPuk(puk, pin, callback);
1437 }
1438
1439 while (!mDone) {
1440 try {
1441 Log.d(LOG_TAG, "wait for done");
1442 wait();
1443 } catch (InterruptedException e) {
1444 // Restore the interrupted status
1445 Thread.currentThread().interrupt();
1446 }
1447 }
1448 Log.d(LOG_TAG, "done");
Wink Saville9de0f752013-10-22 19:04:03 -07001449 int[] resultArray = new int[2];
1450 resultArray[0] = mResult;
1451 resultArray[1] = mRetryCount;
1452 return resultArray;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001453 }
1454 }
1455
1456 public void updateServiceLocation() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001457 updateServiceLocationForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001458
1459 }
1460
Wink Savilleb564aae2014-10-23 10:18:09 -07001461 public void updateServiceLocationForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001462 // No permission check needed here: this call is harmless, and it's
1463 // needed for the ServiceState.requestStateUpdate() call (which is
1464 // already intentionally exposed to 3rd parties.)
Malcolm Chend965c8b2018-02-28 15:00:40 -08001465 final long identity = Binder.clearCallingIdentity();
1466 try {
1467 final Phone phone = getPhone(subId);
1468 if (phone != null) {
1469 phone.updateServiceLocation();
1470 }
1471 } finally {
1472 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001473 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001474 }
1475
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001476 @Override
1477 public boolean isRadioOn(String callingPackage) {
1478 return isRadioOnForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07001479 }
1480
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001481 @Override
1482 public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08001483 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08001484 mApp, subId, callingPackage, "isRadioOnForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001485 return false;
1486 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08001487
1488 final long identity = Binder.clearCallingIdentity();
1489 try {
1490 return isRadioOnForSubscriber(subId);
1491 } finally {
1492 Binder.restoreCallingIdentity(identity);
1493 }
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001494 }
1495
1496 private boolean isRadioOnForSubscriber(int subId) {
Malcolm Chend965c8b2018-02-28 15:00:40 -08001497 final long identity = Binder.clearCallingIdentity();
1498 try {
1499 final Phone phone = getPhone(subId);
1500 if (phone != null) {
1501 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
1502 } else {
1503 return false;
1504 }
1505 } finally {
1506 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001507 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001508 }
1509
1510 public void toggleRadioOnOff() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001511 toggleRadioOnOffForSubscriber(getDefaultSubscription());
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001512 }
Wink Saville36469e72014-06-11 15:17:00 -07001513
Wink Savilleb564aae2014-10-23 10:18:09 -07001514 public void toggleRadioOnOffForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001515 enforceModifyPermission();
Malcolm Chend965c8b2018-02-28 15:00:40 -08001516
1517 final long identity = Binder.clearCallingIdentity();
1518 try {
1519 final Phone phone = getPhone(subId);
1520 if (phone != null) {
1521 phone.setRadioPower(!isRadioOnForSubscriber(subId));
1522 }
1523 } finally {
1524 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001525 }
Wink Saville36469e72014-06-11 15:17:00 -07001526 }
1527
1528 public boolean setRadio(boolean turnOn) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001529 return setRadioForSubscriber(getDefaultSubscription(), turnOn);
Wink Saville36469e72014-06-11 15:17:00 -07001530 }
1531
Wink Savilleb564aae2014-10-23 10:18:09 -07001532 public boolean setRadioForSubscriber(int subId, boolean turnOn) {
Wink Saville36469e72014-06-11 15:17:00 -07001533 enforceModifyPermission();
Malcolm Chend965c8b2018-02-28 15:00:40 -08001534
1535 final long identity = Binder.clearCallingIdentity();
1536 try {
1537 final Phone phone = getPhone(subId);
1538 if (phone == null) {
1539 return false;
1540 }
1541 if ((phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF) != turnOn) {
1542 toggleRadioOnOffForSubscriber(subId);
1543 }
1544 return true;
1545 } finally {
1546 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001547 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001548 }
Wink Saville36469e72014-06-11 15:17:00 -07001549
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001550 public boolean needMobileRadioShutdown() {
1551 /*
1552 * If any of the Radios are available, it will need to be
1553 * shutdown. So return true if any Radio is available.
1554 */
Malcolm Chend965c8b2018-02-28 15:00:40 -08001555 final long identity = Binder.clearCallingIdentity();
1556 try {
1557 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1558 Phone phone = PhoneFactory.getPhone(i);
1559 if (phone != null && phone.isRadioAvailable()) return true;
1560 }
1561 logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown.");
1562 return false;
1563 } finally {
1564 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001565 }
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001566 }
1567
Malcolm Chend965c8b2018-02-28 15:00:40 -08001568 @Override
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001569 public void shutdownMobileRadios() {
Malcolm Chend965c8b2018-02-28 15:00:40 -08001570 enforceModifyPermission();
1571
1572 final long identity = Binder.clearCallingIdentity();
1573 try {
1574 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1575 logv("Shutting down Phone " + i);
1576 shutdownRadioUsingPhoneId(i);
1577 }
1578 } finally {
1579 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001580 }
1581 }
1582
1583 private void shutdownRadioUsingPhoneId(int phoneId) {
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001584 Phone phone = PhoneFactory.getPhone(phoneId);
1585 if (phone != null && phone.isRadioAvailable()) {
1586 phone.shutdownRadio();
1587 }
1588 }
1589
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001590 public boolean setRadioPower(boolean turnOn) {
Jack Yub4e16162017-05-15 12:48:40 -07001591 enforceModifyPermission();
Malcolm Chend965c8b2018-02-28 15:00:40 -08001592
1593 final long identity = Binder.clearCallingIdentity();
1594 try {
1595 final Phone defaultPhone = PhoneFactory.getDefaultPhone();
1596 if (defaultPhone != null) {
1597 defaultPhone.setRadioPower(turnOn);
1598 return true;
1599 } else {
1600 loge("There's no default phone.");
1601 return false;
1602 }
1603 } finally {
1604 Binder.restoreCallingIdentity(identity);
Wei Liu9ae2a062016-08-08 11:09:34 -07001605 }
Wink Saville36469e72014-06-11 15:17:00 -07001606 }
1607
Wink Savilleb564aae2014-10-23 10:18:09 -07001608 public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001609 enforceModifyPermission();
Malcolm Chend965c8b2018-02-28 15:00:40 -08001610
1611 final long identity = Binder.clearCallingIdentity();
1612 try {
1613 final Phone phone = getPhone(subId);
1614 if (phone != null) {
1615 phone.setRadioPower(turnOn);
1616 return true;
1617 } else {
1618 return false;
1619 }
1620 } finally {
1621 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001622 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001623 }
1624
Wink Saville36469e72014-06-11 15:17:00 -07001625 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07001626 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001627 public boolean enableDataConnectivity() {
1628 enforceModifyPermission();
Malcolm Chend965c8b2018-02-28 15:00:40 -08001629
1630 final long identity = Binder.clearCallingIdentity();
1631 try {
1632 int subId = mSubscriptionController.getDefaultDataSubId();
1633 final Phone phone = getPhone(subId);
1634 if (phone != null) {
1635 phone.setUserDataEnabled(true);
1636 return true;
1637 } else {
1638 return false;
1639 }
1640 } finally {
1641 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001642 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001643 }
1644
Wink Saville36469e72014-06-11 15:17:00 -07001645 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07001646 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001647 public boolean disableDataConnectivity() {
1648 enforceModifyPermission();
Malcolm Chend965c8b2018-02-28 15:00:40 -08001649
1650 final long identity = Binder.clearCallingIdentity();
1651 try {
1652 int subId = mSubscriptionController.getDefaultDataSubId();
1653 final Phone phone = getPhone(subId);
1654 if (phone != null) {
1655 phone.setUserDataEnabled(false);
1656 return true;
1657 } else {
1658 return false;
1659 }
1660 } finally {
1661 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001662 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001663 }
1664
Sanket Padawe356d7632015-06-22 14:03:32 -07001665 @Override
Jack Yuacf8a132017-05-01 17:00:48 -07001666 public boolean isDataConnectivityPossible(int subId) {
Malcolm Chend965c8b2018-02-28 15:00:40 -08001667 final long identity = Binder.clearCallingIdentity();
1668 try {
1669 final Phone phone = getPhone(subId);
1670 if (phone != null) {
1671 return phone.isDataAllowed();
1672 } else {
1673 return false;
1674 }
1675 } finally {
1676 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001677 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001678 }
1679
1680 public boolean handlePinMmi(String dialString) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001681 return handlePinMmiForSubscriber(getDefaultSubscription(), dialString);
Wink Saville36469e72014-06-11 15:17:00 -07001682 }
1683
pkanwarae03a6b2016-11-06 20:37:09 -08001684 public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
Malcolm Chend965c8b2018-02-28 15:00:40 -08001685 enforceCallPermission();
1686
1687 final long identity = Binder.clearCallingIdentity();
1688 try {
1689 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1690 return;
1691 }
1692 Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback);
1693 sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId);
1694 } finally {
1695 Binder.restoreCallingIdentity(identity);
1696 }
pkanwar32d516d2016-10-14 19:37:38 -07001697 };
1698
Wink Savilleb564aae2014-10-23 10:18:09 -07001699 public boolean handlePinMmiForSubscriber(int subId, String dialString) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001700 enforceModifyPermission();
Malcolm Chend965c8b2018-02-28 15:00:40 -08001701
1702 final long identity = Binder.clearCallingIdentity();
1703 try {
1704 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1705 return false;
1706 }
1707 return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
1708 } finally {
1709 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001710 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001711 }
1712
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001713 public int getCallState() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07001714 return getCallStateForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001715 }
1716
Sanket Padawe13bac7b2017-03-20 15:04:47 -07001717 public int getCallStateForSlot(int slotIndex) {
Malcolm Chend965c8b2018-02-28 15:00:40 -08001718 final long identity = Binder.clearCallingIdentity();
1719 try {
1720 Phone phone = PhoneFactory.getPhone(slotIndex);
1721 return phone == null ? TelephonyManager.CALL_STATE_IDLE :
1722 PhoneConstantConversions.convertCallState(phone.getState());
1723 } finally {
1724 Binder.restoreCallingIdentity(identity);
1725 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001726 }
1727
Sanket Padawe356d7632015-06-22 14:03:32 -07001728 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001729 public int getDataState() {
Malcolm Chend965c8b2018-02-28 15:00:40 -08001730 final long identity = Binder.clearCallingIdentity();
1731 try {
1732 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1733 if (phone != null) {
1734 return PhoneConstantConversions.convertDataState(phone.getDataConnectionState());
1735 } else {
1736 return PhoneConstantConversions.convertDataState(
1737 PhoneConstants.DataState.DISCONNECTED);
1738 }
1739 } finally {
1740 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001741 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001742 }
1743
Sanket Padawe356d7632015-06-22 14:03:32 -07001744 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001745 public int getDataActivity() {
Malcolm Chend965c8b2018-02-28 15:00:40 -08001746 final long identity = Binder.clearCallingIdentity();
1747 try {
1748 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1749 if (phone != null) {
1750 return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState());
1751 } else {
1752 return TelephonyManager.DATA_ACTIVITY_NONE;
1753 }
1754 } finally {
1755 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001756 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001757 }
1758
1759 @Override
Svetoslav64fad262015-04-14 14:35:21 -07001760 public Bundle getCellLocation(String callingPackage) {
Hall Liu1aa510f2017-11-22 17:40:08 -08001761 mPhone.getContext().getSystemService(AppOpsManager.class)
1762 .checkPackage(Binder.getCallingUid(), callingPackage);
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001763 if (!LocationAccessPolicy.canAccessCellLocation(mPhone.getContext(),
Svet Ganov4af66282018-03-07 19:57:05 -08001764 callingPackage, Binder.getCallingUid(), Binder.getCallingPid(), true)) {
Svetoslav64fad262015-04-14 14:35:21 -07001765 return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001766 }
1767
Narayan Kamathf04b5a12018-01-09 11:47:15 +00001768 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chend965c8b2018-02-28 15:00:40 -08001769 final long identity = Binder.clearCallingIdentity();
1770 try {
1771 if (DBG_LOC) log("getCellLocation: is active user");
1772 Bundle data = new Bundle();
Nathan Harold3ff88932018-08-14 10:19:49 -07001773 int subId = mSubscriptionController.getDefaultDataSubId();
1774 CellLocation cl = (CellLocation) sendRequest(CMD_GET_CELL_LOCATION, workSource, subId);
1775 cl.fillInNotifierBundle(data);
Malcolm Chend965c8b2018-02-28 15:00:40 -08001776 return data;
1777 } finally {
1778 Binder.restoreCallingIdentity(identity);
1779 }
Svetoslav64fad262015-04-14 14:35:21 -07001780 }
1781
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001782 @Override
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001783 public String getNetworkCountryIsoForPhone(int phoneId) {
1784 // Reporting the correct network country is ambiguous when IWLAN could conflict with
1785 // registered cell info, so return a NULL country instead.
1786 final long identity = Binder.clearCallingIdentity();
1787 try {
Malcolm Chen3732c2b2018-07-18 20:15:24 -07001788 if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
1789 // Get default phone in this case.
1790 phoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
1791 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001792 final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
Jack Yu5f7092c2018-04-13 14:05:37 -07001793 // Todo: fix this when we can get the actual cellular network info when the device
1794 // is on IWLAN.
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001795 if (TelephonyManager.NETWORK_TYPE_IWLAN
1796 == getVoiceNetworkTypeForSubscriber(subId, mApp.getPackageName())) {
1797 return "";
1798 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08001799 Phone phone = PhoneFactory.getPhone(phoneId);
1800 if (phone != null) {
1801 ServiceStateTracker sst = phone.getServiceStateTracker();
1802 if (sst != null) {
1803 LocaleTracker lt = sst.getLocaleTracker();
1804 if (lt != null) {
1805 return lt.getCurrentCountry();
1806 }
1807 }
1808 }
1809 return "";
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001810 } finally {
1811 Binder.restoreCallingIdentity(identity);
1812 }
Jonathan Basseribf5362b2017-07-19 12:22:35 -07001813 }
1814
1815 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001816 public void enableLocationUpdates() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001817 enableLocationUpdatesForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001818 }
1819
Sanket Padawe356d7632015-06-22 14:03:32 -07001820 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07001821 public void enableLocationUpdatesForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001822 mApp.enforceCallingOrSelfPermission(
1823 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Malcolm Chend965c8b2018-02-28 15:00:40 -08001824
1825 final long identity = Binder.clearCallingIdentity();
1826 try {
1827 final Phone phone = getPhone(subId);
1828 if (phone != null) {
1829 phone.enableLocationUpdates();
1830 }
1831 } finally {
1832 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001833 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001834 }
1835
1836 @Override
1837 public void disableLocationUpdates() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001838 disableLocationUpdatesForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001839 }
1840
Sanket Padawe356d7632015-06-22 14:03:32 -07001841 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07001842 public void disableLocationUpdatesForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001843 mApp.enforceCallingOrSelfPermission(
1844 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Malcolm Chend965c8b2018-02-28 15:00:40 -08001845
1846 final long identity = Binder.clearCallingIdentity();
1847 try {
1848 final Phone phone = getPhone(subId);
1849 if (phone != null) {
1850 phone.disableLocationUpdates();
1851 }
1852 } finally {
1853 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001854 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001855 }
1856
Nathan Harold31d7ff32018-10-15 20:20:30 -07001857 /**
1858 * Returns the target SDK version number for a given package name.
1859 *
1860 * @return target SDK if the package is found or INT_MAX.
1861 */
1862 private int getTargetSdk(String packageName) {
1863 try {
1864 final ApplicationInfo ai =
1865 mPhone.getContext().getPackageManager().getApplicationInfo(packageName, 0);
1866 if (ai != null) return ai.targetSdkVersion;
1867 } catch (PackageManager.NameNotFoundException unexpected) {
1868 }
1869 return Integer.MAX_VALUE;
1870 }
1871
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001872 @Override
1873 @SuppressWarnings("unchecked")
Nathan Harold31d7ff32018-10-15 20:20:30 -07001874 public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage) {
1875 final int targetSdk = getTargetSdk(callingPackage);
Nathan Harolddbea45a2018-08-30 14:35:07 -07001876 if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
1877 throw new SecurityException(
1878 "getNeighboringCellInfo() is unavailable to callers targeting Q+ SDK levels.");
1879 }
Nathan Haroldb4d55612018-07-20 13:13:08 -07001880
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001881 if (mAppOps.noteOp(AppOpsManager.OP_NEIGHBORING_CELLS, Binder.getCallingUid(),
1882 callingPackage) != AppOpsManager.MODE_ALLOWED) {
1883 return null;
1884 }
Svetoslav64fad262015-04-14 14:35:21 -07001885
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001886 if (DBG_LOC) log("getNeighboringCellInfo: is active user");
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001887
Nathan Haroldf180aac2018-06-01 18:43:55 -07001888 List<CellInfo> info = getAllCellInfo(callingPackage);
1889 if (info == null) return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001890
Nathan Haroldf180aac2018-06-01 18:43:55 -07001891 List<NeighboringCellInfo> neighbors = new ArrayList<NeighboringCellInfo>();
1892 for (CellInfo ci : info) {
1893 if (ci instanceof CellInfoGsm) {
1894 neighbors.add(new NeighboringCellInfo((CellInfoGsm) ci));
1895 } else if (ci instanceof CellInfoWcdma) {
1896 neighbors.add(new NeighboringCellInfo((CellInfoWcdma) ci));
1897 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001898 }
Nathan Haroldf180aac2018-06-01 18:43:55 -07001899 return (neighbors.size()) > 0 ? neighbors : null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001900 }
1901
1902
1903 @Override
Svetoslav64fad262015-04-14 14:35:21 -07001904 public List<CellInfo> getAllCellInfo(String callingPackage) {
Hall Liu1aa510f2017-11-22 17:40:08 -08001905 mPhone.getContext().getSystemService(AppOpsManager.class)
1906 .checkPackage(Binder.getCallingUid(), callingPackage);
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001907 if (!LocationAccessPolicy.canAccessCellLocation(mPhone.getContext(),
Svet Ganov4af66282018-03-07 19:57:05 -08001908 callingPackage, Binder.getCallingUid(), Binder.getCallingPid(), true)) {
Svetoslav64fad262015-04-14 14:35:21 -07001909 return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001910 }
1911
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001912 if (DBG_LOC) log("getAllCellInfo: is active user");
Narayan Kamathf04b5a12018-01-09 11:47:15 +00001913 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chend965c8b2018-02-28 15:00:40 -08001914 final long identity = Binder.clearCallingIdentity();
1915 try {
1916 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
1917 for (Phone phone : PhoneFactory.getPhones()) {
Nathan Harold3ff88932018-08-14 10:19:49 -07001918 final List<CellInfo> info = (List<CellInfo>) sendRequest(
Nathan Harold92bed182018-10-12 18:16:49 -07001919 CMD_GET_ALL_CELL_INFO, null, phone, workSource);
Malcolm Chend965c8b2018-02-28 15:00:40 -08001920 if (info != null) cellInfos.addAll(info);
1921 }
1922 return cellInfos;
1923 } finally {
1924 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001925 }
1926 }
1927
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001928 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001929 public void setCellInfoListRate(int rateInMillis) {
Jack Yua8d8cb82017-01-16 10:15:34 -08001930 enforceModifyPermission();
Narayan Kamathf04b5a12018-01-09 11:47:15 +00001931 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chend965c8b2018-02-28 15:00:40 -08001932
1933 final long identity = Binder.clearCallingIdentity();
1934 try {
1935 mPhone.setCellInfoListRate(rateInMillis, workSource);
1936 } finally {
1937 Binder.restoreCallingIdentity(identity);
1938 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001939 }
1940
Shishir Agrawala9f32182016-04-12 12:00:16 -07001941 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07001942 public String getImeiForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08001943 Phone phone = PhoneFactory.getPhone(slotIndex);
1944 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08001945 return null;
1946 }
Jeff Davidson913390f2018-02-23 17:11:49 -08001947 int subId = phone.getSubId();
1948 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
1949 mApp, subId, callingPackage, "getImeiForSlot")) {
1950 return null;
1951 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08001952
1953 final long identity = Binder.clearCallingIdentity();
1954 try {
1955 return phone.getImei();
1956 } finally {
1957 Binder.restoreCallingIdentity(identity);
1958 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07001959 }
1960
1961 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00001962 public String getTypeAllocationCodeForSlot(int slotIndex) {
1963 Phone phone = PhoneFactory.getPhone(slotIndex);
1964 String tac = null;
1965 if (phone != null) {
1966 String imei = phone.getImei();
1967 tac = imei == null ? null : imei.substring(0, TYPE_ALLOCATION_CODE_LENGTH);
1968 }
1969 return tac;
1970 }
1971
1972 @Override
Jack Yu2af8d712017-03-15 17:14:14 -07001973 public String getMeidForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08001974 Phone phone = PhoneFactory.getPhone(slotIndex);
1975 if (phone == null) {
Jack Yu2af8d712017-03-15 17:14:14 -07001976 return null;
1977 }
Jeff Davidson913390f2018-02-23 17:11:49 -08001978 int subId = phone.getSubId();
1979 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
1980 mApp, subId, callingPackage, "getMeidForSlot")) {
1981 return null;
1982 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08001983
1984 final long identity = Binder.clearCallingIdentity();
1985 try {
1986 return phone.getMeid();
1987 } finally {
1988 Binder.restoreCallingIdentity(identity);
1989 }
Jack Yu2af8d712017-03-15 17:14:14 -07001990 }
1991
1992 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00001993 public String getManufacturerCodeForSlot(int slotIndex) {
1994 Phone phone = PhoneFactory.getPhone(slotIndex);
1995 String manufacturerCode = null;
1996 if (phone != null) {
1997 String meid = phone.getMeid();
1998 manufacturerCode = meid == null ? null : meid.substring(0, MANUFACTURER_CODE_LENGTH);
1999 }
2000 return manufacturerCode;
2001 }
2002
2003 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002004 public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08002005 Phone phone = PhoneFactory.getPhone(slotIndex);
2006 if (phone == null) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002007 return null;
2008 }
Jeff Davidson913390f2018-02-23 17:11:49 -08002009 int subId = phone.getSubId();
2010 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2011 mApp, subId, callingPackage, "getDeviceSoftwareVersionForSlot")) {
2012 return null;
2013 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08002014
2015 final long identity = Binder.clearCallingIdentity();
2016 try {
2017 return phone.getDeviceSvn();
2018 } finally {
2019 Binder.restoreCallingIdentity(identity);
2020 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002021 }
2022
fionaxu43304da2017-11-27 22:51:16 -08002023 @Override
2024 public int getSubscriptionCarrierId(int subId) {
Malcolm Chend965c8b2018-02-28 15:00:40 -08002025 final long identity = Binder.clearCallingIdentity();
2026 try {
2027 final Phone phone = getPhone(subId);
2028 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getCarrierId();
2029 } finally {
2030 Binder.restoreCallingIdentity(identity);
2031 }
fionaxu43304da2017-11-27 22:51:16 -08002032 }
2033
2034 @Override
2035 public String getSubscriptionCarrierName(int subId) {
Malcolm Chend965c8b2018-02-28 15:00:40 -08002036 final long identity = Binder.clearCallingIdentity();
2037 try {
2038 final Phone phone = getPhone(subId);
2039 return phone == null ? null : phone.getCarrierName();
2040 } finally {
2041 Binder.restoreCallingIdentity(identity);
2042 }
fionaxu43304da2017-11-27 22:51:16 -08002043 }
2044
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002045 //
2046 // Internal helper methods.
2047 //
2048
Sanket Padaweee13a9b2016-03-08 17:30:28 -08002049 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002050 * Make sure the caller has the MODIFY_PHONE_STATE permission.
2051 *
2052 * @throws SecurityException if the caller does not have the required permission
2053 */
2054 private void enforceModifyPermission() {
2055 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
2056 }
2057
2058 /**
2059 * Make sure the caller has the CALL_PHONE permission.
2060 *
2061 * @throws SecurityException if the caller does not have the required permission
2062 */
2063 private void enforceCallPermission() {
2064 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
2065 }
2066
Stuart Scott8eef64f2015-04-08 15:13:54 -07002067 private void enforceConnectivityInternalPermission() {
2068 mApp.enforceCallingOrSelfPermission(
2069 android.Manifest.permission.CONNECTIVITY_INTERNAL,
2070 "ConnectivityService");
2071 }
2072
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002073 private String createTelUrl(String number) {
2074 if (TextUtils.isEmpty(number)) {
2075 return null;
2076 }
2077
Jake Hambye994d462014-02-03 13:10:13 -08002078 return "tel:" + number;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002079 }
2080
Ihab Awadf9e92732013-12-05 18:02:52 -08002081 private static void log(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002082 Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg);
2083 }
2084
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002085 private static void logv(String msg) {
2086 Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg);
2087 }
2088
Ihab Awadf9e92732013-12-05 18:02:52 -08002089 private static void loge(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002090 Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg);
2091 }
2092
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002093 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002094 public int getActivePhoneType() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07002095 return getActivePhoneTypeForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002096 }
2097
Sanket Padawe356d7632015-06-22 14:03:32 -07002098 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002099 public int getActivePhoneTypeForSlot(int slotIndex) {
Malcolm Chend965c8b2018-02-28 15:00:40 -08002100 final long identity = Binder.clearCallingIdentity();
2101 try {
2102 final Phone phone = PhoneFactory.getPhone(slotIndex);
2103 if (phone == null) {
2104 return PhoneConstants.PHONE_TYPE_NONE;
2105 } else {
2106 return phone.getPhoneType();
2107 }
2108 } finally {
2109 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002110 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002111 }
2112
2113 /**
2114 * Returns the CDMA ERI icon index to display
2115 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002116 @Override
2117 public int getCdmaEriIconIndex(String callingPackage) {
2118 return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002119 }
2120
Sanket Padawe356d7632015-06-22 14:03:32 -07002121 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002122 public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002123 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002124 mApp, subId, callingPackage, "getCdmaEriIconIndexForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002125 return -1;
2126 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08002127
2128 final long identity = Binder.clearCallingIdentity();
2129 try {
2130 final Phone phone = getPhone(subId);
2131 if (phone != null) {
2132 return phone.getCdmaEriIconIndex();
2133 } else {
2134 return -1;
2135 }
2136 } finally {
2137 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002138 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002139 }
2140
2141 /**
2142 * Returns the CDMA ERI icon mode,
2143 * 0 - ON
2144 * 1 - FLASHING
2145 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002146 @Override
2147 public int getCdmaEriIconMode(String callingPackage) {
2148 return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002149 }
2150
Sanket Padawe356d7632015-06-22 14:03:32 -07002151 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002152 public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002153 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002154 mApp, subId, callingPackage, "getCdmaEriIconModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002155 return -1;
2156 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08002157
2158 final long identity = Binder.clearCallingIdentity();
2159 try {
2160 final Phone phone = getPhone(subId);
2161 if (phone != null) {
2162 return phone.getCdmaEriIconMode();
2163 } else {
2164 return -1;
2165 }
2166 } finally {
2167 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002168 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002169 }
2170
2171 /**
2172 * Returns the CDMA ERI text,
2173 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002174 @Override
2175 public String getCdmaEriText(String callingPackage) {
2176 return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002177 }
2178
Sanket Padawe356d7632015-06-22 14:03:32 -07002179 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002180 public String getCdmaEriTextForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002181 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002182 mApp, subId, callingPackage, "getCdmaEriIconTextForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002183 return null;
2184 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08002185
2186 final long identity = Binder.clearCallingIdentity();
2187 try {
2188 final Phone phone = getPhone(subId);
2189 if (phone != null) {
2190 return phone.getCdmaEriText();
2191 } else {
2192 return null;
2193 }
2194 } finally {
2195 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002196 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002197 }
2198
2199 /**
Junda Liuca05d5d2014-08-14 22:36:34 -07002200 * Returns the CDMA MDN.
2201 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002202 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002203 public String getCdmaMdn(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002204 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2205 mApp, subId, "getCdmaMdn");
Malcolm Chend965c8b2018-02-28 15:00:40 -08002206
2207 final long identity = Binder.clearCallingIdentity();
2208 try {
2209 final Phone phone = getPhone(subId);
2210 if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA && phone != null) {
2211 return phone.getLine1Number();
2212 } else {
2213 return null;
2214 }
2215 } finally {
2216 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07002217 }
2218 }
2219
2220 /**
2221 * Returns the CDMA MIN.
2222 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002223 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002224 public String getCdmaMin(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002225 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2226 mApp, subId, "getCdmaMin");
Malcolm Chend965c8b2018-02-28 15:00:40 -08002227
2228 final long identity = Binder.clearCallingIdentity();
2229 try {
2230 final Phone phone = getPhone(subId);
2231 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
2232 return phone.getCdmaMin();
2233 } else {
2234 return null;
2235 }
2236 } finally {
2237 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07002238 }
2239 }
2240
2241 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002242 * Returns true if CDMA provisioning needs to run.
2243 */
2244 public boolean needsOtaServiceProvisioning() {
Malcolm Chend965c8b2018-02-28 15:00:40 -08002245 final long identity = Binder.clearCallingIdentity();
2246 try {
2247 return mPhone.needsOtaServiceProvisioning();
2248 } finally {
2249 Binder.restoreCallingIdentity(identity);
2250 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002251 }
2252
2253 /**
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002254 * Sets the voice mail number of a given subId.
2255 */
2256 @Override
2257 public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002258 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setVoiceMailNumber");
Malcolm Chend965c8b2018-02-28 15:00:40 -08002259
2260 final long identity = Binder.clearCallingIdentity();
2261 try {
2262 Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
2263 new Pair<String, String>(alphaTag, number), new Integer(subId));
2264 return success;
2265 } finally {
2266 Binder.restoreCallingIdentity(identity);
2267 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002268 }
2269
Ta-wei Yen87c49842016-05-13 21:19:52 -07002270 @Override
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002271 public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
2272 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2273 String systemDialer = TelecomManager.from(mPhone.getContext()).getSystemDialerPackage();
2274 if (!TextUtils.equals(callingPackage, systemDialer)) {
2275 throw new SecurityException("caller must be system dialer");
2276 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08002277
2278 final long identity = Binder.clearCallingIdentity();
2279 try {
2280 PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
2281 if (phoneAccountHandle == null) {
2282 return null;
2283 }
2284 return VisualVoicemailSettingsUtil.dump(mPhone.getContext(), phoneAccountHandle);
2285 } finally {
2286 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002287 }
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002288 }
2289
2290 @Override
Ta-wei Yen409ac562017-03-06 16:00:44 -08002291 public String getVisualVoicemailPackageName(String callingPackage, int subId) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08002292 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jeff Davidson7e17e312018-02-13 18:17:36 -08002293 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002294 mApp, subId, callingPackage, "getVisualVoicemailPackageName")) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08002295 return null;
2296 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08002297
Jeff Davidsona8e4e242018-03-15 17:16:18 -07002298 final long identity = Binder.clearCallingIdentity();
2299 try {
2300 return RemoteVvmTaskManager
2301 .getRemotePackage(mPhone.getContext(), subId).getPackageName();
2302 } finally {
2303 Binder.restoreCallingIdentity(identity);
2304 }
Ta-wei Yendca928f2017-01-10 16:17:08 -08002305 }
2306
2307 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002308 public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
2309 VisualVoicemailSmsFilterSettings settings) {
2310 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chend965c8b2018-02-28 15:00:40 -08002311
2312 final long identity = Binder.clearCallingIdentity();
2313 try {
2314 VisualVoicemailSmsFilterConfig.enableVisualVoicemailSmsFilter(
2315 mPhone.getContext(), callingPackage, subId, settings);
2316 } finally {
2317 Binder.restoreCallingIdentity(identity);
2318 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002319 }
2320
2321 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002322 public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
2323 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chend965c8b2018-02-28 15:00:40 -08002324
2325 final long identity = Binder.clearCallingIdentity();
2326 try {
2327 VisualVoicemailSmsFilterConfig.disableVisualVoicemailSmsFilter(
2328 mPhone.getContext(), callingPackage, subId);
2329 } finally {
2330 Binder.restoreCallingIdentity(identity);
2331 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002332 }
2333
2334 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002335 public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
2336 String callingPackage, int subId) {
2337 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chend965c8b2018-02-28 15:00:40 -08002338
2339 final long identity = Binder.clearCallingIdentity();
2340 try {
2341 return VisualVoicemailSmsFilterConfig.getVisualVoicemailSmsFilterSettings(
2342 mPhone.getContext(), callingPackage, subId);
2343 } finally {
2344 Binder.restoreCallingIdentity(identity);
2345 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002346 }
2347
2348 @Override
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002349 public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
Brad Ebinger4c460712018-10-01 10:40:55 -07002350 enforceReadPrivilegedPermission("getActiveVisualVoicemailSmsFilterSettings");
Malcolm Chend965c8b2018-02-28 15:00:40 -08002351
2352 final long identity = Binder.clearCallingIdentity();
2353 try {
2354 return VisualVoicemailSmsFilterConfig.getActiveVisualVoicemailSmsFilterSettings(
2355 mPhone.getContext(), subId);
2356 } finally {
2357 Binder.restoreCallingIdentity(identity);
2358 }
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002359 }
2360
2361 @Override
2362 public void sendVisualVoicemailSmsForSubscriber(String callingPackage, int subId,
2363 String number, int port, String text, PendingIntent sentIntent) {
2364 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Ta-wei Yen527a9c02017-01-06 15:29:25 -08002365 enforceVisualVoicemailPackage(callingPackage, subId);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002366 enforceSendSmsPermission();
2367 // Make the calls as the phone process.
2368 final long identity = Binder.clearCallingIdentity();
2369 try {
2370 SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(subId);
2371 if (port == 0) {
2372 smsManager.sendTextMessageWithSelfPermissions(number, null, text,
2373 sentIntent, null, false);
2374 } else {
2375 byte[] data = text.getBytes(StandardCharsets.UTF_8);
2376 smsManager.sendDataMessageWithSelfPermissions(number, null,
2377 (short) port, data, sentIntent, null);
2378 }
2379 } finally {
2380 Binder.restoreCallingIdentity(identity);
2381 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002382 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002383 /**
fionaxu0152e512016-11-14 13:36:14 -08002384 * Sets the voice activation state of a given subId.
2385 */
2386 @Override
2387 public void setVoiceActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002388 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2389 mApp, subId, "setVoiceActivationState");
Malcolm Chend965c8b2018-02-28 15:00:40 -08002390
2391 final long identity = Binder.clearCallingIdentity();
2392 try {
2393 final Phone phone = getPhone(subId);
2394 if (phone != null) {
2395 phone.setVoiceActivationState(activationState);
2396 } else {
2397 loge("setVoiceActivationState fails with invalid subId: " + subId);
2398 }
2399 } finally {
2400 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002401 }
2402 }
2403
2404 /**
2405 * Sets the data activation state of a given subId.
2406 */
2407 @Override
2408 public void setDataActivationState(int subId, int activationState) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002409 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2410 mApp, subId, "setDataActivationState");
Malcolm Chend965c8b2018-02-28 15:00:40 -08002411
2412 final long identity = Binder.clearCallingIdentity();
2413 try {
2414 final Phone phone = getPhone(subId);
2415 if (phone != null) {
2416 phone.setDataActivationState(activationState);
2417 } else {
2418 loge("setVoiceActivationState fails with invalid subId: " + subId);
2419 }
2420 } finally {
2421 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002422 }
2423 }
2424
2425 /**
2426 * Returns the voice activation state of a given subId.
2427 */
2428 @Override
2429 public int getVoiceActivationState(int subId, String callingPackage) {
Brad Ebinger4c460712018-10-01 10:40:55 -07002430 enforceReadPrivilegedPermission("getVoiceActivationState");
Malcolm Chend965c8b2018-02-28 15:00:40 -08002431
fionaxu0152e512016-11-14 13:36:14 -08002432 final Phone phone = getPhone(subId);
Malcolm Chend965c8b2018-02-28 15:00:40 -08002433 final long identity = Binder.clearCallingIdentity();
2434 try {
2435 if (phone != null) {
2436 return phone.getVoiceActivationState();
2437 } else {
2438 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2439 }
2440 } finally {
2441 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002442 }
2443 }
2444
2445 /**
2446 * Returns the data activation state of a given subId.
2447 */
2448 @Override
2449 public int getDataActivationState(int subId, String callingPackage) {
Brad Ebinger4c460712018-10-01 10:40:55 -07002450 enforceReadPrivilegedPermission("getDataActivationState");
Malcolm Chend965c8b2018-02-28 15:00:40 -08002451
fionaxu0152e512016-11-14 13:36:14 -08002452 final Phone phone = getPhone(subId);
Malcolm Chend965c8b2018-02-28 15:00:40 -08002453 final long identity = Binder.clearCallingIdentity();
2454 try {
2455 if (phone != null) {
2456 return phone.getDataActivationState();
2457 } else {
2458 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2459 }
2460 } finally {
2461 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002462 }
2463 }
2464
2465 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002466 * Returns the unread count of voicemails
2467 */
2468 public int getVoiceMessageCount() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002469 return getVoiceMessageCountForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002470 }
2471
2472 /**
2473 * Returns the unread count of voicemails for a subId
2474 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002475 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002476 public int getVoiceMessageCountForSubscriber( int subId) {
Malcolm Chend965c8b2018-02-28 15:00:40 -08002477 final long identity = Binder.clearCallingIdentity();
2478 try {
2479 final Phone phone = getPhone(subId);
2480 if (phone != null) {
2481 return phone.getVoiceMessageCount();
2482 } else {
2483 return 0;
2484 }
2485 } finally {
2486 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002487 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002488 }
2489
2490 /**
pkanwar8a4dcfb2017-01-19 13:43:16 -08002491 * returns true, if the device is in a state where both voice and data
2492 * are supported simultaneously. This can change based on location or network condition.
2493 */
2494 @Override
2495 public boolean isConcurrentVoiceAndDataAllowed(int subId) {
Malcolm Chend965c8b2018-02-28 15:00:40 -08002496 final long identity = Binder.clearCallingIdentity();
2497 try {
2498 final Phone phone = getPhone(subId);
2499 return (phone == null ? false : phone.isConcurrentVoiceAndDataAllowed());
2500 } finally {
2501 Binder.restoreCallingIdentity(identity);
2502 }
pkanwar8a4dcfb2017-01-19 13:43:16 -08002503 }
2504
2505 /**
fionaxu235cc5e2017-03-06 22:25:57 -08002506 * Send the dialer code if called from the current default dialer or the caller has
2507 * carrier privilege.
2508 * @param inputCode The dialer code to send
2509 */
2510 @Override
2511 public void sendDialerSpecialCode(String callingPackage, String inputCode) {
2512 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2513 String defaultDialer = TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage();
2514 if (!TextUtils.equals(callingPackage, defaultDialer)) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002515 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
2516 getDefaultSubscription(), "sendDialerSpecialCode");
fionaxu235cc5e2017-03-06 22:25:57 -08002517 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08002518
2519 final long identity = Binder.clearCallingIdentity();
2520 try {
2521 mPhone.sendDialerSpecialCode(inputCode);
2522 } finally {
2523 Binder.restoreCallingIdentity(identity);
2524 }
fionaxu235cc5e2017-03-06 22:25:57 -08002525 }
2526
2527 /**
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002528 * Returns the data network type.
2529 * Legacy call, permission-free.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002530 *
2531 * @Deprecated to be removed Q3 2013 use {@link #getDataNetworkType}.
2532 */
2533 @Override
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002534 public int getNetworkType() {
Malcolm Chend965c8b2018-02-28 15:00:40 -08002535 final long identity = Binder.clearCallingIdentity();
2536 try {
2537 final Phone phone = getPhone(getDefaultSubscription());
2538 if (phone != null) {
2539 return phone.getServiceState().getDataNetworkType();
2540 } else {
2541 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2542 }
2543 } finally {
2544 Binder.restoreCallingIdentity(identity);
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002545 }
Wink Saville36469e72014-06-11 15:17:00 -07002546 }
2547
Pengquan Meng0c05b502018-09-06 09:59:22 -07002548 @Override
2549 public int getNetworkSelectionMode(int subId) {
Pengquan Meng466e2482018-09-21 15:54:48 -07002550 if (!isActiveSubscription(subId)) {
2551 return TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
2552 }
2553
Pengquan Meng0c05b502018-09-06 09:59:22 -07002554 return (int) sendRequest(CMD_GET_NETWORK_SELECTION_MODE, null /* argument */, subId);
2555 }
2556
Brad Ebinger4c460712018-10-01 10:40:55 -07002557 @Override
2558 public void addImsRegistrationCallback(int subId, IImsRegistrationCallback c,
2559 String callingPackage) throws RemoteException {
2560 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
2561 "addImsRegistrationCallback")) {
2562 return;
2563 }
2564 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2565 final long token = Binder.clearCallingIdentity();
2566 try {
2567 ImsManager.getInstance(mPhone.getContext(), getSlotIndexOrException(subId))
2568 .addRegistrationCallbackForSubscription(c, subId);
2569 } finally {
2570 Binder.restoreCallingIdentity(token);
2571 }
2572 }
2573
2574 @Override
2575 public void removeImsRegistrationCallback(int subId, IImsRegistrationCallback c,
2576 String callingPackage) {
2577 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
2578 "removeImsRegistrationCallback")) {
2579 return;
2580 }
2581 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2582 Binder.withCleanCallingIdentity(() ->
2583 ImsManager.getInstance(mPhone.getContext(), getSlotIndexOrException(subId))
2584 .removeRegistrationCallbackForSubscription(c, subId));
2585 }
2586
2587 @Override
2588 public void addMmTelCapabilityCallback(int subId, IImsCapabilityCallback c,
2589 String callingPackage) throws RemoteException {
2590 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
2591 "addMmTelCapabilityCallback")) {
2592 return;
2593 }
2594 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2595 final long token = Binder.clearCallingIdentity();
2596 try {
2597 ImsManager.getInstance(mPhone.getContext(), getSlotIndexOrException(subId))
2598 .addCapabilitiesCallbackForSubscription(c, subId);
2599 } finally {
2600 Binder.restoreCallingIdentity(token);
2601 }
2602 }
2603
2604 @Override
2605 public void removeMmTelCapabilityCallback(int subId, IImsCapabilityCallback c,
2606 String callingPackage) {
2607 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
2608 "removeMmTelCapabilityCallback")) {
2609 return;
2610 }
2611 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2612 Binder.withCleanCallingIdentity(() ->
2613 ImsManager.getInstance(mPhone.getContext(), getSlotIndexOrException(subId))
2614 .removeCapabilitiesCallbackForSubscription(c, subId));
2615 }
2616
2617 @Override
2618 public boolean isCapable(int subId, int capability, int regTech, String callingPackage) {
2619 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
2620 "isCapable")) {
2621 return false;
2622 }
2623 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2624 final long token = Binder.clearCallingIdentity();
2625 try {
2626 return ImsManager.getInstance(mPhone.getContext(),
2627 getSlotIndexOrException(subId)).queryMmTelCapability(capability, regTech);
2628 } catch (ImsException e) {
2629 Log.w(LOG_TAG, "IMS isCapable - service unavailable: " + e.getMessage());
2630 return false;
2631 } finally {
2632 Binder.restoreCallingIdentity(token);
2633 }
2634 }
2635
2636 @Override
2637 public boolean isAvailable(int subId, int capability, int regTech, String callingPackage) {
2638 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
2639 "isAvailable")) {
2640 return false;
2641 }
2642 final long token = Binder.clearCallingIdentity();
2643 try {
2644 Phone phone = getPhone(subId);
2645 if (phone == null) return false;
2646 return phone.isImsCapabilityAvailable(capability, regTech);
2647 } finally {
2648 Binder.restoreCallingIdentity(token);
2649 }
2650 }
2651
2652 @Override
2653 public boolean isAdvancedCallingSettingEnabled(int subId) {
2654 enforceReadPrivilegedPermission("enforceReadPrivilegedPermission");
2655 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2656 final long token = Binder.clearCallingIdentity();
2657 try {
2658 return ImsManager.getInstance(mPhone.getContext(),
2659 getSlotIndexOrException(subId)).isEnhanced4gLteModeSettingEnabledByUser();
2660 } finally {
2661 Binder.restoreCallingIdentity(token);
2662 }
2663 }
2664
2665 @Override
2666 public void setAdvancedCallingSetting(int subId, boolean isEnabled) {
2667 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
2668 "setAdvancedCallingSetting");
2669 final long identity = Binder.clearCallingIdentity();
2670 try {
2671 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2672 ImsManager.getInstance(mPhone.getContext(),
2673 getSlotIndexOrException(subId)).setEnhanced4gLteModeSetting(isEnabled);
2674 } finally {
2675 Binder.restoreCallingIdentity(identity);
2676 }
2677 }
2678
2679 @Override
2680 public boolean isVtSettingEnabled(int subId, String callingPackage) {
2681 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
2682 "isVtSettingEnabled")) {
2683 return false;
2684 }
2685 final long identity = Binder.clearCallingIdentity();
2686 try {
2687 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2688 return ImsManager.getInstance(mPhone.getContext(),
2689 getSlotIndexOrException(subId)).isVtEnabledByUser();
2690 } finally {
2691 Binder.restoreCallingIdentity(identity);
2692 }
2693 }
2694
2695 @Override
2696 public void setVtSetting(int subId, boolean isEnabled) {
2697 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
2698 "setVtSetting");
2699 final long identity = Binder.clearCallingIdentity();
2700 try {
2701 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2702 ImsManager.getInstance(mPhone.getContext(),
2703 getSlotIndexOrException(subId)).setVtSetting(isEnabled);
2704 } finally {
2705 Binder.restoreCallingIdentity(identity);
2706 }
2707 }
2708
2709 @Override
2710 public boolean isVoWiFiSettingEnabled(int subId) {
2711 enforceReadPrivilegedPermission("isVoWiFiSettingEnabled");
2712 final long identity = Binder.clearCallingIdentity();
2713 try {
2714 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2715 return ImsManager.getInstance(mPhone.getContext(),
2716 getSlotIndexOrException(subId)).isWfcEnabledByUser();
2717 } finally {
2718 Binder.restoreCallingIdentity(identity);
2719 }
2720 }
2721
2722 @Override
2723 public void setVoWiFiSetting(int subId, boolean isEnabled) {
2724 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
2725 "setVoWiFiSetting");
2726 final long identity = Binder.clearCallingIdentity();
2727 try {
2728 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2729 ImsManager.getInstance(mPhone.getContext(),
2730 getSlotIndexOrException(subId)).setWfcSetting(isEnabled);
2731 } finally {
2732 Binder.restoreCallingIdentity(identity);
2733 }
2734 }
2735
2736 @Override
2737 public boolean isVoWiFiRoamingSettingEnabled(int subId) {
2738 enforceReadPrivilegedPermission("isVoWiFiRoamingSettingEnabled");
2739 final long identity = Binder.clearCallingIdentity();
2740 try {
2741 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2742 return ImsManager.getInstance(mPhone.getContext(),
2743 getSlotIndexOrException(subId)).isWfcRoamingEnabledByUser();
2744 } finally {
2745 Binder.restoreCallingIdentity(identity);
2746 }
2747 }
2748
2749 @Override
2750 public void setVoWiFiRoamingSetting(int subId, boolean isEnabled) {
2751 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
2752 "setVoWiFiRoamingSetting");
2753 final long identity = Binder.clearCallingIdentity();
2754 try {
2755 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2756 ImsManager.getInstance(mPhone.getContext(),
2757 getSlotIndexOrException(subId)).setWfcRoamingSetting(isEnabled);
2758 } finally {
2759 Binder.restoreCallingIdentity(identity);
2760 }
2761 }
2762
2763 @Override
2764 public void setVoWiFiNonPersistent(int subId, boolean isCapable, int mode) {
2765 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
2766 "setVoWiFiNonPersistent");
2767 final long identity = Binder.clearCallingIdentity();
2768 try {
2769 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2770 ImsManager.getInstance(mPhone.getContext(),
2771 getSlotIndexOrException(subId)).setWfcNonPersistent(isCapable, mode);
2772 } finally {
2773 Binder.restoreCallingIdentity(identity);
2774 }
2775 }
2776
2777 @Override
2778 public int getVoWiFiModeSetting(int subId) {
2779 enforceReadPrivilegedPermission("getVoWiFiModeSetting");
2780 final long identity = Binder.clearCallingIdentity();
2781 try {
2782 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2783 return ImsManager.getInstance(mPhone.getContext(),
2784 getSlotIndexOrException(subId)).getWfcMode(false /*isRoaming*/);
2785 } finally {
2786 Binder.restoreCallingIdentity(identity);
2787 }
2788 }
2789
2790 @Override
2791 public void setVoWiFiModeSetting(int subId, int mode) {
2792 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
2793 "setVoWiFiModeSetting");
2794 final long identity = Binder.clearCallingIdentity();
2795 try {
2796 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2797 ImsManager.getInstance(mPhone.getContext(),
2798 getSlotIndexOrException(subId)).setWfcMode(mode, false /*isRoaming*/);
2799 } finally {
2800 Binder.restoreCallingIdentity(identity);
2801 }
2802 }
2803
2804 @Override
2805 public int getVoWiFiRoamingModeSetting(int subId) {
2806 enforceReadPrivilegedPermission("getVoWiFiRoamingModeSetting");
2807 final long identity = Binder.clearCallingIdentity();
2808 try {
2809 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2810 return ImsManager.getInstance(mPhone.getContext(),
2811 getSlotIndexOrException(subId)).getWfcMode(true /*isRoaming*/);
2812 } finally {
2813 Binder.restoreCallingIdentity(identity);
2814 }
2815 }
2816
2817 @Override
2818 public void setVoWiFiRoamingModeSetting(int subId, int mode) {
2819 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
2820 "setVoWiFiRoamingModeSetting");
2821 final long identity = Binder.clearCallingIdentity();
2822 try {
2823 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2824 ImsManager.getInstance(mPhone.getContext(),
2825 getSlotIndexOrException(subId)).setWfcMode(mode, true /*isRoaming*/);
2826 } finally {
2827 Binder.restoreCallingIdentity(identity);
2828 }
2829 }
2830
2831 @Override
2832 public void setRttCapabilitySetting(int subId, boolean isEnabled) {
2833 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
2834 "setRttCapabilityEnabled");
2835 final long identity = Binder.clearCallingIdentity();
2836 try {
2837 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2838 ImsManager.getInstance(mPhone.getContext(),
2839 getSlotIndexOrException(subId)).setRttEnabled(isEnabled);
2840 } finally {
2841 Binder.restoreCallingIdentity(identity);
2842 }
2843 }
2844
2845 @Override
2846 public boolean isTtyOverVolteEnabled(int subId) {
2847 enforceReadPrivilegedPermission("isTtyOverVolteEnabled");
2848 final long identity = Binder.clearCallingIdentity();
2849 try {
2850 // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
2851 return ImsManager.getInstance(mPhone.getContext(),
2852 getSlotIndexOrException(subId)).isTtyOnVoLteCapable();
2853 } finally {
2854 Binder.restoreCallingIdentity(identity);
2855 }
2856 }
2857
2858 private int getSlotIndexOrException(int subId) throws IllegalArgumentException {
2859 int slotId = SubscriptionManager.getSlotIndex(subId);
2860 if (!SubscriptionManager.isValidSlotIndex(slotId)) {
2861 throw new IllegalArgumentException("Invalid Subscription Id.");
2862 }
2863 return slotId;
2864 }
2865
Wink Saville36469e72014-06-11 15:17:00 -07002866 /**
2867 * Returns the network type for a subId
2868 */
2869 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002870 public int getNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002871 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002872 mApp, subId, callingPackage, "getNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002873 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2874 }
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002875
Malcolm Chend965c8b2018-02-28 15:00:40 -08002876 final long identity = Binder.clearCallingIdentity();
2877 try {
2878 final Phone phone = getPhone(subId);
2879 if (phone != null) {
2880 return phone.getServiceState().getDataNetworkType();
2881 } else {
2882 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2883 }
2884 } finally {
2885 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002886 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002887 }
2888
2889 /**
2890 * Returns the data network type
2891 */
2892 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002893 public int getDataNetworkType(String callingPackage) {
2894 return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002895 }
2896
2897 /**
2898 * Returns the data network type for a subId
2899 */
2900 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002901 public int getDataNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002902 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002903 mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002904 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2905 }
2906
Malcolm Chend965c8b2018-02-28 15:00:40 -08002907 final long identity = Binder.clearCallingIdentity();
2908 try {
2909 final Phone phone = getPhone(subId);
2910 if (phone != null) {
2911 return phone.getServiceState().getDataNetworkType();
2912 } else {
2913 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2914 }
2915 } finally {
2916 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002917 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002918 }
2919
2920 /**
Wink Saville36469e72014-06-11 15:17:00 -07002921 * Returns the Voice network type for a subId
2922 */
2923 @Override
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002924 public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002925 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002926 mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002927 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2928 }
2929
Malcolm Chend965c8b2018-02-28 15:00:40 -08002930 final long identity = Binder.clearCallingIdentity();
2931 try {
2932 final Phone phone = getPhone(subId);
2933 if (phone != null) {
2934 return phone.getServiceState().getVoiceNetworkType();
2935 } else {
2936 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2937 }
2938 } finally {
2939 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002940 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002941 }
2942
2943 /**
2944 * @return true if a ICC card is present
2945 */
2946 public boolean hasIccCard() {
Wink Saville36469e72014-06-11 15:17:00 -07002947 // FIXME Make changes to pass defaultSimId of type int
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002948 return hasIccCardUsingSlotIndex(mSubscriptionController.getSlotIndex(
2949 getDefaultSubscription()));
Wink Saville36469e72014-06-11 15:17:00 -07002950 }
2951
2952 /**
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002953 * @return true if a ICC card is present for a slotIndex
Wink Saville36469e72014-06-11 15:17:00 -07002954 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002955 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002956 public boolean hasIccCardUsingSlotIndex(int slotIndex) {
Malcolm Chend965c8b2018-02-28 15:00:40 -08002957 final long identity = Binder.clearCallingIdentity();
2958 try {
2959 final Phone phone = PhoneFactory.getPhone(slotIndex);
2960 if (phone != null) {
2961 return phone.getIccCard().hasIccCard();
2962 } else {
2963 return false;
2964 }
2965 } finally {
2966 Binder.restoreCallingIdentity(identity);
Amit Mahajana6fc2a82015-01-06 11:53:51 -08002967 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002968 }
2969
2970 /**
2971 * Return if the current radio is LTE on CDMA. This
2972 * is a tri-state return value as for a period of time
2973 * the mode may be unknown.
2974 *
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002975 * @param callingPackage the name of the package making the call.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002976 * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
Jake Hambye994d462014-02-03 13:10:13 -08002977 * or {@link Phone#LTE_ON_CDMA_TRUE}
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002978 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002979 @Override
2980 public int getLteOnCdmaMode(String callingPackage) {
2981 return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002982 }
2983
Sanket Padawe356d7632015-06-22 14:03:32 -07002984 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002985 public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08002986 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08002987 mApp, subId, callingPackage, "getLteOnCdmaModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002988 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
2989 }
2990
Malcolm Chend965c8b2018-02-28 15:00:40 -08002991 final long identity = Binder.clearCallingIdentity();
2992 try {
2993 final Phone phone = getPhone(subId);
2994 if (phone == null) {
2995 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
2996 } else {
2997 return phone.getLteOnCdmaMode();
2998 }
2999 } finally {
3000 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003001 }
Wink Saville36469e72014-06-11 15:17:00 -07003002 }
3003
3004 public void setPhone(Phone phone) {
3005 mPhone = phone;
3006 }
3007
3008 /**
3009 * {@hide}
3010 * Returns Default subId, 0 in the case of single standby.
3011 */
Wink Savilleb564aae2014-10-23 10:18:09 -07003012 private int getDefaultSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08003013 return mSubscriptionController.getDefaultSubId();
Wink Saville36469e72014-06-11 15:17:00 -07003014 }
3015
Shishir Agrawala9f32182016-04-12 12:00:16 -07003016 private int getSlotForDefaultSubscription() {
3017 return mSubscriptionController.getPhoneId(getDefaultSubscription());
3018 }
3019
Wink Savilleb564aae2014-10-23 10:18:09 -07003020 private int getPreferredVoiceSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08003021 return mSubscriptionController.getDefaultVoiceSubId();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07003022 }
Ihab Awadf2177b72013-11-25 13:33:23 -08003023
Pengquan Meng466e2482018-09-21 15:54:48 -07003024 private boolean isActiveSubscription(int subId) {
3025 return mSubscriptionController.isActiveSubId(subId);
3026 }
3027
Ihab Awadf2177b72013-11-25 13:33:23 -08003028 /**
3029 * @see android.telephony.TelephonyManager.WifiCallingChoices
3030 */
3031 public int getWhenToMakeWifiCalls() {
Malcolm Chend965c8b2018-02-28 15:00:40 -08003032 final long identity = Binder.clearCallingIdentity();
3033 try {
3034 return Settings.System.getInt(mPhone.getContext().getContentResolver(),
3035 Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
3036 getWhenToMakeWifiCallsDefaultPreference());
3037 } finally {
3038 Binder.restoreCallingIdentity(identity);
3039 }
Ihab Awadf2177b72013-11-25 13:33:23 -08003040 }
3041
3042 /**
3043 * @see android.telephony.TelephonyManager.WifiCallingChoices
3044 */
3045 public void setWhenToMakeWifiCalls(int preference) {
Malcolm Chend965c8b2018-02-28 15:00:40 -08003046 final long identity = Binder.clearCallingIdentity();
3047 try {
3048 if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference);
3049 Settings.System.putInt(mPhone.getContext().getContentResolver(),
3050 Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference);
3051 } finally {
3052 Binder.restoreCallingIdentity(identity);
3053 }
Ihab Awadf9e92732013-12-05 18:02:52 -08003054 }
3055
Sailesh Nepald1e68152013-12-12 19:08:02 -08003056 private static int getWhenToMakeWifiCallsDefaultPreference() {
Santos Cordonda120f42014-08-06 04:44:34 -07003057 // TODO: Use a build property to choose this value.
Evan Charlton9829e882013-12-19 15:30:38 -08003058 return TelephonyManager.WifiCallingChoices.ALWAYS_USE;
Ihab Awadf2177b72013-11-25 13:33:23 -08003059 }
Shishir Agrawal69f68122013-12-16 17:25:49 -08003060
Shishir Agrawal566b7612013-10-28 14:41:00 -07003061 @Override
Derek Tan740e1672017-06-27 14:56:27 -07003062 public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
3063 int subId, String callingPackage, String aid, int p2) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003064 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3065 mApp, subId, "iccOpenLogicalChannel");
Malcolm Chend965c8b2018-02-28 15:00:40 -08003066 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Shishir Agrawal566b7612013-10-28 14:41:00 -07003067
Malcolm Chend965c8b2018-02-28 15:00:40 -08003068 final long identity = Binder.clearCallingIdentity();
3069 try {
3070 if (TextUtils.equals(ISDR_AID, aid)) {
3071 // Only allows LPA to open logical channel to ISD-R.
3072 ComponentInfo bestComponent =
3073 EuiccConnector.findBestComponent(mPhone.getContext().getPackageManager());
3074 if (bestComponent == null
3075 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
3076 loge("The calling package is not allowed to access ISD-R.");
3077 throw new SecurityException(
3078 "The calling package is not allowed to access ISD-R.");
3079 }
Derek Tan740e1672017-06-27 14:56:27 -07003080 }
Derek Tan740e1672017-06-27 14:56:27 -07003081
Malcolm Chend965c8b2018-02-28 15:00:40 -08003082 if (DBG) {
3083 log("iccOpenLogicalChannel: subId=" + subId + " aid=" + aid + " p2=" + p2);
3084 }
3085 IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse) sendRequest(
3086 CMD_OPEN_CHANNEL, new Pair<String, Integer>(aid, p2), subId);
3087 if (DBG) log("iccOpenLogicalChannel: " + response);
3088 return response;
3089 } finally {
3090 Binder.restoreCallingIdentity(identity);
3091 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003092 }
3093
3094 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003095 public boolean iccCloseLogicalChannel(int subId, int channel) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003096 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3097 mApp, subId, "iccCloseLogicalChannel");
Shishir Agrawal566b7612013-10-28 14:41:00 -07003098
Malcolm Chend965c8b2018-02-28 15:00:40 -08003099 final long identity = Binder.clearCallingIdentity();
3100 try {
3101 if (DBG) log("iccCloseLogicalChannel: subId=" + subId + " chnl=" + channel);
3102 if (channel < 0) {
3103 return false;
3104 }
3105 Boolean success = (Boolean) sendRequest(CMD_CLOSE_CHANNEL, channel, subId);
3106 if (DBG) log("iccCloseLogicalChannel: " + success);
3107 return success;
3108 } finally {
3109 Binder.restoreCallingIdentity(identity);
Shishir Agrawal566b7612013-10-28 14:41:00 -07003110 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003111 }
3112
3113 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003114 public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
Shishir Agrawal566b7612013-10-28 14:41:00 -07003115 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003116 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3117 mApp, subId, "iccTransmitApduLogicalChannel");
Shishir Agrawal566b7612013-10-28 14:41:00 -07003118
Malcolm Chend965c8b2018-02-28 15:00:40 -08003119 final long identity = Binder.clearCallingIdentity();
3120 try {
3121 if (DBG) {
3122 log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel
3123 + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
3124 + p3 + " data=" + data);
3125 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003126
Malcolm Chend965c8b2018-02-28 15:00:40 -08003127 if (channel < 0) {
3128 return "";
3129 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003130
Malcolm Chend965c8b2018-02-28 15:00:40 -08003131 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL,
3132 new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), subId);
3133 if (DBG) log("iccTransmitApduLogicalChannel: " + response);
Shishir Agrawal566b7612013-10-28 14:41:00 -07003134
Malcolm Chend965c8b2018-02-28 15:00:40 -08003135 // Append the returned status code to the end of the response payload.
3136 String s = Integer.toHexString(
3137 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
3138 if (response.payload != null) {
3139 s = IccUtils.bytesToHexString(response.payload) + s;
3140 }
3141 return s;
3142 } finally {
3143 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07003144 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07003145 }
Jake Hambye994d462014-02-03 13:10:13 -08003146
Evan Charltonc66da362014-05-16 14:06:40 -07003147 @Override
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08003148 public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
3149 int command, int p1, int p2, int p3, String data) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003150 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3151 mApp, subId, "iccTransmitApduBasicChannel");
Malcolm Chend965c8b2018-02-28 15:00:40 -08003152 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003153
Malcolm Chend965c8b2018-02-28 15:00:40 -08003154 final long identity = Binder.clearCallingIdentity();
3155 try {
3156 if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
3157 && TextUtils.equals(ISDR_AID, data)) {
3158 // Only allows LPA to select ISD-R.
3159 ComponentInfo bestComponent =
3160 EuiccConnector.findBestComponent(mPhone.getContext().getPackageManager());
3161 if (bestComponent == null
3162 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
3163 loge("The calling package is not allowed to select ISD-R.");
3164 throw new SecurityException(
3165 "The calling package is not allowed to select ISD-R.");
3166 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08003167 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08003168
Malcolm Chend965c8b2018-02-28 15:00:40 -08003169 if (DBG) {
3170 log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd="
3171 + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
3172 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003173
Malcolm Chend965c8b2018-02-28 15:00:40 -08003174 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL,
3175 new IccAPDUArgument(0, cla, command, p1, p2, p3, data), subId);
3176 if (DBG) log("iccTransmitApduBasicChannel: " + response);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003177
Malcolm Chend965c8b2018-02-28 15:00:40 -08003178 // Append the returned status code to the end of the response payload.
3179 String s = Integer.toHexString(
3180 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
3181 if (response.payload != null) {
3182 s = IccUtils.bytesToHexString(response.payload) + s;
3183 }
3184 return s;
3185 } finally {
3186 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07003187 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003188 }
3189
3190 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003191 public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003192 String filePath) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003193 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3194 mApp, subId, "iccExchangeSimIO");
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003195
Malcolm Chend965c8b2018-02-28 15:00:40 -08003196 final long identity = Binder.clearCallingIdentity();
3197 try {
3198 if (DBG) {
3199 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " "
3200 + p1 + " " + p2 + " " + p3 + ":" + filePath);
3201 }
3202
3203 IccIoResult response =
3204 (IccIoResult) sendRequest(CMD_EXCHANGE_SIM_IO,
3205 new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath),
3206 subId);
3207
3208 if (DBG) {
3209 log("Exchange SIM_IO [R]" + response);
3210 }
3211
3212 byte[] result = null;
3213 int length = 2;
3214 if (response.payload != null) {
3215 length = 2 + response.payload.length;
3216 result = new byte[length];
3217 System.arraycopy(response.payload, 0, result, 0, response.payload.length);
3218 } else {
3219 result = new byte[length];
3220 }
3221
3222 result[length - 1] = (byte) response.sw2;
3223 result[length - 2] = (byte) response.sw1;
3224 return result;
3225 } finally {
3226 Binder.restoreCallingIdentity(identity);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003227 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003228 }
3229
Nathan Haroldb3014052017-01-25 15:57:32 -08003230 /**
3231 * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
3232 * on a particular subscription
3233 */
sqianb6e41952018-03-12 14:54:01 -07003234 public String[] getForbiddenPlmns(int subId, int appType, String callingPackage) {
3235 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
3236 mApp, subId, callingPackage, "getForbiddenPlmns")) {
3237 return null;
3238 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08003239
3240 final long identity = Binder.clearCallingIdentity();
3241 try {
3242 if (appType != TelephonyManager.APPTYPE_USIM
3243 && appType != TelephonyManager.APPTYPE_SIM) {
3244 loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
3245 return null;
3246 }
3247 Object response = sendRequest(
3248 CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
3249 if (response instanceof String[]) {
3250 return (String[]) response;
3251 }
3252 // Response is an Exception of some kind,
3253 // which is signalled to the user as a NULL retval
Nathan Haroldb3014052017-01-25 15:57:32 -08003254 return null;
Malcolm Chend965c8b2018-02-28 15:00:40 -08003255 } finally {
3256 Binder.restoreCallingIdentity(identity);
Nathan Haroldb3014052017-01-25 15:57:32 -08003257 }
Nathan Haroldb3014052017-01-25 15:57:32 -08003258 }
3259
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07003260 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003261 public String sendEnvelopeWithStatus(int subId, String content) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003262 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3263 mApp, subId, "sendEnvelopeWithStatus");
Evan Charltonc66da362014-05-16 14:06:40 -07003264
Malcolm Chend965c8b2018-02-28 15:00:40 -08003265 final long identity = Binder.clearCallingIdentity();
3266 try {
3267 IccIoResult response = (IccIoResult) sendRequest(CMD_SEND_ENVELOPE, content, subId);
3268 if (response.payload == null) {
3269 return "";
3270 }
Evan Charltonc66da362014-05-16 14:06:40 -07003271
Malcolm Chend965c8b2018-02-28 15:00:40 -08003272 // Append the returned status code to the end of the response payload.
3273 String s = Integer.toHexString(
3274 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
3275 s = IccUtils.bytesToHexString(response.payload) + s;
3276 return s;
3277 } finally {
3278 Binder.restoreCallingIdentity(identity);
3279 }
Evan Charltonc66da362014-05-16 14:06:40 -07003280 }
3281
Jake Hambye994d462014-02-03 13:10:13 -08003282 /**
3283 * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
3284 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
3285 *
3286 * @param itemID the ID of the item to read
3287 * @return the NV item as a String, or null on error.
3288 */
3289 @Override
3290 public String nvReadItem(int itemID) {
vagdevie435a3e2018-08-15 16:01:53 -07003291 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08003292 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3293 mApp, getDefaultSubscription(), "nvReadItem");
Malcolm Chend965c8b2018-02-28 15:00:40 -08003294
3295 final long identity = Binder.clearCallingIdentity();
3296 try {
3297 if (DBG) log("nvReadItem: item " + itemID);
vagdevie435a3e2018-08-15 16:01:53 -07003298 String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID, workSource);
Malcolm Chend965c8b2018-02-28 15:00:40 -08003299 if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
3300 return value;
3301 } finally {
3302 Binder.restoreCallingIdentity(identity);
3303 }
Jake Hambye994d462014-02-03 13:10:13 -08003304 }
3305
3306 /**
3307 * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
3308 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
3309 *
3310 * @param itemID the ID of the item to read
3311 * @param itemValue the value to write, as a String
3312 * @return true on success; false on any failure
3313 */
3314 @Override
3315 public boolean nvWriteItem(int itemID, String itemValue) {
vagdevie435a3e2018-08-15 16:01:53 -07003316 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Jeff Davidson7e17e312018-02-13 18:17:36 -08003317 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3318 mApp, getDefaultSubscription(), "nvWriteItem");
Malcolm Chend965c8b2018-02-28 15:00:40 -08003319
3320 final long identity = Binder.clearCallingIdentity();
3321 try {
3322 if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
3323 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
vagdevie435a3e2018-08-15 16:01:53 -07003324 new Pair<Integer, String>(itemID, itemValue), workSource);
Malcolm Chend965c8b2018-02-28 15:00:40 -08003325 if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
3326 return success;
3327 } finally {
3328 Binder.restoreCallingIdentity(identity);
3329 }
Jake Hambye994d462014-02-03 13:10:13 -08003330 }
3331
3332 /**
3333 * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
3334 * Used for device configuration by some CDMA operators.
3335 *
3336 * @param preferredRoamingList byte array containing the new PRL
3337 * @return true on success; false on any failure
3338 */
3339 @Override
3340 public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003341 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3342 mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
Malcolm Chend965c8b2018-02-28 15:00:40 -08003343
3344 final long identity = Binder.clearCallingIdentity();
3345 try {
3346 if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
3347 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
3348 if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
3349 return success;
3350 } finally {
3351 Binder.restoreCallingIdentity(identity);
3352 }
Jake Hambye994d462014-02-03 13:10:13 -08003353 }
3354
3355 /**
3356 * Perform the specified type of NV config reset.
3357 * Used for device configuration by some CDMA operators.
3358 *
3359 * @param resetType the type of reset to perform (1 == factory reset; 2 == NV-only reset)
3360 * @return true on success; false on any failure
3361 */
3362 @Override
3363 public boolean nvResetConfig(int resetType) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003364 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3365 mApp, getDefaultSubscription(), "nvResetConfig");
Malcolm Chend965c8b2018-02-28 15:00:40 -08003366
3367 final long identity = Binder.clearCallingIdentity();
3368 try {
3369 if (DBG) log("nvResetConfig: type " + resetType);
3370 Boolean success = (Boolean) sendRequest(CMD_NV_RESET_CONFIG, resetType);
3371 if (DBG) log("nvResetConfig: type " + resetType + ' ' + (success ? "ok" : "fail"));
3372 return success;
3373 } finally {
3374 Binder.restoreCallingIdentity(identity);
3375 }
Jake Hambye994d462014-02-03 13:10:13 -08003376 }
Jake Hamby7c27be32014-03-03 13:25:59 -08003377
Svet Ganovb320e182015-04-16 12:30:10 -07003378 public String[] getPcscfAddress(String apnType, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003379 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003380 mApp, mPhone.getSubId(), callingPackage, "getPcscfAddress")) {
Svet Ganovb320e182015-04-16 12:30:10 -07003381 return new String[0];
3382 }
3383
Malcolm Chend965c8b2018-02-28 15:00:40 -08003384 final long identity = Binder.clearCallingIdentity();
3385 try {
3386 return mPhone.getPcscfAddress(apnType);
3387 } finally {
3388 Binder.restoreCallingIdentity(identity);
3389 }
Wink Saville36469e72014-06-11 15:17:00 -07003390 }
3391
Brad Ebinger51f743a2017-01-23 13:50:20 -08003392 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003393 * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
3394 * status updates, if not already enabled.
Brad Ebinger51f743a2017-01-23 13:50:20 -08003395 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003396 public void enableIms(int slotId) {
Brad Ebinger51f743a2017-01-23 13:50:20 -08003397 enforceModifyPermission();
Malcolm Chend965c8b2018-02-28 15:00:40 -08003398
3399 final long identity = Binder.clearCallingIdentity();
3400 try {
3401 PhoneFactory.getImsResolver().enableIms(slotId);
3402 } finally {
3403 Binder.restoreCallingIdentity(identity);
3404 }
Brad Ebinger34bef922017-11-09 10:27:08 -08003405 }
3406
3407 /**
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003408 * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
3409 * status updates to disabled.
Brad Ebinger34bef922017-11-09 10:27:08 -08003410 */
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003411 public void disableIms(int slotId) {
3412 enforceModifyPermission();
Malcolm Chend965c8b2018-02-28 15:00:40 -08003413
3414 final long identity = Binder.clearCallingIdentity();
3415 try {
3416 PhoneFactory.getImsResolver().disableIms(slotId);
3417 } finally {
3418 Binder.restoreCallingIdentity(identity);
3419 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003420 }
3421
3422 /**
3423 * Returns the {@link IImsMmTelFeature} that corresponds to the given slot Id for the MMTel
3424 * feature or {@link null} if the service is not available. If the feature is available, the
3425 * {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates.
3426 */
3427 public IImsMmTelFeature getMmTelFeatureAndListen(int slotId,
Brad Ebinger34bef922017-11-09 10:27:08 -08003428 IImsServiceFeatureCallback callback) {
3429 enforceModifyPermission();
Malcolm Chend965c8b2018-02-28 15:00:40 -08003430
3431 final long identity = Binder.clearCallingIdentity();
3432 try {
3433 return PhoneFactory.getImsResolver().getMmTelFeatureAndListen(slotId, callback);
3434 } finally {
3435 Binder.restoreCallingIdentity(identity);
3436 }
Brad Ebinger34bef922017-11-09 10:27:08 -08003437 }
3438
3439 /**
3440 * Returns the {@link IImsRcsFeature} that corresponds to the given slot Id for the RCS
3441 * feature during emergency calling or {@link null} if the service is not available. If the
3442 * feature is available, the {@link IImsServiceFeatureCallback} callback is registered as a
3443 * listener for feature updates.
3444 */
3445 public IImsRcsFeature getRcsFeatureAndListen(int slotId, IImsServiceFeatureCallback callback) {
3446 enforceModifyPermission();
Malcolm Chend965c8b2018-02-28 15:00:40 -08003447
3448 final long identity = Binder.clearCallingIdentity();
3449 try {
3450 return PhoneFactory.getImsResolver().getRcsFeatureAndListen(slotId, callback);
3451 } finally {
3452 Binder.restoreCallingIdentity(identity);
3453 }
Brad Ebinger51f743a2017-01-23 13:50:20 -08003454 }
3455
Brad Ebinger5f64b052017-12-14 14:26:15 -08003456 /**
3457 * Returns the {@link IImsRegistration} structure associated with the slotId and feature
3458 * specified.
3459 */
3460 public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
3461 enforceModifyPermission();
Malcolm Chend965c8b2018-02-28 15:00:40 -08003462
3463 final long identity = Binder.clearCallingIdentity();
3464 try {
3465 return PhoneFactory.getImsResolver().getImsRegistration(slotId, feature);
3466 } finally {
3467 Binder.restoreCallingIdentity(identity);
3468 }
Brad Ebinger5f64b052017-12-14 14:26:15 -08003469 }
3470
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003471 /**
3472 * Returns the {@link IImsConfig} structure associated with the slotId and feature
3473 * specified.
3474 */
3475 public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
3476 enforceModifyPermission();
Malcolm Chend965c8b2018-02-28 15:00:40 -08003477
3478 final long identity = Binder.clearCallingIdentity();
3479 try {
3480 return PhoneFactory.getImsResolver().getImsConfig(slotId, feature);
3481 } finally {
3482 Binder.restoreCallingIdentity(identity);
3483 }
Brad Ebinger22bc3e42018-01-16 09:39:35 -08003484 }
3485
Brad Ebinger884c07b2018-02-15 16:17:40 -08003486 /**
Brad Ebingerdac2f002018-04-03 15:17:52 -07003487 * Sets the ImsService Package Name that Telephony will bind to.
3488 *
3489 * @param slotId the slot ID that the ImsService should bind for.
3490 * @param isCarrierImsService true if the ImsService is the carrier override, false if the
3491 * ImsService is the device default ImsService.
3492 * @param packageName The package name of the application that contains the ImsService to bind
3493 * to.
3494 * @return true if setting the ImsService to bind to succeeded, false if it did not.
3495 * @hide
3496 */
3497 public boolean setImsService(int slotId, boolean isCarrierImsService, String packageName) {
Brad Ebingerde696de2018-04-06 09:56:40 -07003498 int[] subIds = SubscriptionManager.getSubId(slotId);
3499 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
3500 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
3501 "setImsService");
3502
Malcolm Chend965c8b2018-02-28 15:00:40 -08003503 final long identity = Binder.clearCallingIdentity();
3504 try {
3505 return PhoneFactory.getImsResolver().overrideImsServiceConfiguration(slotId,
3506 isCarrierImsService, packageName);
3507 } finally {
3508 Binder.restoreCallingIdentity(identity);
3509 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07003510 }
3511
3512 /**
3513 * Return the ImsService configuration.
3514 *
3515 * @param slotId The slot that the ImsService is associated with.
3516 * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
3517 * the device default.
3518 * @return the package name of the ImsService configuration.
3519 */
3520 public String getImsService(int slotId, boolean isCarrierImsService) {
Brad Ebingerde696de2018-04-06 09:56:40 -07003521 int[] subIds = SubscriptionManager.getSubId(slotId);
3522 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
3523 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
3524 "getImsService");
3525
Malcolm Chend965c8b2018-02-28 15:00:40 -08003526 final long identity = Binder.clearCallingIdentity();
3527 try {
3528 return PhoneFactory.getImsResolver().getImsServiceConfiguration(slotId,
3529 isCarrierImsService);
3530 } finally {
3531 Binder.restoreCallingIdentity(identity);
3532 }
Brad Ebingerdac2f002018-04-03 15:17:52 -07003533 }
3534
Wink Saville36469e72014-06-11 15:17:00 -07003535 public void setImsRegistrationState(boolean registered) {
3536 enforceModifyPermission();
Malcolm Chend965c8b2018-02-28 15:00:40 -08003537
3538 final long identity = Binder.clearCallingIdentity();
3539 try {
3540 mPhone.setImsRegistrationState(registered);
3541 } finally {
3542 Binder.restoreCallingIdentity(identity);
3543 }
Wink Saville36469e72014-06-11 15:17:00 -07003544 }
3545
3546 /**
Stuart Scott54788802015-03-30 13:18:01 -07003547 * Set the network selection mode to automatic.
3548 *
3549 */
3550 @Override
3551 public void setNetworkSelectionModeAutomatic(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003552 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3553 mApp, subId, "setNetworkSelectionModeAutomatic");
Malcolm Chend965c8b2018-02-28 15:00:40 -08003554
Pengquan Meng466e2482018-09-21 15:54:48 -07003555 if (!isActiveSubscription(subId)) {
3556 return;
3557 }
3558
Malcolm Chend965c8b2018-02-28 15:00:40 -08003559 final long identity = Binder.clearCallingIdentity();
3560 try {
3561 if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
3562 sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId);
3563 } finally {
3564 Binder.restoreCallingIdentity(identity);
3565 }
Stuart Scott54788802015-03-30 13:18:01 -07003566 }
3567
Pengquan Menga4d9cff2018-09-20 14:57:26 -07003568 /**
3569 * Ask the radio to connect to the input network and change selection mode to manual.
3570 *
3571 * @param subId the id of the subscription.
3572 * @param operatorInfo the operator information, included the PLMN, long name and short name of
3573 * the operator to attach to.
3574 * @param persistSelection whether the selection will persist until reboot. If true, only allows
3575 * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
3576 * normal network selection next time.
3577 * @return {@code true} on success; {@code true} on any failure.
Shishir Agrawal302c8692015-06-19 13:49:39 -07003578 */
3579 @Override
Pengquan Menga4d9cff2018-09-20 14:57:26 -07003580 public boolean setNetworkSelectionModeManual(
3581 int subId, OperatorInfo operatorInfo, boolean persistSelection) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003582 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3583 mApp, subId, "setNetworkSelectionModeManual");
Pengquan Meng466e2482018-09-21 15:54:48 -07003584
3585 if (!isActiveSubscription(subId)) {
3586 return false;
3587 }
3588
Malcolm Chend965c8b2018-02-28 15:00:40 -08003589 final long identity = Binder.clearCallingIdentity();
3590 try {
Pengquan Menga4d9cff2018-09-20 14:57:26 -07003591 ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operatorInfo,
Malcolm Chend965c8b2018-02-28 15:00:40 -08003592 persistSelection);
Pengquan Menga4d9cff2018-09-20 14:57:26 -07003593 if (DBG) {
3594 log("setNetworkSelectionModeManual: subId: " + subId
3595 + " operator: " + operatorInfo);
3596 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08003597 return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
3598 } finally {
3599 Binder.restoreCallingIdentity(identity);
3600 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07003601 }
3602
3603 /**
3604 * Scans for available networks.
3605 */
3606 @Override
3607 public CellNetworkScanResult getCellNetworkScanResults(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003608 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3609 mApp, subId, "getCellNetworkScanResults");
Malcolm Chend965c8b2018-02-28 15:00:40 -08003610
Pengquan Meng0c05b502018-09-06 09:59:22 -07003611 long identity = Binder.clearCallingIdentity();
Malcolm Chend965c8b2018-02-28 15:00:40 -08003612 try {
3613 if (DBG) log("getCellNetworkScanResults: subId " + subId);
Pengquan Meng0c05b502018-09-06 09:59:22 -07003614 return (CellNetworkScanResult) sendRequest(
Malcolm Chend965c8b2018-02-28 15:00:40 -08003615 CMD_PERFORM_NETWORK_SCAN, null, subId);
Malcolm Chend965c8b2018-02-28 15:00:40 -08003616 } finally {
3617 Binder.restoreCallingIdentity(identity);
3618 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07003619 }
3620
3621 /**
yinxub1bed742017-04-17 11:45:04 -07003622 * Starts a new network scan and returns the id of this scan.
yinxu504e1392017-04-12 16:03:22 -07003623 *
yinxub1bed742017-04-17 11:45:04 -07003624 * @param subId id of the subscription
3625 * @param request contains the radio access networks with bands/channels to scan
3626 * @param messenger callback messenger for scan results or errors
3627 * @param binder for the purpose of auto clean when the user thread crashes
yinxu504e1392017-04-12 16:03:22 -07003628 * @return the id of the requested scan which can be used to stop the scan.
3629 */
3630 @Override
3631 public int requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger,
3632 IBinder binder) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003633 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3634 mApp, subId, "requestNetworkScan");
Malcolm Chend965c8b2018-02-28 15:00:40 -08003635
3636 final long identity = Binder.clearCallingIdentity();
3637 try {
3638 return mNetworkScanRequestTracker.startNetworkScan(
3639 request, messenger, binder, getPhone(subId));
3640 } finally {
3641 Binder.restoreCallingIdentity(identity);
3642 }
yinxu504e1392017-04-12 16:03:22 -07003643 }
3644
3645 /**
3646 * Stops an existing network scan with the given scanId.
yinxub1bed742017-04-17 11:45:04 -07003647 *
3648 * @param subId id of the subscription
3649 * @param scanId id of the scan that needs to be stopped
yinxu504e1392017-04-12 16:03:22 -07003650 */
3651 @Override
3652 public void stopNetworkScan(int subId, int scanId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003653 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3654 mApp, subId, "stopNetworkScan");
Malcolm Chend965c8b2018-02-28 15:00:40 -08003655
3656 final long identity = Binder.clearCallingIdentity();
3657 try {
3658 mNetworkScanRequestTracker.stopNetworkScan(scanId);
3659 } finally {
3660 Binder.restoreCallingIdentity(identity);
3661 }
yinxu504e1392017-04-12 16:03:22 -07003662 }
3663
3664 /**
Junda Liu84d15a22014-07-02 11:21:04 -07003665 * Get the calculated preferred network type.
3666 * Used for debugging incorrect network type.
3667 *
3668 * @return the preferred network type, defined in RILConstants.java.
3669 */
3670 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07003671 public int getCalculatedPreferredNetworkType(String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003672 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08003673 mApp, mPhone.getSubId(), callingPackage, "getCalculatedPreferredNetworkType")) {
Svet Ganovb320e182015-04-16 12:30:10 -07003674 return RILConstants.PREFERRED_NETWORK_MODE;
3675 }
3676
Malcolm Chend965c8b2018-02-28 15:00:40 -08003677 final long identity = Binder.clearCallingIdentity();
3678 try {
3679 // FIXME: need to get SubId from somewhere.
3680 return PhoneFactory.calculatePreferredNetworkType(mPhone.getContext(), 0);
3681 } finally {
3682 Binder.restoreCallingIdentity(identity);
3683 }
Junda Liu84d15a22014-07-02 11:21:04 -07003684 }
3685
3686 /**
Jake Hamby7c27be32014-03-03 13:25:59 -08003687 * Get the preferred network type.
3688 * Used for device configuration by some CDMA operators.
3689 *
3690 * @return the preferred network type, defined in RILConstants.java.
3691 */
3692 @Override
Stuart Scott54788802015-03-30 13:18:01 -07003693 public int getPreferredNetworkType(int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003694 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3695 mApp, subId, "getPreferredNetworkType");
Malcolm Chend965c8b2018-02-28 15:00:40 -08003696
3697 final long identity = Binder.clearCallingIdentity();
3698 try {
3699 if (DBG) log("getPreferredNetworkType");
3700 int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null, subId);
3701 int networkType = (result != null ? result[0] : -1);
3702 if (DBG) log("getPreferredNetworkType: " + networkType);
3703 return networkType;
3704 } finally {
3705 Binder.restoreCallingIdentity(identity);
3706 }
Jake Hamby7c27be32014-03-03 13:25:59 -08003707 }
3708
3709 /**
3710 * Set the preferred network type.
3711 * Used for device configuration by some CDMA operators.
3712 *
3713 * @param networkType the preferred network type, defined in RILConstants.java.
3714 * @return true on success; false on any failure.
3715 */
3716 @Override
Stuart Scott54788802015-03-30 13:18:01 -07003717 public boolean setPreferredNetworkType(int subId, int networkType) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003718 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3719 mApp, subId, "setPreferredNetworkType");
Malcolm Chend965c8b2018-02-28 15:00:40 -08003720
3721 final long identity = Binder.clearCallingIdentity();
3722 try {
3723 if (DBG) log("setPreferredNetworkType: subId " + subId + " type " + networkType);
3724 Boolean success = (Boolean) sendRequest(
3725 CMD_SET_PREFERRED_NETWORK_TYPE, networkType, subId);
3726 if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail"));
3727 if (success) {
3728 Settings.Global.putInt(mPhone.getContext().getContentResolver(),
3729 Settings.Global.PREFERRED_NETWORK_MODE + subId, networkType);
3730 }
3731 return success;
3732 } finally {
3733 Binder.restoreCallingIdentity(identity);
Junda Liu80bc0d12014-07-14 16:36:44 -07003734 }
Jake Hamby7c27be32014-03-03 13:25:59 -08003735 }
Robert Greenwalted86e582014-05-21 20:03:20 -07003736
3737 /**
Junda Liu475951f2014-11-07 16:45:03 -08003738 * Check TETHER_DUN_REQUIRED and TETHER_DUN_APN settings, net.tethering.noprovisioning
3739 * SystemProperty, and config_tether_apndata to decide whether DUN APN is required for
3740 * tethering.
3741 *
3742 * @return 0: Not required. 1: required. 2: Not set.
3743 * @hide
3744 */
3745 @Override
3746 public int getTetherApnRequired() {
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003747 enforceModifyPermission();
Malcolm Chend965c8b2018-02-28 15:00:40 -08003748
3749 final long identity = Binder.clearCallingIdentity();
3750 try {
3751 int dunRequired = Settings.Global.getInt(mPhone.getContext().getContentResolver(),
3752 Settings.Global.TETHER_DUN_REQUIRED, 2);
3753 // If not set, check net.tethering.noprovisioning, TETHER_DUN_APN setting and
3754 // config_tether_apndata.
3755 if (dunRequired == 2 && mPhone.hasMatchedTetherApnSetting()) {
3756 dunRequired = 1;
3757 }
3758 return dunRequired;
3759 } finally {
3760 Binder.restoreCallingIdentity(identity);
Junda Liu475951f2014-11-07 16:45:03 -08003761 }
Junda Liu475951f2014-11-07 16:45:03 -08003762 }
3763
3764 /**
Robert Greenwalted86e582014-05-21 20:03:20 -07003765 * Set mobile data enabled
3766 * Used by the user through settings etc to turn on/off mobile data
3767 *
3768 * @param enable {@code true} turn turn data on, else {@code false}
3769 */
3770 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08003771 public void setUserDataEnabled(int subId, boolean enable) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003772 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3773 mApp, subId, "setUserDataEnabled");
Malcolm Chend965c8b2018-02-28 15:00:40 -08003774
3775 final long identity = Binder.clearCallingIdentity();
3776 try {
3777 int phoneId = mSubscriptionController.getPhoneId(subId);
3778 if (DBG) log("setUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
3779 Phone phone = PhoneFactory.getPhone(phoneId);
3780 if (phone != null) {
3781 if (DBG) log("setUserDataEnabled: subId=" + subId + " enable=" + enable);
3782 phone.setUserDataEnabled(enable);
3783 } else {
3784 loge("setUserDataEnabled: no phone for subId=" + subId);
3785 }
3786 } finally {
3787 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08003788 }
Robert Greenwalted86e582014-05-21 20:03:20 -07003789 }
3790
3791 /**
Malcolm Chen964682d2017-11-28 16:20:07 -08003792 * Get the user enabled state of Mobile Data.
3793 *
3794 * TODO: remove and use isUserDataEnabled.
3795 * This can't be removed now because some vendor codes
3796 * calls through ITelephony directly while they should
3797 * use TelephonyManager.
3798 *
3799 * @return true on enabled
3800 */
3801 @Override
3802 public boolean getDataEnabled(int subId) {
3803 return isUserDataEnabled(subId);
3804 }
3805
3806 /**
3807 * Get whether mobile data is enabled per user setting.
3808 *
3809 * There are other factors deciding whether mobile data is actually enabled, but they are
3810 * not considered here. See {@link #isDataEnabled(int)} for more details.
Robert Greenwalt646120a2014-05-23 11:54:03 -07003811 *
Jeff Davidsona1920712016-11-18 17:05:56 -08003812 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
Robert Greenwalted86e582014-05-21 20:03:20 -07003813 *
3814 * @return {@code true} if data is enabled else {@code false}
3815 */
3816 @Override
Malcolm Chen964682d2017-11-28 16:20:07 -08003817 public boolean isUserDataEnabled(int subId) {
Robert Greenwalt646120a2014-05-23 11:54:03 -07003818 try {
3819 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
3820 null);
3821 } catch (Exception e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003822 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3823 mApp, subId, "isUserDataEnabled");
Robert Greenwalt646120a2014-05-23 11:54:03 -07003824 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08003825
3826 final long identity = Binder.clearCallingIdentity();
3827 try {
3828 int phoneId = mSubscriptionController.getPhoneId(subId);
3829 if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
3830 Phone phone = PhoneFactory.getPhone(phoneId);
3831 if (phone != null) {
3832 boolean retVal = phone.isUserDataEnabled();
3833 if (DBG) log("isUserDataEnabled: subId=" + subId + " retVal=" + retVal);
3834 return retVal;
3835 } else {
3836 if (DBG) loge("isUserDataEnabled: no phone subId=" + subId + " retVal=false");
3837 return false;
3838 }
3839 } finally {
3840 Binder.restoreCallingIdentity(identity);
Malcolm Chen964682d2017-11-28 16:20:07 -08003841 }
3842 }
3843
3844 /**
3845 * Get whether mobile data is enabled.
3846 *
3847 * Comparable to {@link #isUserDataEnabled(int)}, this considers all factors deciding
3848 * whether mobile data is actually enabled.
3849 *
3850 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
3851 *
3852 * @return {@code true} if data is enabled else {@code false}
3853 */
3854 @Override
3855 public boolean isDataEnabled(int subId) {
3856 try {
3857 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
3858 null);
3859 } catch (Exception e) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08003860 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3861 mApp, subId, "isDataEnabled");
Malcolm Chen964682d2017-11-28 16:20:07 -08003862 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08003863
3864 final long identity = Binder.clearCallingIdentity();
3865 try {
3866 int phoneId = mSubscriptionController.getPhoneId(subId);
3867 if (DBG) log("isDataEnabled: subId=" + subId + " phoneId=" + phoneId);
3868 Phone phone = PhoneFactory.getPhone(phoneId);
3869 if (phone != null) {
3870 boolean retVal = phone.isDataEnabled();
3871 if (DBG) log("isDataEnabled: subId=" + subId + " retVal=" + retVal);
3872 return retVal;
3873 } else {
3874 if (DBG) loge("isDataEnabled: no phone subId=" + subId + " retVal=false");
3875 return false;
3876 }
3877 } finally {
3878 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08003879 }
Robert Greenwalted86e582014-05-21 20:03:20 -07003880 }
Shishir Agrawal60f9c952014-06-23 12:00:43 -07003881
3882 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003883 public int getCarrierPrivilegeStatus(int subId) {
3884 final Phone phone = getPhone(subId);
3885 if (phone == null) {
3886 loge("getCarrierPrivilegeStatus: Invalid subId");
3887 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
3888 }
3889 UiccCard card = UiccController.getInstance().getUiccCard(phone.getPhoneId());
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07003890 if (card == null) {
Shishir Agrawal5e5becd2014-11-18 11:38:23 -08003891 loge("getCarrierPrivilegeStatus: No UICC");
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07003892 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3893 }
3894 return card.getCarrierPrivilegeStatusForCurrentTransaction(
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003895 phone.getContext().getPackageManager());
Shishir Agrawal60f9c952014-06-23 12:00:43 -07003896 }
Junda Liu29340342014-07-10 15:23:27 -07003897
3898 @Override
Jeff Davidson7e17e312018-02-13 18:17:36 -08003899 public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
3900 final Phone phone = getPhone(subId);
3901 if (phone == null) {
3902 loge("getCarrierPrivilegeStatus: Invalid subId");
3903 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
3904 }
3905 UiccProfile profile =
3906 UiccController.getInstance().getUiccProfileForPhone(phone.getPhoneId());
3907 if (profile == null) {
3908 loge("getCarrierPrivilegeStatus: No UICC");
3909 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3910 }
3911 return profile.getCarrierPrivilegeStatusForUid(phone.getContext().getPackageManager(), uid);
3912 }
3913
3914 @Override
Zach Johnson50ecba32015-05-19 00:24:21 -07003915 public int checkCarrierPrivilegesForPackage(String pkgName) {
Junda Liu317d70b2016-03-08 09:33:53 -08003916 if (TextUtils.isEmpty(pkgName))
3917 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Shishir Agrawal21409252015-01-15 23:33:50 -08003918 UiccCard card = UiccController.getInstance().getUiccCard(mPhone.getPhoneId());
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07003919 if (card == null) {
3920 loge("checkCarrierPrivilegesForPackage: No UICC");
3921 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3922 }
Zach Johnson50ecba32015-05-19 00:24:21 -07003923 return card.getCarrierPrivilegeStatus(mPhone.getContext().getPackageManager(), pkgName);
3924 }
3925
3926 @Override
3927 public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
Junda Liu317d70b2016-03-08 09:33:53 -08003928 if (TextUtils.isEmpty(pkgName))
3929 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Zach Johnson50ecba32015-05-19 00:24:21 -07003930 int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3931 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
3932 UiccCard card = UiccController.getInstance().getUiccCard(i);
3933 if (card == null) {
Jonathan Basseri7d320df2015-06-16 12:17:08 -07003934 // No UICC in that slot.
Zach Johnson50ecba32015-05-19 00:24:21 -07003935 continue;
3936 }
3937
3938 result = card.getCarrierPrivilegeStatus(
3939 mPhone.getContext().getPackageManager(), pkgName);
3940 if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
3941 break;
3942 }
3943 }
3944
3945 return result;
Junda Liu29340342014-07-10 15:23:27 -07003946 }
Derek Tan89e89d42014-07-08 17:00:10 -07003947
3948 @Override
Junda Liue64de782015-04-16 17:19:16 -07003949 public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
3950 if (!SubscriptionManager.isValidPhoneId(phoneId)) {
3951 loge("phoneId " + phoneId + " is not valid.");
3952 return null;
3953 }
3954 UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07003955 if (card == null) {
Diego Pontorieroaf74c862014-08-28 11:51:16 -07003956 loge("getCarrierPackageNamesForIntent: No UICC");
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07003957 return null ;
3958 }
Diego Pontorieroaf74c862014-08-28 11:51:16 -07003959 return card.getCarrierPackageNamesForIntent(
Svetoslav483aff72015-04-21 14:16:07 -07003960 mPhone.getContext().getPackageManager(), intent);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07003961 }
3962
Amith Yamasani6e118872016-02-19 12:53:51 -08003963 @Override
3964 public List<String> getPackagesWithCarrierPrivileges() {
3965 PackageManager pm = mPhone.getContext().getPackageManager();
3966 List<String> privilegedPackages = new ArrayList<>();
3967 List<PackageInfo> packages = null;
3968 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
3969 UiccCard card = UiccController.getInstance().getUiccCard(i);
3970 if (card == null) {
3971 // No UICC in that slot.
3972 continue;
3973 }
3974 if (card.hasCarrierPrivilegeRules()) {
3975 if (packages == null) {
3976 // Only check packages in user 0 for now
3977 packages = pm.getInstalledPackagesAsUser(
3978 PackageManager.MATCH_DISABLED_COMPONENTS
3979 | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
3980 | PackageManager.GET_SIGNATURES, UserHandle.USER_SYSTEM);
3981 }
3982 for (int p = packages.size() - 1; p >= 0; p--) {
3983 PackageInfo pkgInfo = packages.get(p);
3984 if (pkgInfo != null && pkgInfo.packageName != null
3985 && card.getCarrierPrivilegeStatus(pkgInfo)
3986 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
3987 privilegedPackages.add(pkgInfo.packageName);
3988 }
3989 }
3990 }
3991 }
3992 return privilegedPackages;
3993 }
3994
Wink Savilleb564aae2014-10-23 10:18:09 -07003995 private String getIccId(int subId) {
Sanket Padawe356d7632015-06-22 14:03:32 -07003996 final Phone phone = getPhone(subId);
3997 UiccCard card = phone == null ? null : phone.getUiccCard();
Derek Tan97ebb422014-09-05 16:55:38 -07003998 if (card == null) {
3999 loge("getIccId: No UICC");
4000 return null;
4001 }
4002 String iccId = card.getIccId();
4003 if (TextUtils.isEmpty(iccId)) {
4004 loge("getIccId: ICC ID is null or empty.");
4005 return null;
4006 }
4007 return iccId;
4008 }
4009
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07004010 @Override
Jeff Sharkey85190e62014-12-05 09:40:12 -08004011 public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
4012 String number) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004013 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
4014 subId, "setLine1NumberForDisplayForSubscriber");
Derek Tan97ebb422014-09-05 16:55:38 -07004015
Malcolm Chend965c8b2018-02-28 15:00:40 -08004016 final long identity = Binder.clearCallingIdentity();
4017 try {
4018 final String iccId = getIccId(subId);
4019 final Phone phone = getPhone(subId);
4020 if (phone == null) {
4021 return false;
4022 }
4023 final String subscriberId = phone.getSubscriberId();
4024
4025 if (DBG_MERGE) {
4026 Slog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId="
4027 + subscriberId + " to " + number);
4028 }
4029
4030 if (TextUtils.isEmpty(iccId)) {
4031 return false;
4032 }
4033
4034 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
4035
4036 final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
4037 if (alphaTag == null) {
4038 editor.remove(alphaTagPrefKey);
4039 } else {
4040 editor.putString(alphaTagPrefKey, alphaTag);
4041 }
4042
4043 // Record both the line number and IMSI for this ICCID, since we need to
4044 // track all merged IMSIs based on line number
4045 final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
4046 final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
4047 if (number == null) {
4048 editor.remove(numberPrefKey);
4049 editor.remove(subscriberPrefKey);
4050 } else {
4051 editor.putString(numberPrefKey, number);
4052 editor.putString(subscriberPrefKey, subscriberId);
4053 }
4054
4055 editor.commit();
4056 return true;
4057 } finally {
4058 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07004059 }
Derek Tan7226c842014-07-02 17:42:23 -07004060 }
4061
4062 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004063 public String getLine1NumberForDisplay(int subId, String callingPackage) {
Makoto Onukifee69342015-06-29 14:44:50 -07004064 // This is open to apps with WRITE_SMS.
Jeff Davidson7e17e312018-02-13 18:17:36 -08004065 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
Jeff Davidson913390f2018-02-23 17:11:49 -08004066 mApp, subId, callingPackage, "getLine1NumberForDisplay")) {
Amit Mahajan9cf11512015-11-09 11:40:48 -08004067 if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
Svet Ganovb320e182015-04-16 12:30:10 -07004068 return null;
4069 }
Derek Tan97ebb422014-09-05 16:55:38 -07004070
Malcolm Chend965c8b2018-02-28 15:00:40 -08004071 final long identity = Binder.clearCallingIdentity();
4072 try {
4073 String iccId = getIccId(subId);
4074 if (iccId != null) {
4075 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
4076 if (DBG_MERGE) {
4077 log("getLine1NumberForDisplay returning "
4078 + mTelephonySharedPreferences.getString(numberPrefKey, null));
4079 }
4080 return mTelephonySharedPreferences.getString(numberPrefKey, null);
Amit Mahajan9cf11512015-11-09 11:40:48 -08004081 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08004082 if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null");
4083 return null;
4084 } finally {
4085 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07004086 }
Derek Tan7226c842014-07-02 17:42:23 -07004087 }
4088
4089 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004090 public String getLine1AlphaTagForDisplay(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004091 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08004092 mApp, subId, callingPackage, "getLine1AlphaTagForDisplay")) {
Svet Ganovb320e182015-04-16 12:30:10 -07004093 return null;
4094 }
Derek Tan97ebb422014-09-05 16:55:38 -07004095
Malcolm Chend965c8b2018-02-28 15:00:40 -08004096 final long identity = Binder.clearCallingIdentity();
4097 try {
4098 String iccId = getIccId(subId);
4099 if (iccId != null) {
4100 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
4101 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null);
4102 }
4103 return null;
4104 } finally {
4105 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07004106 }
Derek Tan7226c842014-07-02 17:42:23 -07004107 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07004108
4109 @Override
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07004110 public String[] getMergedSubscriberIds(String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08004111 // This API isn't public, so no need to provide a valid subscription ID - we're not worried
4112 // about carrier-privileged callers not having access.
Jeff Davidson7e17e312018-02-13 18:17:36 -08004113 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08004114 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
4115 "getMergedSubscriberIds")) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07004116 return null;
4117 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08004118
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07004119 final long identity = Binder.clearCallingIdentity();
4120 try {
Malcolm Chend965c8b2018-02-28 15:00:40 -08004121 final Context context = mPhone.getContext();
4122 final TelephonyManager tele = TelephonyManager.from(context);
4123 final SubscriptionManager sub = SubscriptionManager.from(context);
4124
4125 // Figure out what subscribers are currently active
4126 final ArraySet<String> activeSubscriberIds = new ArraySet<>();
4127 // Clear calling identity, when calling TelephonyManager, because callerUid must be
4128 // the process, where TelephonyManager was instantiated.
4129 // Otherwise AppOps check will fail.
4130
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07004131 final int[] subIds = sub.getActiveSubscriptionIdList();
4132 for (int subId : subIds) {
4133 activeSubscriberIds.add(tele.getSubscriberId(subId));
4134 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08004135
4136 // First pass, find a number override for an active subscriber
4137 String mergeNumber = null;
4138 final Map<String, ?> prefs = mTelephonySharedPreferences.getAll();
4139 for (String key : prefs.keySet()) {
4140 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) {
4141 final String subscriberId = (String) prefs.get(key);
4142 if (activeSubscriberIds.contains(subscriberId)) {
4143 final String iccId = key.substring(
4144 PREF_CARRIERS_SUBSCRIBER_PREFIX.length());
4145 final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
4146 mergeNumber = (String) prefs.get(numberKey);
4147 if (DBG_MERGE) {
4148 Slog.d(LOG_TAG, "Found line number " + mergeNumber
4149 + " for active subscriber " + subscriberId);
4150 }
4151 if (!TextUtils.isEmpty(mergeNumber)) {
4152 break;
4153 }
4154 }
4155 }
4156 }
4157
4158 // Shortcut when no active merged subscribers
4159 if (TextUtils.isEmpty(mergeNumber)) {
4160 return null;
4161 }
4162
4163 // Second pass, find all subscribers under that line override
4164 final ArraySet<String> result = new ArraySet<>();
4165 for (String key : prefs.keySet()) {
4166 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) {
4167 final String number = (String) prefs.get(key);
4168 if (mergeNumber.equals(number)) {
4169 final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length());
4170 final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
4171 final String subscriberId = (String) prefs.get(subscriberKey);
4172 if (!TextUtils.isEmpty(subscriberId)) {
4173 result.add(subscriberId);
4174 }
4175 }
4176 }
4177 }
4178
4179 final String[] resultArray = result.toArray(new String[result.size()]);
4180 Arrays.sort(resultArray);
4181 if (DBG_MERGE) {
4182 Slog.d(LOG_TAG,
4183 "Found subscribers " + Arrays.toString(resultArray) + " after merge");
4184 }
4185 return resultArray;
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07004186 } finally {
4187 Binder.restoreCallingIdentity(identity);
Jeff Sharkey85190e62014-12-05 09:40:12 -08004188 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08004189 }
4190
4191 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004192 public boolean setOperatorBrandOverride(int subId, String brand) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004193 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
4194 subId, "setOperatorBrandOverride");
Malcolm Chend965c8b2018-02-28 15:00:40 -08004195
4196 final long identity = Binder.clearCallingIdentity();
4197 try {
4198 final Phone phone = getPhone(subId);
4199 return phone == null ? false : phone.setOperatorBrandOverride(brand);
4200 } finally {
4201 Binder.restoreCallingIdentity(identity);
4202 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07004203 }
Steven Liu4bf01bc2014-07-17 11:05:29 -05004204
4205 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004206 public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
Shishir Agrawal621a47c2014-12-01 10:25:09 -08004207 List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
4208 List<String> cdmaNonRoamingList) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004209 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setRoamingOverride");
Malcolm Chend965c8b2018-02-28 15:00:40 -08004210
4211 final long identity = Binder.clearCallingIdentity();
4212 try {
4213 final Phone phone = getPhone(subId);
4214 if (phone == null) {
4215 return false;
4216 }
4217 return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList,
4218 cdmaNonRoamingList);
4219 } finally {
4220 Binder.restoreCallingIdentity(identity);
Shishir Agrawalc04d9752016-02-19 10:41:00 -08004221 }
Shishir Agrawal621a47c2014-12-01 10:25:09 -08004222 }
4223
4224 @Override
Shuo Qian850e4d6a2018-04-25 21:02:08 +00004225 @Deprecated
4226 public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
4227 enforceModifyPermission();
4228
4229 int returnValue = 0;
4230 try {
vagdevie435a3e2018-08-15 16:01:53 -07004231 AsyncResult result = (AsyncResult) sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
Shuo Qian850e4d6a2018-04-25 21:02:08 +00004232 if(result.exception == null) {
4233 if (result.result != null) {
4234 byte[] responseData = (byte[])(result.result);
4235 if(responseData.length > oemResp.length) {
4236 Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +
4237 responseData.length + "bytes. Buffer Size is " +
4238 oemResp.length + "bytes.");
4239 }
4240 System.arraycopy(responseData, 0, oemResp, 0, responseData.length);
4241 returnValue = responseData.length;
4242 }
4243 } else {
4244 CommandException ex = (CommandException) result.exception;
4245 returnValue = ex.getCommandError().ordinal();
4246 if(returnValue > 0) returnValue *= -1;
4247 }
4248 } catch (RuntimeException e) {
4249 Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");
4250 returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());
4251 if(returnValue > 0) returnValue *= -1;
4252 }
4253
4254 return returnValue;
4255 }
4256
4257 @Override
Wink Saville5d475dd2014-10-17 15:00:58 -07004258 public void setRadioCapability(RadioAccessFamily[] rafs) {
4259 try {
4260 ProxyController.getInstance().setRadioCapability(rafs);
4261 } catch (RuntimeException e) {
4262 Log.w(LOG_TAG, "setRadioCapability: Runtime Exception");
4263 }
4264 }
4265
4266 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004267 public int getRadioAccessFamily(int phoneId, String callingPackage) {
Jeff Davidson913390f2018-02-23 17:11:49 -08004268 Phone phone = PhoneFactory.getPhone(phoneId);
4269 if (phone == null) {
4270 return RadioAccessFamily.RAF_UNKNOWN;
4271 }
4272 int subId = phone.getSubId();
Jeff Davidson7e17e312018-02-13 18:17:36 -08004273 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08004274 mApp, subId, callingPackage, "getRadioAccessFamily")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004275 return RadioAccessFamily.RAF_UNKNOWN;
4276 }
4277
Malcolm Chend965c8b2018-02-28 15:00:40 -08004278 final long identity = Binder.clearCallingIdentity();
4279 try {
4280 return ProxyController.getInstance().getRadioAccessFamily(phoneId);
4281 } finally {
4282 Binder.restoreCallingIdentity(identity);
4283 }
Wink Saville5d475dd2014-10-17 15:00:58 -07004284 }
Andrew Leedf14ead2014-10-17 14:22:52 -07004285
4286 @Override
4287 public void enableVideoCalling(boolean enable) {
4288 enforceModifyPermission();
Malcolm Chend965c8b2018-02-28 15:00:40 -08004289
4290 final long identity = Binder.clearCallingIdentity();
4291 try {
4292 ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId()).setVtSetting(enable);
4293 } finally {
4294 Binder.restoreCallingIdentity(identity);
4295 }
Andrew Leedf14ead2014-10-17 14:22:52 -07004296 }
4297
4298 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004299 public boolean isVideoCallingEnabled(String callingPackage) {
Amit Mahajan578e53d2018-03-20 16:18:38 +00004300 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4301 mApp, mPhone.getSubId(), callingPackage, "isVideoCallingEnabled")) {
4302 return false;
4303 }
Svet Ganovb320e182015-04-16 12:30:10 -07004304
Malcolm Chend965c8b2018-02-28 15:00:40 -08004305 final long identity = Binder.clearCallingIdentity();
4306 try {
4307 // Check the user preference and the system-level IMS setting. Even if the user has
4308 // enabled video calling, if IMS is disabled we aren't able to support video calling.
4309 // In the long run, we may instead need to check if there exists a connection service
4310 // which can support video calling.
4311 ImsManager imsManager =
4312 ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId());
4313 return imsManager.isVtEnabledByPlatform()
4314 && imsManager.isEnhanced4gLteModeSettingEnabledByUser()
4315 && imsManager.isVtEnabledByUser();
4316 } finally {
4317 Binder.restoreCallingIdentity(identity);
4318 }
Andrew Leedf14ead2014-10-17 14:22:52 -07004319 }
Libin.Tang@motorola.comafe82642014-12-18 13:27:53 -06004320
Andrew Leea1239f22015-03-02 17:44:07 -08004321 @Override
Malcolm Chend965c8b2018-02-28 15:00:40 -08004322 public boolean canChangeDtmfToneLength(int subId, String callingPackage) {
4323 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4324 mApp, subId, callingPackage, "isVideoCallingEnabled")) {
4325 return false;
4326 }
4327
4328 final long identity = Binder.clearCallingIdentity();
4329 try {
4330 CarrierConfigManager configManager =
4331 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
4332 return configManager.getConfigForSubId(mPhone.getSubId())
4333 .getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL);
4334 } finally {
4335 Binder.restoreCallingIdentity(identity);
4336 }
Andrew Leea1239f22015-03-02 17:44:07 -08004337 }
4338
4339 @Override
Malcolm Chend965c8b2018-02-28 15:00:40 -08004340 public boolean isWorldPhone(int subId, String callingPackage) {
4341 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4342 mApp, subId, callingPackage, "isVideoCallingEnabled")) {
4343 return false;
4344 }
4345
4346 final long identity = Binder.clearCallingIdentity();
4347 try {
4348 CarrierConfigManager configManager =
4349 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
4350 return configManager.getConfigForSubId(mPhone.getSubId())
4351 .getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL);
4352 } finally {
4353 Binder.restoreCallingIdentity(identity);
4354 }
Andrew Leea1239f22015-03-02 17:44:07 -08004355 }
4356
Andrew Lee9431b832015-03-09 18:46:45 -07004357 @Override
4358 public boolean isTtyModeSupported() {
4359 TelecomManager telecomManager = TelecomManager.from(mPhone.getContext());
Wooki Wu1f82f7a2016-02-15 15:59:58 +08004360 return telecomManager.isTtySupported();
Andrew Lee9431b832015-03-09 18:46:45 -07004361 }
4362
4363 @Override
4364 public boolean isHearingAidCompatibilitySupported() {
Malcolm Chend965c8b2018-02-28 15:00:40 -08004365 final long identity = Binder.clearCallingIdentity();
4366 try {
4367 return mPhone.getContext().getResources().getBoolean(R.bool.hac_enabled);
4368 } finally {
4369 Binder.restoreCallingIdentity(identity);
4370 }
Andrew Lee9431b832015-03-09 18:46:45 -07004371 }
4372
Hall Liu98187582018-01-22 19:15:32 -08004373 public boolean isRttSupported() {
Malcolm Chend965c8b2018-02-28 15:00:40 -08004374 final long identity = Binder.clearCallingIdentity();
4375 try {
4376 boolean isCarrierSupported = mApp.getCarrierConfigForSubId(
4377 mPhone.getSubId()).getBoolean(
4378 CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
4379 boolean isDeviceSupported =
4380 mPhone.getContext().getResources().getBoolean(R.bool.config_support_rtt);
4381 return isCarrierSupported && isDeviceSupported;
4382 } finally {
4383 Binder.restoreCallingIdentity(identity);
4384 }
Hall Liu98187582018-01-22 19:15:32 -08004385 }
4386
Hall Liu3ad5f012018-04-06 16:23:39 -07004387 public boolean isRttEnabled() {
Malcolm Chend965c8b2018-02-28 15:00:40 -08004388 final long identity = Binder.clearCallingIdentity();
4389 try {
4390 return isRttSupported() && Settings.Secure.getInt(
4391 mPhone.getContext().getContentResolver(),
4392 Settings.Secure.RTT_CALLING_MODE, 0) != 0;
4393 } finally {
4394 Binder.restoreCallingIdentity(identity);
4395 }
Hall Liu3ad5f012018-04-06 16:23:39 -07004396 }
4397
Sanket Padawe7310cc72015-01-14 09:53:20 -08004398 /**
4399 * Returns the unique device ID of phone, for example, the IMEI for
4400 * GSM and the MEID for CDMA phones. Return null if device ID is not available.
4401 *
4402 * <p>Requires Permission:
4403 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
4404 */
4405 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004406 public String getDeviceId(String callingPackage) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08004407 final Phone phone = PhoneFactory.getPhone(0);
Jeff Davidson913390f2018-02-23 17:11:49 -08004408 if (phone == null) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08004409 return null;
4410 }
Jeff Davidson913390f2018-02-23 17:11:49 -08004411 int subId = phone.getSubId();
4412 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4413 mApp, subId, callingPackage, "getDeviceId")) {
4414 return null;
4415 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08004416
4417 final long identity = Binder.clearCallingIdentity();
4418 try {
4419 return phone.getDeviceId();
4420 } finally {
4421 Binder.restoreCallingIdentity(identity);
4422 }
Sanket Padawe7310cc72015-01-14 09:53:20 -08004423 }
4424
Ping Sunc67b7c22016-03-02 19:16:45 +08004425 /**
4426 * {@hide}
4427 * Returns the IMS Registration Status on a particular subid
4428 *
4429 * @param subId
4430 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004431 public boolean isImsRegistered(int subId) {
Ping Sunc67b7c22016-03-02 19:16:45 +08004432 Phone phone = getPhone(subId);
4433 if (phone != null) {
4434 return phone.isImsRegistered();
4435 } else {
4436 return false;
4437 }
4438 }
4439
Santos Cordon7a1885b2015-02-03 11:15:19 -08004440 @Override
4441 public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) {
Malcolm Chend965c8b2018-02-28 15:00:40 -08004442 final long identity = Binder.clearCallingIdentity();
4443 try {
4444 return PhoneUtils.getSubIdForPhoneAccount(phoneAccount);
4445 } finally {
4446 Binder.restoreCallingIdentity(identity);
4447 }
Santos Cordon7a1885b2015-02-03 11:15:19 -08004448 }
Nathan Harolddcfc7932015-03-18 10:01:20 -07004449
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004450 /**
4451 * @return the VoWiFi calling availability.
Nathan Haroldc55097a2015-03-11 18:14:50 -07004452 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004453 public boolean isWifiCallingAvailable(int subId) {
Malcolm Chend965c8b2018-02-28 15:00:40 -08004454 final long identity = Binder.clearCallingIdentity();
4455 try {
4456 Phone phone = getPhone(subId);
4457 if (phone != null) {
4458 return phone.isWifiCallingEnabled();
4459 } else {
4460 return false;
4461 }
4462 } finally {
4463 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004464 }
Nathan Haroldc55097a2015-03-11 18:14:50 -07004465 }
4466
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004467 /**
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004468 * @return the VT calling availability.
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07004469 */
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004470 public boolean isVideoTelephonyAvailable(int subId) {
Malcolm Chend965c8b2018-02-28 15:00:40 -08004471 final long identity = Binder.clearCallingIdentity();
4472 try {
4473 Phone phone = getPhone(subId);
4474 if (phone != null) {
4475 return phone.isVideoEnabled();
4476 } else {
4477 return false;
4478 }
4479 } finally {
4480 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004481 }
4482 }
4483
4484 /**
4485 * @return the IMS registration technology for the MMTEL feature. Valid return values are
4486 * defined in {@link ImsRegistrationImplBase}.
4487 */
4488 public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel(int subId) {
Malcolm Chend965c8b2018-02-28 15:00:40 -08004489 final long identity = Binder.clearCallingIdentity();
4490 try {
4491 Phone phone = getPhone(subId);
4492 if (phone != null) {
4493 return phone.getImsRegistrationTech();
4494 } else {
4495 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
4496 }
4497 } finally {
4498 Binder.restoreCallingIdentity(identity);
Brad Ebinger1f2b5082018-02-08 16:11:32 -08004499 }
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07004500 }
4501
Stuart Scott8eef64f2015-04-08 15:13:54 -07004502 @Override
4503 public void factoryReset(int subId) {
4504 enforceConnectivityInternalPermission();
Stuart Scott981d8582015-04-21 14:09:50 -07004505 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
4506 return;
4507 }
4508
Svet Ganovcc087f82015-05-12 20:35:54 -07004509 final long identity = Binder.clearCallingIdentity();
4510 try {
Stuart Scott981d8582015-04-21 14:09:50 -07004511 if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
4512 UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
Pengquan Meng85728fb2018-03-12 16:31:21 -07004513 setUserDataEnabled(subId, getDefaultDataEnabled());
Svet Ganovcc087f82015-05-12 20:35:54 -07004514 setNetworkSelectionModeAutomatic(subId);
Pengquan Meng85728fb2018-03-12 16:31:21 -07004515 setPreferredNetworkType(subId, getDefaultNetworkType(subId));
4516 mPhone.setDataRoamingEnabled(getDefaultDataRoamingEnabled(subId));
pkanwar79ec0542017-07-31 14:10:01 -07004517 CarrierInfoManager.deleteAllCarrierKeysForImsiEncryption(mPhone.getContext());
Svet Ganovcc087f82015-05-12 20:35:54 -07004518 }
4519 } finally {
4520 Binder.restoreCallingIdentity(identity);
Stuart Scott8eef64f2015-04-08 15:13:54 -07004521 }
4522 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004523
4524 @Override
4525 public String getLocaleFromDefaultSim() {
Malcolm Chend965c8b2018-02-28 15:00:40 -08004526 final long identity = Binder.clearCallingIdentity();
4527 try {
4528 // We query all subscriptions instead of just the active ones, because
4529 // this might be called early on in the provisioning flow when the
4530 // subscriptions potentially aren't active yet.
4531 final List<SubscriptionInfo> slist = getAllSubscriptionInfoList();
4532 if (slist == null || slist.isEmpty()) {
Narayan Kamath1c496c22015-04-16 14:40:19 +01004533 return null;
4534 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004535
Malcolm Chend965c8b2018-02-28 15:00:40 -08004536 // This function may be called very early, say, from the setup wizard, at
4537 // which point we won't have a default subscription set. If that's the case
4538 // we just choose the first, which will be valid in "most cases".
4539 final int defaultSubId = getDefaultSubscription();
4540 SubscriptionInfo info = null;
4541 if (defaultSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
4542 info = slist.get(0);
4543 } else {
4544 for (SubscriptionInfo item : slist) {
4545 if (item.getSubscriptionId() == defaultSubId) {
4546 info = item;
4547 break;
4548 }
4549 }
4550
4551 if (info == null) {
4552 return null;
Tony Hill183b2de2015-06-24 14:53:58 +01004553 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004554 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004555
Malcolm Chend965c8b2018-02-28 15:00:40 -08004556 // Try and fetch the locale from the carrier properties or from the SIM language
4557 // preferences (EF-PL and EF-LI)...
4558 final int mcc = info.getMcc();
4559 final Phone defaultPhone = getPhone(info.getSubscriptionId());
4560 String simLanguage = null;
4561 if (defaultPhone != null) {
4562 final Locale localeFromDefaultSim = defaultPhone.getLocaleFromSimAndCarrierPrefs();
4563 if (localeFromDefaultSim != null) {
4564 if (!localeFromDefaultSim.getCountry().isEmpty()) {
4565 if (DBG) log("Using locale from default SIM:" + localeFromDefaultSim);
4566 return localeFromDefaultSim.toLanguageTag();
4567 } else {
4568 simLanguage = localeFromDefaultSim.getLanguage();
4569 }
4570 }
4571 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004572
Malcolm Chend965c8b2018-02-28 15:00:40 -08004573 // The SIM language preferences only store a language (e.g. fr = French), not an
4574 // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
4575 // the SIM and carrier preferences does not include a country we add the country
4576 // determined from the SIM MCC to provide an exact locale.
4577 final Locale mccLocale = MccTable.getLocaleFromMcc(mPhone.getContext(), mcc,
4578 simLanguage);
4579 if (mccLocale != null) {
4580 if (DBG) log("No locale from default SIM, using mcc locale:" + mccLocale);
4581 return mccLocale.toLanguageTag();
4582 }
4583
4584 if (DBG) log("No locale found - returning null");
4585 return null;
4586 } finally {
4587 Binder.restoreCallingIdentity(identity);
4588 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004589 }
4590
4591 private List<SubscriptionInfo> getAllSubscriptionInfoList() {
Malcolm Chend965c8b2018-02-28 15:00:40 -08004592 return mSubscriptionController.getAllSubInfoList(
4593 mPhone.getContext().getOpPackageName());
Narayan Kamath1c496c22015-04-16 14:40:19 +01004594 }
4595
Malcolm Chend965c8b2018-02-28 15:00:40 -08004596 /**
4597 * NOTE: this method assumes permission checks are done and caller identity has been cleared.
4598 */
4599 private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
4600 return mSubscriptionController.getActiveSubscriptionInfoList(
4601 mPhone.getContext().getOpPackageName());
Narayan Kamath1c496c22015-04-16 14:40:19 +01004602 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004603
Chenjie Yu1ba97252018-01-11 18:16:20 -08004604 private final ModemActivityInfo mLastModemActivityInfo =
4605 new ModemActivityInfo(0, 0, 0, new int[0], 0, 0);
4606
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004607 /**
Adam Lesinski903a54c2016-04-11 14:49:52 -07004608 * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
4609 * representing the state of the modem.
4610 *
Chenjie Yu1ba97252018-01-11 18:16:20 -08004611 * NOTE: The underlying implementation clears the modem state, so there should only ever be one
4612 * caller to it. Everyone should call this class to get cumulative data.
Adam Lesinski903a54c2016-04-11 14:49:52 -07004613 * @hide
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004614 */
4615 @Override
Adam Lesinski903a54c2016-04-11 14:49:52 -07004616 public void requestModemActivityInfo(ResultReceiver result) {
4617 enforceModifyPermission();
vagdevie435a3e2018-08-15 16:01:53 -07004618 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chend965c8b2018-02-28 15:00:40 -08004619
4620 final long identity = Binder.clearCallingIdentity();
4621 try {
4622 ModemActivityInfo ret = null;
4623 synchronized (mLastModemActivityInfo) {
vagdevie435a3e2018-08-15 16:01:53 -07004624 ModemActivityInfo info = (ModemActivityInfo) sendRequest(
4625 CMD_GET_MODEM_ACTIVITY_INFO,
4626 null, workSource);
Malcolm Chend965c8b2018-02-28 15:00:40 -08004627 if (isModemActivityInfoValid(info)) {
4628 int[] mergedTxTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
4629 for (int i = 0; i < mergedTxTimeMs.length; i++) {
4630 mergedTxTimeMs[i] =
4631 info.getTxTimeMillis()[i] + mLastModemActivityInfo.getTxTimeMillis()[i];
4632 }
4633 mLastModemActivityInfo.setTimestamp(info.getTimestamp());
4634 mLastModemActivityInfo.setSleepTimeMillis(
4635 info.getSleepTimeMillis() + mLastModemActivityInfo.getSleepTimeMillis());
4636 mLastModemActivityInfo.setIdleTimeMillis(
4637 info.getIdleTimeMillis() + mLastModemActivityInfo.getIdleTimeMillis());
4638 mLastModemActivityInfo.setTxTimeMillis(mergedTxTimeMs);
4639 mLastModemActivityInfo.setRxTimeMillis(
4640 info.getRxTimeMillis() + mLastModemActivityInfo.getRxTimeMillis());
4641 mLastModemActivityInfo.setEnergyUsed(
4642 info.getEnergyUsed() + mLastModemActivityInfo.getEnergyUsed());
Chenjie Yu1ba97252018-01-11 18:16:20 -08004643 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08004644 ret = new ModemActivityInfo(mLastModemActivityInfo.getTimestamp(),
4645 mLastModemActivityInfo.getSleepTimeMillis(),
4646 mLastModemActivityInfo.getIdleTimeMillis(),
4647 mLastModemActivityInfo.getTxTimeMillis(),
4648 mLastModemActivityInfo.getRxTimeMillis(),
4649 mLastModemActivityInfo.getEnergyUsed());
Chenjie Yu1ba97252018-01-11 18:16:20 -08004650 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08004651 Bundle bundle = new Bundle();
4652 bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, ret);
4653 result.send(0, bundle);
4654 } finally {
4655 Binder.restoreCallingIdentity(identity);
Chenjie Yu1ba97252018-01-11 18:16:20 -08004656 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004657 }
Jack Yu85bd38a2015-11-09 11:34:32 -08004658
Siddharth Rayf5d29552018-06-17 15:02:38 -07004659 // Checks that ModemActivityInfo is valid. Sleep time, Idle time, Rx time and Tx time should be
4660 // less than total activity duration.
4661 private boolean isModemActivityInfoValid(ModemActivityInfo info) {
4662 if (info == null) {
4663 return false;
4664 }
4665 int activityDurationMs =
4666 (int) (info.getTimestamp() - mLastModemActivityInfo.getTimestamp());
4667 int totalTxTimeMs = 0;
4668 for (int i = 0; i < info.getTxTimeMillis().length; i++) {
4669 totalTxTimeMs += info.getTxTimeMillis()[i];
4670 }
4671 return (info.isValid()
4672 && (info.getSleepTimeMillis() <= activityDurationMs)
4673 && (info.getIdleTimeMillis() <= activityDurationMs)
4674 && (info.getRxTimeMillis() <= activityDurationMs)
4675 && (totalTxTimeMs <= activityDurationMs));
4676 }
4677
Jack Yu85bd38a2015-11-09 11:34:32 -08004678 /**
4679 * {@hide}
4680 * Returns the service state information on specified subscription.
4681 */
4682 @Override
4683 public ServiceState getServiceStateForSubscriber(int subId, String callingPackage) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004684 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08004685 mApp, subId, callingPackage, "getServiceStateForSubscriber")) {
Jack Yu85bd38a2015-11-09 11:34:32 -08004686 return null;
4687 }
4688
Malcolm Chend965c8b2018-02-28 15:00:40 -08004689 final long identity = Binder.clearCallingIdentity();
4690 try {
4691 final Phone phone = getPhone(subId);
4692 if (phone == null) {
4693 return null;
4694 }
Jack Yu85bd38a2015-11-09 11:34:32 -08004695
Malcolm Chend965c8b2018-02-28 15:00:40 -08004696 return phone.getServiceState();
4697 } finally {
4698 Binder.restoreCallingIdentity(identity);
4699 }
Jack Yu85bd38a2015-11-09 11:34:32 -08004700 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004701
4702 /**
4703 * Returns the URI for the per-account voicemail ringtone set in Phone settings.
4704 *
4705 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
4706 * voicemail ringtone.
4707 * @return The URI for the ringtone to play when receiving a voicemail from a specific
4708 * PhoneAccount.
4709 */
4710 @Override
4711 public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
Malcolm Chend965c8b2018-02-28 15:00:40 -08004712 final long identity = Binder.clearCallingIdentity();
4713 try {
4714 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
4715 if (phone == null) {
4716 phone = mPhone;
4717 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004718
Malcolm Chend965c8b2018-02-28 15:00:40 -08004719 return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext());
4720 } finally {
4721 Binder.restoreCallingIdentity(identity);
4722 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004723 }
4724
4725 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004726 * Sets the per-account voicemail ringtone.
4727 *
4728 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
4729 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
4730 *
4731 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
4732 * voicemail ringtone.
4733 * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
4734 * PhoneAccount.
4735 */
4736 @Override
4737 public void setVoicemailRingtoneUri(String callingPackage,
4738 PhoneAccountHandle phoneAccountHandle, Uri uri) {
4739 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4740 if (!TextUtils.equals(callingPackage,
4741 TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004742 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4743 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
4744 "setVoicemailRingtoneUri");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004745 }
Malcolm Chend965c8b2018-02-28 15:00:40 -08004746
4747 final long identity = Binder.clearCallingIdentity();
4748 try {
4749 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
4750 if (phone == null) {
4751 phone = mPhone;
4752 }
4753 VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri);
4754 } finally {
4755 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004756 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004757 }
4758
4759 /**
Nancy Chen31f9ba12016-01-06 11:42:12 -08004760 * Returns whether vibration is set for voicemail notification in Phone settings.
4761 *
4762 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
4763 * voicemail vibration setting.
4764 * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
4765 */
4766 @Override
4767 public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
Malcolm Chend965c8b2018-02-28 15:00:40 -08004768 final long identity = Binder.clearCallingIdentity();
4769 try {
4770 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
4771 if (phone == null) {
4772 phone = mPhone;
4773 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004774
Malcolm Chend965c8b2018-02-28 15:00:40 -08004775 return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext());
4776 } finally {
4777 Binder.restoreCallingIdentity(identity);
4778 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004779 }
4780
Youhan Wange64578a2016-05-02 15:32:42 -07004781 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004782 * Sets the per-account voicemail vibration.
4783 *
4784 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
4785 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
4786 *
4787 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
4788 * voicemail vibration setting.
4789 * @param enabled Whether to enable or disable vibration for voicemail notifications from a
4790 * specific PhoneAccount.
4791 */
4792 @Override
4793 public void setVoicemailVibrationEnabled(String callingPackage,
4794 PhoneAccountHandle phoneAccountHandle, boolean enabled) {
4795 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4796 if (!TextUtils.equals(callingPackage,
4797 TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage())) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004798 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4799 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
4800 "setVoicemailVibrationEnabled");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004801 }
4802
Malcolm Chend965c8b2018-02-28 15:00:40 -08004803 final long identity = Binder.clearCallingIdentity();
4804 try {
4805 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
4806 if (phone == null) {
4807 phone = mPhone;
4808 }
4809 VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled);
4810 } finally {
4811 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004812 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004813 }
4814
4815 /**
Youhan Wange64578a2016-05-02 15:32:42 -07004816 * Make sure either called from same process as self (phone) or IPC caller has read privilege.
4817 *
4818 * @throws SecurityException if the caller does not have the required permission
4819 */
Brad Ebinger4c460712018-10-01 10:40:55 -07004820 private void enforceReadPrivilegedPermission(String message) {
Youhan Wange64578a2016-05-02 15:32:42 -07004821 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
Brad Ebinger4c460712018-10-01 10:40:55 -07004822 message);
Youhan Wange64578a2016-05-02 15:32:42 -07004823 }
4824
4825 /**
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004826 * Make sure either called from same process as self (phone) or IPC caller has send SMS
4827 * permission.
4828 *
4829 * @throws SecurityException if the caller does not have the required permission
4830 */
4831 private void enforceSendSmsPermission() {
4832 mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null);
4833 }
4834
4835 /**
Ta-wei Yen527a9c02017-01-06 15:29:25 -08004836 * Make sure called from the package in charge of visual voicemail.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004837 *
Ta-wei Yen527a9c02017-01-06 15:29:25 -08004838 * @throws SecurityException if the caller is not the visual voicemail package.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004839 */
Ta-wei Yen527a9c02017-01-06 15:29:25 -08004840 private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
Malcolm Chend965c8b2018-02-28 15:00:40 -08004841 final long identity = Binder.clearCallingIdentity();
4842 try {
4843 ComponentName componentName =
4844 RemoteVvmTaskManager.getRemotePackage(mPhone.getContext(), subId);
4845 if (componentName == null) {
4846 throw new SecurityException(
4847 "Caller not current active visual voicemail package[null]");
4848 }
4849 String vvmPackage = componentName.getPackageName();
4850 if (!callingPackage.equals(vvmPackage)) {
4851 throw new SecurityException("Caller not current active visual voicemail package["
4852 + vvmPackage + "]");
4853 }
4854 } finally {
4855 Binder.restoreCallingIdentity(identity);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004856 }
4857 }
4858
4859 /**
Youhan Wange64578a2016-05-02 15:32:42 -07004860 * Return the application ID for the app type.
4861 *
4862 * @param subId the subscription ID that this request applies to.
4863 * @param appType the uicc app type.
4864 * @return Application ID for specificied app type, or null if no uicc.
4865 */
4866 @Override
4867 public String getAidForAppType(int subId, int appType) {
Brad Ebinger4c460712018-10-01 10:40:55 -07004868 enforceReadPrivilegedPermission("getAidForAppType");
Youhan Wange64578a2016-05-02 15:32:42 -07004869 Phone phone = getPhone(subId);
Malcolm Chend965c8b2018-02-28 15:00:40 -08004870
4871 final long identity = Binder.clearCallingIdentity();
Youhan Wange64578a2016-05-02 15:32:42 -07004872 try {
Malcolm Chend965c8b2018-02-28 15:00:40 -08004873 if (phone == null) {
4874 return null;
4875 }
4876 String aid = null;
4877 try {
4878 aid = UiccController.getInstance().getUiccCard(phone.getPhoneId())
4879 .getApplicationByType(appType).getAid();
4880 } catch (Exception e) {
4881 Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e);
4882 }
4883 return aid;
4884 } finally {
4885 Binder.restoreCallingIdentity(identity);
Youhan Wange64578a2016-05-02 15:32:42 -07004886 }
Youhan Wange64578a2016-05-02 15:32:42 -07004887 }
4888
Youhan Wang4001d252016-05-11 10:29:41 -07004889 /**
4890 * Return the Electronic Serial Number.
4891 *
4892 * @param subId the subscription ID that this request applies to.
4893 * @return ESN or null if error.
4894 */
4895 @Override
4896 public String getEsn(int subId) {
Brad Ebinger4c460712018-10-01 10:40:55 -07004897 enforceReadPrivilegedPermission("getEsn");
Youhan Wang4001d252016-05-11 10:29:41 -07004898 Phone phone = getPhone(subId);
Malcolm Chend965c8b2018-02-28 15:00:40 -08004899
4900 final long identity = Binder.clearCallingIdentity();
Youhan Wang4001d252016-05-11 10:29:41 -07004901 try {
Malcolm Chend965c8b2018-02-28 15:00:40 -08004902 if (phone == null) {
4903 return null;
4904 }
4905 String esn = null;
4906 try {
4907 esn = phone.getEsn();
4908 } catch (Exception e) {
4909 Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e);
4910 }
4911 return esn;
4912 } finally {
4913 Binder.restoreCallingIdentity(identity);
Youhan Wang4001d252016-05-11 10:29:41 -07004914 }
Youhan Wang4001d252016-05-11 10:29:41 -07004915 }
4916
Sanket Padawe99ef1e32016-05-18 16:12:33 -07004917 /**
Youhan Wang66ad5d72016-07-18 17:56:58 -07004918 * Return the Preferred Roaming List Version.
4919 *
4920 * @param subId the subscription ID that this request applies to.
4921 * @return PRLVersion or null if error.
4922 */
4923 @Override
4924 public String getCdmaPrlVersion(int subId) {
Brad Ebinger4c460712018-10-01 10:40:55 -07004925 enforceReadPrivilegedPermission("getCdmaPrlVersion");
Youhan Wang66ad5d72016-07-18 17:56:58 -07004926 Phone phone = getPhone(subId);
Malcolm Chend965c8b2018-02-28 15:00:40 -08004927
4928 final long identity = Binder.clearCallingIdentity();
Youhan Wang66ad5d72016-07-18 17:56:58 -07004929 try {
Malcolm Chend965c8b2018-02-28 15:00:40 -08004930 if (phone == null) {
4931 return null;
4932 }
4933 String cdmaPrlVersion = null;
4934 try {
4935 cdmaPrlVersion = phone.getCdmaPrlVersion();
4936 } catch (Exception e) {
4937 Log.e(LOG_TAG, "Not getting PRLVersion", e);
4938 }
4939 return cdmaPrlVersion;
4940 } finally {
4941 Binder.restoreCallingIdentity(identity);
Youhan Wang66ad5d72016-07-18 17:56:58 -07004942 }
Youhan Wang66ad5d72016-07-18 17:56:58 -07004943 }
4944
4945 /**
Sanket Padawe99ef1e32016-05-18 16:12:33 -07004946 * Get snapshot of Telephony histograms
4947 * @return List of Telephony histograms
4948 * @hide
4949 */
4950 @Override
4951 public List<TelephonyHistogram> getTelephonyHistograms() {
Jeff Davidson7e17e312018-02-13 18:17:36 -08004952 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4953 mApp, getDefaultSubscription(), "getTelephonyHistograms");
Malcolm Chend965c8b2018-02-28 15:00:40 -08004954
4955 final long identity = Binder.clearCallingIdentity();
4956 try {
4957 return RIL.getTelephonyRILTimingHistograms();
4958 } finally {
4959 Binder.restoreCallingIdentity(identity);
4960 }
Sanket Padawe99ef1e32016-05-18 16:12:33 -07004961 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07004962
4963 /**
4964 * {@hide}
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004965 * Set the allowed carrier list for slotIndex
Meng Wang1a7c35a2016-05-05 20:56:15 -07004966 * Require system privileges. In the future we may add this to carrier APIs.
4967 *
4968 * @return The number of carriers set successfully, should match length of carriers
4969 */
4970 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004971 public int setAllowedCarriers(int slotIndex, List<CarrierIdentifier> carriers) {
Meng Wang1a7c35a2016-05-05 20:56:15 -07004972 enforceModifyPermission();
vagdevie435a3e2018-08-15 16:01:53 -07004973 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004974
Meng Wang9b7c4e92017-02-17 11:41:27 -08004975 if (carriers == null) {
4976 throw new NullPointerException("carriers cannot be null");
4977 }
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004978
Malcolm Chend965c8b2018-02-28 15:00:40 -08004979 final long identity = Binder.clearCallingIdentity();
4980 try {
4981 int subId = SubscriptionManager.getSubId(slotIndex)[0];
vagdevie435a3e2018-08-15 16:01:53 -07004982 int[] retVal = (int[]) sendRequest(CMD_SET_ALLOWED_CARRIERS, carriers, subId,
4983 workSource);
Malcolm Chend965c8b2018-02-28 15:00:40 -08004984 return retVal[0];
4985 } finally {
4986 Binder.restoreCallingIdentity(identity);
4987 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07004988 }
4989
4990 /**
4991 * {@hide}
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004992 * Get the allowed carrier list for slotIndex.
Meng Wang1a7c35a2016-05-05 20:56:15 -07004993 * Require system privileges. In the future we may add this to carrier APIs.
4994 *
4995 * @return List of {@link android.service.telephony.CarrierIdentifier}; empty list
4996 * means all carriers are allowed.
4997 */
4998 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004999 public List<CarrierIdentifier> getAllowedCarriers(int slotIndex) {
Brad Ebinger4c460712018-10-01 10:40:55 -07005000 enforceReadPrivilegedPermission("getAllowedCarriers");
vagdevie435a3e2018-08-15 16:01:53 -07005001 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chend965c8b2018-02-28 15:00:40 -08005002
5003 final long identity = Binder.clearCallingIdentity();
5004 try {
5005 int subId = SubscriptionManager.getSubId(slotIndex)[0];
vagdevie435a3e2018-08-15 16:01:53 -07005006 return (List<CarrierIdentifier>) sendRequest(CMD_GET_ALLOWED_CARRIERS, null, subId,
5007 workSource);
Malcolm Chend965c8b2018-02-28 15:00:40 -08005008 } finally {
5009 Binder.restoreCallingIdentity(identity);
5010 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07005011 }
5012
fionaxu59545b42016-05-25 15:53:37 -07005013 /**
5014 * Action set from carrier signalling broadcast receivers to enable/disable metered apns
5015 * @param subId the subscription ID that this action applies to.
5016 * @param enabled control enable or disable metered apns.
5017 * {@hide}
5018 */
5019 @Override
5020 public void carrierActionSetMeteredApnsEnabled(int subId, boolean enabled) {
5021 enforceModifyPermission();
5022 final Phone phone = getPhone(subId);
Malcolm Chend965c8b2018-02-28 15:00:40 -08005023
5024 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07005025 if (phone == null) {
5026 loge("carrierAction: SetMeteredApnsEnabled fails with invalid subId: " + subId);
5027 return;
5028 }
5029 try {
5030 phone.carrierActionSetMeteredApnsEnabled(enabled);
5031 } catch (Exception e) {
5032 Log.e(LOG_TAG, "carrierAction: SetMeteredApnsEnabled fails. Exception ex=" + e);
Malcolm Chend965c8b2018-02-28 15:00:40 -08005033 } finally {
5034 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07005035 }
5036 }
5037
5038 /**
5039 * Action set from carrier signalling broadcast receivers to enable/disable radio
5040 * @param subId the subscription ID that this action applies to.
5041 * @param enabled control enable or disable radio.
5042 * {@hide}
5043 */
5044 @Override
5045 public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
5046 enforceModifyPermission();
5047 final Phone phone = getPhone(subId);
Malcolm Chend965c8b2018-02-28 15:00:40 -08005048
5049 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07005050 if (phone == null) {
5051 loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
5052 return;
5053 }
5054 try {
5055 phone.carrierActionSetRadioEnabled(enabled);
5056 } catch (Exception e) {
5057 Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
Malcolm Chend965c8b2018-02-28 15:00:40 -08005058 } finally {
5059 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07005060 }
5061 }
5062
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07005063 /**
fionaxu8da9cb12017-05-23 15:02:46 -07005064 * Action set from carrier signalling broadcast receivers to start/stop reporting the default
5065 * network status based on which carrier apps could apply actions accordingly,
5066 * enable/disable default url handler for example.
5067 *
5068 * @param subId the subscription ID that this action applies to.
5069 * @param report control start/stop reporting the default network status.
5070 * {@hide}
5071 */
5072 @Override
5073 public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
5074 enforceModifyPermission();
5075 final Phone phone = getPhone(subId);
Malcolm Chend965c8b2018-02-28 15:00:40 -08005076
5077 final long identity = Binder.clearCallingIdentity();
fionaxu8da9cb12017-05-23 15:02:46 -07005078 if (phone == null) {
5079 loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId);
5080 return;
5081 }
5082 try {
5083 phone.carrierActionReportDefaultNetworkStatus(report);
5084 } catch (Exception e) {
5085 Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e);
Malcolm Chend965c8b2018-02-28 15:00:40 -08005086 } finally {
5087 Binder.restoreCallingIdentity(identity);
fionaxu8da9cb12017-05-23 15:02:46 -07005088 }
5089 }
5090
5091 /**
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07005092 * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a
5093 * bug report is being generated.
5094 */
5095 @Override
Ta-wei Yen99282e02016-06-21 18:19:35 -07005096 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
dcashman22b950d2016-06-27 11:39:02 -07005097 if (mPhone.getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
5098 != PackageManager.PERMISSION_GRANTED) {
5099 writer.println("Permission Denial: can't dump Phone from pid="
5100 + Binder.getCallingPid()
5101 + ", uid=" + Binder.getCallingUid()
5102 + "without permission "
5103 + android.Manifest.permission.DUMP);
5104 return;
5105 }
Ta-wei Yen99282e02016-06-21 18:19:35 -07005106 DumpsysHandler.dump(mPhone.getContext(), fd, writer, args);
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07005107 }
Jack Yueb89b242016-06-22 13:27:47 -07005108
Brad Ebingerdac2f002018-04-03 15:17:52 -07005109 @Override
5110 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
5111 String[] args, ShellCallback callback, ResultReceiver resultReceiver)
5112 throws RemoteException {
5113 (new TelephonyShellCommand(this)).exec(this, in, out, err, args, callback, resultReceiver);
5114 }
5115
Jack Yueb89b242016-06-22 13:27:47 -07005116 /**
Jack Yu84291ec2017-05-26 16:07:50 -07005117 * Get aggregated video call data usage since boot.
5118 *
5119 * @param perUidStats True if requesting data usage per uid, otherwise overall usage.
5120 * @return Snapshot of video call data usage
Jack Yueb89b242016-06-22 13:27:47 -07005121 * {@hide}
5122 */
5123 @Override
Jack Yu84291ec2017-05-26 16:07:50 -07005124 public NetworkStats getVtDataUsage(int subId, boolean perUidStats) {
Jack Yueb89b242016-06-22 13:27:47 -07005125 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_NETWORK_USAGE_HISTORY,
5126 null);
5127
Malcolm Chend965c8b2018-02-28 15:00:40 -08005128 final long identity = Binder.clearCallingIdentity();
5129 try {
5130 // NetworkStatsService keeps tracking the active network interface and identity. It
5131 // records the delta with the corresponding network identity.
5132 // We just return the total video call data usage snapshot since boot.
5133 Phone phone = getPhone(subId);
5134 if (phone != null) {
5135 return phone.getVtDataUsage(perUidStats);
5136 }
5137 return null;
5138 } finally {
5139 Binder.restoreCallingIdentity(identity);
Jack Yueb89b242016-06-22 13:27:47 -07005140 }
Jack Yueb89b242016-06-22 13:27:47 -07005141 }
Jack Yu75ab2952016-07-08 14:29:33 -07005142
5143 /**
5144 * Policy control of data connection. Usually used when data limit is passed.
5145 * @param enabled True if enabling the data, otherwise disabling.
5146 * @param subId Subscription index
5147 * {@hide}
5148 */
5149 @Override
5150 public void setPolicyDataEnabled(boolean enabled, int subId) {
5151 enforceModifyPermission();
Malcolm Chend965c8b2018-02-28 15:00:40 -08005152
5153 final long identity = Binder.clearCallingIdentity();
5154 try {
5155 Phone phone = getPhone(subId);
5156 if (phone != null) {
5157 phone.setPolicyDataEnabled(enabled);
5158 }
5159 } finally {
5160 Binder.restoreCallingIdentity(identity);
Jack Yu75ab2952016-07-08 14:29:33 -07005161 }
5162 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07005163
5164 /**
5165 * Get Client request stats
5166 * @return List of Client Request Stats
5167 * @hide
5168 */
5169 @Override
5170 public List<ClientRequestStats> getClientRequestStats(String callingPackage, int subId) {
Jeff Davidson7e17e312018-02-13 18:17:36 -08005171 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidson913390f2018-02-23 17:11:49 -08005172 mApp, subId, callingPackage, "getClientRequestStats")) {
Sooraj Sasindran9a909312016-07-18 11:57:25 -07005173 return null;
5174 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07005175 Phone phone = getPhone(subId);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07005176
Malcolm Chend965c8b2018-02-28 15:00:40 -08005177 final long identity = Binder.clearCallingIdentity();
5178 try {
5179 if (phone != null) {
5180 return phone.getClientRequestStats();
5181 }
5182
5183 return null;
5184 } finally {
5185 Binder.restoreCallingIdentity(identity);
5186 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07005187 }
5188
Narayan Kamathf04b5a12018-01-09 11:47:15 +00005189 private WorkSource getWorkSource(int uid) {
Sooraj Sasindran9a909312016-07-18 11:57:25 -07005190 String packageName = mPhone.getContext().getPackageManager().getNameForUid(uid);
Narayan Kamathf04b5a12018-01-09 11:47:15 +00005191 return new WorkSource(uid, packageName);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07005192 }
Jack Yueb4124c2017-02-16 15:32:43 -08005193
5194 /**
Grace Chen70990072017-03-24 17:21:30 -07005195 * Set SIM card power state.
Jack Yueb4124c2017-02-16 15:32:43 -08005196 *
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005197 * @param slotIndex SIM slot id.
Grace Chen70990072017-03-24 17:21:30 -07005198 * @param state State of SIM (power down, power up, pass through)
5199 * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
5200 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
5201 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
Jack Yueb4124c2017-02-16 15:32:43 -08005202 *
5203 **/
5204 @Override
Grace Chen70990072017-03-24 17:21:30 -07005205 public void setSimPowerStateForSlot(int slotIndex, int state) {
Jack Yueb4124c2017-02-16 15:32:43 -08005206 enforceModifyPermission();
Sanket Padawe13bac7b2017-03-20 15:04:47 -07005207 Phone phone = PhoneFactory.getPhone(slotIndex);
5208
vagdevie435a3e2018-08-15 16:01:53 -07005209 WorkSource workSource = getWorkSource(Binder.getCallingUid());
5210
Malcolm Chend965c8b2018-02-28 15:00:40 -08005211 final long identity = Binder.clearCallingIdentity();
5212 try {
5213 if (phone != null) {
vagdevie435a3e2018-08-15 16:01:53 -07005214 phone.setSimPowerState(state, workSource);
Malcolm Chend965c8b2018-02-28 15:00:40 -08005215 }
5216 } finally {
5217 Binder.restoreCallingIdentity(identity);
Jack Yueb4124c2017-02-16 15:32:43 -08005218 }
5219 }
Shuo Qiandd210312017-04-12 22:11:33 +00005220
Tyler Gunn65d45c22017-06-05 11:22:26 -07005221 private boolean isUssdApiAllowed(int subId) {
5222 CarrierConfigManager configManager =
5223 (CarrierConfigManager) mPhone.getContext().getSystemService(
5224 Context.CARRIER_CONFIG_SERVICE);
5225 if (configManager == null) {
5226 return false;
5227 }
5228 PersistableBundle pb = configManager.getConfigForSubId(subId);
5229 if (pb == null) {
5230 return false;
5231 }
5232 return pb.getBoolean(
5233 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL);
5234 }
5235
Shuo Qiandd210312017-04-12 22:11:33 +00005236 /**
5237 * Check if phone is in emergency callback mode
5238 * @return true if phone is in emergency callback mode
5239 * @param subId sub id
5240 */
goneil9c5f4872017-12-05 14:07:56 -08005241 @Override
Shuo Qiandd210312017-04-12 22:11:33 +00005242 public boolean getEmergencyCallbackMode(int subId) {
Brad Ebinger4c460712018-10-01 10:40:55 -07005243 enforceReadPrivilegedPermission("getEmergencyCallbackMode");
Shuo Qiandd210312017-04-12 22:11:33 +00005244 final Phone phone = getPhone(subId);
Malcolm Chend965c8b2018-02-28 15:00:40 -08005245
5246 final long identity = Binder.clearCallingIdentity();
5247 try {
5248 if (phone != null) {
5249 return phone.isInEcm();
5250 } else {
5251 return false;
5252 }
5253 } finally {
5254 Binder.restoreCallingIdentity(identity);
Shuo Qiandd210312017-04-12 22:11:33 +00005255 }
5256 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08005257
5258 /**
5259 * Get the current signal strength information for the given subscription.
5260 * Because this information is not updated when the device is in a low power state
5261 * it should not be relied-upon to be current.
5262 * @param subId Subscription index
5263 * @return the most recent cached signal strength info from the modem
5264 */
5265 @Override
5266 public SignalStrength getSignalStrength(int subId) {
Malcolm Chend965c8b2018-02-28 15:00:40 -08005267 final long identity = Binder.clearCallingIdentity();
5268 try {
5269 Phone p = getPhone(subId);
5270 if (p == null) {
5271 return null;
5272 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08005273
Malcolm Chend965c8b2018-02-28 15:00:40 -08005274 return p.getSignalStrength();
5275 } finally {
5276 Binder.restoreCallingIdentity(identity);
5277 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08005278 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005279
Pengquan Meng9140aec2018-08-22 14:49:57 -07005280 /**
chen xu907e5a22018-10-11 13:21:04 -07005281 * Get the current modem radio state for the given slot.
5282 * @param slotIndex slot index.
5283 * @param callingPackage the name of the package making the call.
5284 * @return the current radio power state from the modem
5285 */
5286 @Override
5287 public int getRadioPowerState(int slotIndex, String callingPackage) {
5288 Phone phone = PhoneFactory.getPhone(slotIndex);
5289 if (phone != null) {
5290 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5291 mApp, phone.getSubId(), callingPackage, "getRadioPowerState")) {
5292 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
5293 }
5294
5295 final long identity = Binder.clearCallingIdentity();
5296 try {
5297 return phone.getRadioPowerState();
5298 } finally {
5299 Binder.restoreCallingIdentity(identity);
5300 }
5301 }
5302 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
5303 }
5304
5305 /**
Pengquan Meng9140aec2018-08-22 14:49:57 -07005306 * Checks if data roaming is enabled on the subscription with id {@code subId}.
5307 *
5308 * <p>Requires one of the following permissions:
5309 * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
5310 * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
5311 * privileges.
5312 *
5313 * @param subId subscription id
5314 * @return {@code true} if data roaming is enabled on this subscription, otherwise return
5315 * {@code false}.
5316 */
5317 @Override
5318 public boolean isDataRoamingEnabled(int subId) {
Pengquan Meng0c05b502018-09-06 09:59:22 -07005319 boolean isEnabled = false;
5320 final long identity = Binder.clearCallingIdentity();
Pengquan Meng9140aec2018-08-22 14:49:57 -07005321 try {
5322 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
Pengquan Meng0c05b502018-09-06 09:59:22 -07005323 null /* message */);
5324 Phone phone = getPhone(subId);
5325 isEnabled = phone != null ? phone.getDataRoamingEnabled() : false;
Pengquan Meng9140aec2018-08-22 14:49:57 -07005326 } catch (Exception e) {
5327 TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
5328 mApp, subId, "isDataRoamingEnabled");
Pengquan Meng0c05b502018-09-06 09:59:22 -07005329 } finally {
5330 Binder.restoreCallingIdentity(identity);
Pengquan Meng9140aec2018-08-22 14:49:57 -07005331 }
Pengquan Meng0c05b502018-09-06 09:59:22 -07005332 return isEnabled;
Pengquan Meng9140aec2018-08-22 14:49:57 -07005333 }
5334
5335
5336 /**
5337 * Enables/Disables the data roaming on the subscription with id {@code subId}.
5338 *
5339 * <p> Requires permission:
5340 * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier
5341 * privileges.
5342 *
5343 * @param subId subscription id
5344 * @param isEnabled {@code true} means enable, {@code false} means disable.
5345 */
5346 @Override
5347 public void setDataRoamingEnabled(int subId, boolean isEnabled) {
Pengquan Meng0c05b502018-09-06 09:59:22 -07005348 final long identity = Binder.clearCallingIdentity();
5349 try {
5350 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5351 mApp, subId, "setDataRoamingEnabled");
Pengquan Meng9140aec2018-08-22 14:49:57 -07005352
Pengquan Meng0c05b502018-09-06 09:59:22 -07005353 Phone phone = getPhone(subId);
5354 if (phone != null) {
5355 phone.setDataRoamingEnabled(isEnabled);
5356 }
5357 } finally {
5358 Binder.restoreCallingIdentity(identity);
Pengquan Meng9140aec2018-08-22 14:49:57 -07005359 }
5360 }
5361
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005362 @Override
Pengquan Meng312de0c2018-10-03 12:19:13 -07005363 public boolean isManualNetworkSelectionAllowed(int subId) {
5364 boolean isAllowed = true;
5365 final long identity = Binder.clearCallingIdentity();
5366 try {
5367 TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
5368 mApp, subId, "isManualNetworkSelectionAllowed");
5369 Phone phone = getPhone(subId);
5370 if (phone != null) {
5371 isAllowed = phone.isCspPlmnEnabled();
5372 }
5373 } finally {
5374 Binder.restoreCallingIdentity(identity);
5375 }
5376 return isAllowed;
5377 }
5378
5379 @Override
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005380 public UiccSlotInfo[] getUiccSlotsInfo() {
Brad Ebinger4c460712018-10-01 10:40:55 -07005381 enforceReadPrivilegedPermission("getUiccSlotsInfo");
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005382
Malcolm Chend965c8b2018-02-28 15:00:40 -08005383 final long identity = Binder.clearCallingIdentity();
5384 try {
5385 UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
5386 if (slots == null) {
5387 Rlog.i(LOG_TAG, "slots is null.");
5388 return null;
5389 }
5390
5391 UiccSlotInfo[] infos = new UiccSlotInfo[slots.length];
5392 for (int i = 0; i < slots.length; i++) {
5393 UiccSlot slot = slots[i];
5394 if (slot == null) {
5395 continue;
5396 }
5397
5398 String cardId;
5399 UiccCard card = slot.getUiccCard();
5400 if (card != null) {
5401 cardId = card.getCardId();
5402 } else {
5403 cardId = slot.getIccId();
5404 }
5405
5406 int cardState = 0;
5407 switch (slot.getCardState()) {
5408 case CARDSTATE_ABSENT:
5409 cardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
5410 break;
5411 case CARDSTATE_PRESENT:
5412 cardState = UiccSlotInfo.CARD_STATE_INFO_PRESENT;
5413 break;
5414 case CARDSTATE_ERROR:
5415 cardState = UiccSlotInfo.CARD_STATE_INFO_ERROR;
5416 break;
5417 case CARDSTATE_RESTRICTED:
5418 cardState = UiccSlotInfo.CARD_STATE_INFO_RESTRICTED;
5419 break;
5420 default:
5421 break;
5422
5423 }
5424
5425 infos[i] = new UiccSlotInfo(
5426 slot.isActive(),
5427 slot.isEuicc(),
5428 cardId,
5429 cardState,
5430 slot.getPhoneId(),
5431 slot.isExtendedApduSupported());
5432 }
5433 return infos;
5434 } finally {
5435 Binder.restoreCallingIdentity(identity);
Holly Jiuyu Sun1d957c52018-04-04 13:52:42 -07005436 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005437 }
5438
5439 @Override
5440 public boolean switchSlots(int[] physicalSlots) {
5441 enforceModifyPermission();
Malcolm Chend965c8b2018-02-28 15:00:40 -08005442
5443 final long identity = Binder.clearCallingIdentity();
5444 try {
5445 return (Boolean) sendRequest(CMD_SWITCH_SLOTS, physicalSlots);
5446 } finally {
5447 Binder.restoreCallingIdentity(identity);
5448 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005449 }
Jack Yu4c988042018-02-27 15:30:01 -08005450
5451 @Override
5452 public void setRadioIndicationUpdateMode(int subId, int filters, int mode) {
5453 enforceModifyPermission();
5454 final Phone phone = getPhone(subId);
5455 if (phone == null) {
5456 loge("setRadioIndicationUpdateMode fails with invalid subId: " + subId);
5457 return;
5458 }
5459
Malcolm Chend965c8b2018-02-28 15:00:40 -08005460 final long identity = Binder.clearCallingIdentity();
5461 try {
5462 phone.setRadioIndicationUpdateMode(filters, mode);
5463 } finally {
5464 Binder.restoreCallingIdentity(identity);
5465 }
Jack Yu4c988042018-02-27 15:30:01 -08005466 }
Pengquan Meng85728fb2018-03-12 16:31:21 -07005467
5468 /**
goneil47ffb6e2018-04-06 15:40:58 -07005469 * A test API to reload the UICC profile.
5470 *
5471 * <p>Requires that the calling app has permission
5472 * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
5473 * @hide
5474 */
5475 @Override
5476 public void refreshUiccProfile(int subId) {
5477 enforceModifyPermission();
5478
5479 final long identity = Binder.clearCallingIdentity();
5480 try {
5481 Phone phone = getPhone(subId);
5482 if (phone == null) {
5483 return;
5484 }
5485 UiccCard uiccCard = phone.getUiccCard();
5486 if (uiccCard == null) {
5487 return;
5488 }
5489 UiccProfile uiccProfile = uiccCard.getUiccProfile();
5490 if (uiccProfile == null) {
5491 return;
5492 }
5493 uiccProfile.refresh();
5494 } finally {
5495 Binder.restoreCallingIdentity(identity);
5496 }
5497 }
5498
5499 /**
Pengquan Meng85728fb2018-03-12 16:31:21 -07005500 * Returns false if the mobile data is disabled by default, otherwise return true.
5501 */
5502 private boolean getDefaultDataEnabled() {
5503 return "true".equalsIgnoreCase(
5504 SystemProperties.get(DEFAULT_MOBILE_DATA_PROPERTY_NAME, "true"));
5505 }
5506
5507 /**
5508 * Returns true if the data roaming is enabled by default, i.e the system property
5509 * of {@link #DEFAULT_DATA_ROAMING_PROPERTY_NAME} is true or the config of
5510 * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} is true.
5511 */
5512 private boolean getDefaultDataRoamingEnabled(int subId) {
5513 final CarrierConfigManager configMgr = (CarrierConfigManager)
5514 mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
5515 boolean isDataRoamingEnabled = "true".equalsIgnoreCase(
5516 SystemProperties.get(DEFAULT_DATA_ROAMING_PROPERTY_NAME, "false"));
5517 isDataRoamingEnabled |= configMgr.getConfigForSubId(subId).getBoolean(
5518 CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
5519 return isDataRoamingEnabled;
5520 }
5521
5522 /**
5523 * Returns the default network type for the given {@code subId}, if the default network type is
5524 * not set, return {@link Phone#PREFERRED_NT_MODE}.
5525 */
5526 private int getDefaultNetworkType(int subId) {
5527 return Integer.parseInt(
5528 TelephonyManager.getTelephonyProperty(
5529 mSubscriptionController.getPhoneId(subId),
5530 DEFAULT_NETWORK_MODE_PROPERTY_NAME,
5531 String.valueOf(Phone.PREFERRED_NT_MODE)));
5532 }
fionaxua13278b2018-03-21 00:08:13 -07005533
5534 @Override
5535 public void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String
5536 gid1, String gid2, String plmn, String spn) {
5537 enforceModifyPermission();
Malcolm Chend965c8b2018-02-28 15:00:40 -08005538
5539 final long identity = Binder.clearCallingIdentity();
5540 try {
5541 final Phone phone = getPhone(subId);
5542 if (phone == null) {
5543 loge("setCarrierTestOverride fails with invalid subId: " + subId);
5544 return;
5545 }
5546 phone.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, plmn, spn);
5547 } finally {
5548 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07005549 }
fionaxua13278b2018-03-21 00:08:13 -07005550 }
5551
5552 @Override
5553 public int getCarrierIdListVersion(int subId) {
Brad Ebinger4c460712018-10-01 10:40:55 -07005554 enforceReadPrivilegedPermission("getCarrierIdListVersion");
Malcolm Chend965c8b2018-02-28 15:00:40 -08005555
5556 final long identity = Binder.clearCallingIdentity();
5557 try {
5558 final Phone phone = getPhone(subId);
5559 if (phone == null) {
5560 loge("getCarrierIdListVersion fails with invalid subId: " + subId);
5561 return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
5562 }
5563 return phone.getCarrierIdListVersion();
5564 } finally {
5565 Binder.restoreCallingIdentity(identity);
fionaxua13278b2018-03-21 00:08:13 -07005566 }
fionaxua13278b2018-03-21 00:08:13 -07005567 }
Malcolm Chenf144d942018-08-14 16:00:53 -07005568
5569 @Override
5570 public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage) {
5571 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5572 mApp, subId, callingPackage, "getNumberOfModemsWithSimultaneousDataConnections")) {
5573 return -1;
5574 }
5575
5576 final long identity = Binder.clearCallingIdentity();
5577 try {
5578 return mPhoneConfigurationManager.getNumberOfModemsWithSimultaneousDataConnections();
5579 } finally {
5580 Binder.restoreCallingIdentity(identity);
5581 }
5582 }
Pengquan Meng0c05b502018-09-06 09:59:22 -07005583
5584 @Override
5585 public int getCdmaRoamingMode(int subId) {
5586 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5587 mApp, subId, "getCdmaRoamingMode");
5588
5589 final long identity = Binder.clearCallingIdentity();
5590 try {
5591 return (int) sendRequest(CMD_GET_CDMA_ROAMING_MODE, null /* argument */, subId);
5592 } finally {
5593 Binder.restoreCallingIdentity(identity);
5594 }
5595 }
5596
5597 @Override
5598 public boolean setCdmaRoamingMode(int subId, int mode) {
5599 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5600 mApp, subId, "setCdmaRoamingMode");
5601
5602 final long identity = Binder.clearCallingIdentity();
5603 try {
5604 return (boolean) sendRequest(CMD_SET_CDMA_ROAMING_MODE, mode, subId);
5605 } finally {
5606 Binder.restoreCallingIdentity(identity);
5607 }
5608 }
5609
5610 @Override
5611 public boolean setCdmaSubscriptionMode(int subId, int mode) {
5612 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5613 mApp, subId, "setCdmaSubscriptionMode");
5614
5615 final long identity = Binder.clearCallingIdentity();
5616 try {
5617 return (boolean) sendRequest(CMD_SET_CDMA_SUBSCRIPTION_MODE, mode, subId);
5618 } finally {
5619 Binder.restoreCallingIdentity(identity);
5620 }
5621 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005622}